]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/llvm/lib/Analysis/OptimizationRemarkEmitter.cpp
Merge ^/head r357408 through r357661.
[FreeBSD/FreeBSD.git] / contrib / llvm-project / llvm / lib / Analysis / OptimizationRemarkEmitter.cpp
1 //===- OptimizationRemarkEmitter.cpp - Optimization Diagnostic --*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Optimization diagnostic interfaces.  It's packaged as an analysis pass so
10 // that by using this service passes become dependent on BFI as well.  BFI is
11 // used to compute the "hotness" of the diagnostic message.
12 //===----------------------------------------------------------------------===//
13
14 #include "llvm/Analysis/OptimizationRemarkEmitter.h"
15 #include "llvm/Analysis/BranchProbabilityInfo.h"
16 #include "llvm/Analysis/LazyBlockFrequencyInfo.h"
17 #include "llvm/Analysis/LoopInfo.h"
18 #include "llvm/IR/DiagnosticInfo.h"
19 #include "llvm/IR/Dominators.h"
20 #include "llvm/IR/LLVMContext.h"
21 #include "llvm/InitializePasses.h"
22
23 using namespace llvm;
24
25 OptimizationRemarkEmitter::OptimizationRemarkEmitter(const Function *F)
26     : F(F), BFI(nullptr) {
27   if (!F->getContext().getDiagnosticsHotnessRequested())
28     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   LI.analyze(DT);
37
38   // Then compute BranchProbabilityInfo.
39   BranchProbabilityInfo BPI;
40   BPI.calculate(*F, LI);
41
42   // Finally compute BFI.
43   OwnedBFI = std::make_unique<BlockFrequencyInfo>(*F, BPI, LI);
44   BFI = OwnedBFI.get();
45 }
46
47 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   if (BFI && Inv.invalidate<BlockFrequencyAnalysis>(F, PA))
53     return true;
54
55   // Otherwise this analysis result remains valid.
56   return false;
57 }
58
59 Optional<uint64_t> OptimizationRemarkEmitter::computeHotness(const Value *V) {
60   if (!BFI)
61     return None;
62
63   return BFI->getBlockProfileCount(cast<BasicBlock>(V));
64 }
65
66 void OptimizationRemarkEmitter::computeHotness(
67     DiagnosticInfoIROptimization &OptDiag) {
68   const Value *V = OptDiag.getCodeRegion();
69   if (V)
70     OptDiag.setHotness(computeHotness(V));
71 }
72
73 void OptimizationRemarkEmitter::emit(
74     DiagnosticInfoOptimizationBase &OptDiagBase) {
75   auto &OptDiag = cast<DiagnosticInfoIROptimization>(OptDiagBase);
76   computeHotness(OptDiag);
77
78   // Only emit it if its hotness meets the threshold.
79   if (OptDiag.getHotness().getValueOr(0) <
80       F->getContext().getDiagnosticsHotnessThreshold()) {
81     return;
82   }
83
84   F->getContext().diagnose(OptDiag);
85 }
86
87 OptimizationRemarkEmitterWrapperPass::OptimizationRemarkEmitterWrapperPass()
88     : FunctionPass(ID) {
89   initializeOptimizationRemarkEmitterWrapperPassPass(
90       *PassRegistry::getPassRegistry());
91 }
92
93 bool OptimizationRemarkEmitterWrapperPass::runOnFunction(Function &Fn) {
94   BlockFrequencyInfo *BFI;
95
96   if (Fn.getContext().getDiagnosticsHotnessRequested())
97     BFI = &getAnalysis<LazyBlockFrequencyInfoPass>().getBFI();
98   else
99     BFI = nullptr;
100
101   ORE = std::make_unique<OptimizationRemarkEmitter>(&Fn, BFI);
102   return false;
103 }
104
105 void OptimizationRemarkEmitterWrapperPass::getAnalysisUsage(
106     AnalysisUsage &AU) const {
107   LazyBlockFrequencyInfoPass::getLazyBFIAnalysisUsage(AU);
108   AU.setPreservesAll();
109 }
110
111 AnalysisKey OptimizationRemarkEmitterAnalysis::Key;
112
113 OptimizationRemarkEmitter
114 OptimizationRemarkEmitterAnalysis::run(Function &F,
115                                        FunctionAnalysisManager &AM) {
116   BlockFrequencyInfo *BFI;
117
118   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 INITIALIZE_PASS_BEGIN(OptimizationRemarkEmitterWrapperPass, ORE_NAME, ore_name,
131                       false, true)
132 INITIALIZE_PASS_DEPENDENCY(LazyBFIPass)
133 INITIALIZE_PASS_END(OptimizationRemarkEmitterWrapperPass, ORE_NAME, ore_name,
134                     false, true)