blob: 6f3d4d536c40144a8f5519346ee3f4669a55925f [file] [log] [blame]
Adam Nemet0965da22017-10-09 23:19:02 +00001//===- OptimizationRemarkEmitter.cpp - Optimization Diagnostic --*- C++ -*-===//
Adam Nemetaad81602016-07-15 17:23:20 +00002//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Adam Nemetaad81602016-07-15 17:23:20 +00006//
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
Adam Nemet0965da22017-10-09 23:19:02 +000014#include "llvm/Analysis/OptimizationRemarkEmitter.h"
Adam Nemet896c09b2016-08-10 00:44:44 +000015#include "llvm/Analysis/BranchProbabilityInfo.h"
Adam Nemetaad81602016-07-15 17:23:20 +000016#include "llvm/Analysis/LazyBlockFrequencyInfo.h"
17#include "llvm/Analysis/LoopInfo.h"
Wei Wang93dc1b52020-11-17 10:43:02 -080018#include "llvm/Analysis/ProfileSummaryInfo.h"
Adam Nemetaad81602016-07-15 17:23:20 +000019#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"
Reid Kleckner05da2fe2019-11-13 13:15:01 -080022#include "llvm/InitializePasses.h"
Adam Nemetaad81602016-07-15 17:23:20 +000023
24using namespace llvm;
25
Justin Bogner8281c812017-02-22 07:38:17 +000026OptimizationRemarkEmitter::OptimizationRemarkEmitter(const Function *F)
Adam Nemet896c09b2016-08-10 00:44:44 +000027 : F(F), BFI(nullptr) {
Brian Gesiak44e5f6c2017-06-30 18:13:59 +000028 if (!F->getContext().getDiagnosticsHotnessRequested())
Adam Nemet896c09b2016-08-10 00:44:44 +000029 return;
30
31 // First create a dominator tree.
32 DominatorTree DT;
Justin Bogner8281c812017-02-22 07:38:17 +000033 DT.recalculate(*const_cast<Function *>(F));
Adam Nemet896c09b2016-08-10 00:44:44 +000034
35 // Generate LoopInfo from it.
36 LoopInfo LI;
37 LI.analyze(DT);
38
39 // Then compute BranchProbabilityInfo.
Evgeniy Brevnov9fb074e2020-06-18 16:20:55 +070040 BranchProbabilityInfo BPI(*F, LI, nullptr, &DT, nullptr);
Adam Nemet896c09b2016-08-10 00:44:44 +000041
42 // Finally compute BFI.
Jonas Devlieghere0eaee542019-08-15 15:54:37 +000043 OwnedBFI = std::make_unique<BlockFrequencyInfo>(*F, BPI, LI);
Adam Nemet896c09b2016-08-10 00:44:44 +000044 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) {
Alina Sbirlea4f33a682020-01-16 15:32:30 -080050 if (OwnedBFI.get()) {
51 OwnedBFI.reset();
52 BFI = nullptr;
53 }
Chandler Carruth1ae34c32017-01-15 08:20:50 +000054 // This analysis has no state and so can be trivially preserved but it needs
55 // a fresh view of BFI if it was constructed with one.
56 if (BFI && Inv.invalidate<BlockFrequencyAnalysis>(F, PA))
57 return true;
58
59 // Otherwise this analysis result remains valid.
60 return false;
61}
62
Adam Nemet6100d162016-07-20 21:44:22 +000063Optional<uint64_t> OptimizationRemarkEmitter::computeHotness(const Value *V) {
Adam Nemetaad81602016-07-15 17:23:20 +000064 if (!BFI)
65 return None;
66
67 return BFI->getBlockProfileCount(cast<BasicBlock>(V));
68}
69
Adam Nemeta62b7e12016-09-27 20:55:07 +000070void OptimizationRemarkEmitter::computeHotness(
Adam Nemet484f93d2017-01-25 23:20:25 +000071 DiagnosticInfoIROptimization &OptDiag) {
Justin Bogner8281c812017-02-22 07:38:17 +000072 const Value *V = OptDiag.getCodeRegion();
Adam Nemeta62b7e12016-09-27 20:55:07 +000073 if (V)
74 OptDiag.setHotness(computeHotness(V));
75}
76
Adam Nemet484f93d2017-01-25 23:20:25 +000077void OptimizationRemarkEmitter::emit(
78 DiagnosticInfoOptimizationBase &OptDiagBase) {
79 auto &OptDiag = cast<DiagnosticInfoIROptimization>(OptDiagBase);
Adam Nemeta62b7e12016-09-27 20:55:07 +000080 computeHotness(OptDiag);
Adam Nemet9303f622017-12-01 20:41:38 +000081
82 // Only emit it if its hotness meets the threshold.
83 if (OptDiag.getHotness().getValueOr(0) <
84 F->getContext().getDiagnosticsHotnessThreshold()) {
Brian Gesiak4ef3daa2017-06-30 23:14:53 +000085 return;
86 }
Adam Nemeta62b7e12016-09-27 20:55:07 +000087
Adam Nemetf31b1f32017-10-04 04:26:23 +000088 F->getContext().diagnose(OptDiag);
Adam Nemeta62b7e12016-09-27 20:55:07 +000089}
90
Adam Nemet79ac42a2016-07-18 16:29:21 +000091OptimizationRemarkEmitterWrapperPass::OptimizationRemarkEmitterWrapperPass()
92 : FunctionPass(ID) {
93 initializeOptimizationRemarkEmitterWrapperPassPass(
94 *PassRegistry::getPassRegistry());
95}
96
97bool OptimizationRemarkEmitterWrapperPass::runOnFunction(Function &Fn) {
98 BlockFrequencyInfo *BFI;
Adam Nemetaad81602016-07-15 17:23:20 +000099
Wei Wang93dc1b52020-11-17 10:43:02 -0800100 auto &Context = Fn.getContext();
101 if (Context.getDiagnosticsHotnessRequested()) {
Adam Nemetaad81602016-07-15 17:23:20 +0000102 BFI = &getAnalysis<LazyBlockFrequencyInfoPass>().getBFI();
Wei Wang93dc1b52020-11-17 10:43:02 -0800103 // Get hotness threshold from PSI. This should only happen once.
104 if (Context.isDiagnosticsHotnessThresholdSetFromPSI()) {
105 if (ProfileSummaryInfo *PSI =
106 &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI())
107 Context.setDiagnosticsHotnessThreshold(
108 PSI->getOrCompHotCountThreshold());
109 }
110 } else
Adam Nemetaad81602016-07-15 17:23:20 +0000111 BFI = nullptr;
112
Jonas Devlieghere0eaee542019-08-15 15:54:37 +0000113 ORE = std::make_unique<OptimizationRemarkEmitter>(&Fn, BFI);
Adam Nemetaad81602016-07-15 17:23:20 +0000114 return false;
115}
116
Adam Nemet79ac42a2016-07-18 16:29:21 +0000117void OptimizationRemarkEmitterWrapperPass::getAnalysisUsage(
118 AnalysisUsage &AU) const {
Adam Nemetaad81602016-07-15 17:23:20 +0000119 LazyBlockFrequencyInfoPass::getLazyBFIAnalysisUsage(AU);
Wei Wang93dc1b52020-11-17 10:43:02 -0800120 AU.addRequired<ProfileSummaryInfoWrapperPass>();
Adam Nemetaad81602016-07-15 17:23:20 +0000121 AU.setPreservesAll();
122}
123
Chandler Carruthdab4eae2016-11-23 17:53:26 +0000124AnalysisKey OptimizationRemarkEmitterAnalysis::Key;
Adam Nemet79ac42a2016-07-18 16:29:21 +0000125
126OptimizationRemarkEmitter
Adam Nemet78d10912016-07-20 21:44:18 +0000127OptimizationRemarkEmitterAnalysis::run(Function &F,
Sean Silva36e0d012016-08-09 00:28:15 +0000128 FunctionAnalysisManager &AM) {
Adam Nemet79ac42a2016-07-18 16:29:21 +0000129 BlockFrequencyInfo *BFI;
Wei Wang93dc1b52020-11-17 10:43:02 -0800130 auto &Context = F.getContext();
Adam Nemet79ac42a2016-07-18 16:29:21 +0000131
Wei Wang93dc1b52020-11-17 10:43:02 -0800132 if (Context.getDiagnosticsHotnessRequested()) {
Adam Nemet79ac42a2016-07-18 16:29:21 +0000133 BFI = &AM.getResult<BlockFrequencyAnalysis>(F);
Wei Wang93dc1b52020-11-17 10:43:02 -0800134 // Get hotness threshold from PSI. This should only happen once.
135 if (Context.isDiagnosticsHotnessThresholdSetFromPSI()) {
136 auto &MAMProxy = AM.getResult<ModuleAnalysisManagerFunctionProxy>(F);
137 if (ProfileSummaryInfo *PSI =
138 MAMProxy.getCachedResult<ProfileSummaryAnalysis>(*F.getParent()))
139 Context.setDiagnosticsHotnessThreshold(
140 PSI->getOrCompHotCountThreshold());
141 }
142 } else
Adam Nemet79ac42a2016-07-18 16:29:21 +0000143 BFI = nullptr;
144
145 return OptimizationRemarkEmitter(&F, BFI);
146}
147
148char OptimizationRemarkEmitterWrapperPass::ID = 0;
Adam Nemetaad81602016-07-15 17:23:20 +0000149static const char ore_name[] = "Optimization Remark Emitter";
150#define ORE_NAME "opt-remark-emitter"
151
Adam Nemet79ac42a2016-07-18 16:29:21 +0000152INITIALIZE_PASS_BEGIN(OptimizationRemarkEmitterWrapperPass, ORE_NAME, ore_name,
153 false, true)
Adam Nemetaad81602016-07-15 17:23:20 +0000154INITIALIZE_PASS_DEPENDENCY(LazyBFIPass)
Wei Wang93dc1b52020-11-17 10:43:02 -0800155INITIALIZE_PASS_DEPENDENCY(ProfileSummaryInfoWrapperPass)
Adam Nemet79ac42a2016-07-18 16:29:21 +0000156INITIALIZE_PASS_END(OptimizationRemarkEmitterWrapperPass, ORE_NAME, ore_name,
157 false, true)