LCOV - code coverage report
Current view: top level - include/llvm/Analysis - OptimizationRemarkEmitter.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 13 13 100.0 %
Date: 2018-07-13 00:08:38 Functions: 78 106 73.6 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- OptimizationRemarkEmitter.h - Optimization Diagnostic ----*- 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             : //
      10             : // Optimization diagnostic interfaces.  It's packaged as an analysis pass so
      11             : // that by using this service passes become dependent on BFI as well.  BFI is
      12             : // used to compute the "hotness" of the diagnostic message.
      13             : //===----------------------------------------------------------------------===//
      14             : 
      15             : #ifndef LLVM_IR_OPTIMIZATIONDIAGNOSTICINFO_H
      16             : #define LLVM_IR_OPTIMIZATIONDIAGNOSTICINFO_H
      17             : 
      18             : #include "llvm/ADT/Optional.h"
      19             : #include "llvm/Analysis/BlockFrequencyInfo.h"
      20             : #include "llvm/IR/DiagnosticInfo.h"
      21             : #include "llvm/IR/Function.h"
      22             : #include "llvm/IR/PassManager.h"
      23             : #include "llvm/Pass.h"
      24             : 
      25             : namespace llvm {
      26             : class DebugLoc;
      27             : class Loop;
      28             : class Pass;
      29             : class Twine;
      30             : class Value;
      31             : 
      32             : /// The optimization diagnostic interface.
      33             : ///
      34             : /// It allows reporting when optimizations are performed and when they are not
      35             : /// along with the reasons for it.  Hotness information of the corresponding
      36             : /// code region can be included in the remark if DiagnosticsHotnessRequested is
      37             : /// enabled in the LLVM context.
      38     1826712 : class OptimizationRemarkEmitter {
      39             : public:
      40             :   OptimizationRemarkEmitter(const Function *F, BlockFrequencyInfo *BFI)
      41      394986 :       : F(F), BFI(BFI) {}
      42             : 
      43             :   /// This variant can be used to generate ORE on demand (without the
      44             :   /// analysis pass).
      45             :   ///
      46             :   /// Note that this ctor has a very different cost depending on whether
      47             :   /// F->getContext().getDiagnosticsHotnessRequested() is on or not.  If it's off
      48             :   /// the operation is free.
      49             :   ///
      50             :   /// Whereas if DiagnosticsHotnessRequested is on, it is fairly expensive
      51             :   /// operation since BFI and all its required analyses are computed.  This is
      52             :   /// for example useful for CGSCC passes that can't use function analyses
      53             :   /// passes in the old PM.
      54             :   OptimizationRemarkEmitter(const Function *F);
      55             : 
      56             :   OptimizationRemarkEmitter(OptimizationRemarkEmitter &&Arg)
      57        2560 :       : F(Arg.F), BFI(Arg.BFI) {}
      58             : 
      59             :   OptimizationRemarkEmitter &operator=(OptimizationRemarkEmitter &&RHS) {
      60             :     F = RHS.F;
      61             :     BFI = RHS.BFI;
      62             :     return *this;
      63             :   }
      64             : 
      65             :   /// Handle invalidation events in the new pass manager.
      66             :   bool invalidate(Function &F, const PreservedAnalyses &PA,
      67             :                   FunctionAnalysisManager::Invalidator &Inv);
      68             : 
      69             :   /// Output the remark via the diagnostic handler and to the
      70             :   /// optimization record file.
      71             :   void emit(DiagnosticInfoOptimizationBase &OptDiag);
      72             : 
      73             :   /// Take a lambda that returns a remark which will be emitted.  Second
      74             :   /// argument is only used to restrict this to functions.
      75             :   template <typename T>
      76      704751 :   void emit(T RemarkBuilder, decltype(RemarkBuilder()) * = nullptr) {
      77             :     // Avoid building the remark unless we know there are at least *some*
      78             :     // remarks enabled. We can't currently check whether remarks are requested
      79             :     // for the calling pass since that requires actually building the remark.
      80             : 
      81     1409300 :     if (F->getContext().getDiagnosticsOutputFile() ||
      82      704549 :         F->getContext().getDiagHandlerPtr()->isAnyRemarkEnabled()) {
      83         572 :       auto R = RemarkBuilder();
      84         572 :       emit((DiagnosticInfoOptimizationBase &)R);
      85             :     }
      86      704751 :   }
      87             : 
      88             :   /// Whether we allow for extra compile-time budget to perform more
      89             :   /// analysis to produce fewer false positives.
      90             :   ///
      91             :   /// This is useful when reporting missed optimizations.  In this case we can
      92             :   /// use the extra analysis (1) to filter trivial false positives or (2) to
      93             :   /// provide more context so that non-trivial false positives can be quickly
      94             :   /// detected by the user.
      95      747196 :   bool allowExtraAnalysis(StringRef PassName) const {
      96     1494357 :     return (F->getContext().getDiagnosticsOutputFile() ||
      97     1494357 :             F->getContext().getDiagHandlerPtr()->isAnyRemarkEnabled(PassName));
      98             :   }
      99             : 
     100             : private:
     101             :   const Function *F;
     102             : 
     103             :   BlockFrequencyInfo *BFI;
     104             : 
     105             :   /// If we generate BFI on demand, we need to free it when ORE is freed.
     106             :   std::unique_ptr<BlockFrequencyInfo> OwnedBFI;
     107             : 
     108             :   /// Compute hotness from IR value (currently assumed to be a block) if PGO is
     109             :   /// available.
     110             :   Optional<uint64_t> computeHotness(const Value *V);
     111             : 
     112             :   /// Similar but use value from \p OptDiag and update hotness there.
     113             :   void computeHotness(DiagnosticInfoIROptimization &OptDiag);
     114             : 
     115             :   /// Only allow verbose messages if we know we're filtering by hotness
     116             :   /// (BFI is only set in this case).
     117             :   bool shouldEmitVerbose() { return BFI != nullptr; }
     118             : 
     119             :   OptimizationRemarkEmitter(const OptimizationRemarkEmitter &) = delete;
     120             :   void operator=(const OptimizationRemarkEmitter &) = delete;
     121             : };
     122             : 
     123             : /// Add a small namespace to avoid name clashes with the classes used in
     124             : /// the streaming interface.  We want these to be short for better
     125             : /// write/readability.
     126             : namespace ore {
     127             : using NV = DiagnosticInfoOptimizationBase::Argument;
     128             : using setIsVerbose = DiagnosticInfoOptimizationBase::setIsVerbose;
     129             : using setExtraArgs = DiagnosticInfoOptimizationBase::setExtraArgs;
     130             : }
     131             : 
     132             : /// OptimizationRemarkEmitter legacy analysis pass
     133             : ///
     134             : /// Note that this pass shouldn't generally be marked as preserved by other
     135             : /// passes.  It's holding onto BFI, so if the pass does not preserve BFI, BFI
     136             : /// could be freed.
     137       48722 : class OptimizationRemarkEmitterWrapperPass : public FunctionPass {
     138             :   std::unique_ptr<OptimizationRemarkEmitter> ORE;
     139             : 
     140             : public:
     141             :   OptimizationRemarkEmitterWrapperPass();
     142             : 
     143             :   bool runOnFunction(Function &F) override;
     144             : 
     145             :   void getAnalysisUsage(AnalysisUsage &AU) const override;
     146             : 
     147             :   OptimizationRemarkEmitter &getORE() {
     148             :     assert(ORE && "pass not run yet");
     149             :     return *ORE;
     150             :   }
     151             : 
     152             :   static char ID;
     153             : };
     154             : 
     155             : class OptimizationRemarkEmitterAnalysis
     156             :     : public AnalysisInfoMixin<OptimizationRemarkEmitterAnalysis> {
     157             :   friend AnalysisInfoMixin<OptimizationRemarkEmitterAnalysis>;
     158             :   static AnalysisKey Key;
     159             : 
     160             : public:
     161             :   /// Provide the result typedef for this analysis pass.
     162             :   typedef OptimizationRemarkEmitter Result;
     163             : 
     164             :   /// Run the analysis pass over a function and produce BFI.
     165             :   Result run(Function &F, FunctionAnalysisManager &AM);
     166             : };
     167             : }
     168             : #endif // LLVM_IR_OPTIMIZATIONDIAGNOSTICINFO_H

Generated by: LCOV version 1.13