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