Skip to content

Commit b0a8ff7

Browse files
committedFeb 3, 2017
[ThinLTO] Add an auto-hide feature
When a symbol is not exported outside of the DSO, it is can be hidden. Usually we try to internalize as much as possible, but it is not always possible, for instance a symbol can be referenced outside of the LTO unit, or there can be cross-module reference in ThinLTO. This is a recommit of r293912 after fixing build failures, and a recommit of r293918 after fixing LLD tests. Differential Revision: https://reviews.llvm.org/D28978 llvm-svn: 293970
1 parent bbb2b95 commit b0a8ff7

File tree

13 files changed

+129
-54
lines changed

13 files changed

+129
-54
lines changed
 

‎lld/test/ELF/lto/thin-archivecollision.ll

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
; RUN: llvm-nm %t | FileCheck %s
1313

1414
; CHECK: T _start
15-
; CHECK: T blah
16-
; CHECK: T foo
15+
; CHECK: t blah
16+
; CHECK: t foo
1717

1818
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
1919
target triple = "x86_64-scei-ps4"

‎llvm/include/llvm/IR/ModuleSummaryIndex.h

+8-2
Original file line numberDiff line numberDiff line change
@@ -126,11 +126,14 @@ class GlobalValueSummary {
126126
/// llvm.global_ctors that the linker does not know about.
127127
unsigned LiveRoot : 1;
128128

129+
/// Indicate if the global value should be hidden.
130+
unsigned AutoHide : 1;
131+
129132
/// Convenience Constructors
130133
explicit GVFlags(GlobalValue::LinkageTypes Linkage,
131-
bool NotEligibleToImport, bool LiveRoot)
134+
bool NotEligibleToImport, bool LiveRoot, bool AutoHide)
132135
: Linkage(Linkage), NotEligibleToImport(NotEligibleToImport),
133-
LiveRoot(LiveRoot) {}
136+
LiveRoot(LiveRoot), AutoHide(AutoHide) {}
134137
};
135138

136139
private:
@@ -198,6 +201,9 @@ class GlobalValueSummary {
198201
Flags.Linkage = Linkage;
199202
}
200203

204+
/// Sets the visibility to be autohidden.
205+
void setAutoHide() { Flags.AutoHide = true; }
206+
201207
/// Return true if this global value can't be imported.
202208
bool notEligibleToImport() const { return Flags.NotEligibleToImport; }
203209

‎llvm/include/llvm/IR/ModuleSummaryIndexYAML.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ template <> struct CustomMappingTraits<GlobalValueSummaryMapTy> {
7979
auto &Elem = V[KeyInt];
8080
for (auto &FSum : FSums) {
8181
GlobalValueSummary::GVFlags GVFlags(GlobalValue::ExternalLinkage, false,
82-
false);
82+
false, /* AutoHide */ false);
8383
Elem.push_back(llvm::make_unique<FunctionSummary>(
8484
GVFlags, 0, ArrayRef<ValueInfo>{},
8585
ArrayRef<FunctionSummary::EdgeTy>{}, std::move(FSum.TypeTests)));

‎llvm/include/llvm/LTO/LTO.h

+7-1
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,18 @@ void thinLTOResolveWeakForLinkerInIndex(
5353
function_ref<void(StringRef, GlobalValue::GUID, GlobalValue::LinkageTypes)>
5454
recordNewLinkage);
5555

56+
/// This enum is used for the returned value of the callback passed to
57+
/// thinLTOInternalizeAndPromoteInIndex, it indicates if a symbol can be made
58+
/// Internal (only referenced from its defining object), Hidden (
59+
/// outside the DSO), or Exported (exposed as public API for the DSO).
60+
enum SummaryResolution { Internal, Hidden, Exported };
61+
5662
/// Update the linkages in the given \p Index to mark exported values
5763
/// as external and non-exported values as internal. The ThinLTO backends
5864
/// must apply the changes to the Module via thinLTOInternalizeModule.
5965
void thinLTOInternalizeAndPromoteInIndex(
6066
ModuleSummaryIndex &Index,
61-
function_ref<bool(StringRef, GlobalValue::GUID)> isExported);
67+
function_ref<SummaryResolution(StringRef, GlobalValue::GUID)> isExported);
6268

6369
namespace lto {
6470

‎llvm/lib/Analysis/ModuleSummaryAnalysis.cpp

+8-4
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,8 @@ computeFunctionSummary(ModuleSummaryIndex &Index, const Module &M,
190190
// FIXME: refactor this to use the same code that inliner is using.
191191
F.isVarArg();
192192
GlobalValueSummary::GVFlags Flags(F.getLinkage(), NotEligibleForImport,
193-
/* LiveRoot = */ false);
193+
/* LiveRoot = */ false,
194+
/* AutoHide */ false);
194195
auto FuncSummary = llvm::make_unique<FunctionSummary>(
195196
Flags, NumInsts, RefEdges.takeVector(), CallGraphEdges.takeVector(),
196197
TypeTests.takeVector());
@@ -207,7 +208,8 @@ computeVariableSummary(ModuleSummaryIndex &Index, const GlobalVariable &V,
207208
findRefEdges(&V, RefEdges, Visited);
208209
bool NonRenamableLocal = isNonRenamableLocal(V);
209210
GlobalValueSummary::GVFlags Flags(V.getLinkage(), NonRenamableLocal,
210-
/* LiveRoot = */ false);
211+
/* LiveRoot = */ false,
212+
/* AutoHide */ false);
211213
auto GVarSummary =
212214
llvm::make_unique<GlobalVarSummary>(Flags, RefEdges.takeVector());
213215
if (NonRenamableLocal)
@@ -220,7 +222,8 @@ computeAliasSummary(ModuleSummaryIndex &Index, const GlobalAlias &A,
220222
DenseSet<GlobalValue::GUID> &CantBePromoted) {
221223
bool NonRenamableLocal = isNonRenamableLocal(A);
222224
GlobalValueSummary::GVFlags Flags(A.getLinkage(), NonRenamableLocal,
223-
/* LiveRoot = */ false);
225+
/* LiveRoot = */ false,
226+
/* AutoHide */ false);
224227
auto AS = llvm::make_unique<AliasSummary>(Flags, ArrayRef<ValueInfo>{});
225228
auto *Aliasee = A.getBaseObject();
226229
auto *AliaseeSummary = Index.getGlobalValueSummary(*Aliasee);
@@ -339,7 +342,8 @@ ModuleSummaryIndex llvm::buildModuleSummaryIndex(
339342
assert(GV->isDeclaration() && "Def in module asm already has definition");
340343
GlobalValueSummary::GVFlags GVFlags(GlobalValue::InternalLinkage,
341344
/* NotEligibleToImport */ true,
342-
/* LiveRoot */ true);
345+
/* LiveRoot */ true,
346+
/* AutoHide */ false);
343347
CantBePromoted.insert(GlobalValue::getGUID(Name));
344348
// Create the appropriate summary type.
345349
if (isa<Function>(GV)) {

‎llvm/lib/Bitcode/Reader/BitcodeReader.cpp

+5-4
Original file line numberDiff line numberDiff line change
@@ -800,13 +800,14 @@ static GlobalValueSummary::GVFlags getDecodedGVSummaryFlags(uint64_t RawFlags,
800800
// like getDecodedLinkage() above. Any future change to the linkage enum and
801801
// to getDecodedLinkage() will need to be taken into account here as above.
802802
auto Linkage = GlobalValue::LinkageTypes(RawFlags & 0xF); // 4 bits
803-
RawFlags = RawFlags >> 4;
804-
bool NotEligibleToImport = (RawFlags & 0x1) || Version < 3;
803+
bool NotEligibleToImport = ((RawFlags >> 4) & 0x1) || Version < 3;
805804
// The LiveRoot flag wasn't introduced until version 3. For dead stripping
806805
// to work correctly on earlier versions, we must conservatively treat all
807806
// values as live.
808-
bool LiveRoot = (RawFlags & 0x2) || Version < 3;
809-
return GlobalValueSummary::GVFlags(Linkage, NotEligibleToImport, LiveRoot);
807+
bool LiveRoot = ((RawFlags >> 5) & 0x1) || Version < 3;
808+
bool AutoHide = (RawFlags >> 6) & 0x1;
809+
return GlobalValueSummary::GVFlags(Linkage, NotEligibleToImport, LiveRoot,
810+
AutoHide);
810811
}
811812

812813
static GlobalValue::VisibilityTypes getDecodedVisibility(unsigned Val) {

‎llvm/lib/Bitcode/Writer/BitcodeWriter.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -971,13 +971,13 @@ static unsigned getEncodedLinkage(const GlobalValue &GV) {
971971
static uint64_t getEncodedGVSummaryFlags(GlobalValueSummary::GVFlags Flags) {
972972
uint64_t RawFlags = 0;
973973

974-
RawFlags |= Flags.NotEligibleToImport; // bool
975-
RawFlags |= (Flags.LiveRoot << 1);
976974
// Linkage don't need to be remapped at that time for the summary. Any future
977975
// change to the getEncodedLinkage() function will need to be taken into
978976
// account here as well.
979-
RawFlags = (RawFlags << 4) | Flags.Linkage; // 4 bits
980-
977+
RawFlags |= Flags.Linkage; // 4 bits linkage
978+
RawFlags |= (Flags.NotEligibleToImport << 4); // bool
979+
RawFlags |= (Flags.LiveRoot << 5); // bool
980+
RawFlags |= (Flags.AutoHide << 6); // bool
981981
return RawFlags;
982982
}
983983

‎llvm/lib/LTO/LTO.cpp

+19-7
Original file line numberDiff line numberDiff line change
@@ -203,11 +203,14 @@ void llvm::thinLTOResolveWeakForLinkerInIndex(
203203

204204
static void thinLTOInternalizeAndPromoteGUID(
205205
GlobalValueSummaryList &GVSummaryList, GlobalValue::GUID GUID,
206-
function_ref<bool(StringRef, GlobalValue::GUID)> isExported) {
206+
function_ref<SummaryResolution(StringRef, GlobalValue::GUID)> isExported) {
207207
for (auto &S : GVSummaryList) {
208-
if (isExported(S->modulePath(), GUID)) {
208+
auto ExportResolution = isExported(S->modulePath(), GUID);
209+
if (ExportResolution != Internal) {
209210
if (GlobalValue::isLocalLinkage(S->linkage()))
210211
S->setLinkage(GlobalValue::ExternalLinkage);
212+
if (ExportResolution == Hidden)
213+
S->setAutoHide();
211214
} else if (!GlobalValue::isLocalLinkage(S->linkage()))
212215
S->setLinkage(GlobalValue::InternalLinkage);
213216
}
@@ -217,7 +220,7 @@ static void thinLTOInternalizeAndPromoteGUID(
217220
// as external and non-exported values as internal.
218221
void llvm::thinLTOInternalizeAndPromoteInIndex(
219222
ModuleSummaryIndex &Index,
220-
function_ref<bool(StringRef, GlobalValue::GUID)> isExported) {
223+
function_ref<SummaryResolution(StringRef, GlobalValue::GUID)> isExported) {
221224
for (auto &I : Index)
222225
thinLTOInternalizeAndPromoteGUID(I.second, I.first, isExported);
223226
}
@@ -951,11 +954,20 @@ Error LTO::runThinLTO(AddStreamFn AddStream, NativeObjectCache Cache,
951954
const GlobalValueSummary *S) {
952955
return ThinLTO.PrevailingModuleForGUID[GUID] == S->modulePath();
953956
};
954-
auto isExported = [&](StringRef ModuleIdentifier, GlobalValue::GUID GUID) {
957+
auto isExported = [&](StringRef ModuleIdentifier,
958+
GlobalValue::GUID GUID) -> SummaryResolution {
955959
const auto &ExportList = ExportLists.find(ModuleIdentifier);
956-
return (ExportList != ExportLists.end() &&
957-
ExportList->second.count(GUID)) ||
958-
ExportedGUIDs.count(GUID);
960+
if ((ExportList != ExportLists.end() && ExportList->second.count(GUID)) ||
961+
ExportedGUIDs.count(GUID)) {
962+
// We could do better by hiding when a symbol is in
963+
// GUIDPreservedSymbols because it is only referenced from regular LTO
964+
// or from native files and not outside the final binary, but that's
965+
// something the native linker could do as gwell.
966+
if (GUIDPreservedSymbols.count(GUID))
967+
return Exported;
968+
return Hidden;
969+
}
970+
return Internal;
959971
};
960972
thinLTOInternalizeAndPromoteInIndex(ThinLTO.CombinedIndex, isExported);
961973

‎llvm/lib/LTO/ThinLTOCodeGenerator.cpp

+34-26
Original file line numberDiff line numberDiff line change
@@ -234,16 +234,16 @@ static void optimizeModule(Module &TheModule, TargetMachine &TM,
234234

235235
// Convert the PreservedSymbols map from "Name" based to "GUID" based.
236236
static DenseSet<GlobalValue::GUID>
237-
computeGUIDPreservedSymbols(const StringSet<> &PreservedSymbols,
238-
const Triple &TheTriple) {
239-
DenseSet<GlobalValue::GUID> GUIDPreservedSymbols(PreservedSymbols.size());
240-
for (auto &Entry : PreservedSymbols) {
237+
convertSymbolNamesToGUID(const StringSet<> &NamedSymbols,
238+
const Triple &TheTriple) {
239+
DenseSet<GlobalValue::GUID> GUIDSymbols(NamedSymbols.size());
240+
for (auto &Entry : NamedSymbols) {
241241
StringRef Name = Entry.first();
242242
if (TheTriple.isOSBinFormatMachO() && Name.size() > 0 && Name[0] == '_')
243243
Name = Name.drop_front();
244-
GUIDPreservedSymbols.insert(GlobalValue::getGUID(Name));
244+
GUIDSymbols.insert(GlobalValue::getGUID(Name));
245245
}
246-
return GUIDPreservedSymbols;
246+
return GUIDSymbols;
247247
}
248248

249249
std::unique_ptr<MemoryBuffer> codegenModule(Module &TheModule,
@@ -554,10 +554,7 @@ void ThinLTOCodeGenerator::preserveSymbol(StringRef Name) {
554554
}
555555

556556
void ThinLTOCodeGenerator::crossReferenceSymbol(StringRef Name) {
557-
// FIXME: At the moment, we don't take advantage of this extra information,
558-
// we're conservatively considering cross-references as preserved.
559-
// CrossReferencedSymbols.insert(Name);
560-
PreservedSymbols.insert(Name);
557+
CrossReferencedSymbols.insert(Name);
561558
}
562559

563560
// TargetMachine factory
@@ -620,7 +617,7 @@ void ThinLTOCodeGenerator::promote(Module &TheModule,
620617
Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
621618

622619
// Convert the preserved symbols set from string to GUID
623-
auto GUIDPreservedSymbols = computeGUIDPreservedSymbols(
620+
auto GUIDPreservedSymbols = convertSymbolNamesToGUID(
624621
PreservedSymbols, Triple(TheModule.getTargetTriple()));
625622

626623
// Compute "dead" symbols, we don't want to import/export these!
@@ -641,11 +638,13 @@ void ThinLTOCodeGenerator::promote(Module &TheModule,
641638

642639
// Promote the exported values in the index, so that they are promoted
643640
// in the module.
644-
auto isExported = [&](StringRef ModuleIdentifier, GlobalValue::GUID GUID) {
641+
auto isExported = [&](StringRef ModuleIdentifier,
642+
GlobalValue::GUID GUID) -> SummaryResolution {
645643
const auto &ExportList = ExportLists.find(ModuleIdentifier);
646-
return (ExportList != ExportLists.end() &&
647-
ExportList->second.count(GUID)) ||
648-
GUIDPreservedSymbols.count(GUID);
644+
if ((ExportList != ExportLists.end() && ExportList->second.count(GUID)) ||
645+
GUIDPreservedSymbols.count(GUID))
646+
return Exported;
647+
return Internal;
649648
};
650649
thinLTOInternalizeAndPromoteInIndex(Index, isExported);
651650

@@ -665,7 +664,7 @@ void ThinLTOCodeGenerator::crossModuleImport(Module &TheModule,
665664
Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
666665

667666
// Convert the preserved symbols set from string to GUID
668-
auto GUIDPreservedSymbols = computeGUIDPreservedSymbols(
667+
auto GUIDPreservedSymbols = convertSymbolNamesToGUID(
669668
PreservedSymbols, Triple(TheModule.getTargetTriple()));
670669

671670
// Compute "dead" symbols, we don't want to import/export these!
@@ -739,7 +738,7 @@ void ThinLTOCodeGenerator::internalize(Module &TheModule,
739738

740739
// Convert the preserved symbols set from string to GUID
741740
auto GUIDPreservedSymbols =
742-
computeGUIDPreservedSymbols(PreservedSymbols, TMBuilder.TheTriple);
741+
convertSymbolNamesToGUID(PreservedSymbols, TMBuilder.TheTriple);
743742

744743
// Collect for each module the list of function it defines (GUID -> Summary).
745744
StringMap<GVSummaryMapTy> ModuleToDefinedGVSummaries(ModuleCount);
@@ -761,11 +760,13 @@ void ThinLTOCodeGenerator::internalize(Module &TheModule,
761760
return;
762761

763762
// Internalization
764-
auto isExported = [&](StringRef ModuleIdentifier, GlobalValue::GUID GUID) {
763+
auto isExported = [&](StringRef ModuleIdentifier,
764+
GlobalValue::GUID GUID) -> SummaryResolution {
765765
const auto &ExportList = ExportLists.find(ModuleIdentifier);
766-
return (ExportList != ExportLists.end() &&
767-
ExportList->second.count(GUID)) ||
768-
GUIDPreservedSymbols.count(GUID);
766+
if ((ExportList != ExportLists.end() && ExportList->second.count(GUID)) ||
767+
GUIDPreservedSymbols.count(GUID))
768+
return Exported;
769+
return Internal;
769770
};
770771
thinLTOInternalizeAndPromoteInIndex(Index, isExported);
771772
thinLTOInternalizeModule(TheModule,
@@ -894,7 +895,9 @@ void ThinLTOCodeGenerator::run() {
894895
// Convert the preserved symbols set from string to GUID, this is needed for
895896
// computing the caching hash and the internalization.
896897
auto GUIDPreservedSymbols =
897-
computeGUIDPreservedSymbols(PreservedSymbols, TMBuilder.TheTriple);
898+
convertSymbolNamesToGUID(PreservedSymbols, TMBuilder.TheTriple);
899+
auto GUIDCrossRefSymbols =
900+
convertSymbolNamesToGUID(CrossReferencedSymbols, TMBuilder.TheTriple);
898901

899902
// Compute "dead" symbols, we don't want to import/export these!
900903
auto DeadSymbols = computeDeadSymbols(*Index, GUIDPreservedSymbols);
@@ -916,11 +919,16 @@ void ThinLTOCodeGenerator::run() {
916919
// impacts the caching.
917920
resolveWeakForLinkerInIndex(*Index, ResolvedODR);
918921

919-
auto isExported = [&](StringRef ModuleIdentifier, GlobalValue::GUID GUID) {
922+
auto isExported = [&](StringRef ModuleIdentifier,
923+
GlobalValue::GUID GUID) -> SummaryResolution {
924+
if (GUIDPreservedSymbols.count(GUID))
925+
return Exported;
926+
if (GUIDCrossRefSymbols.count(GUID))
927+
return Hidden;
920928
const auto &ExportList = ExportLists.find(ModuleIdentifier);
921-
return (ExportList != ExportLists.end() &&
922-
ExportList->second.count(GUID)) ||
923-
GUIDPreservedSymbols.count(GUID);
929+
if (ExportList != ExportLists.end() && ExportList->second.count(GUID))
930+
return Hidden;
931+
return Internal;
924932
};
925933

926934
// Use global summary-based analysis to identify symbols that can be

‎llvm/lib/Transforms/IPO/FunctionImport.cpp

+7
Original file line numberDiff line numberDiff line change
@@ -644,6 +644,13 @@ void llvm::thinLTOInternalizeModule(Module &TheModule,
644644
return !GlobalValue::isLocalLinkage(Linkage);
645645
};
646646

647+
// Try to auto-hide the symbols.
648+
for (auto &GO : TheModule.global_objects()) {
649+
const auto &GS = DefinedGlobals.find(GO.getGUID());
650+
if (GS != DefinedGlobals.end() && GS->second->flags().AutoHide)
651+
GO.setVisibility(GlobalValue::HiddenVisibility);
652+
}
653+
647654
// FIXME: See if we can just internalize directly here via linkage changes
648655
// based on the index, rather than invoking internalizeModule.
649656
llvm::internalizeModule(TheModule, MustPreserveGV);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
2+
target triple = "x86_64-apple-macosx10.11.0"
3+
4+
define weak_odr void @weakodrfunc() {
5+
ret void
6+
}

‎llvm/test/ThinLTO/X86/deadstrip.ll

+4-3
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
; RUN: llvm-lto -thinlto-action=thinlink -o %t.index.bc %t1.bc %t2.bc
44

55
; 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
6-
; 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
6+
; 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
77

88
; RUN: llvm-lto -exported-symbol=_main -thinlto-action=run %t1.bc %t2.bc
99
; RUN: llvm-nm %t1.bc.thinlto.o | FileCheck %s --check-prefix=CHECK-NM
@@ -19,7 +19,7 @@
1919
; RUN: -r %t2.bc,_dead_func,pl \
2020
; RUN: -r %t2.bc,_another_dead_func,pl
2121
; RUN: llvm-dis < %t.out.0.3.import.bc | FileCheck %s
22-
; RUN: llvm-dis < %t.out.1.3.import.bc | FileCheck %s --check-prefix=CHECK2
22+
; RUN: llvm-dis < %t.out.1.3.import.bc | FileCheck %s --check-prefix=CHECK2-LTO2
2323
; RUN: llvm-nm %t.out.1 | FileCheck %s --check-prefix=CHECK2-NM
2424

2525
; Dead-stripping on the index allows to internalize these,
@@ -34,7 +34,8 @@
3434

3535
; Make sure we didn't internalize @boo, which is reachable via
3636
; llvm.global_ctors
37-
; CHECK2: define void @boo()
37+
; CHECK2-LTO: define void @boo()
38+
; CHECK2-LTO2: define hidden void @boo()
3839
; We should have eventually revoved @baz since it was internalized and unused
3940
; CHECK2-NM-NOT: _baz
4041

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
; RUN: opt -module-summary %s -o %t1.bc
2+
; RUN: opt -module-summary %p/Inputs/weak_autohide.ll -o %t2.bc
3+
4+
; RUN: llvm-lto2 %t1.bc %t2.bc -o %t.o -save-temps \
5+
; RUN: -r=%t1.bc,_strong_func,pxl \
6+
; RUN: -r=%t1.bc,_weakodrfunc,pl \
7+
; RUN: -r=%t2.bc,_weakodrfunc,l
8+
; RUN: llvm-dis < %t.o.0.2.internalize.bc | FileCheck %s --check-prefix=AUTOHIDE
9+
10+
11+
; AUTOHIDE: weak_odr hidden void @weakodrfunc
12+
13+
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
14+
target triple = "x86_64-apple-macosx10.11.0"
15+
16+
define weak_odr void @weakodrfunc() #0 {
17+
ret void
18+
}
19+
20+
define void @strong_func() #0 {
21+
call void @weakodrfunc()
22+
ret void
23+
}
24+

0 commit comments

Comments
 (0)
Please sign in to comment.