aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2023-12-18 20:30:12 +0000
committerDimitry Andric <dim@FreeBSD.org>2024-04-06 20:11:55 +0000
commit5f757f3ff9144b609b3c433dfd370cc6bdc191ad (patch)
tree1b4e980b866cd26a00af34c0a653eb640bd09caf /contrib/llvm-project/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp
parent3e1c8a35f741a5d114d0ba670b15191355711fe9 (diff)
parent312c0ed19cc5276a17bacf2120097bec4515b0f1 (diff)
downloadsrc-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.cpp63
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);