blob: 8ece0a2a3ed3d078936648bd1d60a645c074581e [file] [log] [blame]
Adam Nemet0965da22017-10-09 23:19:02 +00001//===- OptimizationRemarkEmitter.cpp - Optimization Diagnostic --*- C++ -*-===//
Adam Nemetaad81602016-07-15 17:23:20 +00002//
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
Adam Nemet0965da22017-10-09 23:19:02 +000015#include "llvm/Analysis/OptimizationRemarkEmitter.h"
Adam Nemet896c09b2016-08-10 00:44:44 +000016#include "llvm/Analysis/BranchProbabilityInfo.h"
Adam Nemetaad81602016-07-15 17:23:20 +000017#include "llvm/Analysis/LazyBlockFrequencyInfo.h"
18#include "llvm/Analysis/LoopInfo.h"
19#include "llvm/IR/DiagnosticInfo.h"
Adam Nemet896c09b2016-08-10 00:44:44 +000020#include "llvm/IR/Dominators.h"
Adam Nemetaad81602016-07-15 17:23:20 +000021#include "llvm/IR/LLVMContext.h"
22
23using namespace llvm;
24
Justin Bogner8281c812017-02-22 07:38:17 +000025OptimizationRemarkEmitter::OptimizationRemarkEmitter(const Function *F)
Adam Nemet896c09b2016-08-10 00:44:44 +000026 : F(F), BFI(nullptr) {
Brian Gesiak44e5f6c2017-06-30 18:13:59 +000027 if (!F->getContext().getDiagnosticsHotnessRequested())
Adam Nemet896c09b2016-08-10 00:44:44 +000028 return;
29
30 // First create a dominator tree.
31 DominatorTree DT;
Justin Bogner8281c812017-02-22 07:38:17 +000032 DT.recalculate(*const_cast<Function *>(F));
Adam Nemet896c09b2016-08-10 00:44:44 +000033
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 = llvm::make_unique<BlockFrequencyInfo>(*F, BPI, LI);
44 BFI = OwnedBFI.get();
45}
46
Chandler Carruth1ae34c32017-01-15 08:20:50 +000047bool 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
Adam Nemet6100d162016-07-20 21:44:22 +000059Optional<uint64_t> OptimizationRemarkEmitter::computeHotness(const Value *V) {
Adam Nemetaad81602016-07-15 17:23:20 +000060 if (!BFI)
61 return None;
62
63 return BFI->getBlockProfileCount(cast<BasicBlock>(V));
64}
65
Adam Nemeta62b7e12016-09-27 20:55:07 +000066void OptimizationRemarkEmitter::computeHotness(
Adam Nemet484f93d2017-01-25 23:20:25 +000067 DiagnosticInfoIROptimization &OptDiag) {
Justin Bogner8281c812017-02-22 07:38:17 +000068 const Value *V = OptDiag.getCodeRegion();
Adam Nemeta62b7e12016-09-27 20:55:07 +000069 if (V)
70 OptDiag.setHotness(computeHotness(V));
71}
72
Adam Nemet484f93d2017-01-25 23:20:25 +000073void OptimizationRemarkEmitter::emit(
74 DiagnosticInfoOptimizationBase &OptDiagBase) {
75 auto &OptDiag = cast<DiagnosticInfoIROptimization>(OptDiagBase);
Adam Nemeta62b7e12016-09-27 20:55:07 +000076 computeHotness(OptDiag);
Adam Nemet9303f622017-12-01 20:41:38 +000077
78 // Only emit it if its hotness meets the threshold.
79 if (OptDiag.getHotness().getValueOr(0) <
80 F->getContext().getDiagnosticsHotnessThreshold()) {
Brian Gesiak4ef3daa2017-06-30 23:14:53 +000081 return;
82 }
Adam Nemeta62b7e12016-09-27 20:55:07 +000083
Adam Nemetf31b1f32017-10-04 04:26:23 +000084 F->getContext().diagnose(OptDiag);
Adam Nemeta62b7e12016-09-27 20:55:07 +000085}
86
Adam Nemet79ac42a2016-07-18 16:29:21 +000087OptimizationRemarkEmitterWrapperPass::OptimizationRemarkEmitterWrapperPass()
88 : FunctionPass(ID) {
89 initializeOptimizationRemarkEmitterWrapperPassPass(
90 *PassRegistry::getPassRegistry());
91}
92
93bool OptimizationRemarkEmitterWrapperPass::runOnFunction(Function &Fn) {
94 BlockFrequencyInfo *BFI;
Adam Nemetaad81602016-07-15 17:23:20 +000095
Brian Gesiak44e5f6c2017-06-30 18:13:59 +000096 if (Fn.getContext().getDiagnosticsHotnessRequested())
Adam Nemetaad81602016-07-15 17:23:20 +000097 BFI = &getAnalysis<LazyBlockFrequencyInfoPass>().getBFI();
98 else
99 BFI = nullptr;
100
Adam Nemet79ac42a2016-07-18 16:29:21 +0000101 ORE = llvm::make_unique<OptimizationRemarkEmitter>(&Fn, BFI);
Adam Nemetaad81602016-07-15 17:23:20 +0000102 return false;
103}
104
Adam Nemet79ac42a2016-07-18 16:29:21 +0000105void OptimizationRemarkEmitterWrapperPass::getAnalysisUsage(
106 AnalysisUsage &AU) const {
Adam Nemetaad81602016-07-15 17:23:20 +0000107 LazyBlockFrequencyInfoPass::getLazyBFIAnalysisUsage(AU);
108 AU.setPreservesAll();
109}
110
Chandler Carruthdab4eae2016-11-23 17:53:26 +0000111AnalysisKey OptimizationRemarkEmitterAnalysis::Key;
Adam Nemet79ac42a2016-07-18 16:29:21 +0000112
113OptimizationRemarkEmitter
Adam Nemet78d10912016-07-20 21:44:18 +0000114OptimizationRemarkEmitterAnalysis::run(Function &F,
Sean Silva36e0d012016-08-09 00:28:15 +0000115 FunctionAnalysisManager &AM) {
Adam Nemet79ac42a2016-07-18 16:29:21 +0000116 BlockFrequencyInfo *BFI;
117
Brian Gesiak44e5f6c2017-06-30 18:13:59 +0000118 if (F.getContext().getDiagnosticsHotnessRequested())
Adam Nemet79ac42a2016-07-18 16:29:21 +0000119 BFI = &AM.getResult<BlockFrequencyAnalysis>(F);
120 else
121 BFI = nullptr;
122
123 return OptimizationRemarkEmitter(&F, BFI);
124}
125
126char OptimizationRemarkEmitterWrapperPass::ID = 0;
Adam Nemetaad81602016-07-15 17:23:20 +0000127static const char ore_name[] = "Optimization Remark Emitter";
128#define ORE_NAME "opt-remark-emitter"
129
Adam Nemet79ac42a2016-07-18 16:29:21 +0000130INITIALIZE_PASS_BEGIN(OptimizationRemarkEmitterWrapperPass, ORE_NAME, ore_name,
131 false, true)
Adam Nemetaad81602016-07-15 17:23:20 +0000132INITIALIZE_PASS_DEPENDENCY(LazyBFIPass)
Adam Nemet79ac42a2016-07-18 16:29:21 +0000133INITIALIZE_PASS_END(OptimizationRemarkEmitterWrapperPass, ORE_NAME, ore_name,
134 false, true)