File indexing completed on 2026-05-10 08:43:31
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #ifndef LLVM_CODEGEN_MACHINEOPTIMIZATIONREMARKEMITTER_H
0016 #define LLVM_CODEGEN_MACHINEOPTIMIZATIONREMARKEMITTER_H
0017
0018 #include "llvm/CodeGen/MachineFunctionPass.h"
0019 #include "llvm/CodeGen/MachinePassManager.h"
0020 #include "llvm/IR/DiagnosticInfo.h"
0021 #include "llvm/IR/Function.h"
0022 #include <optional>
0023
0024 namespace llvm {
0025 class MachineBasicBlock;
0026 class MachineBlockFrequencyInfo;
0027 class MachineInstr;
0028
0029
0030
0031 class DiagnosticInfoMIROptimization : public DiagnosticInfoOptimizationBase {
0032 public:
0033 DiagnosticInfoMIROptimization(enum DiagnosticKind Kind, const char *PassName,
0034 StringRef RemarkName,
0035 const DiagnosticLocation &Loc,
0036 const MachineBasicBlock *MBB)
0037 : DiagnosticInfoOptimizationBase(Kind, DS_Remark, PassName, RemarkName,
0038 MBB->getParent()->getFunction(), Loc),
0039 MBB(MBB) {}
0040
0041
0042 struct MachineArgument : public DiagnosticInfoOptimizationBase::Argument {
0043
0044 MachineArgument(StringRef Key, const MachineInstr &MI);
0045 };
0046
0047 static bool classof(const DiagnosticInfo *DI) {
0048 return DI->getKind() >= DK_FirstMachineRemark &&
0049 DI->getKind() <= DK_LastMachineRemark;
0050 }
0051
0052 const MachineBasicBlock *getBlock() const { return MBB; }
0053
0054 private:
0055 const MachineBasicBlock *MBB;
0056 };
0057
0058
0059 class MachineOptimizationRemark : public DiagnosticInfoMIROptimization {
0060 public:
0061
0062
0063
0064
0065
0066 MachineOptimizationRemark(const char *PassName, StringRef RemarkName,
0067 const DiagnosticLocation &Loc,
0068 const MachineBasicBlock *MBB)
0069 : DiagnosticInfoMIROptimization(DK_MachineOptimizationRemark, PassName,
0070 RemarkName, Loc, MBB) {}
0071
0072 static bool classof(const DiagnosticInfo *DI) {
0073 return DI->getKind() == DK_MachineOptimizationRemark;
0074 }
0075
0076
0077 bool isEnabled() const override {
0078 const Function &Fn = getFunction();
0079 LLVMContext &Ctx = Fn.getContext();
0080 return Ctx.getDiagHandlerPtr()->isPassedOptRemarkEnabled(getPassName());
0081 }
0082 };
0083
0084
0085 class MachineOptimizationRemarkMissed : public DiagnosticInfoMIROptimization {
0086 public:
0087
0088
0089
0090
0091
0092 MachineOptimizationRemarkMissed(const char *PassName, StringRef RemarkName,
0093 const DiagnosticLocation &Loc,
0094 const MachineBasicBlock *MBB)
0095 : DiagnosticInfoMIROptimization(DK_MachineOptimizationRemarkMissed,
0096 PassName, RemarkName, Loc, MBB) {}
0097
0098 static bool classof(const DiagnosticInfo *DI) {
0099 return DI->getKind() == DK_MachineOptimizationRemarkMissed;
0100 }
0101
0102
0103 bool isEnabled() const override {
0104 const Function &Fn = getFunction();
0105 LLVMContext &Ctx = Fn.getContext();
0106 return Ctx.getDiagHandlerPtr()->isMissedOptRemarkEnabled(getPassName());
0107 }
0108 };
0109
0110
0111 class MachineOptimizationRemarkAnalysis : public DiagnosticInfoMIROptimization {
0112 public:
0113
0114
0115
0116
0117
0118 MachineOptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName,
0119 const DiagnosticLocation &Loc,
0120 const MachineBasicBlock *MBB)
0121 : DiagnosticInfoMIROptimization(DK_MachineOptimizationRemarkAnalysis,
0122 PassName, RemarkName, Loc, MBB) {}
0123
0124 MachineOptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName,
0125 const MachineInstr *MI)
0126 : DiagnosticInfoMIROptimization(DK_MachineOptimizationRemarkAnalysis,
0127 PassName, RemarkName, MI->getDebugLoc(),
0128 MI->getParent()) {}
0129
0130 static bool classof(const DiagnosticInfo *DI) {
0131 return DI->getKind() == DK_MachineOptimizationRemarkAnalysis;
0132 }
0133
0134
0135 bool isEnabled() const override {
0136 const Function &Fn = getFunction();
0137 LLVMContext &Ctx = Fn.getContext();
0138 return Ctx.getDiagHandlerPtr()->isAnalysisRemarkEnabled(getPassName());
0139 }
0140 };
0141
0142
0143 namespace ore {
0144 using MNV = DiagnosticInfoMIROptimization::MachineArgument;
0145 }
0146
0147
0148
0149
0150
0151
0152
0153 class MachineOptimizationRemarkEmitter {
0154 public:
0155 MachineOptimizationRemarkEmitter(MachineFunction &MF,
0156 MachineBlockFrequencyInfo *MBFI)
0157 : MF(MF), MBFI(MBFI) {}
0158
0159 MachineOptimizationRemarkEmitter(MachineOptimizationRemarkEmitter &&) =
0160 default;
0161
0162
0163 bool invalidate(MachineFunction &MF, const PreservedAnalyses &PA,
0164 MachineFunctionAnalysisManager::Invalidator &Inv);
0165
0166
0167 void emit(DiagnosticInfoOptimizationBase &OptDiag);
0168
0169
0170
0171
0172
0173
0174
0175
0176 bool allowExtraAnalysis(StringRef PassName) const {
0177 return (
0178 MF.getFunction().getContext().getLLVMRemarkStreamer() ||
0179 MF.getFunction().getContext().getDiagHandlerPtr()->isAnyRemarkEnabled(
0180 PassName));
0181 }
0182
0183
0184
0185 template <typename T>
0186 void emit(T RemarkBuilder, decltype(RemarkBuilder()) * = nullptr) {
0187
0188
0189
0190
0191 if (MF.getFunction().getContext().getLLVMRemarkStreamer() ||
0192 MF.getFunction()
0193 .getContext()
0194 .getDiagHandlerPtr()
0195 ->isAnyRemarkEnabled()) {
0196 auto R = RemarkBuilder();
0197 emit((DiagnosticInfoOptimizationBase &)R);
0198 }
0199 }
0200
0201 MachineBlockFrequencyInfo *getBFI() {
0202 return MBFI;
0203 }
0204
0205 private:
0206 MachineFunction &MF;
0207
0208
0209 MachineBlockFrequencyInfo *MBFI;
0210
0211
0212
0213 std::optional<uint64_t> computeHotness(const MachineBasicBlock &MBB);
0214
0215
0216 void computeHotness(DiagnosticInfoMIROptimization &Remark);
0217
0218
0219
0220 bool shouldEmitVerbose() { return MBFI != nullptr; }
0221 };
0222
0223
0224 class MachineOptimizationRemarkEmitterAnalysis
0225 : public AnalysisInfoMixin<MachineOptimizationRemarkEmitterAnalysis> {
0226 friend AnalysisInfoMixin<MachineOptimizationRemarkEmitterAnalysis>;
0227 static AnalysisKey Key;
0228
0229 public:
0230 using Result = MachineOptimizationRemarkEmitter;
0231 Result run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM);
0232 };
0233
0234
0235
0236
0237
0238
0239 class MachineOptimizationRemarkEmitterPass : public MachineFunctionPass {
0240 std::unique_ptr<MachineOptimizationRemarkEmitter> ORE;
0241
0242 public:
0243 MachineOptimizationRemarkEmitterPass();
0244
0245 bool runOnMachineFunction(MachineFunction &MF) override;
0246
0247 void getAnalysisUsage(AnalysisUsage &AU) const override;
0248
0249 MachineOptimizationRemarkEmitter &getORE() {
0250 assert(ORE && "pass not run yet");
0251 return *ORE;
0252 }
0253
0254 static char ID;
0255 };
0256 }
0257
0258 #endif