LCOV - code coverage report
Current view: top level - include/llvm/CodeGen - MachineOptimizationRemarkEmitter.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 18 42 42.9 %
Date: 2018-09-23 13:06:45 Functions: 3 11 27.3 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13