[LTO][ThinLTO] Use the linker resolutions to mark global values as dso_local.
Now that we have a way to mark GlobalValues as local we can use the symbol resolutions that the linker plugin provides as part of lto/thinlto link step to refine the compilers view on what symbols will end up being local. Differential Revision: https://reviews.llvm.org/D35702 llvm-svn: 317374
This commit is contained in:
parent
3fc9188fa8
commit
36528c2a9b
|
@ -148,11 +148,15 @@ public:
|
||||||
/// In combined summary, indicate that the global value is live.
|
/// In combined summary, indicate that the global value is live.
|
||||||
unsigned Live : 1;
|
unsigned Live : 1;
|
||||||
|
|
||||||
|
/// Indicates that the linker resolved the symbol to a definition from
|
||||||
|
/// within the same linkage unit.
|
||||||
|
unsigned DSOLocal : 1;
|
||||||
|
|
||||||
/// Convenience Constructors
|
/// Convenience Constructors
|
||||||
explicit GVFlags(GlobalValue::LinkageTypes Linkage,
|
explicit GVFlags(GlobalValue::LinkageTypes Linkage,
|
||||||
bool NotEligibleToImport, bool Live)
|
bool NotEligibleToImport, bool Live, bool IsLocal)
|
||||||
: Linkage(Linkage), NotEligibleToImport(NotEligibleToImport),
|
: Linkage(Linkage), NotEligibleToImport(NotEligibleToImport),
|
||||||
Live(Live) {}
|
Live(Live), DSOLocal(IsLocal) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -229,6 +233,10 @@ public:
|
||||||
|
|
||||||
void setLive(bool Live) { Flags.Live = Live; }
|
void setLive(bool Live) { Flags.Live = Live; }
|
||||||
|
|
||||||
|
void setDSOLocal(bool Local) { Flags.DSOLocal = Local; }
|
||||||
|
|
||||||
|
bool isDSOLocal() const { return Flags.DSOLocal; }
|
||||||
|
|
||||||
/// Flag that this global value cannot be imported.
|
/// Flag that this global value cannot be imported.
|
||||||
void setNotEligibleToImport() { Flags.NotEligibleToImport = true; }
|
void setNotEligibleToImport() { Flags.NotEligibleToImport = true; }
|
||||||
|
|
||||||
|
|
|
@ -135,7 +135,7 @@ template <> struct MappingTraits<TypeIdSummary> {
|
||||||
|
|
||||||
struct FunctionSummaryYaml {
|
struct FunctionSummaryYaml {
|
||||||
unsigned Linkage;
|
unsigned Linkage;
|
||||||
bool NotEligibleToImport, Live;
|
bool NotEligibleToImport, Live, IsLocal;
|
||||||
std::vector<uint64_t> TypeTests;
|
std::vector<uint64_t> TypeTests;
|
||||||
std::vector<FunctionSummary::VFuncId> TypeTestAssumeVCalls,
|
std::vector<FunctionSummary::VFuncId> TypeTestAssumeVCalls,
|
||||||
TypeCheckedLoadVCalls;
|
TypeCheckedLoadVCalls;
|
||||||
|
@ -177,6 +177,7 @@ template <> struct MappingTraits<FunctionSummaryYaml> {
|
||||||
io.mapOptional("Linkage", summary.Linkage);
|
io.mapOptional("Linkage", summary.Linkage);
|
||||||
io.mapOptional("NotEligibleToImport", summary.NotEligibleToImport);
|
io.mapOptional("NotEligibleToImport", summary.NotEligibleToImport);
|
||||||
io.mapOptional("Live", summary.Live);
|
io.mapOptional("Live", summary.Live);
|
||||||
|
io.mapOptional("Local", summary.IsLocal);
|
||||||
io.mapOptional("TypeTests", summary.TypeTests);
|
io.mapOptional("TypeTests", summary.TypeTests);
|
||||||
io.mapOptional("TypeTestAssumeVCalls", summary.TypeTestAssumeVCalls);
|
io.mapOptional("TypeTestAssumeVCalls", summary.TypeTestAssumeVCalls);
|
||||||
io.mapOptional("TypeCheckedLoadVCalls", summary.TypeCheckedLoadVCalls);
|
io.mapOptional("TypeCheckedLoadVCalls", summary.TypeCheckedLoadVCalls);
|
||||||
|
@ -211,7 +212,7 @@ template <> struct CustomMappingTraits<GlobalValueSummaryMapTy> {
|
||||||
Elem.SummaryList.push_back(llvm::make_unique<FunctionSummary>(
|
Elem.SummaryList.push_back(llvm::make_unique<FunctionSummary>(
|
||||||
GlobalValueSummary::GVFlags(
|
GlobalValueSummary::GVFlags(
|
||||||
static_cast<GlobalValue::LinkageTypes>(FSum.Linkage),
|
static_cast<GlobalValue::LinkageTypes>(FSum.Linkage),
|
||||||
FSum.NotEligibleToImport, FSum.Live),
|
FSum.NotEligibleToImport, FSum.Live, FSum.IsLocal),
|
||||||
0, FunctionSummary::FFlags{}, ArrayRef<ValueInfo>{},
|
0, FunctionSummary::FFlags{}, ArrayRef<ValueInfo>{},
|
||||||
ArrayRef<FunctionSummary::EdgeTy>{}, std::move(FSum.TypeTests),
|
ArrayRef<FunctionSummary::EdgeTy>{}, std::move(FSum.TypeTests),
|
||||||
std::move(FSum.TypeTestAssumeVCalls),
|
std::move(FSum.TypeTestAssumeVCalls),
|
||||||
|
@ -228,7 +229,8 @@ template <> struct CustomMappingTraits<GlobalValueSummaryMapTy> {
|
||||||
FSums.push_back(FunctionSummaryYaml{
|
FSums.push_back(FunctionSummaryYaml{
|
||||||
FSum->flags().Linkage,
|
FSum->flags().Linkage,
|
||||||
static_cast<bool>(FSum->flags().NotEligibleToImport),
|
static_cast<bool>(FSum->flags().NotEligibleToImport),
|
||||||
static_cast<bool>(FSum->flags().Live), FSum->type_tests(),
|
static_cast<bool>(FSum->flags().Live),
|
||||||
|
static_cast<bool>(FSum->flags().DSOLocal), FSum->type_tests(),
|
||||||
FSum->type_test_assume_vcalls(), FSum->type_checked_load_vcalls(),
|
FSum->type_test_assume_vcalls(), FSum->type_checked_load_vcalls(),
|
||||||
FSum->type_test_assume_const_vcalls(),
|
FSum->type_test_assume_const_vcalls(),
|
||||||
FSum->type_checked_load_const_vcalls()});
|
FSum->type_checked_load_const_vcalls()});
|
||||||
|
|
|
@ -303,7 +303,7 @@ computeFunctionSummary(ModuleSummaryIndex &Index, const Module &M,
|
||||||
// FIXME: refactor this to use the same code that inliner is using.
|
// FIXME: refactor this to use the same code that inliner is using.
|
||||||
F.isVarArg();
|
F.isVarArg();
|
||||||
GlobalValueSummary::GVFlags Flags(F.getLinkage(), NotEligibleForImport,
|
GlobalValueSummary::GVFlags Flags(F.getLinkage(), NotEligibleForImport,
|
||||||
/* Live = */ false);
|
/* Live = */ false, F.isDSOLocal());
|
||||||
FunctionSummary::FFlags FunFlags{
|
FunctionSummary::FFlags FunFlags{
|
||||||
F.hasFnAttribute(Attribute::ReadNone),
|
F.hasFnAttribute(Attribute::ReadNone),
|
||||||
F.hasFnAttribute(Attribute::ReadOnly),
|
F.hasFnAttribute(Attribute::ReadOnly),
|
||||||
|
@ -329,7 +329,7 @@ computeVariableSummary(ModuleSummaryIndex &Index, const GlobalVariable &V,
|
||||||
findRefEdges(Index, &V, RefEdges, Visited);
|
findRefEdges(Index, &V, RefEdges, Visited);
|
||||||
bool NonRenamableLocal = isNonRenamableLocal(V);
|
bool NonRenamableLocal = isNonRenamableLocal(V);
|
||||||
GlobalValueSummary::GVFlags Flags(V.getLinkage(), NonRenamableLocal,
|
GlobalValueSummary::GVFlags Flags(V.getLinkage(), NonRenamableLocal,
|
||||||
/* Live = */ false);
|
/* Live = */ false, V.isDSOLocal());
|
||||||
auto GVarSummary =
|
auto GVarSummary =
|
||||||
llvm::make_unique<GlobalVarSummary>(Flags, RefEdges.takeVector());
|
llvm::make_unique<GlobalVarSummary>(Flags, RefEdges.takeVector());
|
||||||
if (NonRenamableLocal)
|
if (NonRenamableLocal)
|
||||||
|
@ -342,7 +342,7 @@ computeAliasSummary(ModuleSummaryIndex &Index, const GlobalAlias &A,
|
||||||
DenseSet<GlobalValue::GUID> &CantBePromoted) {
|
DenseSet<GlobalValue::GUID> &CantBePromoted) {
|
||||||
bool NonRenamableLocal = isNonRenamableLocal(A);
|
bool NonRenamableLocal = isNonRenamableLocal(A);
|
||||||
GlobalValueSummary::GVFlags Flags(A.getLinkage(), NonRenamableLocal,
|
GlobalValueSummary::GVFlags Flags(A.getLinkage(), NonRenamableLocal,
|
||||||
/* Live = */ false);
|
/* Live = */ false, A.isDSOLocal());
|
||||||
auto AS = llvm::make_unique<AliasSummary>(Flags);
|
auto AS = llvm::make_unique<AliasSummary>(Flags);
|
||||||
auto *Aliasee = A.getBaseObject();
|
auto *Aliasee = A.getBaseObject();
|
||||||
auto *AliaseeSummary = Index.getGlobalValueSummary(*Aliasee);
|
auto *AliaseeSummary = Index.getGlobalValueSummary(*Aliasee);
|
||||||
|
@ -410,7 +410,8 @@ ModuleSummaryIndex llvm::buildModuleSummaryIndex(
|
||||||
assert(GV->isDeclaration() && "Def in module asm already has definition");
|
assert(GV->isDeclaration() && "Def in module asm already has definition");
|
||||||
GlobalValueSummary::GVFlags GVFlags(GlobalValue::InternalLinkage,
|
GlobalValueSummary::GVFlags GVFlags(GlobalValue::InternalLinkage,
|
||||||
/* NotEligibleToImport = */ true,
|
/* NotEligibleToImport = */ true,
|
||||||
/* Live = */ true);
|
/* Live = */ true,
|
||||||
|
/* Local */ GV->isDSOLocal());
|
||||||
CantBePromoted.insert(GlobalValue::getGUID(Name));
|
CantBePromoted.insert(GlobalValue::getGUID(Name));
|
||||||
// Create the appropriate summary type.
|
// Create the appropriate summary type.
|
||||||
if (Function *F = dyn_cast<Function>(GV)) {
|
if (Function *F = dyn_cast<Function>(GV)) {
|
||||||
|
|
|
@ -889,7 +889,9 @@ static GlobalValueSummary::GVFlags getDecodedGVSummaryFlags(uint64_t RawFlags,
|
||||||
// to work correctly on earlier versions, we must conservatively treat all
|
// to work correctly on earlier versions, we must conservatively treat all
|
||||||
// values as live.
|
// values as live.
|
||||||
bool Live = (RawFlags & 0x2) || Version < 3;
|
bool Live = (RawFlags & 0x2) || Version < 3;
|
||||||
return GlobalValueSummary::GVFlags(Linkage, NotEligibleToImport, Live);
|
bool Local = (RawFlags & 0x4);
|
||||||
|
|
||||||
|
return GlobalValueSummary::GVFlags(Linkage, NotEligibleToImport, Live, Local);
|
||||||
}
|
}
|
||||||
|
|
||||||
static GlobalValue::VisibilityTypes getDecodedVisibility(unsigned Val) {
|
static GlobalValue::VisibilityTypes getDecodedVisibility(unsigned Val) {
|
||||||
|
|
|
@ -955,6 +955,8 @@ static uint64_t getEncodedGVSummaryFlags(GlobalValueSummary::GVFlags Flags) {
|
||||||
|
|
||||||
RawFlags |= Flags.NotEligibleToImport; // bool
|
RawFlags |= Flags.NotEligibleToImport; // bool
|
||||||
RawFlags |= (Flags.Live << 1);
|
RawFlags |= (Flags.Live << 1);
|
||||||
|
RawFlags |= (Flags.DSOLocal << 2);
|
||||||
|
|
||||||
// Linkage don't need to be remapped at that time for the summary. Any future
|
// Linkage don't need to be remapped at that time for the summary. Any future
|
||||||
// change to the getEncodedLinkage() function will need to be taken into
|
// change to the getEncodedLinkage() function will need to be taken into
|
||||||
// account here as well.
|
// account here as well.
|
||||||
|
|
|
@ -630,6 +630,9 @@ LTO::addRegularLTO(BitcodeModule BM, ArrayRef<InputFile::Symbol> Syms,
|
||||||
NonPrevailingComdats.insert(GV->getComdat());
|
NonPrevailingComdats.insert(GV->getComdat());
|
||||||
cast<GlobalObject>(GV)->setComdat(nullptr);
|
cast<GlobalObject>(GV)->setComdat(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set the 'local' flag based on the linker resolution for this symbol.
|
||||||
|
GV->setDSOLocal(Res.FinalDefinitionInLinkageUnit);
|
||||||
}
|
}
|
||||||
// Common resolution: collect the maximum size/alignment over all commons.
|
// Common resolution: collect the maximum size/alignment over all commons.
|
||||||
// We also record if we see an instance of a common as prevailing, so that
|
// We also record if we see an instance of a common as prevailing, so that
|
||||||
|
@ -643,7 +646,6 @@ LTO::addRegularLTO(BitcodeModule BM, ArrayRef<InputFile::Symbol> Syms,
|
||||||
CommonRes.Prevailing |= Res.Prevailing;
|
CommonRes.Prevailing |= Res.Prevailing;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: use proposed local attribute for FinalDefinitionInLinkageUnit.
|
|
||||||
}
|
}
|
||||||
if (!M.getComdatSymbolTable().empty())
|
if (!M.getComdatSymbolTable().empty())
|
||||||
for (GlobalValue &GV : M.global_values())
|
for (GlobalValue &GV : M.global_values())
|
||||||
|
@ -698,10 +700,10 @@ Error LTO::addThinLTO(BitcodeModule BM, ArrayRef<InputFile::Symbol> Syms,
|
||||||
assert(ResI != ResE);
|
assert(ResI != ResE);
|
||||||
SymbolResolution Res = *ResI++;
|
SymbolResolution Res = *ResI++;
|
||||||
|
|
||||||
if (Res.Prevailing) {
|
if (!Sym.getIRName().empty()) {
|
||||||
if (!Sym.getIRName().empty()) {
|
auto GUID = GlobalValue::getGUID(GlobalValue::getGlobalIdentifier(
|
||||||
auto GUID = GlobalValue::getGUID(GlobalValue::getGlobalIdentifier(
|
Sym.getIRName(), GlobalValue::ExternalLinkage, ""));
|
||||||
Sym.getIRName(), GlobalValue::ExternalLinkage, ""));
|
if (Res.Prevailing) {
|
||||||
ThinLTO.PrevailingModuleForGUID[GUID] = BM.getModuleIdentifier();
|
ThinLTO.PrevailingModuleForGUID[GUID] = BM.getModuleIdentifier();
|
||||||
|
|
||||||
// For linker redefined symbols (via --wrap or --defsym) we want to
|
// For linker redefined symbols (via --wrap or --defsym) we want to
|
||||||
|
@ -713,6 +715,15 @@ Error LTO::addThinLTO(BitcodeModule BM, ArrayRef<InputFile::Symbol> Syms,
|
||||||
GUID, BM.getModuleIdentifier()))
|
GUID, BM.getModuleIdentifier()))
|
||||||
S->setLinkage(GlobalValue::WeakAnyLinkage);
|
S->setLinkage(GlobalValue::WeakAnyLinkage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the linker resolved the symbol to a local definition then mark it
|
||||||
|
// as local in the summary for the module we are adding.
|
||||||
|
if (Res.FinalDefinitionInLinkageUnit) {
|
||||||
|
if (auto S = ThinLTO.CombinedIndex.findSummaryInModule(
|
||||||
|
GUID, BM.getModuleIdentifier())) {
|
||||||
|
S->setDSOLocal(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -203,6 +203,23 @@ FunctionImportGlobalProcessing::getLinkage(const GlobalValue *SGV,
|
||||||
}
|
}
|
||||||
|
|
||||||
void FunctionImportGlobalProcessing::processGlobalForThinLTO(GlobalValue &GV) {
|
void FunctionImportGlobalProcessing::processGlobalForThinLTO(GlobalValue &GV) {
|
||||||
|
|
||||||
|
// Check the summaries to see if the symbol gets resolved to a known local
|
||||||
|
// definition.
|
||||||
|
if (GV.hasName()) {
|
||||||
|
ValueInfo VI = ImportIndex.getValueInfo(GV.getGUID());
|
||||||
|
if (VI) {
|
||||||
|
// Need to check all summaries are local in case of hash collisions.
|
||||||
|
bool IsLocal = VI.getSummaryList().size() &&
|
||||||
|
llvm::all_of(VI.getSummaryList(),
|
||||||
|
[](const std::unique_ptr<GlobalValueSummary> &Summary) {
|
||||||
|
return Summary->isDSOLocal();
|
||||||
|
});
|
||||||
|
if (IsLocal)
|
||||||
|
GV.setDSOLocal(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool DoPromote = false;
|
bool DoPromote = false;
|
||||||
if (GV.hasLocalLinkage() &&
|
if (GV.hasLocalLinkage() &&
|
||||||
((DoPromote = shouldPromoteLocalToGlobal(&GV)) || isPerformingImport())) {
|
((DoPromote = shouldPromoteLocalToGlobal(&GV)) || isPerformingImport())) {
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
; Bitcode compatibility test for dso_local flag in thin-lto summaries.
|
||||||
|
; Checks that older bitcode summaries without the dso_local op are still
|
||||||
|
; properly parsed and don't set GlobalValues as dso_local.
|
||||||
|
|
||||||
|
; RUN: llvm-dis < %s.bc | FileCheck %s
|
||||||
|
; RUN: llvm-bcanalyzer -dump %s.bc | FileCheck %s --check-prefix=BCAN
|
||||||
|
|
||||||
|
define void @foo() {
|
||||||
|
;CHECK-DAG:define void @foo()
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
@bar = global i32 0
|
||||||
|
;CHECK-DAG: @bar = global i32 0
|
||||||
|
|
||||||
|
@baz = alias i32, i32* @bar
|
||||||
|
;CHECK-DAG: @bar = global i32 0
|
||||||
|
|
||||||
|
;BCAN: <SOURCE_FILENAME
|
||||||
|
;BCAN-NEXT: <GLOBALVAR {{.*}} op7=0/>
|
||||||
|
;BCAN-NEXT: <FUNCTION {{.*}} op16=0/>
|
||||||
|
;BCAN-NEXT: <ALIAS {{.*}} op9=0/>
|
Binary file not shown.
|
@ -17,7 +17,7 @@
|
||||||
; would clash with the copy from this module.
|
; would clash with the copy from this module.
|
||||||
; RUN: llvm-dis %t3.0.0.preopt.bc -o - | FileCheck %s
|
; RUN: llvm-dis %t3.0.0.preopt.bc -o - | FileCheck %s
|
||||||
; CHECK: define internal void @__cxx_global_var_init() section ".text.startup" {
|
; CHECK: define internal void @__cxx_global_var_init() section ".text.startup" {
|
||||||
; CHECK: define available_externally void @testglobfunc() section ".text.startup" {
|
; CHECK: define available_externally dso_local void @testglobfunc() section ".text.startup" {
|
||||||
|
|
||||||
; ModuleID = 'comdat-mixed-lto.o'
|
; ModuleID = 'comdat-mixed-lto.o'
|
||||||
source_filename = "comdat-mixed-lto.cpp"
|
source_filename = "comdat-mixed-lto.cpp"
|
||||||
|
|
|
@ -70,14 +70,14 @@ bb11:
|
||||||
; CHECK-DAG: @a23 = alias i32 (i8*), i32 (i8*)* @f1.2{{$}}
|
; CHECK-DAG: @a23 = alias i32 (i8*), i32 (i8*)* @f1.2{{$}}
|
||||||
; CHECK-DAG: @a24 = alias i16, bitcast (i32 (i8*)* @f1.2 to i16*)
|
; CHECK-DAG: @a24 = alias i16, bitcast (i32 (i8*)* @f1.2 to i16*)
|
||||||
|
|
||||||
; CHECK: define weak_odr i32 @f1(i8*) comdat($c1) {
|
; CHECK: define weak_odr dso_local i32 @f1(i8*) comdat($c1) {
|
||||||
; CHECK-NEXT: bb10:
|
; CHECK-NEXT: bb10:
|
||||||
; CHECK-NEXT: br label %bb11{{$}}
|
; CHECK-NEXT: br label %bb11{{$}}
|
||||||
; CHECK: bb11:
|
; CHECK: bb11:
|
||||||
; CHECK-NEXT: ret i32 42
|
; CHECK-NEXT: ret i32 42
|
||||||
; CHECK-NEXT: }
|
; CHECK-NEXT: }
|
||||||
|
|
||||||
; CHECK: define internal i32 @f1.2(i8* %this) comdat($c2) {
|
; CHECK: define internal dso_local i32 @f1.2(i8* %this) comdat($c2) {
|
||||||
; CHECK-NEXT: bb20:
|
; CHECK-NEXT: bb20:
|
||||||
; CHECK-NEXT: store i8* %this, i8** null
|
; CHECK-NEXT: store i8* %this, i8** null
|
||||||
; CHECK-NEXT: br label %bb21
|
; CHECK-NEXT: br label %bb21
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
; RUN: llvm-dis -o - %t.out.0.0.preopt.bc | FileCheck %s
|
; RUN: llvm-dis -o - %t.out.0.0.preopt.bc | FileCheck %s
|
||||||
|
|
||||||
; A strong definition should override the common
|
; A strong definition should override the common
|
||||||
; CHECK: @x = global i32 42, align 4
|
; CHECK: @x = dso_local global i32 42, align 4
|
||||||
|
|
||||||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||||
target triple = "x86_64-unknown-linux-gnu"
|
target triple = "x86_64-unknown-linux-gnu"
|
||||||
|
|
|
@ -18,8 +18,8 @@
|
||||||
; RUN: -r %t2.bc,_boo,pl \
|
; RUN: -r %t2.bc,_boo,pl \
|
||||||
; RUN: -r %t2.bc,_dead_func,pl \
|
; RUN: -r %t2.bc,_dead_func,pl \
|
||||||
; RUN: -r %t2.bc,_another_dead_func,pl
|
; RUN: -r %t2.bc,_another_dead_func,pl
|
||||||
; RUN: llvm-dis < %t.out.0.3.import.bc | FileCheck %s
|
; RUN: llvm-dis < %t.out.0.3.import.bc | FileCheck %s --check-prefix=LTO2
|
||||||
; RUN: llvm-dis < %t.out.1.3.import.bc | FileCheck %s --check-prefix=CHECK2
|
; RUN: llvm-dis < %t.out.1.3.import.bc | FileCheck %s --check-prefix=LTO2-CHECK2
|
||||||
; RUN: llvm-nm %t.out.1 | FileCheck %s --check-prefix=CHECK2-NM
|
; RUN: llvm-nm %t.out.1 | FileCheck %s --check-prefix=CHECK2-NM
|
||||||
|
|
||||||
; RUN: llvm-bcanalyzer -dump %t.out.index.bc | FileCheck %s --check-prefix=COMBINED
|
; RUN: llvm-bcanalyzer -dump %t.out.index.bc | FileCheck %s --check-prefix=COMBINED
|
||||||
|
@ -27,14 +27,14 @@
|
||||||
; COMBINED-DAG: <COMBINED {{.*}} op2=55
|
; COMBINED-DAG: <COMBINED {{.*}} op2=55
|
||||||
; Live, Internal
|
; Live, Internal
|
||||||
; COMBINED-DAG: <COMBINED {{.*}} op2=39
|
; COMBINED-DAG: <COMBINED {{.*}} op2=39
|
||||||
; Live, External
|
; Live, Local, External
|
||||||
; COMBINED-DAG: <COMBINED {{.*}} op2=32
|
; COMBINED-DAG: <COMBINED {{.*}} op2=96
|
||||||
; COMBINED-DAG: <COMBINED {{.*}} op2=32
|
; COMBINED-DAG: <COMBINED {{.*}} op2=96
|
||||||
; COMBINED-DAG: <COMBINED {{.*}} op2=32
|
; COMBINED-DAG: <COMBINED {{.*}} op2=96
|
||||||
; (Dead)
|
; Local, (Dead)
|
||||||
; COMBINED-DAG: <COMBINED {{.*}} op2=0
|
; COMBINED-DAG: <COMBINED {{.*}} op2=64
|
||||||
; COMBINED-DAG: <COMBINED {{.*}} op2=0
|
; COMBINED-DAG: <COMBINED {{.*}} op2=64
|
||||||
; COMBINED-DAG: <COMBINED {{.*}} op2=0
|
; COMBINED-DAG: <COMBINED {{.*}} op2=64
|
||||||
|
|
||||||
; Dead-stripping on the index allows to internalize these,
|
; Dead-stripping on the index allows to internalize these,
|
||||||
; and limit the import of @baz thanks to early pruning.
|
; and limit the import of @baz thanks to early pruning.
|
||||||
|
@ -45,10 +45,18 @@
|
||||||
; CHECK: define internal void @bar_internal()
|
; CHECK: define internal void @bar_internal()
|
||||||
; CHECK: define internal void @dead_func() {
|
; CHECK: define internal void @dead_func() {
|
||||||
; CHECK-NOT: available_externally {{.*}} @baz()
|
; CHECK-NOT: available_externally {{.*}} @baz()
|
||||||
|
; LTO2-NOT: available_externally {{.*}} @baz()
|
||||||
|
; LTO2: @llvm.global_ctors =
|
||||||
|
; LTO2: define internal void @_GLOBAL__I_a()
|
||||||
|
; LTO2: define internal dso_local void @bar() {
|
||||||
|
; LTO2: define internal void @bar_internal()
|
||||||
|
; LTO2: define internal dso_local void @dead_func() {
|
||||||
|
; LTO2-NOT: available_externally {{.*}} @baz()
|
||||||
|
|
||||||
; Make sure we didn't internalize @boo, which is reachable via
|
; Make sure we didn't internalize @boo, which is reachable via
|
||||||
; llvm.global_ctors
|
; llvm.global_ctors
|
||||||
; CHECK2: define void @boo()
|
; CHECK2: define void @boo()
|
||||||
|
; LTO2-CHECK2: define dso_local void @boo()
|
||||||
; We should have eventually removed @baz since it was internalized and unused
|
; We should have eventually removed @baz since it was internalized and unused
|
||||||
; CHECK2-NM-NOT: _baz
|
; CHECK2-NM-NOT: _baz
|
||||||
|
|
||||||
|
@ -80,7 +88,7 @@
|
||||||
|
|
||||||
; We can't internalize @dead_func because of the use in the regular LTO
|
; We can't internalize @dead_func because of the use in the regular LTO
|
||||||
; partition.
|
; partition.
|
||||||
; CHECK-NOTDEAD: define void @dead_func()
|
; CHECK-NOTDEAD: define dso_local void @dead_func()
|
||||||
; We also can't eliminate @baz because it is in the regular LTO partition
|
; We also can't eliminate @baz because it is in the regular LTO partition
|
||||||
; and called from @dead_func.
|
; and called from @dead_func.
|
||||||
; CHECK-NM-NOTDEAD: T _baz
|
; CHECK-NM-NOTDEAD: T _baz
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
; RUN: -r=%t2.bc,_main,plx \
|
; RUN: -r=%t2.bc,_main,plx \
|
||||||
; RUN: -r=%t2.bc,_foo,l
|
; RUN: -r=%t2.bc,_foo,l
|
||||||
; RUN: llvm-dis %t.o.1.3.import.bc -o - | FileCheck %s
|
; RUN: llvm-dis %t.o.1.3.import.bc -o - | FileCheck %s
|
||||||
; CHECK: define available_externally void @foo()
|
; CHECK: define available_externally dso_local void @foo()
|
||||||
|
|
||||||
; We shouldn't do any importing at -O0
|
; We shouldn't do any importing at -O0
|
||||||
; rm -f %t.o.1.3.import.bc
|
; rm -f %t.o.1.3.import.bc
|
||||||
|
@ -17,7 +17,7 @@
|
||||||
; RUN: -r=%t2.bc,_main,plx \
|
; RUN: -r=%t2.bc,_main,plx \
|
||||||
; RUN: -r=%t2.bc,_foo,l
|
; RUN: -r=%t2.bc,_foo,l
|
||||||
; RUN: llvm-dis %t.o.1.3.import.bc -o - | FileCheck %s --check-prefix=CHECKO0
|
; RUN: llvm-dis %t.o.1.3.import.bc -o - | FileCheck %s --check-prefix=CHECKO0
|
||||||
; CHECKO0: declare void @foo(...)
|
; CHECKO0: declare dso_local void @foo(...)
|
||||||
|
|
||||||
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
|
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
|
||||||
target triple = "x86_64-apple-macosx10.11.0"
|
target triple = "x86_64-apple-macosx10.11.0"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
;; RUN: opt -module-summary %s -o %t1.bc
|
; RUN: opt -module-summary %s -o %t1.bc
|
||||||
; RUN: llvm-lto -thinlto-action=thinlink -o %t.index.bc %t1.bc
|
; RUN: llvm-lto -thinlto-action=thinlink -o %t.index.bc %t1.bc
|
||||||
; RUN: llvm-lto -thinlto-action=internalize -thinlto-index %t.index.bc %t1.bc -o - | llvm-dis -o - | FileCheck %s --check-prefix=REGULAR
|
; RUN: llvm-lto -thinlto-action=internalize -thinlto-index %t.index.bc %t1.bc -o - | llvm-dis -o - | FileCheck %s --check-prefix=REGULAR
|
||||||
; RUN: llvm-lto -thinlto-action=internalize -thinlto-index %t.index.bc %t1.bc -o - --exported-symbol=foo | llvm-dis -o - | FileCheck %s --check-prefix=INTERNALIZE
|
; RUN: llvm-lto -thinlto-action=internalize -thinlto-index %t.index.bc %t1.bc -o - --exported-symbol=foo | llvm-dis -o - | FileCheck %s --check-prefix=INTERNALIZE
|
||||||
|
@ -7,7 +7,7 @@
|
||||||
; RUN: -r=%t1.bc,_foo,pxl \
|
; RUN: -r=%t1.bc,_foo,pxl \
|
||||||
; RUN: -r=%t1.bc,_bar,pl \
|
; RUN: -r=%t1.bc,_bar,pl \
|
||||||
; RUN: -r=%t1.bc,_linkonce_func,pl
|
; RUN: -r=%t1.bc,_linkonce_func,pl
|
||||||
; RUN: llvm-dis < %t.o.0.2.internalize.bc | FileCheck %s --check-prefix=INTERNALIZE
|
; RUN: llvm-dis < %t.o.0.2.internalize.bc | FileCheck %s --check-prefix=INTERNALIZE2
|
||||||
|
|
||||||
|
|
||||||
; REGULAR: define void @foo
|
; REGULAR: define void @foo
|
||||||
|
@ -16,6 +16,9 @@
|
||||||
; INTERNALIZE: define void @foo
|
; INTERNALIZE: define void @foo
|
||||||
; INTERNALIZE: define internal void @bar
|
; INTERNALIZE: define internal void @bar
|
||||||
; INTERNALIZE: define internal void @linkonce_func()
|
; INTERNALIZE: define internal void @linkonce_func()
|
||||||
|
; INTERNALIZE2: define dso_local void @foo
|
||||||
|
; INTERNALIZE2: define internal dso_local void @bar
|
||||||
|
; INTERNALIZE2: define internal dso_local void @linkonce_func()
|
||||||
|
|
||||||
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
|
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
|
||||||
target triple = "x86_64-apple-macosx10.11.0"
|
target triple = "x86_64-apple-macosx10.11.0"
|
||||||
|
@ -29,4 +32,4 @@ define void @bar() {
|
||||||
}
|
}
|
||||||
define linkonce void @linkonce_func() {
|
define linkonce void @linkonce_func() {
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ target triple = "x86_64-apple-macosx10.11.0"
|
||||||
|
|
||||||
; We want foo to be imported in the main module!
|
; We want foo to be imported in the main module!
|
||||||
; RUN: llvm-dis < %t.o.1.3.import.bc | FileCheck %s --check-prefix=IMPORT
|
; RUN: llvm-dis < %t.o.1.3.import.bc | FileCheck %s --check-prefix=IMPORT
|
||||||
; IMPORT: define available_externally i8** @foo()
|
; IMPORT: define available_externally dso_local i8** @foo()
|
||||||
define i8 **@foo() {
|
define i8 **@foo() {
|
||||||
ret i8 **@b
|
ret i8 **@b
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
; SUMMARY-NEXT: - Linkage: 0
|
; SUMMARY-NEXT: - Linkage: 0
|
||||||
; SUMMARY-NEXT: NotEligibleToImport: false
|
; SUMMARY-NEXT: NotEligibleToImport: false
|
||||||
; SUMMARY-NEXT: Live: true
|
; SUMMARY-NEXT: Live: true
|
||||||
|
; SUMMARY-NEXT: Local: false
|
||||||
; SUMMARY-NEXT: TypeTests: [ 123 ]
|
; SUMMARY-NEXT: TypeTests: [ 123 ]
|
||||||
; SUMMARY-NEXT: TypeIdMap:
|
; SUMMARY-NEXT: TypeIdMap:
|
||||||
; SUMMARY-NEXT: typeid1:
|
; SUMMARY-NEXT: typeid1:
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
; RUN: llvm-nm %t3.2 | FileCheck %s --check-prefix=NM
|
; RUN: llvm-nm %t3.2 | FileCheck %s --check-prefix=NM
|
||||||
; NM: _ZL3barv
|
; NM: _ZL3barv
|
||||||
; RUN: llvm-dis < %t3.2.2.internalize.bc | FileCheck %s --check-prefix=INTERNALIZE
|
; RUN: llvm-dis < %t3.2.2.internalize.bc | FileCheck %s --check-prefix=INTERNALIZE
|
||||||
; INTERNALIZE: define void @_ZL3barv
|
; INTERNALIZE: define dso_local void @_ZL3barv
|
||||||
|
|
||||||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||||
target triple = "x86_64-unknown-linux-gnu"
|
target triple = "x86_64-unknown-linux-gnu"
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
; SUMMARY-NEXT: - Linkage: 0
|
; SUMMARY-NEXT: - Linkage: 0
|
||||||
; SUMMARY-NEXT: NotEligibleToImport: false
|
; SUMMARY-NEXT: NotEligibleToImport: false
|
||||||
; SUMMARY-NEXT: Live: true
|
; SUMMARY-NEXT: Live: true
|
||||||
|
; SUMMARY-NEXT: Local: false
|
||||||
; SUMMARY-NEXT: TypeTestAssumeVCalls:
|
; SUMMARY-NEXT: TypeTestAssumeVCalls:
|
||||||
; SUMMARY-NEXT: - GUID: 123
|
; SUMMARY-NEXT: - GUID: 123
|
||||||
; SUMMARY-NEXT: Offset: 0
|
; SUMMARY-NEXT: Offset: 0
|
||||||
|
|
Loading…
Reference in New Issue