Various patches against gmp-4.3.0

Peter Cordes peter at cordes.ca
Wed May 6 03:11:11 CEST 2009


On Mon, May 04, 2009 at 11:53:17AM +0200, Marc Glisse wrote:
> On Mon, 4 May 2009, Torbjorn Granlund wrote:
>
>>  For C, I just checked a bit what happens with a recent version of Sun
>>  Studio. I compiled several files that include the same header with a
>>  static inline function and all use it. I then used nm to look at the
>>  result. With optimization, the function disappears. Without
>>  optimization, I end up with 2 copies of the function (not exported).
>>
>> 2 copies in same object file?!?
>
> Only one in each .o file. But when I link several .o files together (in a 
> .so for instance), with static they remain distinct, and with extern they 
> get merged. It is not very surprising that static functions don't get  
> merged, gcc+binutiles don't merge them either. I think I heard that MSVC  
> does though, as long as the compiler generated the exact same code for  
> both (nice optimization).
>
> I am actually more surprised by extern inline, where depending on the  
> options gcc either generates no function or generates functions that 
> cause a multiple definition error at link time (where with sunpro the 
> multiple definitions get merged).
>
> Plain "inline" seems to be the sunpro (and C99) equivalent of the gcc  
> "extern inline attribute((gnu_inline))".
>
>> I'll use the following:
>>
>> /* Recent enough Sun C compilers accept "extern inline" */
>> #if defined (__SUNPRO_C) && __SUNPRO_C >= 0x560
>> #define __GMP_EXTERN_INLINE  extern inline
>> #endif
>>
>> /* Somewhat older Sun C compilers accept "static inline" */
>> #if defined (__SUNPRO_C) && __SUNPRO_C >= 0x540
>> #define __GMP_EXTERN_INLINE  static inline
>> #endif
>
> I guess you mean in the reverse order, or with a  
> !defined(__GMP_EXTERN_INLINE) :-)

static  means the declaration is only visible within the scope of the
translation unit (usually a single .c source file).  So the compiler
knows that if it did decide to inline the function everywhere it was
used, it doesn't have to generate a standalone callable version of it
that might be called e.g. by another source file that only had the
prototype, not the whole definition.  Similarly, if it's not called by
anything that includes the header, no object code is generated.

 If the compiler sometimes decides not to inline a function, then each
translation unit where that was the case will have its own copy of the
object code without global symbols.  (subject to clever linker
optimizations).

BTW, modern gcc tries to be too clever for its own good, and tries to
decide for itself whether to honour the inline keyword.  It can
sometimes make mistakes and generate a lot of code for a function that
would inline down to a couple instructions given that it's always
called with a compile time constant as one of its parameters.  Linux
(the kernel) works around this by using __attribute__((always_inline)).
see http://lkml.org/lkml/2008/11/14/203
http://lkml.org/lkml/2009/1/6/293.
I posted a followup to one of those threads, but it seems to have not
been accepted by the listserv, since it's not in the kernel archives...
summary: constant_test_bit should compile to a single inline
instruction, but gcc decided to make it a bulky standalone function. :(

 Anyway, if you have a way to make sure the compiler doesn't generate
multiple compies of object code for different translation units, then
great.  However, if it comes at the expense of having it always
generate one (uncalled because the function is always inlined), then
that's not optimal.  But probably not harmful.

-- 
#define X(x,y) x##y
Peter Cordes ;  e-mail: X(peter at cor , des.ca)

"The gods confound the man who first found out how to distinguish the hours!
 Confound him, too, who in this place set up a sundial, to cut and hack
 my day so wretchedly into small pieces!" -- Plautus, 200 BC


More information about the gmp-devel mailing list