File indexing completed on 2026-05-10 08:43:16
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef LLVM_ANALYSIS_OPTIMIZATIONREMARKEMITTER_H
0015 #define LLVM_ANALYSIS_OPTIMIZATIONREMARKEMITTER_H
0016
0017 #include "llvm/Analysis/BlockFrequencyInfo.h"
0018 #include "llvm/IR/DiagnosticInfo.h"
0019 #include "llvm/IR/Function.h"
0020 #include "llvm/IR/PassManager.h"
0021 #include "llvm/Pass.h"
0022 #include <optional>
0023
0024 namespace llvm {
0025
0026
0027
0028
0029
0030
0031
0032 class OptimizationRemarkEmitter {
0033 public:
0034 OptimizationRemarkEmitter(const Function *F, BlockFrequencyInfo *BFI)
0035 : F(F), BFI(BFI) {}
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048 OptimizationRemarkEmitter(const Function *F);
0049
0050 OptimizationRemarkEmitter(OptimizationRemarkEmitter &&Arg)
0051 : F(Arg.F), BFI(Arg.BFI) {}
0052
0053 OptimizationRemarkEmitter &operator=(OptimizationRemarkEmitter &&RHS) {
0054 F = RHS.F;
0055 BFI = RHS.BFI;
0056 return *this;
0057 }
0058
0059
0060 bool invalidate(Function &F, const PreservedAnalyses &PA,
0061 FunctionAnalysisManager::Invalidator &Inv);
0062
0063
0064 bool enabled() const {
0065 return F->getContext().getLLVMRemarkStreamer() ||
0066 F->getContext().getDiagHandlerPtr()->isAnyRemarkEnabled();
0067 }
0068
0069
0070
0071 void emit(DiagnosticInfoOptimizationBase &OptDiag);
0072
0073
0074
0075 template <typename T>
0076 void emit(T RemarkBuilder, decltype(RemarkBuilder()) * = nullptr) {
0077
0078
0079
0080
0081 if (enabled()) {
0082 auto R = RemarkBuilder();
0083 static_assert(
0084 std::is_base_of<DiagnosticInfoOptimizationBase, decltype(R)>::value,
0085 "the lambda passed to emit() must return a remark");
0086 emit((DiagnosticInfoOptimizationBase &)R);
0087 }
0088 }
0089
0090
0091
0092
0093
0094
0095
0096
0097 bool allowExtraAnalysis(StringRef PassName) const {
0098 return OptimizationRemarkEmitter::allowExtraAnalysis(*F, PassName);
0099 }
0100 static bool allowExtraAnalysis(const Function &F, StringRef PassName) {
0101 return allowExtraAnalysis(F.getContext(), PassName);
0102 }
0103 static bool allowExtraAnalysis(LLVMContext &Ctx, StringRef PassName) {
0104 return Ctx.getLLVMRemarkStreamer() ||
0105 Ctx.getDiagHandlerPtr()->isAnyRemarkEnabled(PassName);
0106 }
0107
0108 private:
0109 const Function *F;
0110
0111 BlockFrequencyInfo *BFI;
0112
0113
0114 std::unique_ptr<BlockFrequencyInfo> OwnedBFI;
0115
0116
0117
0118 std::optional<uint64_t> computeHotness(const Value *V);
0119
0120
0121 void computeHotness(DiagnosticInfoIROptimization &OptDiag);
0122
0123
0124
0125 bool shouldEmitVerbose() { return BFI != nullptr; }
0126
0127 OptimizationRemarkEmitter(const OptimizationRemarkEmitter &) = delete;
0128 void operator=(const OptimizationRemarkEmitter &) = delete;
0129 };
0130
0131
0132
0133
0134 namespace ore {
0135 using NV = DiagnosticInfoOptimizationBase::Argument;
0136 using setIsVerbose = DiagnosticInfoOptimizationBase::setIsVerbose;
0137 using setExtraArgs = DiagnosticInfoOptimizationBase::setExtraArgs;
0138 }
0139
0140
0141
0142
0143
0144
0145 class OptimizationRemarkEmitterWrapperPass : public FunctionPass {
0146 std::unique_ptr<OptimizationRemarkEmitter> ORE;
0147
0148 public:
0149 OptimizationRemarkEmitterWrapperPass();
0150
0151 bool runOnFunction(Function &F) override;
0152
0153 void getAnalysisUsage(AnalysisUsage &AU) const override;
0154
0155 OptimizationRemarkEmitter &getORE() {
0156 assert(ORE && "pass not run yet");
0157 return *ORE;
0158 }
0159
0160 static char ID;
0161 };
0162
0163 class OptimizationRemarkEmitterAnalysis
0164 : public AnalysisInfoMixin<OptimizationRemarkEmitterAnalysis> {
0165 friend AnalysisInfoMixin<OptimizationRemarkEmitterAnalysis>;
0166 static AnalysisKey Key;
0167
0168 public:
0169
0170 typedef OptimizationRemarkEmitter Result;
0171
0172
0173 Result run(Function &F, FunctionAnalysisManager &AM);
0174 };
0175 }
0176 #endif