aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2023-02-11 12:38:04 +0000
committerDimitry Andric <dim@FreeBSD.org>2023-02-11 12:38:11 +0000
commite3b557809604d036af6e00c60f012c2025b59a5e (patch)
tree8a11ba2269a3b669601e2fd41145b174008f4da8 /llvm/lib/Analysis/ModuleSummaryAnalysis.cpp
parent08e8dd7b9db7bb4a9de26d44c1cbfd24e869c014 (diff)
Diffstat (limited to 'llvm/lib/Analysis/ModuleSummaryAnalysis.cpp')
-rw-r--r--llvm/lib/Analysis/ModuleSummaryAnalysis.cpp77
1 files changed, 68 insertions, 9 deletions
diff --git a/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp b/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp
index efe60586979a..3dfa2d821e83 100644
--- a/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp
+++ b/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp
@@ -24,6 +24,7 @@
#include "llvm/Analysis/BranchProbabilityInfo.h"
#include "llvm/Analysis/IndirectCallPromotionAnalysis.h"
#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Analysis/MemoryProfileInfo.h"
#include "llvm/Analysis/ProfileSummaryInfo.h"
#include "llvm/Analysis/StackSafetyAnalysis.h"
#include "llvm/Analysis/TypeMetadataUtils.h"
@@ -56,14 +57,18 @@
#include <vector>
using namespace llvm;
+using namespace llvm::memprof;
#define DEBUG_TYPE "module-summary-analysis"
// Option to force edges cold which will block importing when the
// -import-cold-multiplier is set to 0. Useful for debugging.
+namespace llvm {
FunctionSummary::ForceSummaryHotnessType ForceSummaryEdgesCold =
FunctionSummary::FSHT_None;
-cl::opt<FunctionSummary::ForceSummaryHotnessType, true> FSEC(
+} // namespace llvm
+
+static cl::opt<FunctionSummary::ForceSummaryHotnessType, true> FSEC(
"force-summary-edges-cold", cl::Hidden, cl::location(ForceSummaryEdgesCold),
cl::desc("Force all edges in the function summary to cold"),
cl::values(clEnumValN(FunctionSummary::FSHT_None, "none", "None."),
@@ -71,10 +76,9 @@ cl::opt<FunctionSummary::ForceSummaryHotnessType, true> FSEC(
"all-non-critical", "All non-critical edges."),
clEnumValN(FunctionSummary::FSHT_All, "all", "All edges.")));
-cl::opt<std::string> ModuleSummaryDotFile(
- "module-summary-dot-file", cl::init(""), cl::Hidden,
- cl::value_desc("filename"),
- cl::desc("File to emit dot graph of new summary into."));
+static cl::opt<std::string> ModuleSummaryDotFile(
+ "module-summary-dot-file", cl::Hidden, cl::value_desc("filename"),
+ cl::desc("File to emit dot graph of new summary into"));
// Walk through the operands of a given User via worklist iteration and populate
// the set of GlobalValue references encountered. Invoked either on an
@@ -275,6 +279,9 @@ static void computeFunctionSummary(
std::vector<const Instruction *> NonVolatileLoads;
std::vector<const Instruction *> NonVolatileStores;
+ std::vector<CallsiteInfo> Callsites;
+ std::vector<AllocInfo> Allocs;
+
bool HasInlineAsmMaybeReferencingInternal = false;
bool HasIndirBranchToBlockAddress = false;
bool HasUnknownCall = false;
@@ -417,6 +424,57 @@ static void computeFunctionSummary(
CallGraphEdges[Index.getOrInsertValueInfo(Candidate.Value)]
.updateHotness(getHotness(Candidate.Count, PSI));
}
+
+ // TODO: Skip indirect calls for now. Need to handle these better, likely
+ // by creating multiple Callsites, one per target, then speculatively
+ // devirtualize while applying clone info in the ThinLTO backends. This
+ // will also be important because we will have a different set of clone
+ // versions per target. This handling needs to match that in the ThinLTO
+ // backend so we handle things consistently for matching of callsite
+ // summaries to instructions.
+ if (!CalledFunction)
+ continue;
+
+ // Compute the list of stack ids first (so we can trim them from the stack
+ // ids on any MIBs).
+ CallStack<MDNode, MDNode::op_iterator> InstCallsite(
+ I.getMetadata(LLVMContext::MD_callsite));
+ auto *MemProfMD = I.getMetadata(LLVMContext::MD_memprof);
+ if (MemProfMD) {
+ std::vector<MIBInfo> MIBs;
+ for (auto &MDOp : MemProfMD->operands()) {
+ auto *MIBMD = cast<const MDNode>(MDOp);
+ MDNode *StackNode = getMIBStackNode(MIBMD);
+ assert(StackNode);
+ SmallVector<unsigned> StackIdIndices;
+ CallStack<MDNode, MDNode::op_iterator> StackContext(StackNode);
+ // Collapse out any on the allocation call (inlining).
+ for (auto ContextIter =
+ StackContext.beginAfterSharedPrefix(InstCallsite);
+ ContextIter != StackContext.end(); ++ContextIter) {
+ unsigned StackIdIdx = Index.addOrGetStackIdIndex(*ContextIter);
+ // If this is a direct recursion, simply skip the duplicate
+ // entries. If this is mutual recursion, handling is left to
+ // the LTO link analysis client.
+ if (StackIdIndices.empty() || StackIdIndices.back() != StackIdIdx)
+ StackIdIndices.push_back(StackIdIdx);
+ }
+ MIBs.push_back(
+ MIBInfo(getMIBAllocType(MIBMD), std::move(StackIdIndices)));
+ }
+ Allocs.push_back(AllocInfo(std::move(MIBs)));
+ } else if (!InstCallsite.empty()) {
+ SmallVector<unsigned> StackIdIndices;
+ for (auto StackId : InstCallsite)
+ StackIdIndices.push_back(Index.addOrGetStackIdIndex(StackId));
+ // Use the original CalledValue, in case it was an alias. We want
+ // to record the call edge to the alias in that case. Eventually
+ // an alias summary will be created to associate the alias and
+ // aliasee.
+ auto CalleeValueInfo =
+ Index.getOrInsertValueInfo(cast<GlobalValue>(CalledValue));
+ Callsites.push_back({CalleeValueInfo, StackIdIndices});
+ }
}
}
Index.addBlockCount(F.size());
@@ -492,8 +550,7 @@ static void computeFunctionSummary(
F.getLinkage(), F.getVisibility(), NotEligibleForImport,
/* Live = */ false, F.isDSOLocal(), F.canBeOmittedFromSymbolTable());
FunctionSummary::FFlags FunFlags{
- F.hasFnAttribute(Attribute::ReadNone),
- F.hasFnAttribute(Attribute::ReadOnly),
+ F.doesNotAccessMemory(), F.onlyReadsMemory() && !F.doesNotAccessMemory(),
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.
@@ -509,7 +566,8 @@ static void computeFunctionSummary(
CallGraphEdges.takeVector(), TypeTests.takeVector(),
TypeTestAssumeVCalls.takeVector(), TypeCheckedLoadVCalls.takeVector(),
TypeTestAssumeConstVCalls.takeVector(),
- TypeCheckedLoadConstVCalls.takeVector(), std::move(ParamAccesses));
+ TypeCheckedLoadConstVCalls.takeVector(), std::move(ParamAccesses),
+ std::move(Callsites), std::move(Allocs));
if (NonRenamableLocal)
CantBePromoted.insert(F.getGUID());
Index.addGlobalValueSummary(F, std::move(FuncSummary));
@@ -758,7 +816,8 @@ ModuleSummaryIndex llvm::buildModuleSummaryIndex(
ArrayRef<FunctionSummary::VFuncId>{},
ArrayRef<FunctionSummary::ConstVCall>{},
ArrayRef<FunctionSummary::ConstVCall>{},
- ArrayRef<FunctionSummary::ParamAccess>{});
+ ArrayRef<FunctionSummary::ParamAccess>{},
+ ArrayRef<CallsiteInfo>{}, ArrayRef<AllocInfo>{});
Index.addGlobalValueSummary(*GV, std::move(Summary));
} else {
std::unique_ptr<GlobalVarSummary> Summary =