[llvm-commits] [llvm] r154124 - /llvm/trunk/tools/lto/LTOCodeGenerator.cpp
Duncan Sands
baldrick at free.fr
Fri Apr 6 00:34:16 PDT 2012
Hi Bill,
> The internalize pass can be dangerous for LTO.
I'm kind of confused by your examples. In your first example
> Consider the following program:
>
> $ cat main.c
> void foo(void) { }
>
> int main(int argc, char *argv[]) {
> foo();
> return 0;
> }
> $ cat bundle.c
> extern void foo(void);
>
> void bar(void) {
> foo();
> }
> $ clang -o main main.c
> $ clang -o bundle.so bundle.c -bundle -bundle_loader ./main
> $ nm -m bundle.so
> 0000000000000f40 (__TEXT,__text) external _bar
> (undefined) external _foo (from executable)
> (undefined) external dyld_stub_binder (from libSystem)
> $ clang -o main main.c -O4
(^ If this is running internalize then that's a bug. But it doesn't, right?)
> $ clang -o bundle.so bundle.c -bundle -bundle_loader ./main
> Undefined symbols for architecture x86_64:
> "_foo", referenced from:
> _bar in bundle-elQN6d.o
> ld: symbol(s) not found for architecture x86_64
> clang: error: linker command failed with exit code 1 (use -v to see invocation)
This looks like a bug: the linker should observe that bundle uses the symbol foo
and that main provides the symbol foo, and pass "foo" to the internalize pass in
the list of external symbols. I think this is how the gold plugin does it. It's
not a reason to turn off internalize altogether. Hopefully Rafael can comment.
> The linker was told that the 'foo' in 'main' was 'internal' and had no uses, so
> it was dead stripped.
>
> Another situation is something like:
>
> define void @foo() {
> ret void
> }
>
> define void @bar() {
> call asm volatile "call _foo" ...
> ret void
> }
>
> The only use of 'foo' is inside of an inline ASM call. Since we don't look
> inside those for uses of functions, we don't specify this as a "use."
This is user error: the user should add a "used" attribute to foo. This isn't
anything new: lots of people make this mistake (it's come up again and again on
the mailing list and in bugzilla). The user should be educated here.
Ciao, Duncan.
>
> Get around this by not invoking the 'internalize' pass by default. This is an
> admitted hack for LTO correctness.
> <rdar://problem/11185386>
>
> Modified:
> llvm/trunk/tools/lto/LTOCodeGenerator.cpp
>
> Modified: llvm/trunk/tools/lto/LTOCodeGenerator.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lto/LTOCodeGenerator.cpp?rev=154124&r1=154123&r2=154124&view=diff
> ==============================================================================
> --- llvm/trunk/tools/lto/LTOCodeGenerator.cpp (original)
> +++ llvm/trunk/tools/lto/LTOCodeGenerator.cpp Thu Apr 5 16:26:44 2012
> @@ -46,10 +46,13 @@
> #include "llvm/ADT/StringExtras.h"
> using namespace llvm;
>
> -static cl::opt<bool> DisableInline("disable-inlining",
> +static cl::opt<bool> EnableInternalizing("enable-internalizing", cl::init(false),
> + cl::desc("Internalize functions during LTO"));
> +
> +static cl::opt<bool> DisableInline("disable-inlining", cl::init(false),
> cl::desc("Do not run the inliner pass"));
>
> -static cl::opt<bool> DisableGVNLoadPRE("disable-gvn-loadpre",
> +static cl::opt<bool> DisableGVNLoadPRE("disable-gvn-loadpre", cl::init(false),
> cl::desc("Do not run the GVN load PRE pass"));
>
> const char* LTOCodeGenerator::getVersionString() {
> @@ -275,6 +278,14 @@
> }
>
> void LTOCodeGenerator::applyScopeRestrictions() {
> + // Internalize only if specifically asked for. Otherwise, global symbols which
> + // exist in the final image, but which are used outside of that image
> + // (e.g. bundling) may be removed. This also happens when a function is used
> + // only in inline asm. LLVM doesn't recognize that as a "use", so it could be
> + // stripped.
> + if (!EnableInternalizing)
> + return;
> +
> if (_scopeRestrictionsDone) return;
> Module *mergedModule = _linker.getModule();
>
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list