diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2023-12-18 20:30:12 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2024-04-06 20:11:55 +0000 |
commit | 5f757f3ff9144b609b3c433dfd370cc6bdc191ad (patch) | |
tree | 1b4e980b866cd26a00af34c0a653eb640bd09caf /contrib/llvm-project/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp | |
parent | 3e1c8a35f741a5d114d0ba670b15191355711fe9 (diff) | |
parent | 312c0ed19cc5276a17bacf2120097bec4515b0f1 (diff) | |
download | src-5f757f3ff9144b609b3c433dfd370cc6bdc191ad.tar.gz src-5f757f3ff9144b609b3c433dfd370cc6bdc191ad.zip |
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp')
-rw-r--r-- | contrib/llvm-project/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp | 63 |
1 files changed, 44 insertions, 19 deletions
diff --git a/contrib/llvm-project/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp b/contrib/llvm-project/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp index 2076ed48ea34..1f15e9478324 100644 --- a/contrib/llvm-project/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp +++ b/contrib/llvm-project/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp @@ -93,7 +93,7 @@ extern cl::opt<bool> ScalePartialSampleProfileWorkingSetSize; // instruction in it takes an address of any basic block, because instruction // can only take an address of basic block located in the same function. static bool findRefEdges(ModuleSummaryIndex &Index, const User *CurUser, - SetVector<ValueInfo> &RefEdges, + SetVector<ValueInfo, std::vector<ValueInfo>> &RefEdges, SmallPtrSet<const User *, 8> &Visited) { bool HasBlockAddress = false; SmallVector<const User *, 32> Worklist; @@ -144,9 +144,12 @@ static bool isNonRenamableLocal(const GlobalValue &GV) { /// Determine whether this call has all constant integer arguments (excluding /// "this") and summarize it to VCalls or ConstVCalls as appropriate. -static void addVCallToSet(DevirtCallSite Call, GlobalValue::GUID Guid, - SetVector<FunctionSummary::VFuncId> &VCalls, - SetVector<FunctionSummary::ConstVCall> &ConstVCalls) { +static void addVCallToSet( + DevirtCallSite Call, GlobalValue::GUID Guid, + SetVector<FunctionSummary::VFuncId, std::vector<FunctionSummary::VFuncId>> + &VCalls, + SetVector<FunctionSummary::ConstVCall, + std::vector<FunctionSummary::ConstVCall>> &ConstVCalls) { std::vector<uint64_t> Args; // Start from the second argument to skip the "this" pointer. for (auto &Arg : drop_begin(Call.CB.args())) { @@ -163,11 +166,18 @@ static void addVCallToSet(DevirtCallSite Call, GlobalValue::GUID Guid, /// If this intrinsic call requires that we add information to the function /// summary, do so via the non-constant reference arguments. static void addIntrinsicToSummary( - const CallInst *CI, SetVector<GlobalValue::GUID> &TypeTests, - SetVector<FunctionSummary::VFuncId> &TypeTestAssumeVCalls, - SetVector<FunctionSummary::VFuncId> &TypeCheckedLoadVCalls, - SetVector<FunctionSummary::ConstVCall> &TypeTestAssumeConstVCalls, - SetVector<FunctionSummary::ConstVCall> &TypeCheckedLoadConstVCalls, + const CallInst *CI, + SetVector<GlobalValue::GUID, std::vector<GlobalValue::GUID>> &TypeTests, + SetVector<FunctionSummary::VFuncId, std::vector<FunctionSummary::VFuncId>> + &TypeTestAssumeVCalls, + SetVector<FunctionSummary::VFuncId, std::vector<FunctionSummary::VFuncId>> + &TypeCheckedLoadVCalls, + SetVector<FunctionSummary::ConstVCall, + std::vector<FunctionSummary::ConstVCall>> + &TypeTestAssumeConstVCalls, + SetVector<FunctionSummary::ConstVCall, + std::vector<FunctionSummary::ConstVCall>> + &TypeCheckedLoadConstVCalls, DominatorTree &DT) { switch (CI->getCalledFunction()->getIntrinsicID()) { case Intrinsic::type_test: @@ -269,12 +279,14 @@ static void computeFunctionSummary( MapVector<ValueInfo, CalleeInfo, DenseMap<ValueInfo, unsigned>, std::vector<std::pair<ValueInfo, CalleeInfo>>> CallGraphEdges; - SetVector<ValueInfo> RefEdges, LoadRefEdges, StoreRefEdges; - SetVector<GlobalValue::GUID> TypeTests; - SetVector<FunctionSummary::VFuncId> TypeTestAssumeVCalls, - TypeCheckedLoadVCalls; - SetVector<FunctionSummary::ConstVCall> TypeTestAssumeConstVCalls, - TypeCheckedLoadConstVCalls; + SetVector<ValueInfo, std::vector<ValueInfo>> RefEdges, LoadRefEdges, + StoreRefEdges; + SetVector<GlobalValue::GUID, std::vector<GlobalValue::GUID>> TypeTests; + SetVector<FunctionSummary::VFuncId, std::vector<FunctionSummary::VFuncId>> + TypeTestAssumeVCalls, TypeCheckedLoadVCalls; + SetVector<FunctionSummary::ConstVCall, + std::vector<FunctionSummary::ConstVCall>> + TypeTestAssumeConstVCalls, TypeCheckedLoadConstVCalls; ICallPromotionAnalysis ICallAnalysis; SmallPtrSet<const User *, 8> Visited; @@ -293,6 +305,7 @@ static void computeFunctionSummary( bool HasInlineAsmMaybeReferencingInternal = false; bool HasIndirBranchToBlockAddress = false; + bool HasIFuncCall = false; bool HasUnknownCall = false; bool MayThrow = false; for (const BasicBlock &BB : F) { @@ -396,15 +409,27 @@ static void computeFunctionSummary( auto &ValueInfo = CallGraphEdges[Index.getOrInsertValueInfo( cast<GlobalValue>(CalledValue))]; ValueInfo.updateHotness(Hotness); + if (CB->isTailCall()) + ValueInfo.setHasTailCall(true); // Add the relative block frequency to CalleeInfo if there is no profile // information. if (BFI != nullptr && Hotness == CalleeInfo::HotnessType::Unknown) { uint64_t BBFreq = BFI->getBlockFreq(&BB).getFrequency(); - uint64_t EntryFreq = BFI->getEntryFreq(); + uint64_t EntryFreq = BFI->getEntryFreq().getFrequency(); ValueInfo.updateRelBlockFreq(BBFreq, EntryFreq); } } else { HasUnknownCall = true; + // If F is imported, a local linkage ifunc (e.g. target_clones on a + // static function) called by F will be cloned. Since summaries don't + // track ifunc, we do not know implementation functions referenced by + // the ifunc resolver need to be promoted in the exporter, and we will + // get linker errors due to cloned declarations for implementation + // functions. As a simple fix, just mark F as not eligible for import. + // Non-local ifunc is not cloned and does not have the issue. + if (auto *GI = dyn_cast_if_present<GlobalIFunc>(CalledValue)) + if (GI->hasLocalLinkage()) + HasIFuncCall = true; // Skip inline assembly calls. if (CI && CI->isInlineAsm()) continue; @@ -505,7 +530,7 @@ static void computeFunctionSummary( std::vector<ValueInfo> Refs; if (IsThinLTO) { auto AddRefEdges = [&](const std::vector<const Instruction *> &Instrs, - SetVector<ValueInfo> &Edges, + SetVector<ValueInfo, std::vector<ValueInfo>> &Edges, SmallPtrSet<const User *, 8> &Cache) { for (const auto *I : Instrs) { Cache.erase(I); @@ -587,7 +612,7 @@ static void computeFunctionSummary( bool NonRenamableLocal = isNonRenamableLocal(F); bool NotEligibleForImport = NonRenamableLocal || HasInlineAsmMaybeReferencingInternal || - HasIndirBranchToBlockAddress; + HasIndirBranchToBlockAddress || HasIFuncCall; GlobalValueSummary::GVFlags Flags( F.getLinkage(), F.getVisibility(), NotEligibleForImport, /* Live = */ false, F.isDSOLocal(), F.canBeOmittedFromSymbolTable()); @@ -710,7 +735,7 @@ static void computeVariableSummary(ModuleSummaryIndex &Index, DenseSet<GlobalValue::GUID> &CantBePromoted, const Module &M, SmallVectorImpl<MDNode *> &Types) { - SetVector<ValueInfo> RefEdges; + SetVector<ValueInfo, std::vector<ValueInfo>> RefEdges; SmallPtrSet<const User *, 8> Visited; bool HasBlockAddress = findRefEdges(Index, &V, RefEdges, Visited); bool NonRenamableLocal = isNonRenamableLocal(V); |