llvm.org GIT mirror llvm / 38fd8b4
Revert "[ThinLTO] Add an auto-hide feature" This reverts commit r293970. After more discussion, this belongs to the linker side and there is no added value to do it at this level. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@293993 91177308-0d34-0410-b5e6-96231b3b80d8 Mehdi Amini 3 years ago
12 changed file(s) with 53 addition(s) and 128 deletion(s). Raw diff Collapse all Expand all
125125 /// llvm.global_ctors that the linker does not know about.
126126 unsigned LiveRoot : 1;
127127
128 /// Indicate if the global value should be hidden.
129 unsigned AutoHide : 1;
130
131128 /// Convenience Constructors
132129 explicit GVFlags(GlobalValue::LinkageTypes Linkage,
133 bool NotEligibleToImport, bool LiveRoot, bool AutoHide)
130 bool NotEligibleToImport, bool LiveRoot)
134131 : Linkage(Linkage), NotEligibleToImport(NotEligibleToImport),
135 LiveRoot(LiveRoot), AutoHide(AutoHide) {}
132 LiveRoot(LiveRoot) {}
136133 };
137134
138135 private:
199196 void setLinkage(GlobalValue::LinkageTypes Linkage) {
200197 Flags.Linkage = Linkage;
201198 }
202
203 /// Sets the visibility to be autohidden.
204 void setAutoHide() { Flags.AutoHide = true; }
205199
206200 /// Return true if this global value can't be imported.
207201 bool notEligibleToImport() const { return Flags.NotEligibleToImport; }
7878 auto &Elem = V[KeyInt];
7979 for (auto &FSum : FSums) {
8080 GlobalValueSummary::GVFlags GVFlags(GlobalValue::ExternalLinkage, false,
81 false, /* AutoHide */ false);
81 false);
8282 Elem.push_back(llvm::make_unique(
8383 GVFlags, 0, ArrayRef{},
8484 ArrayRef{}, std::move(FSum.TypeTests)));
5252 function_ref
5353 recordNewLinkage);
5454
55 /// This enum is used for the returned value of the callback passed to
56 /// thinLTOInternalizeAndPromoteInIndex, it indicates if a symbol can be made
57 /// Internal (only referenced from its defining object), Hidden (
58 /// outside the DSO), or Exported (exposed as public API for the DSO).
59 enum SummaryResolution { Internal, Hidden, Exported };
60
6155 /// Update the linkages in the given \p Index to mark exported values
6256 /// as external and non-exported values as internal. The ThinLTO backends
6357 /// must apply the changes to the Module via thinLTOInternalizeModule.
6458 void thinLTOInternalizeAndPromoteInIndex(
6559 ModuleSummaryIndex &Index,
66 function_ref<SummaryResolution(StringRef, GlobalValue::GUID)> isExported);
60 function_ref<bool(StringRef, GlobalValue::GUID)> isExported);
6761
6862 namespace lto {
6963
189189 // FIXME: refactor this to use the same code that inliner is using.
190190 F.isVarArg();
191191 GlobalValueSummary::GVFlags Flags(F.getLinkage(), NotEligibleForImport,
192 /* LiveRoot = */ false,
193 /* AutoHide */ false);
192 /* LiveRoot = */ false);
194193 auto FuncSummary = llvm::make_unique(
195194 Flags, NumInsts, RefEdges.takeVector(), CallGraphEdges.takeVector(),
196195 TypeTests.takeVector());
207206 findRefEdges(&V, RefEdges, Visited);
208207 bool NonRenamableLocal = isNonRenamableLocal(V);
209208 GlobalValueSummary::GVFlags Flags(V.getLinkage(), NonRenamableLocal,
210 /* LiveRoot = */ false,
211 /* AutoHide */ false);
209 /* LiveRoot = */ false);
212210 auto GVarSummary =
213211 llvm::make_unique(Flags, RefEdges.takeVector());
214212 if (NonRenamableLocal)
221219 DenseSet &CantBePromoted) {
222220 bool NonRenamableLocal = isNonRenamableLocal(A);
223221 GlobalValueSummary::GVFlags Flags(A.getLinkage(), NonRenamableLocal,
224 /* LiveRoot = */ false,
225 /* AutoHide */ false);
222 /* LiveRoot = */ false);
226223 auto AS = llvm::make_unique(Flags, ArrayRef{});
227224 auto *Aliasee = A.getBaseObject();
228225 auto *AliaseeSummary = Index.getGlobalValueSummary(*Aliasee);
341338 assert(GV->isDeclaration() && "Def in module asm already has definition");
342339 GlobalValueSummary::GVFlags GVFlags(GlobalValue::InternalLinkage,
343340 /* NotEligibleToImport */ true,
344 /* LiveRoot */ true,
345 /* AutoHide */ false);
341 /* LiveRoot */ true);
346342 CantBePromoted.insert(GlobalValue::getGUID(Name));
347343 // Create the appropriate summary type.
348344 if (isa(GV)) {
799799 // like getDecodedLinkage() above. Any future change to the linkage enum and
800800 // to getDecodedLinkage() will need to be taken into account here as above.
801801 auto Linkage = GlobalValue::LinkageTypes(RawFlags & 0xF); // 4 bits
802 bool NotEligibleToImport = ((RawFlags >> 4) & 0x1) || Version < 3;
802 RawFlags = RawFlags >> 4;
803 bool NotEligibleToImport = (RawFlags & 0x1) || Version < 3;
803804 // The LiveRoot flag wasn't introduced until version 3. For dead stripping
804805 // to work correctly on earlier versions, we must conservatively treat all
805806 // values as live.
806 bool LiveRoot = ((RawFlags >> 5) & 0x1) || Version < 3;
807 bool AutoHide = (RawFlags >> 6) & 0x1;
808 return GlobalValueSummary::GVFlags(Linkage, NotEligibleToImport, LiveRoot,
809 AutoHide);
807 bool LiveRoot = (RawFlags & 0x2) || Version < 3;
808 return GlobalValueSummary::GVFlags(Linkage, NotEligibleToImport, LiveRoot);
810809 }
811810
812811 static GlobalValue::VisibilityTypes getDecodedVisibility(unsigned Val) {
970970 static uint64_t getEncodedGVSummaryFlags(GlobalValueSummary::GVFlags Flags) {
971971 uint64_t RawFlags = 0;
972972
973 RawFlags |= Flags.NotEligibleToImport; // bool
974 RawFlags |= (Flags.LiveRoot << 1);
973975 // Linkage don't need to be remapped at that time for the summary. Any future
974976 // change to the getEncodedLinkage() function will need to be taken into
975977 // account here as well.
976 RawFlags |= Flags.Linkage; // 4 bits linkage
977 RawFlags |= (Flags.NotEligibleToImport << 4); // bool
978 RawFlags |= (Flags.LiveRoot << 5); // bool
979 RawFlags |= (Flags.AutoHide << 6); // bool
978 RawFlags = (RawFlags << 4) | Flags.Linkage; // 4 bits
979
980980 return RawFlags;
981981 }
982982
202202
203203 static void thinLTOInternalizeAndPromoteGUID(
204204 GlobalValueSummaryList &GVSummaryList, GlobalValue::GUID GUID,
205 function_ref<SummaryResolution(StringRef, GlobalValue::GUID)> isExported) {
205 function_ref<bool(StringRef, GlobalValue::GUID)> isExported) {
206206 for (auto &S : GVSummaryList) {
207 auto ExportResolution = isExported(S->modulePath(), GUID);
208 if (ExportResolution != Internal) {
207 if (isExported(S->modulePath(), GUID)) {
209208 if (GlobalValue::isLocalLinkage(S->linkage()))
210209 S->setLinkage(GlobalValue::ExternalLinkage);
211 if (ExportResolution == Hidden)
212 S->setAutoHide();
213210 } else if (!GlobalValue::isLocalLinkage(S->linkage()))
214211 S->setLinkage(GlobalValue::InternalLinkage);
215212 }
219216 // as external and non-exported values as internal.
220217 void llvm::thinLTOInternalizeAndPromoteInIndex(
221218 ModuleSummaryIndex &Index,
222 function_ref<SummaryResolution(StringRef, GlobalValue::GUID)> isExported) {
219 function_ref<bool(StringRef, GlobalValue::GUID)> isExported) {
223220 for (auto &I : Index)
224221 thinLTOInternalizeAndPromoteGUID(I.second, I.first, isExported);
225222 }
953950 const GlobalValueSummary *S) {
954951 return ThinLTO.PrevailingModuleForGUID[GUID] == S->modulePath();
955952 };
956 auto isExported = [&](StringRef ModuleIdentifier,
957 GlobalValue::GUID GUID) -> SummaryResolution {
953 auto isExported = [&](StringRef ModuleIdentifier, GlobalValue::GUID GUID) {
958954 const auto &ExportList = ExportLists.find(ModuleIdentifier);
959 if ((ExportList != ExportLists.end() && ExportList->second.count(GUID)) ||
960 ExportedGUIDs.count(GUID)) {
961 // We could do better by hiding when a symbol is in
962 // GUIDPreservedSymbols because it is only referenced from regular LTO
963 // or from native files and not outside the final binary, but that's
964 // something the native linker could do as gwell.
965 if (GUIDPreservedSymbols.count(GUID))
966 return Exported;
967 return Hidden;
968 }
969 return Internal;
955 return (ExportList != ExportLists.end() &&
956 ExportList->second.count(GUID)) ||
957 ExportedGUIDs.count(GUID);
970958 };
971959 thinLTOInternalizeAndPromoteInIndex(ThinLTO.CombinedIndex, isExported);
972960
233233
234234 // Convert the PreservedSymbols map from "Name" based to "GUID" based.
235235 static DenseSet
236 convertSymbolNamesToGUID(const StringSet<> &NamedSymbols,
237 const Triple &TheTriple) {
238 DenseSet GUIDSymbols(NamedSymbols.size());
239 for (auto &Entry : NamedSymbols) {
236 computeGUIDPreservedSymbols(const StringSet<> &PreservedSymbols,
237 const Triple &TheTriple) {
238 DenseSet GUIDPreservedSymbols(PreservedSymbols.size());
239 for (auto &Entry : PreservedSymbols) {
240240 StringRef Name = Entry.first();
241241 if (TheTriple.isOSBinFormatMachO() && Name.size() > 0 && Name[0] == '_')
242242 Name = Name.drop_front();
243 GUIDSymbols.insert(GlobalValue::getGUID(Name));
244 }
245 return GUIDSymbols;
243 GUIDPreservedSymbols.insert(GlobalValue::getGUID(Name));
244 }
245 return GUIDPreservedSymbols;
246246 }
247247
248248 std::unique_ptr codegenModule(Module &TheModule,
553553 }
554554
555555 void ThinLTOCodeGenerator::crossReferenceSymbol(StringRef Name) {
556 CrossReferencedSymbols.insert(Name);
556 // FIXME: At the moment, we don't take advantage of this extra information,
557 // we're conservatively considering cross-references as preserved.
558 // CrossReferencedSymbols.insert(Name);
559 PreservedSymbols.insert(Name);
557560 }
558561
559562 // TargetMachine factory
616619 Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
617620
618621 // Convert the preserved symbols set from string to GUID
619 auto GUIDPreservedSymbols = convertSymbolNamesToGUID(
622 auto GUIDPreservedSymbols = computeGUIDPreservedSymbols(
620623 PreservedSymbols, Triple(TheModule.getTargetTriple()));
621624
622625 // Compute "dead" symbols, we don't want to import/export these!
637640
638641 // Promote the exported values in the index, so that they are promoted
639642 // in the module.
640 auto isExported = [&](StringRef ModuleIdentifier,
641 GlobalValue::GUID GUID) -> SummaryResolution {
643 auto isExported = [&](StringRef ModuleIdentifier, GlobalValue::GUID GUID) {
642644 const auto &ExportList = ExportLists.find(ModuleIdentifier);
643 if ((ExportList != ExportLists.end() && ExportList->second.count(GUID)) ||
644 GUIDPreservedSymbols.count(GUID))
645 return Exported;
646 return Internal;
645 return (ExportList != ExportLists.end() &&
646 ExportList->second.count(GUID)) ||
647 GUIDPreservedSymbols.count(GUID);
647648 };
648649 thinLTOInternalizeAndPromoteInIndex(Index, isExported);
649650
663664 Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
664665
665666 // Convert the preserved symbols set from string to GUID
666 auto GUIDPreservedSymbols = convertSymbolNamesToGUID(
667 auto GUIDPreservedSymbols = computeGUIDPreservedSymbols(
667668 PreservedSymbols, Triple(TheModule.getTargetTriple()));
668669
669670 // Compute "dead" symbols, we don't want to import/export these!
737738
738739 // Convert the preserved symbols set from string to GUID
739740 auto GUIDPreservedSymbols =
740 convertSymbolNamesToGUID(PreservedSymbols, TMBuilder.TheTriple);
741 computeGUIDPreservedSymbols(PreservedSymbols, TMBuilder.TheTriple);
741742
742743 // Collect for each module the list of function it defines (GUID -> Summary).
743744 StringMap ModuleToDefinedGVSummaries(ModuleCount);
759760 return;
760761
761762 // Internalization
762 auto isExported = [&](StringRef ModuleIdentifier,
763 GlobalValue::GUID GUID) -> SummaryResolution {
763 auto isExported = [&](StringRef ModuleIdentifier, GlobalValue::GUID GUID) {
764764 const auto &ExportList = ExportLists.find(ModuleIdentifier);
765 if ((ExportList != ExportLists.end() && ExportList->second.count(GUID)) ||
766 GUIDPreservedSymbols.count(GUID))
767 return Exported;
768 return Internal;
765 return (ExportList != ExportLists.end() &&
766 ExportList->second.count(GUID)) ||
767 GUIDPreservedSymbols.count(GUID);
769768 };
770769 thinLTOInternalizeAndPromoteInIndex(Index, isExported);
771770 thinLTOInternalizeModule(TheModule,
894893 // Convert the preserved symbols set from string to GUID, this is needed for
895894 // computing the caching hash and the internalization.
896895 auto GUIDPreservedSymbols =
897 convertSymbolNamesToGUID(PreservedSymbols, TMBuilder.TheTriple);
898 auto GUIDCrossRefSymbols =
899 convertSymbolNamesToGUID(CrossReferencedSymbols, TMBuilder.TheTriple);
896 computeGUIDPreservedSymbols(PreservedSymbols, TMBuilder.TheTriple);
900897
901898 // Compute "dead" symbols, we don't want to import/export these!
902899 auto DeadSymbols = computeDeadSymbols(*Index, GUIDPreservedSymbols);
918915 // impacts the caching.
919916 resolveWeakForLinkerInIndex(*Index, ResolvedODR);
920917
921 auto isExported = [&](StringRef ModuleIdentifier,
922 GlobalValue::GUID GUID) -> SummaryResolution {
923 if (GUIDPreservedSymbols.count(GUID))
924 return Exported;
925 if (GUIDCrossRefSymbols.count(GUID))
926 return Hidden;
918 auto isExported = [&](StringRef ModuleIdentifier, GlobalValue::GUID GUID) {
927919 const auto &ExportList = ExportLists.find(ModuleIdentifier);
928 if (ExportList != ExportLists.end() && ExportList->second.count(GUID))
929 return Hidden;
930 return Internal;
920 return (ExportList != ExportLists.end() &&
921 ExportList->second.count(GUID)) ||
922 GUIDPreservedSymbols.count(GUID);
931923 };
932924
933925 // Use global summary-based analysis to identify symbols that can be
643643 return !GlobalValue::isLocalLinkage(Linkage);
644644 };
645645
646 // Try to auto-hide the symbols.
647 for (auto &GO : TheModule.global_objects()) {
648 const auto &GS = DefinedGlobals.find(GO.getGUID());
649 if (GS != DefinedGlobals.end() && GS->second->flags().AutoHide)
650 GO.setVisibility(GlobalValue::HiddenVisibility);
651 }
652
653646 // FIXME: See if we can just internalize directly here via linkage changes
654647 // based on the index, rather than invoking internalizeModule.
655648 llvm::internalizeModule(TheModule, MustPreserveGV);
+0
-6
test/ThinLTO/X86/Inputs/weak_autohide.ll less more
None target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
1 target triple = "x86_64-apple-macosx10.11.0"
2
3 define weak_odr void @weakodrfunc() {
4 ret void
5 }
22 ; RUN: llvm-lto -thinlto-action=thinlink -o %t.index.bc %t1.bc %t2.bc
33
44 ; RUN: llvm-lto -exported-symbol=_main -thinlto-action=promote %t1.bc -thinlto-index=%t.index.bc -o - | llvm-lto -exported-symbol=_main -thinlto-action=internalize -thinlto-index %t.index.bc -thinlto-module-id=%t1.bc - -o - | llvm-dis -o - | FileCheck %s
5 ; RUN: llvm-lto -exported-symbol=_main -thinlto-action=promote %t2.bc -thinlto-index=%t.index.bc -o - | llvm-lto -exported-symbol=_main -thinlto-action=internalize -thinlto-index %t.index.bc -thinlto-module-id=%t2.bc - -o - | llvm-dis -o - | FileCheck %s --check-prefix=CHECK2-LTO
5 ; RUN: llvm-lto -exported-symbol=_main -thinlto-action=promote %t2.bc -thinlto-index=%t.index.bc -o - | llvm-lto -exported-symbol=_main -thinlto-action=internalize -thinlto-index %t.index.bc -thinlto-module-id=%t2.bc - -o - | llvm-dis -o - | FileCheck %s --check-prefix=CHECK2
66
77 ; RUN: llvm-lto -exported-symbol=_main -thinlto-action=run %t1.bc %t2.bc
88 ; RUN: llvm-nm %t1.bc.thinlto.o | FileCheck %s --check-prefix=CHECK-NM
1818 ; RUN: -r %t2.bc,_dead_func,pl \
1919 ; RUN: -r %t2.bc,_another_dead_func,pl
2020 ; RUN: llvm-dis < %t.out.0.3.import.bc | FileCheck %s
21 ; RUN: llvm-dis < %t.out.1.3.import.bc | FileCheck %s --check-prefix=CHECK2-LTO2
21 ; RUN: llvm-dis < %t.out.1.3.import.bc | FileCheck %s --check-prefix=CHECK2
2222 ; RUN: llvm-nm %t.out.1 | FileCheck %s --check-prefix=CHECK2-NM
2323
2424 ; Dead-stripping on the index allows to internalize these,
3333
3434 ; Make sure we didn't internalize @boo, which is reachable via
3535 ; llvm.global_ctors
36 ; CHECK2-LTO: define void @boo()
37 ; CHECK2-LTO2: define hidden void @boo()
36 ; CHECK2: define void @boo()
3837 ; We should have eventually revoved @baz since it was internalized and unused
3938 ; CHECK2-NM-NOT: _baz
4039
+0
-24
test/ThinLTO/X86/weak_autohide.ll less more
None ; RUN: opt -module-summary %s -o %t1.bc
1 ; RUN: opt -module-summary %p/Inputs/weak_autohide.ll -o %t2.bc
2
3 ; RUN: llvm-lto2 %t1.bc %t2.bc -o %t.o -save-temps \
4 ; RUN: -r=%t1.bc,_strong_func,pxl \
5 ; RUN: -r=%t1.bc,_weakodrfunc,pl \
6 ; RUN: -r=%t2.bc,_weakodrfunc,l
7 ; RUN: llvm-dis < %t.o.0.2.internalize.bc | FileCheck %s --check-prefix=AUTOHIDE
8
9
10 ; AUTOHIDE: weak_odr hidden void @weakodrfunc
11
12 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
13 target triple = "x86_64-apple-macosx10.11.0"
14
15 define weak_odr void @weakodrfunc() #0 {
16 ret void
17 }
18
19 define void @strong_func() #0 {
20 call void @weakodrfunc()
21 ret void
22 }
23