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 Amazon.com items which are sent to your address, a direct bank transfer etc..

Best regards,
Elmar

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'.



Reply via email to