LCOV - code coverage report
Current view: top level - lib/Analysis - OptimizationDiagnosticInfo.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 95 96 99.0 %
Date: 2017-09-14 15:23:50 Functions: 14 14 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- OptimizationDiagnosticInfo.cpp - 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             : #include "llvm/Analysis/OptimizationDiagnosticInfo.h"
      16             : #include "llvm/Analysis/BranchProbabilityInfo.h"
      17             : #include "llvm/Analysis/LazyBlockFrequencyInfo.h"
      18             : #include "llvm/Analysis/LoopInfo.h"
      19             : #include "llvm/IR/DebugInfo.h"
      20             : #include "llvm/IR/DiagnosticInfo.h"
      21             : #include "llvm/IR/Dominators.h"
      22             : #include "llvm/IR/LLVMContext.h"
      23             : 
      24             : using namespace llvm;
      25             : 
      26     1084419 : OptimizationRemarkEmitter::OptimizationRemarkEmitter(const Function *F)
      27     2168838 :     : F(F), BFI(nullptr) {
      28     1084419 :   if (!F->getContext().getDiagnosticsHotnessRequested())
      29     1084296 :     return;
      30             : 
      31             :   // First create a dominator tree.
      32         246 :   DominatorTree DT;
      33         123 :   DT.recalculate(*const_cast<Function *>(F));
      34             : 
      35             :   // Generate LoopInfo from it.
      36         246 :   LoopInfo LI;
      37         123 :   LI.analyze(DT);
      38             : 
      39             :   // Then compute BranchProbabilityInfo.
      40         246 :   BranchProbabilityInfo BPI;
      41         123 :   BPI.calculate(*F, LI);
      42             : 
      43             :   // Finally compute BFI.
      44         123 :   OwnedBFI = llvm::make_unique<BlockFrequencyInfo>(*F, BPI, LI);
      45         246 :   BFI = OwnedBFI.get();
      46             : }
      47             : 
      48        1142 : bool OptimizationRemarkEmitter::invalidate(
      49             :     Function &F, const PreservedAnalyses &PA,
      50             :     FunctionAnalysisManager::Invalidator &Inv) {
      51             :   // This analysis has no state and so can be trivially preserved but it needs
      52             :   // a fresh view of BFI if it was constructed with one.
      53        1160 :   if (BFI && Inv.invalidate<BlockFrequencyAnalysis>(F, PA))
      54             :     return true;
      55             : 
      56             :   // Otherwise this analysis result remains valid.
      57             :   return false;
      58             : }
      59             : 
      60      746466 : Optional<uint64_t> OptimizationRemarkEmitter::computeHotness(const Value *V) {
      61      746466 :   if (!BFI)
      62             :     return None;
      63             : 
      64         174 :   return BFI->getBlockProfileCount(cast<BasicBlock>(V));
      65             : }
      66             : 
      67             : namespace llvm {
      68             : namespace yaml {
      69             : 
      70         223 : void MappingTraits<DiagnosticInfoOptimizationBase *>::mapping(
      71             :     IO &io, DiagnosticInfoOptimizationBase *&OptDiag) {
      72             :   assert(io.outputting() && "input not yet implemented");
      73             : 
      74         446 :   if (io.mapTag("!Passed",
      75         383 :                 (OptDiag->getKind() == DK_OptimizationRemark ||
      76         383 :                  OptDiag->getKind() == DK_MachineOptimizationRemark)))
      77             :     ;
      78         320 :   else if (io.mapTag(
      79             :                "!Missed",
      80         273 :                (OptDiag->getKind() == DK_OptimizationRemarkMissed ||
      81         273 :                 OptDiag->getKind() == DK_MachineOptimizationRemarkMissed)))
      82             :     ;
      83         214 :   else if (io.mapTag(
      84             :                "!Analysis",
      85         184 :                (OptDiag->getKind() == DK_OptimizationRemarkAnalysis ||
      86         184 :                 OptDiag->getKind() == DK_MachineOptimizationRemarkAnalysis)))
      87             :     ;
      88           6 :   else if (io.mapTag("!AnalysisFPCommute",
      89           3 :                      OptDiag->getKind() ==
      90           3 :                          DK_OptimizationRemarkAnalysisFPCommute))
      91             :     ;
      92           6 :   else if (io.mapTag("!AnalysisAliasing",
      93           3 :                      OptDiag->getKind() ==
      94           3 :                          DK_OptimizationRemarkAnalysisAliasing))
      95             :     ;
      96           4 :   else if (io.mapTag("!Failure", OptDiag->getKind() == DK_OptimizationFailure))
      97             :     ;
      98             :   else
      99           0 :     llvm_unreachable("Unknown remark type");
     100             : 
     101             :   // These are read-only for now.
     102         446 :   DiagnosticLocation DL = OptDiag->getLocation();
     103             :   StringRef FN =
     104         223 :       GlobalValue::dropLLVMManglingEscape(OptDiag->getFunction().getName());
     105             : 
     106         446 :   StringRef PassName(OptDiag->PassName);
     107         223 :   io.mapRequired("Pass", PassName);
     108         446 :   io.mapRequired("Name", OptDiag->RemarkName);
     109         446 :   if (!io.outputting() || DL.isValid())
     110             :     io.mapOptional("DebugLoc", DL);
     111         223 :   io.mapRequired("Function", FN);
     112         446 :   io.mapOptional("Hotness", OptDiag->Hotness);
     113         446 :   io.mapOptional("Args", OptDiag->Args);
     114         223 : }
     115             : 
     116             : template <> struct MappingTraits<DiagnosticLocation> {
     117         117 :   static void mapping(IO &io, DiagnosticLocation &DL) {
     118             :     assert(io.outputting() && "input not yet implemented");
     119             : 
     120         117 :     StringRef File = DL.getFilename();
     121         117 :     unsigned Line = DL.getLine();
     122         117 :     unsigned Col = DL.getColumn();
     123             : 
     124         117 :     io.mapRequired("File", File);
     125         117 :     io.mapRequired("Line", Line);
     126         117 :     io.mapRequired("Column", Col);
     127         117 :   }
     128             : 
     129             :   static const bool flow = true;
     130             : };
     131             : 
     132             : // Implement this as a mapping for now to get proper quotation for the value.
     133             : template <> struct MappingTraits<DiagnosticInfoOptimizationBase::Argument> {
     134         706 :   static void mapping(IO &io, DiagnosticInfoOptimizationBase::Argument &A) {
     135             :     assert(io.outputting() && "input not yet implemented");
     136        2118 :     io.mapRequired(A.Key.data(), A.Val);
     137        1412 :     if (A.Loc.isValid())
     138          25 :       io.mapOptional("DebugLoc", A.Loc);
     139         706 :   }
     140             : };
     141             : 
     142             : } // end namespace yaml
     143             : } // end namespace llvm
     144             : 
     145             : LLVM_YAML_IS_SEQUENCE_VECTOR(DiagnosticInfoOptimizationBase::Argument)
     146             : 
     147      746466 : void OptimizationRemarkEmitter::computeHotness(
     148             :     DiagnosticInfoIROptimization &OptDiag) {
     149      746466 :   const Value *V = OptDiag.getCodeRegion();
     150      746466 :   if (V)
     151     2239398 :     OptDiag.setHotness(computeHotness(V));
     152      746466 : }
     153             : 
     154      746466 : void OptimizationRemarkEmitter::emit(
     155             :     DiagnosticInfoOptimizationBase &OptDiagBase) {
     156      746466 :   auto &OptDiag = cast<DiagnosticInfoIROptimization>(OptDiagBase);
     157      746466 :   computeHotness(OptDiag);
     158             :   // If a diagnostic has a hotness value, then only emit it if its hotness
     159             :   // meets the threshold.
     160     2985988 :   if (OptDiag.getHotness() &&
     161      746646 :       *OptDiag.getHotness() <
     162      746528 :           F->getContext().getDiagnosticsHotnessThreshold()) {
     163             :     return;
     164             :   }
     165             : 
     166      746460 :   yaml::Output *Out = F->getContext().getDiagnosticsOutputFile();
     167      746460 :   if (Out) {
     168             :     // For remarks the << operator takes a reference to a pointer.
     169         143 :     auto *P = &OptDiagBase;
     170         143 :     *Out << P;
     171             :   }
     172             :   // FIXME: now that IsVerbose is part of DI, filtering for this will be moved
     173             :   // from here to clang.
     174      746460 :   if (!OptDiag.isVerbose() || shouldEmitVerbose())
     175      651116 :     F->getContext().diagnose(OptDiag);
     176             : }
     177             : 
     178       20245 : OptimizationRemarkEmitterWrapperPass::OptimizationRemarkEmitterWrapperPass()
     179       60735 :     : FunctionPass(ID) {
     180       20245 :   initializeOptimizationRemarkEmitterWrapperPassPass(
     181       20245 :       *PassRegistry::getPassRegistry());
     182       20245 : }
     183             : 
     184      374810 : bool OptimizationRemarkEmitterWrapperPass::runOnFunction(Function &Fn) {
     185             :   BlockFrequencyInfo *BFI;
     186             : 
     187      374810 :   if (Fn.getContext().getDiagnosticsHotnessRequested())
     188         276 :     BFI = &getAnalysis<LazyBlockFrequencyInfoPass>().getBFI();
     189             :   else
     190             :     BFI = nullptr;
     191             : 
     192      749620 :   ORE = llvm::make_unique<OptimizationRemarkEmitter>(&Fn, BFI);
     193      374810 :   return false;
     194             : }
     195             : 
     196       20248 : void OptimizationRemarkEmitterWrapperPass::getAnalysisUsage(
     197             :     AnalysisUsage &AU) const {
     198       20248 :   LazyBlockFrequencyInfoPass::getLazyBFIAnalysisUsage(AU);
     199       20248 :   AU.setPreservesAll();
     200       20248 : }
     201             : 
     202             : AnalysisKey OptimizationRemarkEmitterAnalysis::Key;
     203             : 
     204             : OptimizationRemarkEmitter
     205         928 : OptimizationRemarkEmitterAnalysis::run(Function &F,
     206             :                                        FunctionAnalysisManager &AM) {
     207             :   BlockFrequencyInfo *BFI;
     208             : 
     209         928 :   if (F.getContext().getDiagnosticsHotnessRequested())
     210          18 :     BFI = &AM.getResult<BlockFrequencyAnalysis>(F);
     211             :   else
     212             :     BFI = nullptr;
     213             : 
     214         928 :   return OptimizationRemarkEmitter(&F, BFI);
     215             : }
     216             : 
     217             : char OptimizationRemarkEmitterWrapperPass::ID = 0;
     218             : static const char ore_name[] = "Optimization Remark Emitter";
     219             : #define ORE_NAME "opt-remark-emitter"
     220             : 
     221       41843 : INITIALIZE_PASS_BEGIN(OptimizationRemarkEmitterWrapperPass, ORE_NAME, ore_name,
     222             :                       false, true)
     223       41843 : INITIALIZE_PASS_DEPENDENCY(LazyBFIPass)
     224      931171 : INITIALIZE_PASS_END(OptimizationRemarkEmitterWrapperPass, ORE_NAME, ore_name,
     225             :                     false, true)

Generated by: LCOV version 1.13