[LLVMdev] [RFC] Linkage of user-supplied library functions in LTO
Duncan P. N. Exon Smith
dexonsmith at apple.com
Mon Mar 10 10:17:08 PDT 2014
On Mar 8, 2014, at 4:03 PM, Nick Kledzik <kledzik at apple.com> wrote:
> 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.
This is interesting. So the distinction does matter for shared objects,
but not for main executables. But LTO will be told to preserve all the
global symbols anyway for shared objects.
> 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.
That’s an idea, but I don’t think it’s necessary.
In static binaries, it’s important to optimize out unused user-supplied
library functions for size reasons. But the linker is going to do that
whether we make these functions local or global, so there’s no benefit
to internalizing them.
In dynamic binaries, users will link against a dynamic libc and are
unlikely to provide their own library function implementations. So
there’s no benefit to internalizing them here, either.
>> 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?
Exactly. libLTO will only dead strip functions with local linkage (such
as internal). During normal (non-LTO) optimizations, only functions with
local linkage are safe to remove. LTO runs -internalize before other
optimizations so that the rest of the optimizations don’t need to know
that anything is different.
(This is where I got the (apparently incorrect) idea that the linker
would only dead-strip internal functions.)
> 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.
Okay, great. I think then it’s safe to remove the @llvm.compiler.used
hack that I went with originally, and just leave them external.
More information about the llvm-dev
mailing list