blob: 09a4ce5147218d76c4cb1ad3f221d8071dd6b353 [file] [log] [blame]
Adam Nemetaad81602016-07-15 17:23:20 +00001//===- OptimizationDiagnosticInfo.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//===----------------------------------------------------------------------===//
14
15#include "llvm/Analysis/OptimizationDiagnosticInfo.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
Adam Nemet896c09b2016-08-10 00:44:44 +000025OptimizationRemarkEmitter::OptimizationRemarkEmitter(Function *F)
26 : F(F), BFI(nullptr) {
27 if (!F->getContext().getDiagnosticHotnessRequested())
28 return;
29
30 // First create a dominator tree.
31 DominatorTree DT;
32 DT.recalculate(*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 = llvm::make_unique<BlockFrequencyInfo>(*F, BPI, LI);
44 BFI = OwnedBFI.get();
45}
46
Adam Nemet6100d162016-07-20 21:44:22 +000047Optional<uint64_t> OptimizationRemarkEmitter::computeHotness(const Value *V) {
Adam Nemetaad81602016-07-15 17:23:20 +000048 if (!BFI)
49 return None;
50
51 return BFI->getBlockProfileCount(cast<BasicBlock>(V));
52}
53
Adam Nemet7cfd5972016-07-21 01:07:13 +000054void OptimizationRemarkEmitter::emitOptimizationRemark(const char *PassName,
55 const DebugLoc &DLoc,
56 const Value *V,
57 const Twine &Msg) {
58 LLVMContext &Ctx = F->getContext();
59 Ctx.diagnose(DiagnosticInfoOptimizationRemark(PassName, *F, DLoc, Msg,
60 computeHotness(V)));
61}
62
63void OptimizationRemarkEmitter::emitOptimizationRemark(const char *PassName,
64 Loop *L,
65 const Twine &Msg) {
66 emitOptimizationRemark(PassName, L->getStartLoc(), L->getHeader(), Msg);
67}
68
Adam Nemetaad81602016-07-15 17:23:20 +000069void OptimizationRemarkEmitter::emitOptimizationRemarkMissed(
Adam Nemet6100d162016-07-20 21:44:22 +000070 const char *PassName, const DebugLoc &DLoc, const Value *V,
Adam Nemetcef33142016-08-26 20:21:05 +000071 const Twine &Msg, bool IsVerbose) {
Adam Nemetaad81602016-07-15 17:23:20 +000072 LLVMContext &Ctx = F->getContext();
Adam Nemetcef33142016-08-26 20:21:05 +000073 if (!IsVerbose || shouldEmitVerbose())
74 Ctx.diagnose(DiagnosticInfoOptimizationRemarkMissed(PassName, *F, DLoc, Msg,
75 computeHotness(V)));
Adam Nemetaad81602016-07-15 17:23:20 +000076}
77
78void OptimizationRemarkEmitter::emitOptimizationRemarkMissed(
Adam Nemetcef33142016-08-26 20:21:05 +000079 const char *PassName, Loop *L, const Twine &Msg, bool IsVerbose) {
80 emitOptimizationRemarkMissed(PassName, L->getStartLoc(), L->getHeader(), Msg,
81 IsVerbose);
Adam Nemetaad81602016-07-15 17:23:20 +000082}
83
Adam Nemet5b3a5cf2016-07-20 21:44:26 +000084void OptimizationRemarkEmitter::emitOptimizationRemarkAnalysis(
85 const char *PassName, const DebugLoc &DLoc, const Value *V,
Adam Nemetcef33142016-08-26 20:21:05 +000086 const Twine &Msg, bool IsVerbose) {
Adam Nemet5b3a5cf2016-07-20 21:44:26 +000087 LLVMContext &Ctx = F->getContext();
Adam Nemetcef33142016-08-26 20:21:05 +000088 if (!IsVerbose || shouldEmitVerbose())
89 Ctx.diagnose(DiagnosticInfoOptimizationRemarkAnalysis(
90 PassName, *F, DLoc, Msg, computeHotness(V)));
Adam Nemet5b3a5cf2016-07-20 21:44:26 +000091}
92
93void OptimizationRemarkEmitter::emitOptimizationRemarkAnalysis(
Adam Nemetcef33142016-08-26 20:21:05 +000094 const char *PassName, Loop *L, const Twine &Msg, bool IsVerbose) {
Adam Nemet5b3a5cf2016-07-20 21:44:26 +000095 emitOptimizationRemarkAnalysis(PassName, L->getStartLoc(), L->getHeader(),
Adam Nemetcef33142016-08-26 20:21:05 +000096 Msg, IsVerbose);
Adam Nemet5b3a5cf2016-07-20 21:44:26 +000097}
98
Adam Nemet0e0e2d52016-07-20 23:50:32 +000099void OptimizationRemarkEmitter::emitOptimizationRemarkAnalysisFPCommute(
Adam Nemetcbe2a9b2016-07-21 01:11:12 +0000100 const char *PassName, const DebugLoc &DLoc, const Value *V,
101 const Twine &Msg) {
Adam Nemet0e0e2d52016-07-20 23:50:32 +0000102 LLVMContext &Ctx = F->getContext();
103 Ctx.diagnose(DiagnosticInfoOptimizationRemarkAnalysisFPCommute(
104 PassName, *F, DLoc, Msg, computeHotness(V)));
105}
106
107void OptimizationRemarkEmitter::emitOptimizationRemarkAnalysisAliasing(
Adam Nemetcbe2a9b2016-07-21 01:11:12 +0000108 const char *PassName, const DebugLoc &DLoc, const Value *V,
109 const Twine &Msg) {
Adam Nemet0e0e2d52016-07-20 23:50:32 +0000110 LLVMContext &Ctx = F->getContext();
111 Ctx.diagnose(DiagnosticInfoOptimizationRemarkAnalysisAliasing(
112 PassName, *F, DLoc, Msg, computeHotness(V)));
113}
114
115void OptimizationRemarkEmitter::emitOptimizationRemarkAnalysisAliasing(
116 const char *PassName, Loop *L, const Twine &Msg) {
117 emitOptimizationRemarkAnalysisAliasing(PassName, L->getStartLoc(),
118 L->getHeader(), Msg);
119}
120
Adam Nemet79ac42a2016-07-18 16:29:21 +0000121OptimizationRemarkEmitterWrapperPass::OptimizationRemarkEmitterWrapperPass()
122 : FunctionPass(ID) {
123 initializeOptimizationRemarkEmitterWrapperPassPass(
124 *PassRegistry::getPassRegistry());
125}
126
127bool OptimizationRemarkEmitterWrapperPass::runOnFunction(Function &Fn) {
128 BlockFrequencyInfo *BFI;
Adam Nemetaad81602016-07-15 17:23:20 +0000129
130 if (Fn.getContext().getDiagnosticHotnessRequested())
131 BFI = &getAnalysis<LazyBlockFrequencyInfoPass>().getBFI();
132 else
133 BFI = nullptr;
134
Adam Nemet79ac42a2016-07-18 16:29:21 +0000135 ORE = llvm::make_unique<OptimizationRemarkEmitter>(&Fn, BFI);
Adam Nemetaad81602016-07-15 17:23:20 +0000136 return false;
137}
138
Adam Nemet79ac42a2016-07-18 16:29:21 +0000139void OptimizationRemarkEmitterWrapperPass::getAnalysisUsage(
140 AnalysisUsage &AU) const {
Adam Nemetaad81602016-07-15 17:23:20 +0000141 LazyBlockFrequencyInfoPass::getLazyBFIAnalysisUsage(AU);
142 AU.setPreservesAll();
143}
144
Adam Nemet79ac42a2016-07-18 16:29:21 +0000145char OptimizationRemarkEmitterAnalysis::PassID;
146
147OptimizationRemarkEmitter
Adam Nemet78d10912016-07-20 21:44:18 +0000148OptimizationRemarkEmitterAnalysis::run(Function &F,
Sean Silva36e0d012016-08-09 00:28:15 +0000149 FunctionAnalysisManager &AM) {
Adam Nemet79ac42a2016-07-18 16:29:21 +0000150 BlockFrequencyInfo *BFI;
151
152 if (F.getContext().getDiagnosticHotnessRequested())
153 BFI = &AM.getResult<BlockFrequencyAnalysis>(F);
154 else
155 BFI = nullptr;
156
157 return OptimizationRemarkEmitter(&F, BFI);
158}
159
160char OptimizationRemarkEmitterWrapperPass::ID = 0;
Adam Nemetaad81602016-07-15 17:23:20 +0000161static const char ore_name[] = "Optimization Remark Emitter";
162#define ORE_NAME "opt-remark-emitter"
163
Adam Nemet79ac42a2016-07-18 16:29:21 +0000164INITIALIZE_PASS_BEGIN(OptimizationRemarkEmitterWrapperPass, ORE_NAME, ore_name,
165 false, true)
Adam Nemetaad81602016-07-15 17:23:20 +0000166INITIALIZE_PASS_DEPENDENCY(LazyBFIPass)
Adam Nemet79ac42a2016-07-18 16:29:21 +0000167INITIALIZE_PASS_END(OptimizationRemarkEmitterWrapperPass, ORE_NAME, ore_name,
168 false, true)