Index: include/llvm/LTO/legacy/LTOCodeGenerator.h =================================================================== --- include/llvm/LTO/legacy/LTOCodeGenerator.h +++ include/llvm/LTO/legacy/LTOCodeGenerator.h @@ -48,6 +48,9 @@ #include #include +/// Enable global value internalization in LTO. +extern llvm::cl::opt EnableLTOInternalization; + namespace llvm { template class ArrayRef; class LLVMContext; @@ -233,7 +236,7 @@ unsigned OptLevel = 2; lto_diagnostic_handler_t DiagHandler = nullptr; void *DiagContext = nullptr; - bool ShouldInternalize = true; + bool ShouldInternalize = EnableLTOInternalization; bool ShouldEmbedUselists = false; bool ShouldRestoreGlobalsLinkage = false; TargetMachine::CodeGenFileType FileType = TargetMachine::CGFT_ObjectFile; Index: lib/LTO/LTO.cpp =================================================================== --- lib/LTO/LTO.cpp +++ lib/LTO/LTO.cpp @@ -56,6 +56,11 @@ DumpThinCGSCCs("dump-thin-cg-sccs", cl::init(false), cl::Hidden, cl::desc("Dump the SCCs in the ThinLTO index's callgraph")); +/// Enable global value internalization in LTO. +cl::opt EnableLTOInternalization( + "enable-lto-internalization", cl::init(true), cl::Hidden, + cl::desc("Enable global value internalization in LTO")); + // Returns a unique hash for the Module considering the current list of // export/import and other global analysis results. // The hash is produced in \p Key. @@ -344,7 +349,8 @@ if (isExported(S->modulePath(), GUID)) { if (GlobalValue::isLocalLinkage(S->linkage())) S->setLinkage(GlobalValue::ExternalLinkage); - } else if (!GlobalValue::isLocalLinkage(S->linkage())) + } else if (EnableLTOInternalization && + !GlobalValue::isLocalLinkage(S->linkage())) S->setLinkage(GlobalValue::InternalLinkage); } } @@ -876,7 +882,7 @@ continue; GV->setUnnamedAddr(R.second.UnnamedAddr ? GlobalValue::UnnamedAddr::Global : GlobalValue::UnnamedAddr::None); - if (R.second.Partition == 0) + if (EnableLTOInternalization && R.second.Partition == 0) GV->setLinkage(GlobalValue::InternalLinkage); } Index: test/LTO/X86/internalize.ll =================================================================== --- /dev/null +++ test/LTO/X86/internalize.ll @@ -0,0 +1,41 @@ +; RUN: opt -module-summary %s -o %t1.bc + +; RUN: llvm-lto2 run %t1.bc -o %t.o -save-temps \ +; RUN: -r=%t1.bc,_foo,pxl \ +; RUN: -r=%t1.bc,_bar,pl +; RUN: llvm-dis < %t.o.0.2.internalize.bc | FileCheck %s --check-prefix=INTERNALIZE2 + +; Test the enable-lto-internalization option by setting it to false. +; enable-lto-internalization=false makes sure internalization does not happen in runRegularLTO(). +; RUN: llvm-lto2 run %t1.bc -o %t.o -save-temps -enable-lto-internalization=false \ +; RUN: -r=%t1.bc,_foo,pxl \ +; RUN: -r=%t1.bc,_bar,pl +; RUN: llvm-dis < %t.o.0.2.internalize.bc | FileCheck %s --check-prefix=INTERNALIZE2-OPTION-DISABLE + +; INTERNALIZE2: define dso_local void @foo +; INTERNALIZE2: define internal void @bar +; INTERNALIZE2-OPTION-DISABLE: define dso_local void @foo +; INTERNALIZE2-OPTION-DISABLE: define dso_local void @bar + +target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-apple-macosx10.11.0" + +define void @foo() { + call void @bar() + ret void +} +define void @bar() { + ret void +} + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!2, !3, !4, !5} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1) +!1 = !DIFile(filename: "t.cc", directory: "/tmp/t") +!2 = !{i32 2, !"Dwarf Version", i32 4} +!3 = !{i32 2, !"Debug Info Version", i32 3} +!4 = !{i32 1, !"wchar_size", i32 4} +!5 = !{i32 1, !"ThinLTO", i32 0} +!6 = distinct !DISubprogram(unit: !0) +!7 = !DILocalVariable(name: "get", scope: !6) Index: test/ThinLTO/X86/internalize.ll =================================================================== --- test/ThinLTO/X86/internalize.ll +++ test/ThinLTO/X86/internalize.ll @@ -3,12 +3,23 @@ ; RUN: llvm-lto -thinlto-action=internalize -thinlto-index %t.index.bc %t1.bc -o - | llvm-dis -o - | FileCheck %s --check-prefix=REGULAR ; RUN: llvm-lto -thinlto-action=internalize -thinlto-index %t.index.bc %t1.bc -o - --exported-symbol=foo | llvm-dis -o - | FileCheck %s --check-prefix=INTERNALIZE +; Test the enable-lto-internalization option by setting it to false. +; enable-lto-internalization makes sure indices are not marked as internallinkage and therefore internalization does not happen. +; RUN: llvm-lto -thinlto-action=internalize -thinlto-index %t.index.bc %t1.bc -enable-lto-internalization=false -o - --exported-symbol=foo | llvm-dis -o - | FileCheck %s --check-prefix=INTERNALIZE-OPTION-DISABLE + ; RUN: llvm-lto2 run %t1.bc -o %t.o -save-temps \ ; RUN: -r=%t1.bc,_foo,pxl \ ; RUN: -r=%t1.bc,_bar,pl \ ; RUN: -r=%t1.bc,_linkonce_func,pl ; RUN: llvm-dis < %t.o.1.2.internalize.bc | FileCheck %s --check-prefix=INTERNALIZE2 +; Test the enable-lto-internalization option by setting it to false. +; enable-lto-internalization makes sure indices are not marked as internallinkage and therefore internalization does not happen. +; RUN: llvm-lto2 run %t1.bc -o %t.o -save-temps -enable-lto-internalization=false \ +; RUN: -r=%t1.bc,_foo,pxl \ +; RUN: -r=%t1.bc,_bar,pl \ +; RUN: -r=%t1.bc,_linkonce_func,pl +; RUN: llvm-dis < %t.o.1.2.internalize.bc | FileCheck %s --check-prefix=INTERNALIZE2-OPTION-DISABLE ; REGULAR: define void @foo ; REGULAR: define void @bar @@ -16,9 +27,15 @@ ; INTERNALIZE: define void @foo ; INTERNALIZE: define internal void @bar ; INTERNALIZE: define internal void @linkonce_func() +; INTERNALIZE-OPTION-DISABLE: define void @foo +; INTERNALIZE-OPTION-DISABLE: define void @bar +; INTERNALIZE-OPTION-DISABLE: define linkonce void @linkonce_func() ; INTERNALIZE2: define dso_local void @foo ; INTERNALIZE2: define internal void @bar ; INTERNALIZE2: define internal void @linkonce_func() +; INTERNALIZE2-OPTION-DISABLE: define dso_local void @foo +; INTERNALIZE2-OPTION-DISABLE: define dso_local void @bar +; INTERNALIZE2-OPTION-DISABLE: define weak dso_local void @linkonce_func() target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-apple-macosx10.11.0"