llvm.org GIT mirror llvm / a921816
ThinLTO: Don't import aliases of any kind (even linkonce_odr) Summary: Until a more advanced version of importing can be implemented for aliases (one that imports an alias as an available_externally definition of the aliasee), skip the narrow subset of cases that was possible but came at a cost: aliases of linkonce_odr functions could be imported because the linkonce_odr function could be safely duplicated from the source module. This came/comes at the cost of not being able to 'home' imported linkonce functions (they had to be emitted linkonce_odr in all the destination modules (even if they weren't used by an alias) rather than as available_externally - causing extra object size). Tangentially, this also was the only reason ThinLTO would emit multiple CUs in to the resulting DWARF - which happens to be a problem for Fission (there's a fix for this in GDB but not released yet, etc). (actually it's not the only reason - but I'm sending a patch to fix the other reason shortly) There's no reason to believe this particularly narrow alias importing was especially/meaningfully important, only that it was /possible/ to implement in this way. When a more general solution is done, it should still satisfy the DWARF concerns above, since the import will still be available_externally, and thus not create extra CUs. Since now all aliases are treated the same, I removed/simplified some test cases since they were testing corner cases where there are no longer any corners. Reviewers: tejohnson, mehdi_amini Differential Revision: https://reviews.llvm.org/D35875 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@309278 91177308-0d34-0410-b5e6-96231b3b80d8 David Blaikie 2 years ago
6 changed file(s) with 35 addition(s) and 128 deletion(s). Raw diff Collapse all Expand all
131131 if (GlobalValue::isInterposableLinkage(GVSummary->linkage()))
132132 // There is no point in importing these, we can't inline them
133133 return false;
134 if (auto *AS = dyn_cast(GVSummary)) {
135 GVSummary = &AS->getAliasee();
136 // Alias can't point to "available_externally". However when we import
137 // linkOnceODR the linkage does not change. So we import the alias
138 // and aliasee only in this case.
134 if (auto *AS = dyn_cast(GVSummary))
135 // Aliases can't point to "available_externally".
139136 // FIXME: we should import alias as available_externally *function*,
140 // the destination module does need to know it is an alias.
141 if (!GlobalValue::isLinkOnceODRLinkage(GVSummary->linkage()))
142 return false;
143 }
137 // the destination module does not need to know it is an alias.
138 return false;
144139
145140 auto *Summary = cast(GVSummary);
146141
226221 DEBUG(dbgs() << "ignored! No qualifying callee with summary found.\n");
227222 continue;
228223 }
229 // "Resolve" the summary, traversing alias,
230 const FunctionSummary *ResolvedCalleeSummary;
231 if (isa(CalleeSummary)) {
232 ResolvedCalleeSummary = cast(
233 &cast(CalleeSummary)->getAliasee());
234 assert(
235 GlobalValue::isLinkOnceODRLinkage(ResolvedCalleeSummary->linkage()) &&
236 "Unexpected alias to a non-linkonceODR in import list");
237 } else
238 ResolvedCalleeSummary = cast(CalleeSummary);
224
225 // "Resolve" the summary
226 assert(!isa(CalleeSummary) &&
227 "Unexpected alias in import list");
228 const auto *ResolvedCalleeSummary = cast(CalleeSummary);
239229
240230 assert(ResolvedCalleeSummary->instCount() <= NewThreshold &&
241231 "selectCallee() didn't honor the threshold");
2222 bool FunctionImportGlobalProcessing::doImportAsDefinition(
2323 const GlobalValue *SGV, SetVector *GlobalsToImport) {
2424
25 // For alias, we tie the definition to the base object. Extract it and recurse
26 if (auto *GA = dyn_cast(SGV)) {
27 if (GA->isInterposable())
28 return false;
29 const GlobalObject *GO = GA->getBaseObject();
30 if (!GO->hasLinkOnceODRLinkage())
31 return false;
32 return FunctionImportGlobalProcessing::doImportAsDefinition(
33 GO, GlobalsToImport);
34 }
3525 // Only import the globals requested for importing.
3626 if (GlobalsToImport->count(const_cast(SGV)))
3727 return true;
28
29 assert(!isa(SGV) &&
30 "Unexpected global alias in the import list.");
31
3832 // Otherwise no.
3933 return false;
4034 }
131125 return SGV->getLinkage();
132126
133127 switch (SGV->getLinkage()) {
128 case GlobalValue::LinkOnceAnyLinkage:
129 case GlobalValue::LinkOnceODRLinkage:
134130 case GlobalValue::ExternalLinkage:
135 // External defnitions are converted to available_externally
131 // External and linkonce definitions are converted to available_externally
136132 // definitions upon import, so that they are available for inlining
137133 // and/or optimization, but are turned into declarations later
138134 // during the EliminateAvailableExternally pass.
147143 if (!doImportAsDefinition(SGV))
148144 return GlobalValue::ExternalLinkage;
149145 // An imported available_externally declaration stays that way.
150 return SGV->getLinkage();
151
152 case GlobalValue::LinkOnceAnyLinkage:
153 case GlobalValue::LinkOnceODRLinkage:
154 // These both stay the same when importing the definition.
155 // The ThinLTO pass will eventually force-import their definitions.
156146 return SGV->getLinkage();
157147
158148 case GlobalValue::WeakAnyLinkage:
5858 ; IMPORTGLOB4-DAG: define available_externally void @globalfunc1
5959 ; IMPORTGLOB4-DAG: declare void @weakalias
6060
61 ; An alias to an imported function is imported as alias if the function is not
62 ; available_externally.
61 ; An alias is never imported.
6362 ; RUN: llvm-link %t2.bc -summary-index=%t3.thinlto.bc -import=linkoncefunc:%t.bc -S | FileCheck %s --check-prefix=IMPORTGLOB5
64 ; IMPORTGLOB5-DAG: linkoncealias = alias void (...), bitcast (void ()* @linkoncefunc to void (...)*)
65 ; IMPORTGLOB5-DAG: define linkonce_odr void @linkoncefunc()
63 ; IMPORTGLOB5-NOT: @linkoncealias
64 ; IMPORTGLOB5-DAG: define available_externally void @linkoncefunc()
6665
6766 ; Ensure that imported static variable and function references are correctly
6867 ; promoted and renamed (including static constant variable).
11 ; RUN: opt -module-summary %p/Inputs/alias_import.ll -o %t2.bc
22 ; RUN: llvm-lto -thinlto-action=thinlink -o %t.index.bc %t1.bc %t2.bc
33 ; RUN: llvm-lto -thinlto-action=promote -thinlto-index %t.index.bc %t2.bc -o - | llvm-dis -o - | FileCheck %s --check-prefix=PROMOTE
4 ; RUN: llvm-lto -thinlto-action=promote -thinlto-index %t.index.bc %t2.bc -o - | llvm-lto -thinlto-action=internalize -thinlto-index %t.index.bc -thinlto-module-id=%t2.bc - -o - | llvm-dis -o - | FileCheck %s --check-prefix=PROMOTE-INTERNALIZE
54 ; RUN: llvm-lto -thinlto-action=import -thinlto-index %t.index.bc %t1.bc -o - | llvm-dis -o - | FileCheck %s --check-prefix=IMPORT
65
7 ;
8 ; Alias can't point to "available_externally", so we can only import an alias
9 ; when we can import the aliasee with a linkage that won't be
10 ; available_externally, i.e linkOnceODR. (FIXME this limitation could be lifted)
6 ; Alias can't point to "available_externally", so they cannot be imported for
7 ; now. This could be implemented by importing the alias as an
8 ; available_externally definition copied from the aliasee's body.
119 ; PROMOTE-DAG: @globalfuncAlias = alias void (...), bitcast (void ()* @globalfunc to void (...)*)
1210 ; PROMOTE-DAG: @globalfuncWeakAlias = weak alias void (...), bitcast (void ()* @globalfunc to void (...)*)
1311 ; PROMOTE-DAG: @globalfuncLinkonceAlias = weak alias void (...), bitcast (void ()* @globalfunc to void (...)*)
3331 ; PROMOTE-DAG: @weakODRfuncLinkonceAlias = weak alias void (...), bitcast (void ()* @weakODRfunc to void (...)*)
3432 ; PROMOTE-DAG: @weakODRfuncWeakODRAlias = weak_odr alias void (...), bitcast (void ()* @weakODRfunc to void (...)*)
3533 ; PROMOTE-DAG: @weakODRfuncLinkonceODRAlias = weak_odr alias void (...), bitcast (void ()* @weakODRfunc to void (...)*)
36
37 ; Only alias to LinkonceODR aliasee can be imported
3834 ; PROMOTE-DAG: @linkonceODRfuncAlias = alias void (...), bitcast (void ()* @linkonceODRfunc to void (...)*)
3935 ; PROMOTE-DAG: @linkonceODRfuncWeakAlias = weak alias void (...), bitcast (void ()* @linkonceODRfunc to void (...)*)
4036 ; PROMOTE-DAG: @linkonceODRfuncWeakODRAlias = weak_odr alias void (...), bitcast (void ()* @linkonceODRfunc to void (...)*)
41 ; Amongst these that are imported, check that we promote only linkonce->weak
4237 ; PROMOTE-DAG: @linkonceODRfuncLinkonceAlias = weak alias void (...), bitcast (void ()* @linkonceODRfunc to void (...)*)
4338 ; PROMOTE-DAG: @linkonceODRfuncLinkonceODRAlias = weak_odr alias void (...), bitcast (void ()* @linkonceODRfunc to void (...)*)
4439
45 ; These will be imported, check the linkage/renaming after promotion
4640 ; PROMOTE-DAG: define void @globalfunc()
4741 ; PROMOTE-DAG: define internal void @internalfunc()
4842 ; PROMOTE-DAG: define weak_odr void @linkonceODRfunc()
5044 ; PROMOTE-DAG: define weak void @linkoncefunc()
5145 ; PROMOTE-DAG: define weak void @weakfunc()
5246
53 ; On the import side now, verify that aliases to a linkonce_odr are imported, but the weak/linkonce (we can't inline them)
47 ; On the import side now, verify that aliases are not imported
5448 ; IMPORT-DAG: declare void @linkonceODRfuncWeakAlias
55 ; IMPORT-DAG: declare void @linkonceODRfuncLinkonceAlias
56 ; IMPORT-DAG: @linkonceODRfuncAlias = alias void (...), bitcast (void ()* @linkonceODRfunc to void (...)*)
57 ; IMPORT-DAG: @linkonceODRfuncWeakODRAlias = alias void (...), bitcast (void ()* @linkonceODRfunc to void (...)*)
58 ; IMPORT-DAG: @linkonceODRfuncLinkonceODRAlias = linkonce_odr alias void (...), bitcast (void ()* @linkonceODRfunc to void (...)*)
59 ; IMPORT-DAG: define linkonce_odr void @linkonceODRfunc()
49 ; IMPORT-DAG: declare void @linkonceODRfuncLinkonceAlias
50 ; IMPORT-DAG: declare void @linkonceODRfuncAlias
51 ; IMPORT-DAG: declare void @linkonceODRfuncWeakODRAlias
52 ; IMPORT-DAG: declare void @linkonceODRfuncLinkonceODRAlias
6053
6154
6255 ; On the import side, these aliases are not imported (they don't point to a linkonce_odr)
8578 ; IMPORT-DAG: declare void @weakfuncLinkonceAlias()
8679 ; IMPORT-DAG: declare void @weakfuncWeakODRAlias()
8780 ; IMPORT-DAG: declare void @weakfuncLinkonceODRAlias()
88
89 ; Promotion + internalization should internalize all of these, except for aliases of
90 ; linkonce_odr functions, because alias to linkonce_odr are the only aliases we will
91 ; import (see selectCallee() in FunctionImport.cpp).
92 ; PROMOTE-INTERNALIZE-DAG: @globalfuncAlias = internal alias void (...), bitcast (void ()* @globalfunc to void (...)*)
93 ; PROMOTE-INTERNALIZE-DAG: @globalfuncWeakAlias = internal alias void (...), bitcast (void ()* @globalfunc to void (...)*)
94 ; PROMOTE-INTERNALIZE-DAG: @globalfuncLinkonceAlias = internal alias void (...), bitcast (void ()* @globalfunc to void (...)*)
95 ; PROMOTE-INTERNALIZE-DAG: @globalfuncWeakODRAlias = internal alias void (...), bitcast (void ()* @globalfunc to void (...)*)
96 ; PROMOTE-INTERNALIZE-DAG: @globalfuncLinkonceODRAlias = internal alias void (...), bitcast (void ()* @globalfunc to void (...)*)
97 ; PROMOTE-INTERNALIZE-DAG: @internalfuncAlias = internal alias void (...), bitcast (void ()* @internalfunc to void (...)*)
98 ; PROMOTE-INTERNALIZE-DAG: @internalfuncWeakAlias = internal alias void (...), bitcast (void ()* @internalfunc to void (...)*)
99 ; PROMOTE-INTERNALIZE-DAG: @internalfuncLinkonceAlias = internal alias void (...), bitcast (void ()* @internalfunc to void (...)*)
100 ; PROMOTE-INTERNALIZE-DAG: @internalfuncWeakODRAlias = internal alias void (...), bitcast (void ()* @internalfunc to void (...)*)
101 ; PROMOTE-INTERNALIZE-DAG: @internalfuncLinkonceODRAlias = internal alias void (...), bitcast (void ()* @internalfunc to void (...)*)
102 ; PROMOTE-INTERNALIZE-DAG: @linkonceODRfuncAlias = alias void (...), bitcast (void ()* @linkonceODRfunc to void (...)*)
103 ; PROMOTE-INTERNALIZE-DAG: @linkonceODRfuncWeakAlias = internal alias void (...), bitcast (void ()* @linkonceODRfunc to void (...)*)
104 ; PROMOTE-INTERNALIZE-DAG: @linkonceODRfuncLinkonceAlias = internal alias void (...), bitcast (void ()* @linkonceODRfunc to void (...)*)
105 ; PROMOTE-INTERNALIZE-DAG: @linkonceODRfuncWeakODRAlias = weak_odr alias void (...), bitcast (void ()* @linkonceODRfunc to void (...)*)
106 ; PROMOTE-INTERNALIZE-DAG: @linkonceODRfuncLinkonceODRAlias = weak_odr alias void (...), bitcast (void ()* @linkonceODRfunc to void (...)*)
107 ; PROMOTE-INTERNALIZE-DAG: @weakODRfuncAlias = internal alias void (...), bitcast (void ()* @weakODRfunc to void (...)*)
108 ; PROMOTE-INTERNALIZE-DAG: @weakODRfuncWeakAlias = internal alias void (...), bitcast (void ()* @weakODRfunc to void (...)*)
109 ; PROMOTE-INTERNALIZE-DAG: @weakODRfuncLinkonceAlias = internal alias void (...), bitcast (void ()* @weakODRfunc to void (...)*)
110 ; PROMOTE-INTERNALIZE-DAG: @weakODRfuncWeakODRAlias = internal alias void (...), bitcast (void ()* @weakODRfunc to void (...)*)
111 ; PROMOTE-INTERNALIZE-DAG: @weakODRfuncLinkonceODRAlias = internal alias void (...), bitcast (void ()* @weakODRfunc to void (...)*)
112 ; PROMOTE-INTERNALIZE-DAG: @linkoncefuncAlias = internal alias void (...), bitcast (void ()* @linkoncefunc to void (...)*)
113 ; PROMOTE-INTERNALIZE-DAG: @linkoncefuncWeakAlias = internal alias void (...), bitcast (void ()* @linkoncefunc to void (...)*)
114 ; PROMOTE-INTERNALIZE-DAG: @linkoncefuncLinkonceAlias = internal alias void (...), bitcast (void ()* @linkoncefunc to void (...)*)
115 ; PROMOTE-INTERNALIZE-DAG: @linkoncefuncWeakODRAlias = internal alias void (...), bitcast (void ()* @linkoncefunc to void (...)*)
116 ; PROMOTE-INTERNALIZE-DAG: @linkoncefuncLinkonceODRAlias = internal alias void (...), bitcast (void ()* @linkoncefunc to void (...)*)
117 ; PROMOTE-INTERNALIZE-DAG: @weakfuncAlias = internal alias void (...), bitcast (void ()* @weakfunc to void (...)*)
118 ; PROMOTE-INTERNALIZE-DAG: @weakfuncWeakAlias = internal alias void (...), bitcast (void ()* @weakfunc to void (...)*)
119 ; PROMOTE-INTERNALIZE-DAG: @weakfuncLinkonceAlias = internal alias void (...), bitcast (void ()* @weakfunc to void (...)*)
120 ; PROMOTE-INTERNALIZE-DAG: @weakfuncWeakODRAlias = internal alias void (...), bitcast (void ()* @weakfunc to void (...)*)
121 ; PROMOTE-INTERNALIZE-DAG: @weakfuncLinkonceODRAlias = internal alias void (...), bitcast (void ()* @weakfunc to void (...)*)
122 ; PROMOTE-INTERNALIZE-DAG: define internal void @globalfunc()
123 ; PROMOTE-INTERNALIZE-DAG: define internal void @internalfunc()
124 ; PROMOTE-INTERNALIZE-DAG: define internal void @linkonceODRfunc()
125 ; PROMOTE-INTERNALIZE-DAG: define internal void @weakODRfunc()
126 ; PROMOTE-INTERNALIZE-DAG: define internal void @linkoncefunc()
127 ; PROMOTE-INTERNALIZE-DAG: define internal void @weakfunc()
81 ; IMPORT-DAG: declare void @linkonceODRfuncAlias()
82 ; IMPORT-DAG: declare void @linkonceODRfuncWeakAlias()
83 ; IMPORT-DAG: declare void @linkonceODRfuncWeakODRAlias()
84 ; IMPORT-DAG: declare void @linkonceODRfuncLinkonceAlias()
85 ; IMPORT-DAG: declare void @linkonceODRfuncLinkonceODRAlias()
12886
12987 define i32 @main() #0 {
13088 entry:
+0
-27
test/ThinLTO/X86/select_right_alias_definition.ll less more
None ; RUN: opt -module-summary %s -o %t_main.bc
1 ; RUN: opt -module-summary %p/Inputs/select_right_alias_definition1.ll -o %t1.bc
2 ; RUN: opt -module-summary %p/Inputs/select_right_alias_definition2.ll -o %t2.bc
3
4 ; Make sure that we always select the right definition for alia foo, whatever
5 ; order the files are linked in.
6
7 ; Try with one order
8 ; RUN: llvm-lto -thinlto-action=thinlink -o %t.index1.bc %t_main.bc %t1.bc %t2.bc
9 ; RUN: llvm-lto -thinlto-action=import -thinlto-index %t.index1.bc %t_main.bc -o - | llvm-dis -o - | FileCheck %s --check-prefix=IMPORT
10
11 ; Try with the other order (reversing %t1.bc and %t2.bc)
12 ; RUN: llvm-lto -thinlto-action=thinlink -o %t.index2.bc %t_main.bc %t2.bc %t1.bc
13 ; RUN: llvm-lto -thinlto-action=import -thinlto-index %t.index2.bc %t_main.bc -o - | llvm-dis -o - | FileCheck %s --check-prefix=IMPORT
14
15 ; IMPORT: @foo = alias i32 (...), bitcast (i32 ()* @foo2 to i32 (...)*)
16 ; IMPORT: define linkonce_odr i32 @foo2() {
17 ; IMPORT-NEXT: %ret = add i32 42, 42
18 ; IMPORT-NEXT: ret i32 %ret
19 ; IMPORT-NEXT: }
20
21 declare i32 @foo()
22
23 define i32 @main() {
24 %ret = call i32 @foo()
25 ret i32 %ret
26 }
3939 ; CHECK-DAG: declare void @analias
4040 declare void @analias(...) #1
4141
42 ; Aliases import the aliasee function
42 ; Aliases are not imported
4343 declare void @linkoncealias(...) #1
44 ; INSTLIMDEF-DAG: Import linkoncealias
45 ; INSTLIMDEF-DAG: Import linkoncefunc
46 ; CHECK-DAG: define linkonce_odr void @linkoncefunc()
47 ; CHECK-DAG: @linkoncealias = alias void (...), bitcast (void ()* @linkoncefunc to void (...)*
44 ; CHECK-DAG: declare void @linkoncealias(...)
4845
4946 ; INSTLIMDEF-DAG: Import referencestatics
5047 ; INSTLIMDEF-DAG: define available_externally i32 @referencestatics(i32 %i) !thinlto_src_module !0 {
107104 declare void @variadic(...)
108105
109106 ; INSTLIMDEF-DAG: Import globalfunc2
110 ; INSTLIMDEF-DAG: 13 function-import - Number of functions imported
107 ; INSTLIMDEF-DAG: 11 function-import - Number of functions imported
111108 ; CHECK-DAG: !0 = !{!"{{.*}}/Inputs/funcimport.ll"}
112109
113110 ; The actual GUID values will depend on path to test.