This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Hi David, hi Andrew,

One other thing I just thought of: GCC has a history of very smart
extensions to C that allow to write faster and more elegant code. If I
look at my code, there are mostly two sources of 'dirty hacks' left. One
that could be fixed easily is the 'void** pointer problem', that
clutters my code with nasty explicit type casts:

A simple example is the function freesetnull, that frees a pointer and
sets it NULL (ptradd is a pointer address):

void freesetnull(void **ptradd)
{ free(*ptradd);
*ptradd=NULL; }


Normally, good style encourages using static inline functions instead of macros, but here I would go for a macro:

freesetnull(_p) do { free(_p); _p = NULL; } while (0)

Note the slight change in the semantics - you pass the pointer, not a
pointer to the pointer.

I expect this will also have the bonus of improving the speed of the
resulting program - and possibly even of the compilation.

Many thanks, but this was really just the most simple example to illustrate how GCC's prohibition to pass a 'pointer to any pointer' to a function expecting a void** causes more problems than it solves. In your case, you are forced to use a macro (with the usual side-effects problem) instead of a safe 'static inline' to circumvent the problem.


But my code is full of cases that go beyond what can reasonably be done with macros.

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

Regarding compile time, modern gcc has "-funit-at-a-time" and
"-ftop-level-reorder" enabled by default, even with no optimisation
enabled. These could take time on such a huge source code. Try compiling
with "-fno-unit-at-a-time" (which implies "-fno-toplevel-reorder").

Many thanks, tried that and the time at -O !increased! (I am writing this from a slower computer) from 6 minutes 38 to 7 minutes. BTW, the time with -O0 is just 17 seconds.


And to Andrew Haley:

>> To me, that just looks like a remnant from the ancient past that hinders
>> the future. On the other hand, my feeling tells me that this patch would
>> not be accepted, that's why I'm asking for my chances in advance ;-)
>
> Not at all high.  See Type-Based Alias Analysis
> <http://www.drdobbs.com/cpp/type-based-alias-analysis/184404273>
> for one reason.

Thanks, I read the article, but didn't really see how forbidding a function with argument void** to accept a pointer to any pointer helps with aliasing.

If it's perfectly normal that a function with argument void* accepts any pointer, then a function with argument void** should accept a pointer to any pointer by analogy, without having additional aliasing problems, no?

All the best,
Elmar

--
Elmar Krieger, PhD
YASARA Biosciences & CMBI Outstation Austria
Wagramer Strasse 25/3/45
1220 Vienna
Austria/Europe
www.YASARA.org


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]