Some Haifa scheduler bugs

Craig Burley burley@gnu.ai.mit.edu
Thu Sep 4 09:33:00 GMT 1997


>Actually, we've come full circle over the years on this issue.
>
>First it was good, because "all the (unix) world was a pdp/vax" and you were
>allowed to do this on those systems.
>
>Then later as people decided depending on such behavior was a bad programming
>practice OS folks started forcing null pointer dereferences to cause faults
>and people fixed their code to avoid dereferencing null pointers.
>
>Now we have code which explicitly avoids dereferencing null pointers, but
>some OSs (hpux, aix, solaris?) have options to allow null pointer dereferences
>to allow the scheduler to perform more speculative code motions.

Good summary.

The way I look at it is, all things being equal, I'd prefer an OS
default to faulting on dereferecing NULL when running generic C code
simply because C code shouldn't be dereferencing NULL.  If it is,
maybe it'll be "lucky" and get the right values (behave the way it
happened to on the original developer's system) if the system allowed
it, or maybe it'll be "lucky" and never care, but it's too risky to
*assume* it'll be correct.  I'd rather have it crash and not be correct,
and make a specific decision to risk running it with such faulting
disabled, personally.

However, that view is basically orthagonal to whether an OS should
default to faulting for *generated* code that could run faster if
such faulting was disabled.  In this case, of course, good engineering
would mandate that the executable be marked with a flag saying "this
executable contains code that assumes dereferencing, but never using,
NULL is fast"; which in turn would suggest that objects be marked
that way and the linker cooperate accordingly; which the compiler
would in turn set when the appropriate optimizations were enabled or,
better yet, actually used; but, failing that, the usual black-box
approach we take to such thing should suffice.

Essentially this seems to me a lot like the issue of NaNs in code
using floating-point arithmetic on IEEE 754 machines.  Some people
want any generation of a NaN to immediately cause a fault, because
they want the potentially buggy code they're running to cause an
exception rather than silently produce wrong results.  OTOH, others
want NaN generation to silently and speedily continue, because
that's what makes sense for lots of code written (or compiled) to
the IEEE 754 model.

Unfortunately, we do seem to collectively refuse to provide, or use,
any kinds of clear markers in our code and utilities that explicitly
*mean* "This code should never generate NaNs" or "This code certainly
can generate NaNs and still be working well", so picking the right
defaults becomes a religious issue.

Someday I hope the free-software community will offer solutions to
this overall problem.  (Other things like tracking the licensing
requirements of compiled code through objects to executables and
libraries are part of it.)

In the meantime, I'd suggest using the approach of not defaulting
to *either* behavior, that is, leaving the default to be whatever
the target configuration wants, and maybe *that* could default to
not scheduling NULL dereferences.  Generally it is better to
default to not doing potentially hurtful optimizations, since users
who know they want optimizations know enough to specify them; but
it seems reasonable for a given target to specify that this kind
of optimization is actually not hurtful.

However, this might violate some other worthwhile principles in
general, or for egcs/gcc in particular.  For example, the documentation
would have to specify that the default depends on the target
system's configuration.

Note that the documentation should be *very* clear that, even if
this option is enabled, it does *not* guarantee that C (or Fortran
etc.) code can then be written that explicitly dereferences NULL.

That is, the issue of whether NULL-dereferencing is safe for
code *generation* should be kept very distinct from whether
NULL-dereferencing is needed by the code being compiled.  If
the latter seems like a useful thing to provide, that should
be a separate option (at the very least; in fact, it should be
a source-level language construct, per my comments above, but
that's probably beyond the scope of egcs at this point).

(Right now it might seem nonsensical for the user to specify
one option, or getting it as a default for a target, saying
"don't schedule NULL dereferences" and another saying "this
code assumes it can safely dereference NULL".  But these are
two different concepts, and, in the future, combining them might
actually produce a useful result, e.g. the compiler could
generate code to check all uncertain addresses before
dereferencing them.  In the meantime, a warning could be issued
if the combination isn't supported, something like what we do
for `-Wuninitialized -O0'.)

        tq vm, (burley)



More information about the Gcc mailing list