aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp
diff options
context:
space:
mode:
authormodimo <modimo@fb.com>2021-09-27 12:24:28 -0700
committermodimo <modimo@fb.com>2021-09-27 12:28:07 -0700
commit20faf789199d31a40c7f1a359361980c65067aab (patch)
tree2979f644ca4617bf88503deb7242ee105c19337a /llvm/lib/Analysis/ModuleSummaryAnalysis.cpp
parentd20d0e145d2fce3a39bd6a76df47455134167cdd (diff)
downloadllvm-20faf789199d31a40c7f1a359361980c65067aab.zip
llvm-20faf789199d31a40c7f1a359361980c65067aab.tar.gz
llvm-20faf789199d31a40c7f1a359361980c65067aab.tar.bz2
[ThinLTO] Add noRecurse and noUnwind thinlink function attribute propagation
Thinlink provides an opportunity to propagate function attributes across modules, enabling additional propagation opportunities. This change propagates (currently default off, turn on with `disable-thinlto-funcattrs=1`) noRecurse and noUnwind based off of function summaries of the prevailing functions in bottom-up call-graph order. Testing on clang self-build: 1. There's a 35-40% increase in noUnwind functions due to the additional propagation opportunities. 2. Throughput is measured at 10-15% increase in thinlink time which itself is 1.5% of E2E link time. Implementation-wise this adds the following summary function attributes: 1. noUnwind: function is noUnwind 2. mayThrow: function contains a non-call instruction that `Instruction::mayThrow` returns true on (e.g. windows SEH instructions) 3. hasUnknownCall: function contains calls that don't make it into the summary call-graph thus should not be propagated from (e.g. indirect for now, could add no-opt functions as well) Testing: Clang self-build passes and 2nd stage build passes check-all ninja check-all with newly added tests passing Reviewed By: tejohnson Differential Revision: https://reviews.llvm.org/D36850
Diffstat (limited to 'llvm/lib/Analysis/ModuleSummaryAnalysis.cpp')
-rw-r--r--llvm/lib/Analysis/ModuleSummaryAnalysis.cpp17
1 files changed, 14 insertions, 3 deletions
diff --git a/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp b/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp
index 6a5320e..7008410 100644
--- a/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp
+++ b/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp
@@ -265,6 +265,8 @@ static void computeFunctionSummary(
bool HasInlineAsmMaybeReferencingInternal = false;
bool HasIndirBranchToBlockAddress = false;
+ bool HasUnknownCall = false;
+ bool MayThrow = false;
for (const BasicBlock &BB : F) {
// We don't allow inlining of function with indirect branch to blockaddress.
// If the blockaddress escapes the function, e.g., via a global variable,
@@ -282,6 +284,7 @@ static void computeFunctionSummary(
if (I.isDebugOrPseudoInst())
continue;
++NumInsts;
+
// Regular LTO module doesn't participate in ThinLTO import,
// so no reference from it can be read/writeonly, since this
// would require importing variable as local copy
@@ -313,8 +316,11 @@ static void computeFunctionSummary(
}
findRefEdges(Index, &I, RefEdges, Visited);
const auto *CB = dyn_cast<CallBase>(&I);
- if (!CB)
+ if (!CB) {
+ if (I.mayThrow())
+ MayThrow = true;
continue;
+ }
const auto *CI = dyn_cast<CallInst>(&I);
// Since we don't know exactly which local values are referenced in inline
@@ -370,6 +376,7 @@ static void computeFunctionSummary(
ValueInfo.updateRelBlockFreq(BBFreq, EntryFreq);
}
} else {
+ HasUnknownCall = true;
// Skip inline assembly calls.
if (CI && CI->isInlineAsm())
continue;
@@ -480,7 +487,8 @@ static void computeFunctionSummary(
// FIXME: refactor this to use the same code that inliner is using.
// Don't try to import functions with noinline attribute.
F.getAttributes().hasFnAttr(Attribute::NoInline),
- F.hasFnAttribute(Attribute::AlwaysInline)};
+ F.hasFnAttribute(Attribute::AlwaysInline),
+ F.hasFnAttribute(Attribute::NoUnwind), MayThrow, HasUnknownCall};
std::vector<FunctionSummary::ParamAccess> ParamAccesses;
if (auto *SSI = GetSSICallback(F))
ParamAccesses = SSI->getParamAccesses(Index);
@@ -726,7 +734,10 @@ ModuleSummaryIndex llvm::buildModuleSummaryIndex(
F->hasFnAttribute(Attribute::NoRecurse),
F->returnDoesNotAlias(),
/* NoInline = */ false,
- F->hasFnAttribute(Attribute::AlwaysInline)},
+ F->hasFnAttribute(Attribute::AlwaysInline),
+ F->hasFnAttribute(Attribute::NoUnwind),
+ /* MayThrow */ true,
+ /* HasUnknownCall */ true},
/*EntryCount=*/0, ArrayRef<ValueInfo>{},
ArrayRef<FunctionSummary::EdgeTy>{},
ArrayRef<GlobalValue::GUID>{},