New GCC takes 19x as long to compile my program (compared to old GCC), plus void** patch suggestion

Elmar Krieger
Mon Aug 13 11:09:00 GMT 2012

Hi Richard,

many thanks for saving my time.

>> time gcc -m32 -g -O -fno-strict-aliasing -x c -Wall -Werror -c model.i
> That's within reasonable bounds as well, IMHO (you can't really compare
> -O1 from 3.2.3 with -O1 from 4.6.3).  One more data point (-O2 tends to
> be more focused on, no debuginfo generation turns off improvements
> and its costs there):
> /usr/bin/time /space/rguenther/install/gcc-3.2.3/bin/gcc -S -o
> /dev/null model.i -march=i386 -fno-strict-aliasing -w -O2
> 17.31user 0.43system 0:17.82elapsed 99%CPU (0avgtext+0avgdata
> 427392maxresident)k
> 72inputs+0outputs (2major+69895minor)pagefaults 0swaps
> /usr/bin/time gcc-4.6 -S -o /dev/null model.i -march=i386
> -fno-strict-aliasing  -m32 -w -O2
> 18.12user 0.21system 0:18.43elapsed 99%CPU (0avgtext+0avgdata
> 1752784maxresident)k
> 0inputs+0outputs (0major+124029minor)pagefaults 0swaps
> same time, I am surprised again ;) (with improvements in CPU speed the
> compilation
> with 4.6.3 is actually _faster_ comparing commodity platforms from the
> date of the compiler releases).

 > You might want to try -ftime-report, if it says you have extra 
checkings enabled
 > for one compiler but not the other that will explain the different 
outcome at
 > your side:

Good news, and especially the -ftime-report trick was highly useful.

For example, I got a huge slowdown also with this compiler:

gcc44 (GCC) 4.4.6 20110731 (Red Hat 4.4.6-3)
Copyright (C) 2010 Free Software Foundation, Inc.

which spends all its time in 'variable tracking':

variable tracking     : 126.07 (89%) usr   0.26 ( 7%) sys 126.50 (87%) 
wall   20647 kB ( 6%) ggc
  TOTAL                 : 141.94             3.66           145.61 
        336368 kB

real    2m26.703s

And the Google Android compiler I reported originally...

i686-linux-android-gcc (GCC) 4.6.x-google 20120106 (prerelease)
Copyright (C) 2011 Free Software Foundation, Inc.

...which takes more than twice as long spends its time here:

phase cgraph          : 347.75 (100%) usr  10.73 (76%) sys 358.51 (99%) 
wall  130837 kB (84%) ggc
phase generate        : 347.85 (100%) usr  10.77 (76%) sys 358.64 (99%) 
wall  132490 kB (85%) ggc
var-tracking dataflow : 284.34 (82%) usr   0.00 ( 0%) sys 284.21 (78%) 
wall       0 kB ( 0%) ggc
TOTAL                 : 350.04            12.53           362.60 
      155292 kB

real    6m3.567s

I really didn't expect that RedHat and Google both mess up GCC with 
their modifications, so I'll report it to them instead ;-)

Anyway, please send by private email your favorite way of receiving the 
promised 100 USD. Could be PayPal, a list of items which are 
sent to your address, a direct bank transfer etc..

Best regards,

>> If you don't find an enormous slowdown with the second command (please post
>> your timings) and conclude that this problem has been introduced by Google
>> in their custom GCC, I'll pay you 100 USD for the 5 minutes wasted.
> Extra diagnostic checks enabled; compiler may run slowly.
> Configure with --enable-checking=release to disable checks.
> Disclaimer: I had to delete an include statement on top of the file I sent you
> to make it compile.
> Richard.

>>> Aliasing issues arise when a function has two pointers, and determine
>>> whether an assignment to *p1 might change the value at *p2.  There are
>>> no aliasing issues with a void* pointer, because if p1 is void* then
>>> *p1 is invalid.  That is not true for a void** pointer, so aliasing
>>> issues do arise.  If p1 is void** and p2 is int**, then GCC will
>>> assume that an assignment to *p1 does not change the value at *p2, as
>>> the language standard states.  It's easy to imagine that that could
>>> break a program after inlining.
>> Many thanks for the clarification, and it also points to a simple solution:
>> GCC could simply permit to pass a pointer to any pointer to a function, if
>> the function argument is of type 'void **restrict myptr'.
>> If adding a 'restrict' to a function declaration was the only thing required
>> to get rid of countless nasty explicit type casts, the day would already be
>> saved. There really seem to be lots of problem classes that cannot be solved
>> with explicit type casts otherwise. The example for loading a binary file
>> from disk and allocating the required memory to store the file contents
>> being just one of them...
>> Best regards,
>> Elmar
>>> Just one more complicated example:
>>> A function that loads a binary file from disk and allocates the required
>>> memory to store the file contents, returning the number of bytes read.
>>> dstadd is the address where the newly allocated pointer is stored:
>>> int dsc_loadfilealloc(void *dstadd,char *filename)
>>> { int read,size;
>>>    FILE *fb;
>>>    if ((fb=fopen(filename,"rb")))
>>>    { size=dsc_filesize(filename);
>>>      *(void**)dstadd=mem_alloc(size);
>>>      read=dsc_readbytes(*(void**)dstadd,fb,size);
>>>      *(void**)dstadd=mem_realloc(*(void**)dstadd,read);
>>>      fclose(fb);
>>>      return(read); }
>>>    *(void**)dstadd=NULL;
>>>    return(0); }
>>> Again, nasty casts all over the place, which would all disappear if GCC
>>> allowed me to write
>>> int dsc_loadfilealloc(void **dstadd,char *filename)
>>> which could then be used to load anything from text files to an array of
>>> 'struct foo'.

More information about the Gcc mailing list