llvm.org GIT mirror llvm / d7e41ba
[ThinLTO] Recommit of import global variables This wasreverted in r326638 due to link problems and fixed afterwards git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@327254 91177308-0d34-0410-b5e6-96231b3b80d8 Eugene Leviant 1 year, 6 months ago
8 changed file(s) with 171 addition(s) and 24 deletion(s). Raw diff Collapse all Expand all
10501050 ValueMap.MD()[CU->getRawEnumTypes()].reset(nullptr);
10511051 ValueMap.MD()[CU->getRawMacros()].reset(nullptr);
10521052 ValueMap.MD()[CU->getRawRetainedTypes()].reset(nullptr);
1053 // If we ever start importing global variable defs, we'll need to
1054 // add their DIGlobalVariable to the globals list on the imported
1055 // DICompileUnit. Confirm none are imported, and then we can
1056 // map the list of global variables to nullptr.
1057 assert(none_of(
1058 ValuesToLink,
1059 [](const GlobalValue *GV) { return isa(GV); }) &&
1060 "Unexpected importing of a GlobalVariable definition");
1053 // We import global variables only temporarily in order for instcombine
1054 // and globalopt to perform constant folding and static constructor
1055 // evaluation. After that elim-avail-extern will covert imported globals
1056 // back to declarations, so we don't need debug info for them.
10611057 ValueMap.MD()[CU->getRawGlobalVariables()].reset(nullptr);
10621058
10631059 // Imported entities only need to be mapped in if they have local
6060 #define DEBUG_TYPE "function-import"
6161
6262 STATISTIC(NumImportedFunctions, "Number of functions imported");
63 STATISTIC(NumImportedGlobalVars, "Number of global variables imported");
6364 STATISTIC(NumImportedModules, "Number of modules imported from");
6465 STATISTIC(NumDeadSymbols, "Number of dead stripped symbols in index");
6566 STATISTIC(NumLiveSymbols, "Number of live symbols in index");
237238 return Index.getValueInfo(GUID);
238239 }
239240
241 static void computeImportForReferencedGlobals(
242 const FunctionSummary &Summary, const GVSummaryMapTy &DefinedGVSummaries,
243 FunctionImporter::ImportMapTy &ImportList,
244 StringMap *ExportLists) {
245 for (auto &VI : Summary.refs()) {
246 if (DefinedGVSummaries.count(VI.getGUID())) {
247 DEBUG(dbgs() << "Ref ignored! Target already in destination module.\n");
248 continue;
249 }
250
251 DEBUG(dbgs() << " ref -> " << VI.getGUID() << "\n");
252
253 for (auto &RefSummary : VI.getSummaryList())
254 if (RefSummary->getSummaryKind() == GlobalValueSummary::GlobalVarKind &&
255 // Don't try to import regular LTO summaries added to dummy module.
256 !RefSummary->modulePath().empty() &&
257 !GlobalValue::isInterposableLinkage(RefSummary->linkage()) &&
258 RefSummary->refs().empty()) {
259 ImportList[RefSummary->modulePath()][VI.getGUID()] = 1;
260 if (ExportLists)
261 (*ExportLists)[RefSummary->modulePath()].insert(VI.getGUID());
262 break;
263 }
264 }
265 }
266
240267 /// Compute the list of functions to import for a given caller. Mark these
241268 /// imported functions and the symbols they reference in their source module as
242269 /// exported from their source module.
246273 SmallVectorImpl &Worklist,
247274 FunctionImporter::ImportMapTy &ImportList,
248275 StringMap *ExportLists = nullptr) {
276 computeImportForReferencedGlobals(Summary, DefinedGVSummaries, ImportList,
277 ExportLists);
249278 for (auto &Edge : Summary.calls()) {
250279 ValueInfo VI = Edge.first;
251280 DEBUG(dbgs() << " edge -> " << VI.getGUID() << " Threshold:" << Threshold
388417 }
389418 }
390419
420 #ifndef NDEBUG
421 static bool isGlobalVarSummary(const ModuleSummaryIndex &Index,
422 GlobalValue::GUID G) {
423 if (const auto &VI = Index.getValueInfo(G)) {
424 auto SL = VI.getSummaryList();
425 if (!SL.empty())
426 return SL[0]->getSummaryKind() == GlobalValueSummary::GlobalVarKind;
427 }
428 return false;
429 }
430
431 static GlobalValue::GUID getGUID(GlobalValue::GUID G) { return G; }
432
433 static GlobalValue::GUID
434 getGUID(const std::pair &P) {
435 return P.first;
436 }
437
438 template
439 unsigned numGlobalVarSummaries(const ModuleSummaryIndex &Index, T &Cont) {
440 unsigned NumGVS = 0;
441 for (auto &V : Cont)
442 if (isGlobalVarSummary(Index, getGUID(V)))
443 ++NumGVS;
444 return NumGVS;
445 }
446 #endif
447
391448 /// Compute all the import and export for every module using the Index.
392449 void llvm::ComputeCrossModuleImport(
393450 const ModuleSummaryIndex &Index,
425482 for (auto &ModuleImports : ImportLists) {
426483 auto ModName = ModuleImports.first();
427484 auto &Exports = ExportLists[ModName];
428 DEBUG(dbgs() << "* Module " << ModName << " exports " << Exports.size()
429 << " functions. Imports from " << ModuleImports.second.size()
430 << " modules.\n");
485 unsigned NumGVS = numGlobalVarSummaries(Index, Exports);
486 DEBUG(dbgs() << "* Module " << ModName << " exports "
487 << Exports.size() - NumGVS << " functions and " << NumGVS
488 << " vars. Imports from "
489 << ModuleImports.second.size() << " modules.\n");
431490 for (auto &Src : ModuleImports.second) {
432491 auto SrcModName = Src.first();
433 DEBUG(dbgs() << " - " << Src.second.size() << " functions imported from "
492 unsigned NumGVSPerMod = numGlobalVarSummaries(Index, Src.second);
493 DEBUG(dbgs() << " - " << Src.second.size() - NumGVSPerMod
494 << " functions imported from " << SrcModName << "\n");
495 DEBUG(dbgs() << " - " << NumGVSPerMod << " global vars imported from "
434496 << SrcModName << "\n");
435497 }
436498 }
438500 }
439501
440502 #ifndef NDEBUG
441 static void dumpImportListForModule(StringRef ModulePath,
503 static void dumpImportListForModule(const ModuleSummaryIndex &Index,
504 StringRef ModulePath,
442505 FunctionImporter::ImportMapTy &ImportList) {
443506 DEBUG(dbgs() << "* Module " << ModulePath << " imports from "
444507 << ImportList.size() << " modules.\n");
445508 for (auto &Src : ImportList) {
446509 auto SrcModName = Src.first();
447 DEBUG(dbgs() << " - " << Src.second.size() << " functions imported from "
510 unsigned NumGVSPerMod = numGlobalVarSummaries(Index, Src.second);
511 DEBUG(dbgs() << " - " << Src.second.size() - NumGVSPerMod
512 << " functions imported from " << SrcModName << "\n");
513 DEBUG(dbgs() << " - " << NumGVSPerMod << " vars imported from "
448514 << SrcModName << "\n");
449515 }
450516 }
464530 ComputeImportForModule(FunctionSummaryMap, Index, ImportList);
465531
466532 #ifndef NDEBUG
467 dumpImportListForModule(ModulePath, ImportList);
533 dumpImportListForModule(Index, ModulePath, ImportList);
468534 #endif
469535 }
470536
491557 ImportList[Summary->modulePath()][GUID] = 1;
492558 }
493559 #ifndef NDEBUG
494 dumpImportListForModule(ModulePath, ImportList);
560 dumpImportListForModule(Index, ModulePath, ImportList);
495561 #endif
496562 }
497563
769835 Module &DestModule, const FunctionImporter::ImportMapTy &ImportList) {
770836 DEBUG(dbgs() << "Starting import for Module "
771837 << DestModule.getModuleIdentifier() << "\n");
772 unsigned ImportedCount = 0;
838 unsigned ImportedCount = 0, ImportedGVCount = 0;
773839
774840 IRMover Mover(DestModule);
775841 // Do the actual import of functions now, one Module at a time
829895 if (Import) {
830896 if (Error Err = GV.materialize())
831897 return std::move(Err);
832 GlobalsToImport.insert(&GV);
898 ImportedGVCount += GlobalsToImport.insert(&GV);
833899 }
834900 }
835901 for (GlobalAlias &GA : SrcModule->aliases()) {
886952 NumImportedModules++;
887953 }
888954
889 NumImportedFunctions += ImportedCount;
890
891 DEBUG(dbgs() << "Imported " << ImportedCount << " functions for Module "
955 NumImportedFunctions += (ImportedCount - ImportedGVCount);
956 NumImportedGlobalVars += ImportedGVCount;
957
958 DEBUG(dbgs() << "Imported " << ImportedCount - ImportedGVCount
959 << " functions for Module " << DestModule.getModuleIdentifier()
960 << "\n");
961 DEBUG(dbgs() << "Imported " << ImportedGVCount
962 << " global variables for Module "
892963 << DestModule.getModuleIdentifier() << "\n");
893964 return ImportedCount;
894965 }
0 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
1 target triple = "x86_64-pc-linux-gnu"
2
3 @baz = local_unnamed_addr constant i32 10, align 4
0 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
1 target triple = "x86_64-pc-linux-gnu"
2
3 @baz = internal constant i32 10, align 4
4
5 define linkonce_odr i32 @foo() {
6 %1 = load i32, i32* @baz, align 4
7 ret i32 %1
8 }
0 ; RUN: opt -module-summary %s -o %t1.bc
1 ; RUN: opt -module-summary %p/Inputs/globals-import-cf-baz.ll -o %t2.bc
2 ; RUN: llvm-lto -thinlto-action=thinlink %t1.bc %t2.bc -o %t3.index.bc
3
4 ; RUN: llvm-lto -thinlto-action=import %t1.bc %t2.bc -thinlto-index=%t3.index.bc
5 ; RUN: llvm-dis %t1.bc.thinlto.imported.bc -o - | FileCheck --check-prefix=IMPORT %s
6 ; RUN: llvm-lto -thinlto-action=optimize %t1.bc.thinlto.imported.bc -o %t1.bc.thinlto.opt.bc
7 ; RUN: llvm-dis %t1.bc.thinlto.opt.bc -o - | FileCheck --check-prefix=OPTIMIZE %s
8
9 ; IMPORT: @baz = available_externally local_unnamed_addr constant i32 10
10
11 ; OPTIMIZE: define i32 @main()
12 ; OPTIMIZE-NEXT: ret i32 10
13
14 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
15 target triple = "x86_64-pc-linux-gnu"
16
17 @baz = external local_unnamed_addr constant i32, align 4
18
19 define i32 @main() local_unnamed_addr {
20 %1 = load i32, i32* @baz, align 4
21 ret i32 %1
22 }
0 ; Test to ensure that we import a single copy of a global variable. This is
1 ; important when we link in an object file twice, which is normally works when
2 ; all symbols have either weak or internal linkage. If we import an internal
3 ; global variable twice it will get promoted in each module, and given the same
4 ; name as the IR hash will be identical, resulting in multiple defs when linking.
5 ; RUN: opt -module-summary %s -o %t1.bc
6 ; RUN: opt -module-summary %p/Inputs/globals-import.ll -o %t2.bc
7 ; RUN: opt -module-summary %p/Inputs/globals-import.ll -o %t2b.bc
8 ; RUN: llvm-lto -thinlto-action=thinlink %t1.bc %t2.bc %t2b.bc -o %t3.index.bc
9
10 ; RUN: llvm-lto -thinlto-action=import %t1.bc -thinlto-index=%t3.index.bc
11 ; RUN: llvm-dis %t1.bc.thinlto.imported.bc -o - | FileCheck --check-prefix=IMPORT %s
12 ; RUN: llvm-lto -thinlto-action=promote %t2.bc -thinlto-index=%t3.index.bc
13 ; RUN: llvm-lto -thinlto-action=promote %t2b.bc -thinlto-index=%t3.index.bc
14 ; RUN: llvm-dis %t2.bc.thinlto.promoted.bc -o - | FileCheck --check-prefix=PROMOTE1 %s
15 ; RUN: llvm-dis %t2b.bc.thinlto.promoted.bc -o - | FileCheck --check-prefix=PROMOTE2 %s
16
17 ; IMPORT: @baz.llvm.0 = available_externally hidden constant i32 10, align 4
18
19 ; PROMOTE1: @baz.llvm.0 = hidden constant i32 10, align 4
20 ; PROMOTE1: define weak_odr i32 @foo() {
21
22 ; Second copy of IR object should not have any symbols imported/promoted.
23 ; PROMOTE2: @baz = internal constant i32 10, align 4
24 ; PROMOTE2: define available_externally i32 @foo() {
25
26 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
27 target triple = "x86_64-pc-linux-gnu"
28
29 declare i32 @foo()
30
31 define i32 @main() local_unnamed_addr {
32 %1 = call i32 @foo()
33 ret i32 %1
34 }
66 ; RUN: opt -function-import -stats -print-imports -enable-import-metadata -summary-file %t3.thinlto.bc %t.bc -S 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=INSTLIMDEF
77 ; Try again with new pass manager
88 ; RUN: opt -passes='function-import' -stats -print-imports -enable-import-metadata -summary-file %t3.thinlto.bc %t.bc -S 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=INSTLIMDEF
9 ; "-stats" requires +Asserts.
9 ; RUN: opt -passes='function-import' -debug-only=function-import -enable-import-metadata -summary-file %t3.thinlto.bc %t.bc -S 2>&1 | FileCheck %s --check-prefix=DUMP
10 ; "-stats" and "-debug-only" require +Asserts.
1011 ; REQUIRES: asserts
1112
1213 ; Test import with smaller instruction limit
7980
8081 ; Ensure that all uses of local variable @P which has used in setfuncptr
8182 ; and callfuncptr are to the same promoted/renamed global.
82 ; CHECK-DAG: @P.llvm.{{.*}} = external hidden global void ()*
83 ; CHECK-DAG: @P.llvm.{{.*}} = available_externally hidden global void ()* null
8384 ; CHECK-DAG: %0 = load void ()*, void ()** @P.llvm.
8485 ; CHECK-DAG: store void ()* @staticfunc2.llvm.{{.*}}, void ()** @P.llvm.
8586
106107
107108 ; INSTLIMDEF-DAG: Import globalfunc2
108109 ; INSTLIMDEF-DAG: 13 function-import - Number of functions imported
110 ; INSTLIMDEF-DAG: 4 function-import - Number of global variables imported
111
109112 ; CHECK-DAG: !0 = !{!"{{.*}}/Inputs/funcimport.ll"}
110113
111114 ; The actual GUID values will depend on path to test.
141144 ; GUID-DAG: GUID {{.*}} is linkoncealias
142145 ; GUID-DAG: GUID {{.*}} is callfuncptr
143146 ; GUID-DAG: GUID {{.*}} is linkoncefunc
147
148 ; DUMP: Module [[M1:.*]] imports from 1 module
149 ; DUMP-NEXT: 13 functions imported from [[M2:.*]]
150 ; DUMP-NEXT: 4 vars imported from [[M2]]
151 ; DUMP: Imported 13 functions for Module [[M1]]
152 ; DUMP-NEXT: Imported 4 global variables for Module [[M1]]
55
66 ; Test to make sure importing and dead stripping works in the
77 ; case where the target is a local function that also indirectly calls itself.
8 ; RUN: llvm-lto2 run -save-temps -o %t3 %t.bc %t2.bc -r %t.bc,fptr,plx -r %t.bc,main,plx -r %t2.bc,_Z6updatei,pl -r %t2.bc,fptr,l -print-imports 2>&1 | FileCheck %s --check-prefix=IMPORTS
8 ; RUN: llvm-lto2 run -thinlto-threads=1 -save-temps -o %t3 %t.bc %t2.bc -r %t.bc,fptr,plx -r %t.bc,main,plx -r %t2.bc,_Z6updatei,pl -r %t2.bc,fptr,l -print-imports 2>&1 | FileCheck %s --check-prefix=IMPORTS
99 ; Make sure we import the promted indirectly called target
1010 ; IMPORTS: Import _ZL3foov.llvm.0
1111