[llvm] r272239 - [ThinLTO/gold] Enable summary-based internalization
Teresa Johnson via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 8 18:14:14 PDT 2016
Author: tejohnson
Date: Wed Jun 8 20:14:13 2016
New Revision: 272239
URL: http://llvm.org/viewvc/llvm-project?rev=272239&view=rev
Log:
[ThinLTO/gold] Enable summary-based internalization
Summary: Enable existing summary-based importing support in the gold-plugin.
Reviewers: mehdi_amini
Subscribers: llvm-commits, mehdi_amini
Differential Revision: http://reviews.llvm.org/D21080
Added:
llvm/trunk/test/tools/gold/X86/Inputs/thinlto_alias.ll
llvm/trunk/test/tools/gold/X86/Inputs/thinlto_internalize.ll
llvm/trunk/test/tools/gold/X86/thinlto_alias.ll
llvm/trunk/test/tools/gold/X86/thinlto_internalize.ll
Modified:
llvm/trunk/lib/Transforms/IPO/FunctionImport.cpp
llvm/trunk/test/tools/gold/X86/thinlto_linkonceresolution.ll
llvm/trunk/tools/gold/gold-plugin.cpp
Modified: llvm/trunk/lib/Transforms/IPO/FunctionImport.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/FunctionImport.cpp?rev=272239&r1=272238&r2=272239&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/FunctionImport.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/FunctionImport.cpp Wed Jun 8 20:14:13 2016
@@ -525,8 +525,19 @@ void llvm::thinLTOInternalizeModule(Modu
OrigName, GlobalValue::InternalLinkage,
TheModule.getSourceFileName());
const auto &GS = DefinedGlobals.find(GlobalValue::getGUID(OrigId));
- assert(GS != DefinedGlobals.end());
- Linkage = GS->second->linkage();
+ if (GS == DefinedGlobals.end()) {
+ // Also check the original non-promoted non-globalized name. In some
+ // cases a preempted weak value is linked in as a local copy because
+ // it is referenced by an alias (IRLinker::linkGlobalValueProto).
+ // In that case, since it was originally not a local value, it was
+ // recorded in the index using the original name.
+ // FIXME: This may not be needed once PR27866 is fixed.
+ const auto &GS = DefinedGlobals.find(GlobalValue::getGUID(OrigName));
+ assert(GS != DefinedGlobals.end());
+ Linkage = GS->second->linkage();
+ } else {
+ Linkage = GS->second->linkage();
+ }
} else
Linkage = GS->second->linkage();
return !GlobalValue::isLocalLinkage(Linkage);
Added: llvm/trunk/test/tools/gold/X86/Inputs/thinlto_alias.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/gold/X86/Inputs/thinlto_alias.ll?rev=272239&view=auto
==============================================================================
--- llvm/trunk/test/tools/gold/X86/Inputs/thinlto_alias.ll (added)
+++ llvm/trunk/test/tools/gold/X86/Inputs/thinlto_alias.ll Wed Jun 8 20:14:13 2016
@@ -0,0 +1,4 @@
+define weak void @weakfunc() {
+entry:
+ ret void
+}
Added: llvm/trunk/test/tools/gold/X86/Inputs/thinlto_internalize.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/gold/X86/Inputs/thinlto_internalize.ll?rev=272239&view=auto
==============================================================================
--- llvm/trunk/test/tools/gold/X86/Inputs/thinlto_internalize.ll (added)
+++ llvm/trunk/test/tools/gold/X86/Inputs/thinlto_internalize.ll Wed Jun 8 20:14:13 2016
@@ -0,0 +1,6 @@
+target triple = "x86_64-unknown-linux-gnu"
+declare i32 @g()
+define i32 @main() {
+ call i32 @g()
+ ret i32 0
+}
Added: llvm/trunk/test/tools/gold/X86/thinlto_alias.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/gold/X86/thinlto_alias.ll?rev=272239&view=auto
==============================================================================
--- llvm/trunk/test/tools/gold/X86/thinlto_alias.ll (added)
+++ llvm/trunk/test/tools/gold/X86/thinlto_alias.ll Wed Jun 8 20:14:13 2016
@@ -0,0 +1,30 @@
+; RUN: opt -module-summary %s -o %t.o
+; RUN: opt -module-summary %p/Inputs/thinlto_alias.ll -o %t2.o
+
+; Ensure that a preempted weak symbol that is linked in as a local
+; copy is handled properly. Specifically, the local copy will be promoted,
+; and internalization should be able to use the original non-promoted
+; name to locate the summary (otherwise internalization will abort because
+; it expects to locate summaries for all definitions).
+; Note that gold picks the first copy of weakfunc() as the prevailing one,
+; so listing %t2.o first is sufficient to ensure that this copy is
+; preempted.
+; RUN: %gold -m elf_x86_64 -plugin %llvmshlibdir/LLVMgold.so \
+; RUN: --plugin-opt=thinlto \
+; RUN: --plugin-opt=save-temps \
+; RUN: -o %t3.o %t2.o %t.o
+; RUN: llvm-nm %t3.o | FileCheck %s
+; RUN: llvm-dis %t.o.opt.bc -o - | FileCheck --check-prefix=OPT %s
+; RUN: llvm-dis %t2.o.opt.bc -o - | FileCheck --check-prefix=OPT2 %s
+
+; CHECK-NOT: U f
+; OPT: define hidden void @weakfunc.llvm.0()
+; OPT2: define weak void @weakfunc()
+
+target triple = "x86_64-unknown-linux-gnu"
+
+ at weakfuncAlias = alias void (...), bitcast (void ()* @weakfunc to void (...)*)
+define weak void @weakfunc() {
+entry:
+ ret void
+}
Added: llvm/trunk/test/tools/gold/X86/thinlto_internalize.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/gold/X86/thinlto_internalize.ll?rev=272239&view=auto
==============================================================================
--- llvm/trunk/test/tools/gold/X86/thinlto_internalize.ll (added)
+++ llvm/trunk/test/tools/gold/X86/thinlto_internalize.ll Wed Jun 8 20:14:13 2016
@@ -0,0 +1,21 @@
+; RUN: opt -module-summary %s -o %t.o
+; RUN: opt -module-summary %p/Inputs/thinlto_internalize.ll -o %t2.o
+
+; RUN: %gold -m elf_x86_64 -plugin %llvmshlibdir/LLVMgold.so \
+; RUN: --plugin-opt=thinlto \
+; RUN: --plugin-opt=-import-instr-limit=0 \
+; RUN: --plugin-opt=save-temps \
+; RUN: -o %t3.o %t2.o %t.o
+; RUN: llvm-dis %t.o.opt.bc -o - | FileCheck %s
+
+; f() should be internalized and eliminated after inlining
+; CHECK-NOT: @f()
+
+target triple = "x86_64-unknown-linux-gnu"
+define i32 @g() {
+ call void @f()
+ ret i32 0
+}
+define void @f() {
+ ret void
+}
Modified: llvm/trunk/test/tools/gold/X86/thinlto_linkonceresolution.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/gold/X86/thinlto_linkonceresolution.ll?rev=272239&r1=272238&r2=272239&view=diff
==============================================================================
--- llvm/trunk/test/tools/gold/X86/thinlto_linkonceresolution.ll (original)
+++ llvm/trunk/test/tools/gold/X86/thinlto_linkonceresolution.ll Wed Jun 8 20:14:13 2016
@@ -11,6 +11,7 @@
; RUN: --plugin-opt=thinlto \
; RUN: --plugin-opt=-import-instr-limit=0 \
; RUN: --plugin-opt=save-temps \
+; RUN: -shared \
; RUN: -o %t3.o %t2.o %t.o
; RUN: llvm-nm %t3.o | FileCheck %s
; RUN: llvm-dis %t.o.opt.bc -o - | FileCheck --check-prefix=OPT %s
Modified: llvm/trunk/tools/gold/gold-plugin.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/gold/gold-plugin.cpp?rev=272239&r1=272238&r2=272239&view=diff
==============================================================================
--- llvm/trunk/tools/gold/gold-plugin.cpp (original)
+++ llvm/trunk/tools/gold/gold-plugin.cpp Wed Jun 8 20:14:13 2016
@@ -897,6 +897,9 @@ class CodeGen {
// Functions to import into this module.
FunctionImporter::ImportMapTy *ImportList;
+ // Map of globals defined in this module to their summary.
+ std::map<GlobalValue::GUID, GlobalValueSummary *> *DefinedGlobals;
+
public:
/// Constructor used by full LTO.
CodeGen(std::unique_ptr<llvm::Module> M)
@@ -908,10 +911,11 @@ public:
CodeGen(std::unique_ptr<llvm::Module> M, raw_fd_ostream *OS, int TaskID,
const ModuleSummaryIndex *CombinedIndex, std::string Filename,
StringMap<MemoryBufferRef> *ModuleMap,
- FunctionImporter::ImportMapTy *ImportList)
+ FunctionImporter::ImportMapTy *ImportList,
+ std::map<GlobalValue::GUID, GlobalValueSummary *> *DefinedGlobals)
: M(std::move(M)), OS(OS), TaskID(TaskID), CombinedIndex(CombinedIndex),
SaveTempsFilename(std::move(Filename)), ModuleMap(ModuleMap),
- ImportList(ImportList) {
+ ImportList(ImportList), DefinedGlobals(DefinedGlobals) {
assert(options::thinlto == !!CombinedIndex &&
"Expected module summary index iff performing ThinLTO");
initTargetMachine();
@@ -996,6 +1000,14 @@ void CodeGen::runLTOPasses() {
M->setDataLayout(TM->createDataLayout());
if (CombinedIndex) {
+ // Apply summary-based internalization decisions. Skip if there are no
+ // defined globals from the summary since not only is it unnecessary, but
+ // if this module did not have a summary section the internalizer will
+ // assert if it finds any definitions in this module that aren't in the
+ // DefinedGlobals set.
+ if (!DefinedGlobals->empty())
+ thinLTOInternalizeModule(*M, *DefinedGlobals);
+
// Create a loader that will parse the bitcode from the buffers
// in the ModuleMap.
ModuleLoader Loader(M->getContext(), *ModuleMap);
@@ -1137,7 +1149,7 @@ void CodeGen::runAll() {
static void linkInModule(LLVMContext &Context, IRMover &L, claimed_file &F,
const void *View, StringRef Name,
raw_fd_ostream *ApiFile, StringSet<> &Internalize,
- StringSet<> &Maybe) {
+ StringSet<> &Maybe, bool SetName = false) {
std::vector<GlobalValue *> Keep;
StringMap<unsigned> Realign;
std::unique_ptr<Module> M = getModuleForFile(
@@ -1150,6 +1162,12 @@ static void linkInModule(LLVMContext &Co
M->setTargetTriple(DefaultTriple);
}
+ // For ThinLTO we want to propagate the source file name to ensure
+ // we can create the correct global identifiers matching those in the
+ // original module.
+ if (SetName)
+ L.getModule().setSourceFileName(M->getSourceFileName());
+
if (Error E = L.move(std::move(M), Keep,
[](GlobalValue &, IRMover::ValueAdder) {})) {
handleAllErrors(std::move(E), [&](const llvm::ErrorInfoBase &EIB) {
@@ -1173,7 +1191,8 @@ static void thinLTOBackendTask(claimed_f
const ModuleSummaryIndex &CombinedIndex,
raw_fd_ostream *OS, unsigned TaskID,
StringMap<MemoryBufferRef> &ModuleMap,
- FunctionImporter::ImportMapTy &ImportList) {
+ FunctionImporter::ImportMapTy &ImportList,
+ std::map<GlobalValue::GUID, GlobalValueSummary *> &DefinedGlobals) {
// Need to use a separate context for each task
LLVMContext Context;
Context.setDiscardValueNames(options::TheOutputType !=
@@ -1185,12 +1204,12 @@ static void thinLTOBackendTask(claimed_f
IRMover L(*NewModule.get());
StringSet<> Dummy;
- linkInModule(Context, L, F, View, Name, ApiFile, Dummy, Dummy);
+ linkInModule(Context, L, F, View, Name, ApiFile, Dummy, Dummy, true);
if (renameModuleForThinLTO(*NewModule, CombinedIndex))
message(LDPL_FATAL, "Failed to rename module for ThinLTO");
CodeGen codeGen(std::move(NewModule), OS, TaskID, &CombinedIndex, Name,
- &ModuleMap, &ImportList);
+ &ModuleMap, &ImportList, &DefinedGlobals);
codeGen.runAll();
}
@@ -1199,7 +1218,9 @@ static void
thinLTOBackends(raw_fd_ostream *ApiFile,
const ModuleSummaryIndex &CombinedIndex,
StringMap<MemoryBufferRef> &ModuleMap,
- StringMap<FunctionImporter::ImportMapTy> &ImportLists) {
+ StringMap<FunctionImporter::ImportMapTy> &ImportLists,
+ StringMap<std::map<GlobalValue::GUID, GlobalValueSummary *>>
+ &ModuleToDefinedGVSummaries) {
unsigned TaskCount = 0;
std::vector<ThinLTOTaskInfo> Tasks;
Tasks.reserve(Modules.size());
@@ -1243,7 +1264,8 @@ thinLTOBackends(raw_fd_ostream *ApiFile,
ThinLTOThreadPool.async(thinLTOBackendTask, std::ref(F), View, F.name,
ApiFile, std::ref(CombinedIndex), OS.get(),
TaskCount, std::ref(ModuleMap),
- std::ref(ImportLists[F.name]));
+ std::ref(ImportLists[F.name]),
+ std::ref(ModuleToDefinedGVSummaries[F.name]));
// Record the information needed by the task or during its cleanup
// to a ThinLTOTaskInfo instance. For information needed by the task
@@ -1298,6 +1320,11 @@ static ld_plugin_status thinLTOLink(raw_
// interfaces with gold.
DenseMap<void *, std::unique_ptr<PluginInputFile>> HandleToInputFile;
+ // Keep track of internalization candidates as well as those that may not
+ // be internalized because they are refereneced from other IR modules.
+ DenseSet<GlobalValue::GUID> Internalize;
+ DenseSet<GlobalValue::GUID> CrossReferenced;
+
ModuleSummaryIndex CombinedIndex;
uint64_t NextModuleId = 0;
for (claimed_file &F : Modules) {
@@ -1321,11 +1348,23 @@ static ld_plugin_status thinLTOLink(raw_
// Skip files without a module summary.
if (Index)
CombinedIndex.mergeFrom(std::move(Index), ++NextModuleId);
+
+ // Look for internalization candidates based on gold's symbol resolution
+ // information. Also track symbols referenced from other IR modules.
+ for (auto &Sym : F.syms) {
+ ld_plugin_symbol_resolution Resolution =
+ (ld_plugin_symbol_resolution)Sym.resolution;
+ if (Resolution == LDPR_PREVAILING_DEF_IRONLY)
+ Internalize.insert(GlobalValue::getGUID(Sym.name));
+ if (Resolution == LDPR_RESOLVED_IR || Resolution == LDPR_PREEMPTED_IR)
+ CrossReferenced.insert(GlobalValue::getGUID(Sym.name));
+ }
}
- if (options::thinlto_emit_imports_files && !options::thinlto_index_only)
- message(LDPL_WARNING,
- "thinlto-emit-imports-files ignored unless thinlto-index-only");
+ // Remove symbols referenced from other IR modules from the internalization
+ // candidate set.
+ for (auto &S : CrossReferenced)
+ Internalize.erase(S);
// Collect for each module the list of function it defines (GUID ->
// Summary).
@@ -1338,6 +1377,25 @@ static ld_plugin_status thinLTOLink(raw_
ComputeCrossModuleImport(CombinedIndex, ModuleToDefinedGVSummaries,
ImportLists, ExportLists);
+ // Callback for internalization, to prevent internalization of symbols
+ // that were not candidates initially, and those that are being imported
+ // (which introduces new cross references).
+ auto isExported = [&](StringRef ModuleIdentifier, GlobalValue::GUID GUID) {
+ const auto &ExportList = ExportLists.find(ModuleIdentifier);
+ return (ExportList != ExportLists.end() &&
+ ExportList->second.count(GUID)) ||
+ !Internalize.count(GUID);
+ };
+
+ // Use global summary-based analysis to identify symbols that can be
+ // internalized (because they aren't exported or preserved as per callback).
+ // Changes are made in the index, consumed in the ThinLTO backends.
+ thinLTOInternalizeAndPromoteInIndex(CombinedIndex, isExported);
+
+ if (options::thinlto_emit_imports_files && !options::thinlto_index_only)
+ message(LDPL_WARNING,
+ "thinlto-emit-imports-files ignored unless thinlto-index-only");
+
if (options::thinlto_index_only) {
// If the thinlto-prefix-replace option was specified, parse it and
// extract the old and new prefixes.
@@ -1388,7 +1446,8 @@ static ld_plugin_status thinLTOLink(raw_
WriteIndexToFile(CombinedIndex, OS);
}
- thinLTOBackends(ApiFile, CombinedIndex, ModuleMap, ImportLists);
+ thinLTOBackends(ApiFile, CombinedIndex, ModuleMap, ImportLists,
+ ModuleToDefinedGVSummaries);
return LDPS_OK;
}
More information about the llvm-commits
mailing list