mirror of
https://github.com/RPCS3/llvm.git
synced 2026-07-19 15:13:49 -04:00
[ThinLTO] Internalize readonly globals
This patch allows internalising globals if all accesses to them (from live functions) are from non-volatile load instructions Differential revision: https://reviews.llvm.org/D49362 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@346584 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -220,10 +220,19 @@ static void addIntrinsicToSummary(
|
||||
}
|
||||
}
|
||||
|
||||
static void computeFunctionSummary(
|
||||
ModuleSummaryIndex &Index, const Module &M, const Function &F,
|
||||
BlockFrequencyInfo *BFI, ProfileSummaryInfo *PSI, DominatorTree &DT,
|
||||
bool HasLocalsInUsedOrAsm, DenseSet<GlobalValue::GUID> &CantBePromoted) {
|
||||
static bool isNonVolatileLoad(const Instruction *I) {
|
||||
if (const auto *LI = dyn_cast<LoadInst>(I))
|
||||
return !LI->isVolatile();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void computeFunctionSummary(ModuleSummaryIndex &Index, const Module &M,
|
||||
const Function &F, BlockFrequencyInfo *BFI,
|
||||
ProfileSummaryInfo *PSI, DominatorTree &DT,
|
||||
bool HasLocalsInUsedOrAsm,
|
||||
DenseSet<GlobalValue::GUID> &CantBePromoted,
|
||||
bool IsThinLTO) {
|
||||
// Summary not currently supported for anonymous functions, they should
|
||||
// have been named.
|
||||
assert(F.hasName());
|
||||
@@ -244,6 +253,7 @@ static void computeFunctionSummary(
|
||||
// Add personality function, prefix data and prologue data to function's ref
|
||||
// list.
|
||||
findRefEdges(Index, &F, RefEdges, Visited);
|
||||
std::vector<const Instruction *> NonVolatileLoads;
|
||||
|
||||
bool HasInlineAsmMaybeReferencingInternal = false;
|
||||
for (const BasicBlock &BB : F)
|
||||
@@ -251,6 +261,13 @@ static void computeFunctionSummary(
|
||||
if (isa<DbgInfoIntrinsic>(I))
|
||||
continue;
|
||||
++NumInsts;
|
||||
if (isNonVolatileLoad(&I)) {
|
||||
// Postpone processing of non-volatile load instructions
|
||||
// See comments below
|
||||
Visited.insert(&I);
|
||||
NonVolatileLoads.push_back(&I);
|
||||
continue;
|
||||
}
|
||||
findRefEdges(Index, &I, RefEdges, Visited);
|
||||
auto CS = ImmutableCallSite(&I);
|
||||
if (!CS)
|
||||
@@ -340,6 +357,24 @@ static void computeFunctionSummary(
|
||||
}
|
||||
}
|
||||
|
||||
// By now we processed all instructions in a function, except
|
||||
// non-volatile loads. All new refs we add in a loop below
|
||||
// are obviously constant. All constant refs are grouped in the
|
||||
// end of RefEdges vector, so we can use a single integer value
|
||||
// to identify them.
|
||||
unsigned RefCnt = RefEdges.size();
|
||||
for (const Instruction *I : NonVolatileLoads) {
|
||||
Visited.erase(I);
|
||||
findRefEdges(Index, I, RefEdges, Visited);
|
||||
}
|
||||
std::vector<ValueInfo> Refs = RefEdges.takeVector();
|
||||
// Regular LTO module doesn't participate in ThinLTO import,
|
||||
// so no reference from it can be readonly, since this would
|
||||
// require importing variable as local copy
|
||||
if (IsThinLTO)
|
||||
for (; RefCnt < Refs.size(); ++RefCnt)
|
||||
Refs[RefCnt].setReadOnly();
|
||||
|
||||
// Explicit add hot edges to enforce importing for designated GUIDs for
|
||||
// sample PGO, to enable the same inlines as the profiled optimized binary.
|
||||
for (auto &I : F.getImportGUIDs())
|
||||
@@ -363,9 +398,9 @@ static void computeFunctionSummary(
|
||||
// Don't try to import functions with noinline attribute.
|
||||
F.getAttributes().hasFnAttribute(Attribute::NoInline)};
|
||||
auto FuncSummary = llvm::make_unique<FunctionSummary>(
|
||||
Flags, NumInsts, FunFlags, RefEdges.takeVector(),
|
||||
CallGraphEdges.takeVector(), TypeTests.takeVector(),
|
||||
TypeTestAssumeVCalls.takeVector(), TypeCheckedLoadVCalls.takeVector(),
|
||||
Flags, NumInsts, FunFlags, std::move(Refs), CallGraphEdges.takeVector(),
|
||||
TypeTests.takeVector(), TypeTestAssumeVCalls.takeVector(),
|
||||
TypeCheckedLoadVCalls.takeVector(),
|
||||
TypeTestAssumeConstVCalls.takeVector(),
|
||||
TypeCheckedLoadConstVCalls.takeVector());
|
||||
if (NonRenamableLocal)
|
||||
@@ -382,8 +417,13 @@ computeVariableSummary(ModuleSummaryIndex &Index, const GlobalVariable &V,
|
||||
bool NonRenamableLocal = isNonRenamableLocal(V);
|
||||
GlobalValueSummary::GVFlags Flags(V.getLinkage(), NonRenamableLocal,
|
||||
/* Live = */ false, V.isDSOLocal());
|
||||
auto GVarSummary =
|
||||
llvm::make_unique<GlobalVarSummary>(Flags, RefEdges.takeVector());
|
||||
|
||||
// Don't mark variables we won't be able to internalize as read-only.
|
||||
GlobalVarSummary::GVarFlags VarFlags(
|
||||
!V.hasComdat() && !V.hasAppendingLinkage() && !V.isInterposable() &&
|
||||
!V.hasAvailableExternallyLinkage() && !V.hasDLLExportStorageClass());
|
||||
auto GVarSummary = llvm::make_unique<GlobalVarSummary>(Flags, VarFlags,
|
||||
RefEdges.takeVector());
|
||||
if (NonRenamableLocal)
|
||||
CantBePromoted.insert(V.getGUID());
|
||||
if (HasBlockAddress)
|
||||
@@ -487,13 +527,19 @@ ModuleSummaryIndex llvm::buildModuleSummaryIndex(
|
||||
Index.addGlobalValueSummary(*GV, std::move(Summary));
|
||||
} else {
|
||||
std::unique_ptr<GlobalVarSummary> Summary =
|
||||
llvm::make_unique<GlobalVarSummary>(GVFlags,
|
||||
ArrayRef<ValueInfo>{});
|
||||
llvm::make_unique<GlobalVarSummary>(
|
||||
GVFlags, GlobalVarSummary::GVarFlags(),
|
||||
ArrayRef<ValueInfo>{});
|
||||
Index.addGlobalValueSummary(*GV, std::move(Summary));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
bool IsThinLTO = true;
|
||||
if (auto *MD =
|
||||
mdconst::extract_or_null<ConstantInt>(M.getModuleFlag("ThinLTO")))
|
||||
IsThinLTO = MD->getZExtValue();
|
||||
|
||||
// Compute summaries for all functions defined in module, and save in the
|
||||
// index.
|
||||
for (auto &F : M) {
|
||||
@@ -514,7 +560,7 @@ ModuleSummaryIndex llvm::buildModuleSummaryIndex(
|
||||
|
||||
computeFunctionSummary(Index, M, F, BFI, PSI, DT,
|
||||
!LocalsUsed.empty() || HasLocalInlineAsmSymbol,
|
||||
CantBePromoted);
|
||||
CantBePromoted, IsThinLTO);
|
||||
}
|
||||
|
||||
// Compute summaries for all variables defined in module, and save in the
|
||||
@@ -545,11 +591,6 @@ ModuleSummaryIndex llvm::buildModuleSummaryIndex(
|
||||
setLiveRoot(Index, "llvm.global_dtors");
|
||||
setLiveRoot(Index, "llvm.global.annotations");
|
||||
|
||||
bool IsThinLTO = true;
|
||||
if (auto *MD =
|
||||
mdconst::extract_or_null<ConstantInt>(M.getModuleFlag("ThinLTO")))
|
||||
IsThinLTO = MD->getZExtValue();
|
||||
|
||||
for (auto &GlobalList : Index) {
|
||||
// Ignore entries for references that are undefined in the current module.
|
||||
if (GlobalList.second.SummaryList.empty())
|
||||
|
||||
Reference in New Issue
Block a user