Fix for PR34888.
[llvm-core.git] / lib / Analysis / OptimizationRemarkEmitter.cpp
blobcd6a93668010d2a1035384d951665446c01f8aa7
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 //===----------------------------------------------------------------------===//
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/DebugInfo.h"
20 #include "llvm/IR/DiagnosticInfo.h"
21 #include "llvm/IR/Dominators.h"
22 #include "llvm/IR/LLVMContext.h"
24 using namespace llvm;
26 OptimizationRemarkEmitter::OptimizationRemarkEmitter(const Function *F)
27 : F(F), BFI(nullptr) {
28 if (!F->getContext().getDiagnosticsHotnessRequested())
29 return;
31 // First create a dominator tree.
32 DominatorTree DT;
33 DT.recalculate(*const_cast<Function *>(F));
35 // Generate LoopInfo from it.
36 LoopInfo LI;
37 LI.analyze(DT);
39 // Then compute BranchProbabilityInfo.
40 BranchProbabilityInfo BPI;
41 BPI.calculate(*F, LI);
43 // Finally compute BFI.
44 OwnedBFI = llvm::make_unique<BlockFrequencyInfo>(*F, BPI, LI);
45 BFI = OwnedBFI.get();
48 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 if (BFI && Inv.invalidate<BlockFrequencyAnalysis>(F, PA))
54 return true;
56 // Otherwise this analysis result remains valid.
57 return false;
60 Optional<uint64_t> OptimizationRemarkEmitter::computeHotness(const Value *V) {
61 if (!BFI)
62 return None;
64 return BFI->getBlockProfileCount(cast<BasicBlock>(V));
67 void OptimizationRemarkEmitter::computeHotness(
68 DiagnosticInfoIROptimization &OptDiag) {
69 const Value *V = OptDiag.getCodeRegion();
70 if (V)
71 OptDiag.setHotness(computeHotness(V));
74 void OptimizationRemarkEmitter::emit(
75 DiagnosticInfoOptimizationBase &OptDiagBase) {
76 auto &OptDiag = cast<DiagnosticInfoIROptimization>(OptDiagBase);
77 computeHotness(OptDiag);
78 // If a diagnostic has a hotness value, then only emit it if its hotness
79 // meets the threshold.
80 if (OptDiag.getHotness() &&
81 *OptDiag.getHotness() <
82 F->getContext().getDiagnosticsHotnessThreshold()) {
83 return;
86 F->getContext().diagnose(OptDiag);
89 OptimizationRemarkEmitterWrapperPass::OptimizationRemarkEmitterWrapperPass()
90 : FunctionPass(ID) {
91 initializeOptimizationRemarkEmitterWrapperPassPass(
92 *PassRegistry::getPassRegistry());
95 bool OptimizationRemarkEmitterWrapperPass::runOnFunction(Function &Fn) {
96 BlockFrequencyInfo *BFI;
98 if (Fn.getContext().getDiagnosticsHotnessRequested())
99 BFI = &getAnalysis<LazyBlockFrequencyInfoPass>().getBFI();
100 else
101 BFI = nullptr;
103 ORE = llvm::make_unique<OptimizationRemarkEmitter>(&Fn, BFI);
104 return false;
107 void OptimizationRemarkEmitterWrapperPass::getAnalysisUsage(
108 AnalysisUsage &AU) const {
109 LazyBlockFrequencyInfoPass::getLazyBFIAnalysisUsage(AU);
110 AU.setPreservesAll();
113 AnalysisKey OptimizationRemarkEmitterAnalysis::Key;
115 OptimizationRemarkEmitter
116 OptimizationRemarkEmitterAnalysis::run(Function &F,
117 FunctionAnalysisManager &AM) {
118 BlockFrequencyInfo *BFI;
120 if (F.getContext().getDiagnosticsHotnessRequested())
121 BFI = &AM.getResult<BlockFrequencyAnalysis>(F);
122 else
123 BFI = nullptr;
125 return OptimizationRemarkEmitter(&F, BFI);
128 char OptimizationRemarkEmitterWrapperPass::ID = 0;
129 static const char ore_name[] = "Optimization Remark Emitter";
130 #define ORE_NAME "opt-remark-emitter"
132 INITIALIZE_PASS_BEGIN(OptimizationRemarkEmitterWrapperPass, ORE_NAME, ore_name,
133 false, true)
134 INITIALIZE_PASS_DEPENDENCY(LazyBFIPass)
135 INITIALIZE_PASS_END(OptimizationRemarkEmitterWrapperPass, ORE_NAME, ore_name,
136 false, true)