Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. ///===- MachineOptimizationRemarkEmitter.h - Opt Diagnostics -*- C++ -*----===//
  2. ///
  3. /// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. /// See https://llvm.org/LICENSE.txt for license information.
  5. /// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. ///
  7. ///===---------------------------------------------------------------------===//
  8. /// \file
  9. /// Optimization diagnostic interfaces for machine passes.  It's packaged as an
  10. /// analysis pass so that by using this service passes become dependent on MBFI
  11. /// as well.  MBFI is used to compute the "hotness" of the diagnostic message.
  12. ///
  13. ///===---------------------------------------------------------------------===//
  14.  
  15. #ifndef LLVM_CODEGEN_MACHINEOPTIMIZATIONREMARKEMITTER_H
  16. #define LLVM_CODEGEN_MACHINEOPTIMIZATIONREMARKEMITTER_H
  17.  
  18. #include "llvm/CodeGen/MachineFunctionPass.h"
  19. #include "llvm/IR/DiagnosticInfo.h"
  20. #include "llvm/IR/Function.h"
  21. #include <optional>
  22.  
  23. namespace llvm {
  24. class MachineBasicBlock;
  25. class MachineBlockFrequencyInfo;
  26. class MachineInstr;
  27.  
  28. /// Common features for diagnostics dealing with optimization remarks
  29. /// that are used by machine passes.
  30. class DiagnosticInfoMIROptimization : public DiagnosticInfoOptimizationBase {
  31. public:
  32.   DiagnosticInfoMIROptimization(enum DiagnosticKind Kind, const char *PassName,
  33.                                 StringRef RemarkName,
  34.                                 const DiagnosticLocation &Loc,
  35.                                 const MachineBasicBlock *MBB)
  36.       : DiagnosticInfoOptimizationBase(Kind, DS_Remark, PassName, RemarkName,
  37.                                        MBB->getParent()->getFunction(), Loc),
  38.         MBB(MBB) {}
  39.  
  40.   /// MI-specific kinds of diagnostic Arguments.
  41.   struct MachineArgument : public DiagnosticInfoOptimizationBase::Argument {
  42.     /// Print an entire MachineInstr.
  43.     MachineArgument(StringRef Key, const MachineInstr &MI);
  44.   };
  45.  
  46.   static bool classof(const DiagnosticInfo *DI) {
  47.     return DI->getKind() >= DK_FirstMachineRemark &&
  48.            DI->getKind() <= DK_LastMachineRemark;
  49.   }
  50.  
  51.   const MachineBasicBlock *getBlock() const { return MBB; }
  52.  
  53. private:
  54.   const MachineBasicBlock *MBB;
  55. };
  56.  
  57. /// Diagnostic information for applied optimization remarks.
  58. class MachineOptimizationRemark : public DiagnosticInfoMIROptimization {
  59. public:
  60.   /// \p PassName is the name of the pass emitting this diagnostic. If this name
  61.   /// matches the regular expression given in -Rpass=, then the diagnostic will
  62.   /// be emitted.  \p RemarkName is a textual identifier for the remark.  \p
  63.   /// Loc is the debug location and \p MBB is the block that the optimization
  64.   /// operates in.
  65.   MachineOptimizationRemark(const char *PassName, StringRef RemarkName,
  66.                             const DiagnosticLocation &Loc,
  67.                             const MachineBasicBlock *MBB)
  68.       : DiagnosticInfoMIROptimization(DK_MachineOptimizationRemark, PassName,
  69.                                       RemarkName, Loc, MBB) {}
  70.  
  71.   static bool classof(const DiagnosticInfo *DI) {
  72.     return DI->getKind() == DK_MachineOptimizationRemark;
  73.   }
  74.  
  75.   /// \see DiagnosticInfoOptimizationBase::isEnabled.
  76.   bool isEnabled() const override {
  77.     const Function &Fn = getFunction();
  78.     LLVMContext &Ctx = Fn.getContext();
  79.     return Ctx.getDiagHandlerPtr()->isPassedOptRemarkEnabled(getPassName());
  80.   }
  81. };
  82.  
  83. /// Diagnostic information for missed-optimization remarks.
  84. class MachineOptimizationRemarkMissed : public DiagnosticInfoMIROptimization {
  85. public:
  86.   /// \p PassName is the name of the pass emitting this diagnostic. If this name
  87.   /// matches the regular expression given in -Rpass-missed=, then the
  88.   /// diagnostic will be emitted.  \p RemarkName is a textual identifier for the
  89.   /// remark.  \p Loc is the debug location and \p MBB is the block that the
  90.   /// optimization operates in.
  91.   MachineOptimizationRemarkMissed(const char *PassName, StringRef RemarkName,
  92.                                   const DiagnosticLocation &Loc,
  93.                                   const MachineBasicBlock *MBB)
  94.       : DiagnosticInfoMIROptimization(DK_MachineOptimizationRemarkMissed,
  95.                                       PassName, RemarkName, Loc, MBB) {}
  96.  
  97.   static bool classof(const DiagnosticInfo *DI) {
  98.     return DI->getKind() == DK_MachineOptimizationRemarkMissed;
  99.   }
  100.  
  101.   /// \see DiagnosticInfoOptimizationBase::isEnabled.
  102.   bool isEnabled() const override {
  103.     const Function &Fn = getFunction();
  104.     LLVMContext &Ctx = Fn.getContext();
  105.     return Ctx.getDiagHandlerPtr()->isMissedOptRemarkEnabled(getPassName());
  106.   }
  107. };
  108.  
  109. /// Diagnostic information for optimization analysis remarks.
  110. class MachineOptimizationRemarkAnalysis : public DiagnosticInfoMIROptimization {
  111. public:
  112.   /// \p PassName is the name of the pass emitting this diagnostic. If this name
  113.   /// matches the regular expression given in -Rpass-analysis=, then the
  114.   /// diagnostic will be emitted.  \p RemarkName is a textual identifier for the
  115.   /// remark.  \p Loc is the debug location and \p MBB is the block that the
  116.   /// optimization operates in.
  117.   MachineOptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName,
  118.                                     const DiagnosticLocation &Loc,
  119.                                     const MachineBasicBlock *MBB)
  120.       : DiagnosticInfoMIROptimization(DK_MachineOptimizationRemarkAnalysis,
  121.                                       PassName, RemarkName, Loc, MBB) {}
  122.  
  123.   MachineOptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName,
  124.                                     const MachineInstr *MI)
  125.       : DiagnosticInfoMIROptimization(DK_MachineOptimizationRemarkAnalysis,
  126.                                       PassName, RemarkName, MI->getDebugLoc(),
  127.                                       MI->getParent()) {}
  128.  
  129.   static bool classof(const DiagnosticInfo *DI) {
  130.     return DI->getKind() == DK_MachineOptimizationRemarkAnalysis;
  131.   }
  132.  
  133.   /// \see DiagnosticInfoOptimizationBase::isEnabled.
  134.   bool isEnabled() const override {
  135.     const Function &Fn = getFunction();
  136.     LLVMContext &Ctx = Fn.getContext();
  137.     return Ctx.getDiagHandlerPtr()->isAnalysisRemarkEnabled(getPassName());
  138.   }
  139. };
  140.  
  141. /// Extend llvm::ore:: with MI-specific helper names.
  142. namespace ore {
  143. using MNV = DiagnosticInfoMIROptimization::MachineArgument;
  144. }
  145.  
  146. /// The optimization diagnostic interface.
  147. ///
  148. /// It allows reporting when optimizations are performed and when they are not
  149. /// along with the reasons for it.  Hotness information of the corresponding
  150. /// code region can be included in the remark if DiagnosticsHotnessRequested is
  151. /// enabled in the LLVM context.
  152. class MachineOptimizationRemarkEmitter {
  153. public:
  154.   MachineOptimizationRemarkEmitter(MachineFunction &MF,
  155.                                    MachineBlockFrequencyInfo *MBFI)
  156.       : MF(MF), MBFI(MBFI) {}
  157.  
  158.   /// Emit an optimization remark.
  159.   void emit(DiagnosticInfoOptimizationBase &OptDiag);
  160.  
  161.   /// Whether we allow for extra compile-time budget to perform more
  162.   /// analysis to be more informative.
  163.   ///
  164.   /// This is useful to enable additional missed optimizations to be reported
  165.   /// that are normally too noisy.  In this mode, we can use the extra analysis
  166.   /// (1) to filter trivial false positives or (2) to provide more context so
  167.   /// that non-trivial false positives can be quickly detected by the user.
  168.   bool allowExtraAnalysis(StringRef PassName) const {
  169.     return (
  170.         MF.getFunction().getContext().getLLVMRemarkStreamer() ||
  171.         MF.getFunction().getContext().getDiagHandlerPtr()->isAnyRemarkEnabled(
  172.             PassName));
  173.   }
  174.  
  175.   /// Take a lambda that returns a remark which will be emitted.  Second
  176.   /// argument is only used to restrict this to functions.
  177.   template <typename T>
  178.   void emit(T RemarkBuilder, decltype(RemarkBuilder()) * = nullptr) {
  179.     // Avoid building the remark unless we know there are at least *some*
  180.     // remarks enabled. We can't currently check whether remarks are requested
  181.     // for the calling pass since that requires actually building the remark.
  182.  
  183.     if (MF.getFunction().getContext().getLLVMRemarkStreamer() ||
  184.         MF.getFunction()
  185.             .getContext()
  186.             .getDiagHandlerPtr()
  187.             ->isAnyRemarkEnabled()) {
  188.       auto R = RemarkBuilder();
  189.       emit((DiagnosticInfoOptimizationBase &)R);
  190.     }
  191.   }
  192.  
  193.   MachineBlockFrequencyInfo *getBFI() {
  194.     return MBFI;
  195.   }
  196.  
  197. private:
  198.   MachineFunction &MF;
  199.  
  200.   /// MBFI is only set if hotness is requested.
  201.   MachineBlockFrequencyInfo *MBFI;
  202.  
  203.   /// Compute hotness from IR value (currently assumed to be a block) if PGO is
  204.   /// available.
  205.   std::optional<uint64_t> computeHotness(const MachineBasicBlock &MBB);
  206.  
  207.   /// Similar but use value from \p OptDiag and update hotness there.
  208.   void computeHotness(DiagnosticInfoMIROptimization &Remark);
  209.  
  210.   /// Only allow verbose messages if we know we're filtering by hotness
  211.   /// (BFI is only set in this case).
  212.   bool shouldEmitVerbose() { return MBFI != nullptr; }
  213. };
  214.  
  215. /// The analysis pass
  216. ///
  217. /// Note that this pass shouldn't generally be marked as preserved by other
  218. /// passes.  It's holding onto BFI, so if the pass does not preserve BFI, BFI
  219. /// could be freed.
  220. class MachineOptimizationRemarkEmitterPass : public MachineFunctionPass {
  221.   std::unique_ptr<MachineOptimizationRemarkEmitter> ORE;
  222.  
  223. public:
  224.   MachineOptimizationRemarkEmitterPass();
  225.  
  226.   bool runOnMachineFunction(MachineFunction &MF) override;
  227.  
  228.   void getAnalysisUsage(AnalysisUsage &AU) const override;
  229.  
  230.   MachineOptimizationRemarkEmitter &getORE() {
  231.     assert(ORE && "pass not run yet");
  232.     return *ORE;
  233.   }
  234.  
  235.   static char ID;
  236. };
  237. }
  238.  
  239. #endif
  240.