[RFC] Have assert macros

Nathan Sidwell nathan@codesourcery.com
Mon Aug 23 20:03:00 GMT 2004


Hi,
I did some measurements to determine how much leaving in our self checking
mechanism of the form
     if (expr)
       abort()
was costing us in compilation speed.  I built 4 --disable-checking
compilers, with the following tweaks
0) baseline
1) #define abort to no-op, thus allowing the optimizer can remove the
controlling expression
2) #define abort to no-op and g++'s my_friendly_assert to no-op
3) Leave abort alone, but #define my_friendly_assert to
    __builtin_constant_p (expr) && !expr ? abort() :  0
   thus removing the runtime-checked asserts but leaving in the compile
time checked asserts.

The results I got for cc1plus on an i686-pc-linux-gnu system were (for the
two sets of flags)
     -g -O0      -g -O2          textsize
#0   2.75      2.81            4,582,627
#1   2.79(+1.5%)  2.77(-1.5%)    4,488,595(-2.0%)
#2   2.74(-0.5%)  2.79(-0.8%)    4,468,467(-2.5%)
#3   2.71(-1.5%)  2.74(-2.5%)    4,565,603(-0.5%)

As you can see, all but unoptimzed #1 is an improvement. Why is that one
worse?  One thing noticable about #1 is that I had many 'foo might be used
uninitialized' warnings during bootstrap.  These all come from code like
     switch (expr)
     {
       case ...
      case ...
      default: abort ();
     }
Thus, turning abort into a nop, alters cfg, such that I suspect other
value propagation-like optimizations are disabled.

you'll notice that #3 gave a 1.5% speed improvement with a 0.5% code size
reduction.  #2 gives a 2.5% code size reduction, showing how much code
could potentially be removed. If the static code size is an indication
of potential speed savings, then perhaps up to 7.5% speed improvement
would be achievable by removing the correct set of aborts (). (I suspect
this is over optimistic, but maybe 5% is acheivable.)

Thus I propose adding two macros,
     gcc_assert (EXPR)
     gcc_unreachable ()

The former would be used (with suitable condition inverstion) in place of
     if (expr)
        abort ()
It would also replace the overly cute 'my_friendly_assert'. The latter
would be used in place of
     switch (expr) {
        default: abort ();
     }
and similar situations.  gcc_assert(0) would never be used for this
purpose.

In addition, an --enable-assert configure option would be added, that would
normally be enabled, but could be explicitly disabled to remove the
gcc_assert bodies.  (This might be spelt --enable-checking=assert.) What
the default release compiler does is undecided. Even if they were to be
left in, we could certainly employ __builtin_expect to tell the compiler
what we think will happen.

The assert macro would make some hypothetical __builtin_presume intrinsic
immediately useful.  Indeed, if such a builtin already existed, I beleive
the argument for gcc_assert would be much stronger.  However, one of the
two has to be done first, and I'd like it to be gcc_assert.

The danger of disabling these assertions is that we turn ICES into
wrong-code bugs.  How many assertions will catch bugs that, if uncaught,
do not turn into segmentation faults or other fatal errors?

Conversly, having a gcc_assert macro, might well encourage more self
checking use in development compilers, and thus flush out bugs more
quickly.  I know Mark and I have been fairly liberal with using
my_friendly_assert within the C++ front end -- their use has
caught many broken preconditions.  There are current uses of
#if ENABLE_CHECKING to control some simple aborts.  Implementing gcc_assert
could remove some (many? most?) of them

I recall some opposition of the syntax from a previous time this was raised
wrt my_friendly_assert.  Support for the
     if (expr)
       abort ();
syntax was voiced.  I am at a loss to understand that, finding
     gcc_assert (!expr);
to be much more understandable.  Certainly there are cases of
     if (expr1)
       ...
     else if (expr2)
       abort ()
     else if (expr3)
       ...
where a gcc_unreachable use might well make sense.

Opinions on this proposal?

nathan

-- 
Nathan Sidwell    ::   http://www.codesourcery.com   ::     CodeSourcery LLC
nathan@codesourcery.com    ::     http://www.planetfall.pwp.blueyonder.co.uk




More information about the Gcc mailing list