[LLVMdev] [RFC] Linkage of user-supplied library functions in LTO

Nick Kledzik kledzik at apple.com
Sat Mar 8 16:03:30 PST 2014


On Mar 8, 2014, at 8:59 AM, Duncan P. N. Exon Smith wrote:

> +nick and rafael, who seem to a lot about linkage.
> 
> I made the following claim on llmv-commits [1]:
> 
> On 2014 Mar 3, at 15:01, Duncan P. N. Exon Smith <dexonsmith at apple.com> wrote:
> 
>> Giving these functions internal linkage allows them to be dead-stripped.
> 
> Is that even correct?
> 
> This is the assumption I’ve been working under, but I’m not sure where I
> got it from.  It seems like the linker is free to dead-strip symbols
> whether they’re internal or external.
The darwin linker does not care about internal vs external when doing
liveness analysis.  But, by default when dylibs (DSOs) are created,
all global symbols are marked live at the start of the analysis.  This
is not the case for main executables which just have main() and any 
initializers marked live initially.  




> 
> The current state of user-supplied library functions in LTO is that we
> internalize library functions, add them to llvm.compiler.used so that
> optimizations don’t modify them, and then optimizations incorrectly
> modify them.  LLVM *really* doesn't expect library functions to have
> local linkage.
> 
Since most code is dynamic that is probably why LLVM expects library
functions to not be local.

The case that revealed this bug was someone building a static binary.
Most code these days is dynamic, so libLTO will not see the implementation
of libcalls functions.  Whereas with static binaries, it will always see libcall
function implementations.  I don't know if supply that (static vs dynamic)
to libLTO would help.  


> And I’m not sure internal linkage is the right model anyway.
> 
> I see two paths forward:
> 
> 1. Add a new linkage type called “linker_internal”, which LLVM treats as
>    a type of non-local linkage, but gets emitted as internal.  This
>    might be worth it if linkers don’t dead strip external symbols.
> 
> 2. If linkers *do* dead strip external symbols, then we should not
>    internalize user-supplied library functions in -internalize.
> 
> Do linkers dead strip symbols with external linkage?  
This is probably the wrong question.  When linking main executables, the
linker can dead strip external functions.  But if LTO is used with a main
executable, the linker will not tell libLTO to preserve the global symbols,
so they will quickly be made internal.  

My question:  will libLTO ever dead strip a non-internal function?  If not,
is that one of the reasons the internalize pass tries to make functions 
internal?



> Any other reason to
> prefer one path over the other?  Is there another way?
>From the darwin linker's perspective, if libLTO does not dead strip
a libcall function implementation, that is OK.  The linker runs another 
liveness analysis pass after the libLTO result and any other mach-o f
files are merged. So any extra functions will still get deleted from the 
final output.

-Nick






More information about the llvm-dev mailing list