diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2022-03-20 11:40:34 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2022-05-14 11:43:05 +0000 |
commit | 349cc55c9796c4596a5b9904cd3281af295f878f (patch) | |
tree | 410c5a785075730a35f1272ca6a7adf72222ad03 /contrib/llvm-project/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp | |
parent | cb2ae6163174b90e999326ecec3699ee093a5d43 (diff) | |
parent | c0981da47d5696fe36474fcf86b4ce03ae3ff818 (diff) |
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp')
-rw-r--r-- | contrib/llvm-project/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp | 46 |
1 files changed, 36 insertions, 10 deletions
diff --git a/contrib/llvm-project/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp b/contrib/llvm-project/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp index e43553222128..d80814852e19 100644 --- a/contrib/llvm-project/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp +++ b/contrib/llvm-project/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp @@ -264,11 +264,27 @@ static void computeFunctionSummary( std::vector<const Instruction *> NonVolatileStores; bool HasInlineAsmMaybeReferencingInternal = false; - for (const BasicBlock &BB : F) + 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, + // inlining may lead to an invalid cross-function reference. So we shouldn't + // import such function either. + if (BB.hasAddressTaken()) { + for (User *U : BlockAddress::get(const_cast<BasicBlock *>(&BB))->users()) + if (!isa<CallBrInst>(*U)) { + HasIndirBranchToBlockAddress = true; + break; + } + } + for (const Instruction &I : BB) { - if (isa<DbgInfoIntrinsic>(I)) + 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 @@ -300,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 @@ -323,7 +342,7 @@ static void computeFunctionSummary( // called aliasee for the checks below. if (auto *GA = dyn_cast<GlobalAlias>(CalledValue)) { assert(!CalledFunction && "Expected null called function in callsite for alias"); - CalledFunction = dyn_cast<Function>(GA->getBaseObject()); + CalledFunction = dyn_cast<Function>(GA->getAliaseeObject()); } // Check if this is a direct call to a known function or a known // intrinsic, or an indirect call with profile data. @@ -357,6 +376,7 @@ static void computeFunctionSummary( ValueInfo.updateRelBlockFreq(BBFreq, EntryFreq); } } else { + HasUnknownCall = true; // Skip inline assembly calls. if (CI && CI->isInlineAsm()) continue; @@ -386,6 +406,7 @@ static void computeFunctionSummary( .updateHotness(getHotness(Candidate.Count, PSI)); } } + } Index.addBlockCount(F.size()); std::vector<ValueInfo> Refs; @@ -452,8 +473,9 @@ static void computeFunctionSummary( : CalleeInfo::HotnessType::Critical); bool NonRenamableLocal = isNonRenamableLocal(F); - bool NotEligibleForImport = - NonRenamableLocal || HasInlineAsmMaybeReferencingInternal; + bool NotEligibleForImport = NonRenamableLocal || + HasInlineAsmMaybeReferencingInternal || + HasIndirBranchToBlockAddress; GlobalValueSummary::GVFlags Flags( F.getLinkage(), F.getVisibility(), NotEligibleForImport, /* Live = */ false, F.isDSOLocal(), @@ -464,8 +486,9 @@ static void computeFunctionSummary( F.hasFnAttribute(Attribute::NoRecurse), F.returnDoesNotAlias(), // FIXME: refactor this to use the same code that inliner is using. // Don't try to import functions with noinline attribute. - F.getAttributes().hasFnAttribute(Attribute::NoInline), - F.hasFnAttribute(Attribute::AlwaysInline)}; + F.getAttributes().hasFnAttr(Attribute::NoInline), + F.hasFnAttribute(Attribute::AlwaysInline), + F.hasFnAttribute(Attribute::NoUnwind), MayThrow, HasUnknownCall}; std::vector<FunctionSummary::ParamAccess> ParamAccesses; if (auto *SSI = GetSSICallback(F)) ParamAccesses = SSI->getParamAccesses(Index); @@ -622,7 +645,7 @@ computeAliasSummary(ModuleSummaryIndex &Index, const GlobalAlias &A, /* Live = */ false, A.isDSOLocal(), A.hasLinkOnceODRLinkage() && A.hasGlobalUnnamedAddr()); auto AS = std::make_unique<AliasSummary>(Flags); - auto *Aliasee = A.getBaseObject(); + auto *Aliasee = A.getAliaseeObject(); auto AliaseeVI = Index.getValueInfo(Aliasee->getGUID()); assert(AliaseeVI && "Alias expects aliasee summary to be available"); assert(AliaseeVI.getSummaryList().size() == 1 && @@ -711,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>{}, |