Line data Source code
1 : //===- OptimizationRemarkEmitter.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/OptimizationRemarkEmitter.h"
16 : #include "llvm/Analysis/BranchProbabilityInfo.h"
17 : #include "llvm/Analysis/LazyBlockFrequencyInfo.h"
18 : #include "llvm/Analysis/LoopInfo.h"
19 : #include "llvm/IR/DiagnosticInfo.h"
20 : #include "llvm/IR/Dominators.h"
21 : #include "llvm/IR/LLVMContext.h"
22 :
23 : using namespace llvm;
24 :
25 6439422 : OptimizationRemarkEmitter::OptimizationRemarkEmitter(const Function *F)
26 6439422 : : F(F), BFI(nullptr) {
27 6439422 : if (!F->getContext().getDiagnosticsHotnessRequested())
28 6439248 : return;
29 :
30 : // First create a dominator tree.
31 : DominatorTree DT;
32 : DT.recalculate(*const_cast<Function *>(F));
33 :
34 : // Generate LoopInfo from it.
35 : LoopInfo LI;
36 174 : LI.analyze(DT);
37 :
38 : // Then compute BranchProbabilityInfo.
39 174 : BranchProbabilityInfo BPI;
40 174 : BPI.calculate(*F, LI);
41 :
42 : // Finally compute BFI.
43 174 : OwnedBFI = llvm::make_unique<BlockFrequencyInfo>(*F, BPI, LI);
44 174 : BFI = OwnedBFI.get();
45 : }
46 :
47 1665 : bool OptimizationRemarkEmitter::invalidate(
48 : Function &F, const PreservedAnalyses &PA,
49 : FunctionAnalysisManager::Invalidator &Inv) {
50 : // This analysis has no state and so can be trivially preserved but it needs
51 : // a fresh view of BFI if it was constructed with one.
52 1689 : if (BFI && Inv.invalidate<BlockFrequencyAnalysis>(F, PA))
53 23 : return true;
54 :
55 : // Otherwise this analysis result remains valid.
56 : return false;
57 : }
58 :
59 951920 : Optional<uint64_t> OptimizationRemarkEmitter::computeHotness(const Value *V) {
60 951920 : if (!BFI)
61 : return None;
62 :
63 124 : return BFI->getBlockProfileCount(cast<BasicBlock>(V));
64 : }
65 :
66 951920 : void OptimizationRemarkEmitter::computeHotness(
67 : DiagnosticInfoIROptimization &OptDiag) {
68 951920 : const Value *V = OptDiag.getCodeRegion();
69 951920 : if (V)
70 1903840 : OptDiag.setHotness(computeHotness(V));
71 951920 : }
72 :
73 951920 : void OptimizationRemarkEmitter::emit(
74 : DiagnosticInfoOptimizationBase &OptDiagBase) {
75 : auto &OptDiag = cast<DiagnosticInfoIROptimization>(OptDiagBase);
76 951920 : computeHotness(OptDiag);
77 :
78 : // Only emit it if its hotness meets the threshold.
79 951920 : if (OptDiag.getHotness().getValueOr(0) <
80 951920 : F->getContext().getDiagnosticsHotnessThreshold()) {
81 : return;
82 : }
83 :
84 951904 : F->getContext().diagnose(OptDiag);
85 : }
86 :
87 56554 : OptimizationRemarkEmitterWrapperPass::OptimizationRemarkEmitterWrapperPass()
88 28277 : : FunctionPass(ID) {
89 28277 : initializeOptimizationRemarkEmitterWrapperPassPass(
90 28277 : *PassRegistry::getPassRegistry());
91 28277 : }
92 :
93 479636 : bool OptimizationRemarkEmitterWrapperPass::runOnFunction(Function &Fn) {
94 : BlockFrequencyInfo *BFI;
95 :
96 479636 : if (Fn.getContext().getDiagnosticsHotnessRequested())
97 225 : BFI = &getAnalysis<LazyBlockFrequencyInfoPass>().getBFI();
98 : else
99 : BFI = nullptr;
100 :
101 479636 : ORE = llvm::make_unique<OptimizationRemarkEmitter>(&Fn, BFI);
102 479636 : return false;
103 : }
104 :
105 28280 : void OptimizationRemarkEmitterWrapperPass::getAnalysisUsage(
106 : AnalysisUsage &AU) const {
107 28280 : LazyBlockFrequencyInfoPass::getLazyBFIAnalysisUsage(AU);
108 : AU.setPreservesAll();
109 28280 : }
110 :
111 : AnalysisKey OptimizationRemarkEmitterAnalysis::Key;
112 :
113 : OptimizationRemarkEmitter
114 1433 : OptimizationRemarkEmitterAnalysis::run(Function &F,
115 : FunctionAnalysisManager &AM) {
116 : BlockFrequencyInfo *BFI;
117 :
118 1433 : if (F.getContext().getDiagnosticsHotnessRequested())
119 : BFI = &AM.getResult<BlockFrequencyAnalysis>(F);
120 : else
121 : BFI = nullptr;
122 :
123 : return OptimizationRemarkEmitter(&F, BFI);
124 : }
125 :
126 : char OptimizationRemarkEmitterWrapperPass::ID = 0;
127 : static const char ore_name[] = "Optimization Remark Emitter";
128 : #define ORE_NAME "opt-remark-emitter"
129 :
130 61371 : INITIALIZE_PASS_BEGIN(OptimizationRemarkEmitterWrapperPass, ORE_NAME, ore_name,
131 : false, true)
132 61371 : INITIALIZE_PASS_DEPENDENCY(LazyBFIPass)
133 486162 : INITIALIZE_PASS_END(OptimizationRemarkEmitterWrapperPass, ORE_NAME, ore_name,
134 : false, true)
|