- ///===- MachineOptimizationRemarkEmitter.h - Opt Diagnostics -*- C++ -*----===// 
- /// 
- /// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 
- /// See https://llvm.org/LICENSE.txt for license information. 
- /// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 
- /// 
- ///===---------------------------------------------------------------------===// 
- /// \file 
- /// Optimization diagnostic interfaces for machine passes.  It's packaged as an 
- /// analysis pass so that by using this service passes become dependent on MBFI 
- /// as well.  MBFI is used to compute the "hotness" of the diagnostic message. 
- /// 
- ///===---------------------------------------------------------------------===// 
-   
- #ifndef LLVM_CODEGEN_MACHINEOPTIMIZATIONREMARKEMITTER_H 
- #define LLVM_CODEGEN_MACHINEOPTIMIZATIONREMARKEMITTER_H 
-   
- #include "llvm/CodeGen/MachineFunctionPass.h" 
- #include "llvm/IR/DiagnosticInfo.h" 
- #include "llvm/IR/Function.h" 
- #include <optional> 
-   
- namespace llvm { 
- class MachineBasicBlock; 
- class MachineBlockFrequencyInfo; 
- class MachineInstr; 
-   
- /// Common features for diagnostics dealing with optimization remarks 
- /// that are used by machine passes. 
- class DiagnosticInfoMIROptimization : public DiagnosticInfoOptimizationBase { 
- public: 
-   DiagnosticInfoMIROptimization(enum DiagnosticKind Kind, const char *PassName, 
-                                 StringRef RemarkName, 
-                                 const DiagnosticLocation &Loc, 
-                                 const MachineBasicBlock *MBB) 
-       : DiagnosticInfoOptimizationBase(Kind, DS_Remark, PassName, RemarkName, 
-                                        MBB->getParent()->getFunction(), Loc), 
-         MBB(MBB) {} 
-   
-   /// MI-specific kinds of diagnostic Arguments. 
-   struct MachineArgument : public DiagnosticInfoOptimizationBase::Argument { 
-     /// Print an entire MachineInstr. 
-     MachineArgument(StringRef Key, const MachineInstr &MI); 
-   }; 
-   
-   static bool classof(const DiagnosticInfo *DI) { 
-     return DI->getKind() >= DK_FirstMachineRemark && 
-            DI->getKind() <= DK_LastMachineRemark; 
-   } 
-   
-   const MachineBasicBlock *getBlock() const { return MBB; } 
-   
- private: 
-   const MachineBasicBlock *MBB; 
- }; 
-   
- /// Diagnostic information for applied optimization remarks. 
- class MachineOptimizationRemark : public DiagnosticInfoMIROptimization { 
- public: 
-   /// \p PassName is the name of the pass emitting this diagnostic. If this name 
-   /// matches the regular expression given in -Rpass=, then the diagnostic will 
-   /// be emitted.  \p RemarkName is a textual identifier for the remark.  \p 
-   /// Loc is the debug location and \p MBB is the block that the optimization 
-   /// operates in. 
-   MachineOptimizationRemark(const char *PassName, StringRef RemarkName, 
-                             const DiagnosticLocation &Loc, 
-                             const MachineBasicBlock *MBB) 
-       : DiagnosticInfoMIROptimization(DK_MachineOptimizationRemark, PassName, 
-                                       RemarkName, Loc, MBB) {} 
-   
-   static bool classof(const DiagnosticInfo *DI) { 
-     return DI->getKind() == DK_MachineOptimizationRemark; 
-   } 
-   
-   /// \see DiagnosticInfoOptimizationBase::isEnabled. 
-   bool isEnabled() const override { 
-     const Function &Fn = getFunction(); 
-     LLVMContext &Ctx = Fn.getContext(); 
-     return Ctx.getDiagHandlerPtr()->isPassedOptRemarkEnabled(getPassName()); 
-   } 
- }; 
-   
- /// Diagnostic information for missed-optimization remarks. 
- class MachineOptimizationRemarkMissed : public DiagnosticInfoMIROptimization { 
- public: 
-   /// \p PassName is the name of the pass emitting this diagnostic. If this name 
-   /// matches the regular expression given in -Rpass-missed=, then the 
-   /// diagnostic will be emitted.  \p RemarkName is a textual identifier for the 
-   /// remark.  \p Loc is the debug location and \p MBB is the block that the 
-   /// optimization operates in. 
-   MachineOptimizationRemarkMissed(const char *PassName, StringRef RemarkName, 
-                                   const DiagnosticLocation &Loc, 
-                                   const MachineBasicBlock *MBB) 
-       : DiagnosticInfoMIROptimization(DK_MachineOptimizationRemarkMissed, 
-                                       PassName, RemarkName, Loc, MBB) {} 
-   
-   static bool classof(const DiagnosticInfo *DI) { 
-     return DI->getKind() == DK_MachineOptimizationRemarkMissed; 
-   } 
-   
-   /// \see DiagnosticInfoOptimizationBase::isEnabled. 
-   bool isEnabled() const override { 
-     const Function &Fn = getFunction(); 
-     LLVMContext &Ctx = Fn.getContext(); 
-     return Ctx.getDiagHandlerPtr()->isMissedOptRemarkEnabled(getPassName()); 
-   } 
- }; 
-   
- /// Diagnostic information for optimization analysis remarks. 
- class MachineOptimizationRemarkAnalysis : public DiagnosticInfoMIROptimization { 
- public: 
-   /// \p PassName is the name of the pass emitting this diagnostic. If this name 
-   /// matches the regular expression given in -Rpass-analysis=, then the 
-   /// diagnostic will be emitted.  \p RemarkName is a textual identifier for the 
-   /// remark.  \p Loc is the debug location and \p MBB is the block that the 
-   /// optimization operates in. 
-   MachineOptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName, 
-                                     const DiagnosticLocation &Loc, 
-                                     const MachineBasicBlock *MBB) 
-       : DiagnosticInfoMIROptimization(DK_MachineOptimizationRemarkAnalysis, 
-                                       PassName, RemarkName, Loc, MBB) {} 
-   
-   MachineOptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName, 
-                                     const MachineInstr *MI) 
-       : DiagnosticInfoMIROptimization(DK_MachineOptimizationRemarkAnalysis, 
-                                       PassName, RemarkName, MI->getDebugLoc(), 
-                                       MI->getParent()) {} 
-   
-   static bool classof(const DiagnosticInfo *DI) { 
-     return DI->getKind() == DK_MachineOptimizationRemarkAnalysis; 
-   } 
-   
-   /// \see DiagnosticInfoOptimizationBase::isEnabled. 
-   bool isEnabled() const override { 
-     const Function &Fn = getFunction(); 
-     LLVMContext &Ctx = Fn.getContext(); 
-     return Ctx.getDiagHandlerPtr()->isAnalysisRemarkEnabled(getPassName()); 
-   } 
- }; 
-   
- /// Extend llvm::ore:: with MI-specific helper names. 
- namespace ore { 
- using MNV = DiagnosticInfoMIROptimization::MachineArgument; 
- } 
-   
- /// The optimization diagnostic interface. 
- /// 
- /// It allows reporting when optimizations are performed and when they are not 
- /// along with the reasons for it.  Hotness information of the corresponding 
- /// code region can be included in the remark if DiagnosticsHotnessRequested is 
- /// enabled in the LLVM context. 
- class MachineOptimizationRemarkEmitter { 
- public: 
-   MachineOptimizationRemarkEmitter(MachineFunction &MF, 
-                                    MachineBlockFrequencyInfo *MBFI) 
-       : MF(MF), MBFI(MBFI) {} 
-   
-   /// Emit an optimization remark. 
-   void emit(DiagnosticInfoOptimizationBase &OptDiag); 
-   
-   /// Whether we allow for extra compile-time budget to perform more 
-   /// analysis to be more informative. 
-   /// 
-   /// This is useful to enable additional missed optimizations to be reported 
-   /// that are normally too noisy.  In this mode, we can use the extra analysis 
-   /// (1) to filter trivial false positives or (2) to provide more context so 
-   /// that non-trivial false positives can be quickly detected by the user. 
-   bool allowExtraAnalysis(StringRef PassName) const { 
-     return ( 
-         MF.getFunction().getContext().getLLVMRemarkStreamer() || 
-         MF.getFunction().getContext().getDiagHandlerPtr()->isAnyRemarkEnabled( 
-             PassName)); 
-   } 
-   
-   /// Take a lambda that returns a remark which will be emitted.  Second 
-   /// argument is only used to restrict this to functions. 
-   template <typename T> 
-   void emit(T RemarkBuilder, decltype(RemarkBuilder()) * = nullptr) { 
-     // Avoid building the remark unless we know there are at least *some* 
-     // remarks enabled. We can't currently check whether remarks are requested 
-     // for the calling pass since that requires actually building the remark. 
-   
-     if (MF.getFunction().getContext().getLLVMRemarkStreamer() || 
-         MF.getFunction() 
-             .getContext() 
-             .getDiagHandlerPtr() 
-             ->isAnyRemarkEnabled()) { 
-       auto R = RemarkBuilder(); 
-       emit((DiagnosticInfoOptimizationBase &)R); 
-     } 
-   } 
-   
-   MachineBlockFrequencyInfo *getBFI() { 
-     return MBFI; 
-   } 
-   
- private: 
-   MachineFunction &MF; 
-   
-   /// MBFI is only set if hotness is requested. 
-   MachineBlockFrequencyInfo *MBFI; 
-   
-   /// Compute hotness from IR value (currently assumed to be a block) if PGO is 
-   /// available. 
-   std::optional<uint64_t> computeHotness(const MachineBasicBlock &MBB); 
-   
-   /// Similar but use value from \p OptDiag and update hotness there. 
-   void computeHotness(DiagnosticInfoMIROptimization &Remark); 
-   
-   /// Only allow verbose messages if we know we're filtering by hotness 
-   /// (BFI is only set in this case). 
-   bool shouldEmitVerbose() { return MBFI != nullptr; } 
- }; 
-   
- /// The analysis pass 
- /// 
- /// Note that this pass shouldn't generally be marked as preserved by other 
- /// passes.  It's holding onto BFI, so if the pass does not preserve BFI, BFI 
- /// could be freed. 
- class MachineOptimizationRemarkEmitterPass : public MachineFunctionPass { 
-   std::unique_ptr<MachineOptimizationRemarkEmitter> ORE; 
-   
- public: 
-   MachineOptimizationRemarkEmitterPass(); 
-   
-   bool runOnMachineFunction(MachineFunction &MF) override; 
-   
-   void getAnalysisUsage(AnalysisUsage &AU) const override; 
-   
-   MachineOptimizationRemarkEmitter &getORE() { 
-     assert(ORE && "pass not run yet"); 
-     return *ORE; 
-   } 
-   
-   static char ID; 
- }; 
- } 
-   
- #endif 
-