1 //===- OptimizationRemarkEmitter.cpp - Optimization Diagnostic --*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
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"
26 OptimizationRemarkEmitter::OptimizationRemarkEmitter(const Function
*F
)
27 : F(F
), BFI(nullptr) {
28 if (!F
->getContext().getDiagnosticsHotnessRequested())
31 // First create a dominator tree.
33 DT
.recalculate(*const_cast<Function
*>(F
));
35 // Generate LoopInfo from it.
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
);
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
))
56 // Otherwise this analysis result remains valid.
60 Optional
<uint64_t> OptimizationRemarkEmitter::computeHotness(const Value
*V
) {
64 return BFI
->getBlockProfileCount(cast
<BasicBlock
>(V
));
67 void OptimizationRemarkEmitter::computeHotness(
68 DiagnosticInfoIROptimization
&OptDiag
) {
69 const Value
*V
= OptDiag
.getCodeRegion();
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()) {
86 F
->getContext().diagnose(OptDiag
);
89 OptimizationRemarkEmitterWrapperPass::OptimizationRemarkEmitterWrapperPass()
91 initializeOptimizationRemarkEmitterWrapperPassPass(
92 *PassRegistry::getPassRegistry());
95 bool OptimizationRemarkEmitterWrapperPass::runOnFunction(Function
&Fn
) {
96 BlockFrequencyInfo
*BFI
;
98 if (Fn
.getContext().getDiagnosticsHotnessRequested())
99 BFI
= &getAnalysis
<LazyBlockFrequencyInfoPass
>().getBFI();
103 ORE
= llvm::make_unique
<OptimizationRemarkEmitter
>(&Fn
, BFI
);
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
);
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
,
134 INITIALIZE_PASS_DEPENDENCY(LazyBFIPass
)
135 INITIALIZE_PASS_END(OptimizationRemarkEmitterWrapperPass
, ORE_NAME
, ore_name
,