Re: Specification issues

Norman Ramsey <[email protected]> Mon, 05 Sep 2005 17:48:48 -0400
Newsgroups gmane.comp.lang.c--
Message-ID <[email protected]>
Thanks for your kind words about the C-- specification.
I am trying to keep the specification relatively stable, 
which means I won't let people change it just when they think they
have a good idea.  But I am absolutely open to changing the
specification to fix bugs or to enable new uses.

Aside from a couple of nasty bits that I don't know how to solve, I
think that most of issues you raise can be dealt with in the framework
of the current specification.  On to the details!


 > + The specification hints that C-- is entitled to do certain
 >   optimizations, notably including CSE and presumably including
 >   strength reduction and code hoisting if serious loop optimization
 >   is contemplated.
 > 
 >   If so, it is a deficiency in the C-- design that the front end
 >   cannot prohibit rearrangement of computational flow. I'm thinking here
 >   about numerical analysis codes, where the front end has carefully
 >   preserved a user-provided statement of computation order, and the back
 >   end must not rearrange this inappropriately. Such instructions can
 >   be reordered, and existing computations can be reused, but the
 >   expression tree may not be computationally rearranged to expose
 >   opportunities for CSE (though in all cases I know of, arguments to
 >   +, -, and * can safely be swapped for purposes of CSE discovery).

I'm not quite sure what you're saying here.
If you are saying 'the C-- back end must not, for purposes of
optimization, assume that floating-point operations are associative', 
then we're in violent agreement :-)  Any "computational rearrangement"
performed by a C-- back end must preserve the semantics of the
program. 

 >   Perhaps the intention was to restrict such optimizations to address
 >   expressions. If so, then my concern is withdrawn but this needs to
 >   be stated more clearly.

If you can suggest a place in the specification for me to put this
information, I will do so.

 >   If it is indeed intended to allow the back end this latitude, then
 >   some mechanism to prevent mishandling is required.

My thinking is more that the back end should never have this latitude.
I know there are people out there who like this kind of behavior, and
maybe one day we will allow a front end to say 'I'm really keen to get
wrong answers fast; for purposes of optimization, please assume that
floating-point arithmetic behaves like real-number arithmetic.'  But
I'm not keen to add such a feature any time soon.

 > + In order for debugging and related information to be meaningful,
 >   the specification needs to be clear about the limits of code motion.
 >   I would suggest a block-structured barrier construct.
 >   Regardless of debugging, the specification needs to be clearer about
 >   the degree of code motion that the C-- back end is entitled to
 >   undertake.

This is a problem we have failed several times to solve.  We have
considered barrier constructs, but when we have tried to give them a
precise semantics, we have succeeded only in choosing between one of
two evils:
  * Essentially no code motion
  * All barrier constructs can be squeezed together and moved to 
    the code point of your choice
I have graduate students looking for PhD topics who ought to be aware
of this problem, but until we have some kind of reasonable solution, 
I'm reluctant to bake anything into the specification.

For now, you can assume that when execution is suspended at a call
site, it's the back end's job to make the world appear as it ought to
according to the source code.   Away from a call site, anything can
happen. 

Long term, I have fairly serious ambitions about stopping a program
anywhere and debugging in the presence of code motion---but this isn't
the place for the details.

 > + If loop optimizations are contemplated, then I question the
 >   wisdom of removing loop primitives from the language. Perhaps
 >   the state of the art has changed, but my experience was that
 >   loop rediscovery was painful, and that you really want to do
 >   this to guide the optimizer in attempting strength reduction,
 >   hoisting, and so forth.

We're drawing on the work of Jack Davidson, who has shown that it's
actually pretty easy to do loop optimization on very low-level
intermediate codes.  It's been years since I looked at the details,l
but if I remember correctly, given a control-flow graph it's fairly
straightforward to compute a dominator tree and then use it to
identify loops.  At present, our implementation has the dominator
tree, but we haven't actually written any interesting loop
optimizations.

 > + The current #line directive is horribly bad. We would have killed it
 >   at Bell Labs 20 years ago if we could have figured out how to do so
 >   compatibly. Don't replicate our error purely for the sake of
 >   verisimilitude. ADD A CHARACTER OFFSET! Allow -1 for "unspecified".

I take your point, but I'm reluctant.  That we support #line is
primarily a concession to people who are really, really keen to push
their C-- code through cpp.  C-- is intended to be generated by a
compiler, not to be preprocessed, and I'm reluctant to invest even
more effort in a strategy that I think is bad.

 > + A directive is needed to allow (line, offset, file) information
 >   to be associated with labels so that source locations of labels
 >   can be accurately represented.

That would be one of the many uses of the 'span' directive.  

 > + Since register selection is deferred to the C-- implementation,
 >   serious debugging support requires that the C-- compiler emit
 >   detailed location maps for variables, of the form:
 > 
 >     (PC start, PC end, variable, location)
 > 
 >   This can be represented compactly, but lesser information
 >   is insufficient for debugging in the face of code rearrangement.
 > 
 >   Such n-tuples should be present for all live addresses. The
 >   absence of a statement of location should be interpreted by
 >   the debugger as a statement that the variable is not live.
 > 
 >   Unfortunately, I see no way to emit this information from
 >   any place other than the back end.

You are exactly right, but the details are private to the
implementation of C--.  If your debugger wants access to register
variables, it must use the Cmm_FindLocalVar function.
This function does indeed look at 'PC maps' in much the spirit you
describe. 

 > + Floating point literals need to be fixed. Support for a 128 bit
 >   floating point representation should be supported, and support
 >   for rounding modes needs to be implemented. [Deferable]

I'm not aware of anything broken about floating-point literals.

If IEEE 754 defines a semantics for 128-bit literals, then the C--
specification incorporates that semantics by reference.  If not, who
defines the meaning of a 128-bit floating-point literal.

In the current implementation, owing to a bad decision made by a
person who shall remain nameless, there's no support for literals of
any kind wider than 64 bits.

Support for rounding modes is implemented (and tested!) in the current
compiler. 

 > + BitC would tremendously benefit from support for unicode literals.
 >   It would be entirely sufficient if we simply encoded them using
 >   octal escapes, but I suspect it is desirable to have distinguished
 >   character and string types for these. I don't see how to do this
 >   without taking a position on encoding. The right position is UTF-8,
 >   not the screwed up Java/C# double byte code point screwup -- but
 >   the mere fact that I need to say so serves to illustrate why this
 >   is a hairball.
 > 
 >   Perhaps it is simpler here, because the backend really doesn't
 >   need to understand the literal content. It might be sufficient
 >   for the front end to qualify the literal syntax for strings; the
 >   issue here is the need to know which NUL characters in the string
 >   are significant.

We lost a good 4 weeks in 2000 discussing proper C-- support for
Unicode.  And in the end, we couldn't figure out what we should do.
If my sysadmins can ever get the spam scrubbed out of the mailing-list
archives, you can see that traffic.

In the meantime, what I know is that nobody on the C-- team
understands Unicode.  If someone who does can make a proposal that I
can understand and can implement, we will run it by this list, and if
it doesn't go down in flames, we will adopt it and implement it.

 > + I suggest that all string literals be optionally length prefixed.
 >   Length in *bytes* is sufficient (and avoids unicode hassles). This is
 >   comparable to the .ASCII/.ASCIIZ distinction.

In C--, string literals are used in two contexts:

  * To communicate various machine-dependent bits and pieces, e.g.,
    the names of sections, foreign calling conventions, and parameter
    kinds.

  * To define values in initialized data.

Because it is already possible to put an explicit length in
initialized data, I'm puzzled as to why you want a length on string
literals.


I hope this information will help you decide if C-- might suit your
needs.