llvm.org GIT mirror llvm / 97d9903
The internalize pass can be dangerous for LTO. 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 $ 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) 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." Get around this by not invoking the 'internalize' pass by default. This is an admitted hack for LTO correctness. <rdar://problem/11185386> git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@154124 91177308-0d34-0410-b5e6-96231b3b80d8 Bill Wendling 7 years ago
1 changed file(s) with 13 addition(s) and 2 deletion(s). Raw diff Collapse all Expand all
4545 #include "llvm/ADT/StringExtras.h"
4646 using namespace llvm;
48 static cl::opt DisableInline("disable-inlining",
48 static cl::opt EnableInternalizing("enable-internalizing", cl::init(false),
49 cl::desc("Internalize functions during LTO"));
51 static cl::opt DisableInline("disable-inlining", cl::init(false),
4952 cl::desc("Do not run the inliner pass"));
51 static cl::opt DisableGVNLoadPRE("disable-gvn-loadpre",
54 static cl::opt DisableGVNLoadPRE("disable-gvn-loadpre", cl::init(false),
5255 cl::desc("Do not run the GVN load PRE pass"));
5457 const char* LTOCodeGenerator::getVersionString() {
274277 }
276279 void LTOCodeGenerator::applyScopeRestrictions() {
280 // Internalize only if specifically asked for. Otherwise, global symbols which
281 // exist in the final image, but which are used outside of that image
282 // (e.g. bundling) may be removed. This also happens when a function is used
283 // only in inline asm. LLVM doesn't recognize that as a "use", so it could be
284 // stripped.
285 if (!EnableInternalizing)
286 return;
277288 if (_scopeRestrictionsDone) return;
278289 Module *mergedModule = _linker.getModule();