File indexing completed on 2026-05-10 08:43:12
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef LLVM_ANALYSIS_CTXPROFANALYSIS_H
0010 #define LLVM_ANALYSIS_CTXPROFANALYSIS_H
0011
0012 #include "llvm/ADT/SetVector.h"
0013 #include "llvm/IR/GlobalValue.h"
0014 #include "llvm/IR/InstrTypes.h"
0015 #include "llvm/IR/IntrinsicInst.h"
0016 #include "llvm/IR/PassManager.h"
0017 #include "llvm/ProfileData/PGOCtxProfReader.h"
0018 #include <optional>
0019
0020 namespace llvm {
0021
0022 class CtxProfAnalysis;
0023
0024
0025
0026
0027 using CtxProfFlatProfile =
0028 std::map<GlobalValue::GUID, SmallVector<uint64_t, 1>>;
0029
0030
0031 class PGOContextualProfile {
0032 friend class CtxProfAnalysis;
0033 friend class CtxProfAnalysisPrinterPass;
0034 struct FunctionInfo {
0035 uint32_t NextCounterIndex = 0;
0036 uint32_t NextCallsiteIndex = 0;
0037 const std::string Name;
0038 PGOCtxProfContext Index;
0039 FunctionInfo(StringRef Name) : Name(Name) {}
0040 };
0041 std::optional<PGOCtxProfContext::CallTargetMapTy> Profiles;
0042
0043
0044 std::map<GlobalValue::GUID, FunctionInfo> FuncInfo;
0045
0046
0047 GlobalValue::GUID getDefinedFunctionGUID(const Function &F) const;
0048
0049
0050
0051 PGOContextualProfile() = default;
0052
0053 void initIndex();
0054
0055 public:
0056 PGOContextualProfile(const PGOContextualProfile &) = delete;
0057 PGOContextualProfile(PGOContextualProfile &&) = default;
0058
0059 operator bool() const { return Profiles.has_value(); }
0060
0061 const PGOCtxProfContext::CallTargetMapTy &profiles() const {
0062 return *Profiles;
0063 }
0064
0065 bool isFunctionKnown(const Function &F) const {
0066 return getDefinedFunctionGUID(F) != 0;
0067 }
0068
0069 StringRef getFunctionName(GlobalValue::GUID GUID) const {
0070 auto It = FuncInfo.find(GUID);
0071 if (It == FuncInfo.end())
0072 return "";
0073 return It->second.Name;
0074 }
0075
0076 uint32_t getNumCounters(const Function &F) const {
0077 assert(isFunctionKnown(F));
0078 return FuncInfo.find(getDefinedFunctionGUID(F))->second.NextCounterIndex;
0079 }
0080
0081 uint32_t getNumCallsites(const Function &F) const {
0082 assert(isFunctionKnown(F));
0083 return FuncInfo.find(getDefinedFunctionGUID(F))->second.NextCallsiteIndex;
0084 }
0085
0086 uint32_t allocateNextCounterIndex(const Function &F) {
0087 assert(isFunctionKnown(F));
0088 return FuncInfo.find(getDefinedFunctionGUID(F))->second.NextCounterIndex++;
0089 }
0090
0091 uint32_t allocateNextCallsiteIndex(const Function &F) {
0092 assert(isFunctionKnown(F));
0093 return FuncInfo.find(getDefinedFunctionGUID(F))->second.NextCallsiteIndex++;
0094 }
0095
0096 using ConstVisitor = function_ref<void(const PGOCtxProfContext &)>;
0097 using Visitor = function_ref<void(PGOCtxProfContext &)>;
0098
0099 void update(Visitor, const Function &F);
0100 void visit(ConstVisitor, const Function *F = nullptr) const;
0101
0102 const CtxProfFlatProfile flatten() const;
0103
0104 bool invalidate(Module &, const PreservedAnalyses &PA,
0105 ModuleAnalysisManager::Invalidator &) {
0106
0107
0108 auto PAC = PA.getChecker<CtxProfAnalysis>();
0109 return !PAC.preservedWhenStateless();
0110 }
0111 };
0112
0113 class CtxProfAnalysis : public AnalysisInfoMixin<CtxProfAnalysis> {
0114 const std::optional<StringRef> Profile;
0115
0116 public:
0117 static AnalysisKey Key;
0118 explicit CtxProfAnalysis(std::optional<StringRef> Profile = std::nullopt);
0119
0120 using Result = PGOContextualProfile;
0121
0122 PGOContextualProfile run(Module &M, ModuleAnalysisManager &MAM);
0123
0124
0125
0126 static InstrProfCallsite *getCallsiteInstrumentation(CallBase &CB);
0127
0128
0129 static InstrProfIncrementInst *getBBInstrumentation(BasicBlock &BB);
0130
0131
0132 static InstrProfIncrementInstStep *getSelectInstrumentation(SelectInst &SI);
0133
0134
0135 static void collectIndirectCallPromotionList(
0136 CallBase &IC, Result &Profile,
0137 SetVector<std::pair<CallBase *, Function *>> &Candidates);
0138 };
0139
0140 class CtxProfAnalysisPrinterPass
0141 : public PassInfoMixin<CtxProfAnalysisPrinterPass> {
0142 public:
0143 enum class PrintMode { Everything, YAML };
0144 explicit CtxProfAnalysisPrinterPass(raw_ostream &OS);
0145
0146 PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
0147 static bool isRequired() { return true; }
0148
0149 private:
0150 raw_ostream &OS;
0151 const PrintMode Mode;
0152 };
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163 class AssignGUIDPass : public PassInfoMixin<AssignGUIDPass> {
0164 public:
0165 explicit AssignGUIDPass() = default;
0166
0167
0168
0169 PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
0170 static const char *GUIDMetadataName;
0171
0172 static uint64_t getGUID(const Function &F);
0173 };
0174
0175 }
0176 #endif