1 | ///===- MachineOptimizationRemarkEmitter.cpp - Opt 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 | /// \file |
9 | /// Optimization diagnostic interfaces for machine passes. It's packaged as an |
10 | /// analysis pass so that by using this service passes become dependent on MBFI |
11 | /// as well. MBFI is used to compute the "hotness" of the diagnostic message. |
12 | /// |
13 | ///===---------------------------------------------------------------------===// |
14 | |
15 | #include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h" |
16 | #include "llvm/CodeGen/LazyMachineBlockFrequencyInfo.h" |
17 | #include "llvm/CodeGen/MachineInstr.h" |
18 | #include "llvm/IR/DiagnosticInfo.h" |
19 | #include "llvm/IR/LLVMContext.h" |
20 | #include "llvm/InitializePasses.h" |
21 | #include <optional> |
22 | |
23 | using namespace llvm; |
24 | |
25 | DiagnosticInfoMIROptimization::MachineArgument::MachineArgument( |
26 | StringRef MKey, const MachineInstr &MI) { |
27 | Key = std::string(MKey); |
28 | |
29 | raw_string_ostream OS(Val); |
30 | MI.print(OS, /*IsStandalone=*/true, /*SkipOpers=*/false, |
31 | /*SkipDebugLoc=*/true); |
32 | } |
33 | |
34 | bool MachineOptimizationRemarkEmitter::( |
35 | MachineFunction &MF, const PreservedAnalyses &PA, |
36 | MachineFunctionAnalysisManager::Invalidator &Inv) { |
37 | // This analysis has no state and so can be trivially preserved but it needs |
38 | // a fresh view of BFI if it was constructed with one. |
39 | return MBFI && Inv.invalidate<MachineBlockFrequencyAnalysis>(IR&: MF, PA); |
40 | } |
41 | |
42 | std::optional<uint64_t> |
43 | MachineOptimizationRemarkEmitter::(const MachineBasicBlock &MBB) { |
44 | if (!MBFI) |
45 | return std::nullopt; |
46 | |
47 | return MBFI->getBlockProfileCount(MBB: &MBB); |
48 | } |
49 | |
50 | void MachineOptimizationRemarkEmitter::( |
51 | DiagnosticInfoMIROptimization &) { |
52 | const MachineBasicBlock *MBB = Remark.getBlock(); |
53 | if (MBB) |
54 | Remark.setHotness(computeHotness(MBB: *MBB)); |
55 | } |
56 | |
57 | void MachineOptimizationRemarkEmitter::( |
58 | DiagnosticInfoOptimizationBase &OptDiagCommon) { |
59 | auto &OptDiag = cast<DiagnosticInfoMIROptimization>(Val&: OptDiagCommon); |
60 | computeHotness(Remark&: OptDiag); |
61 | |
62 | LLVMContext &Ctx = MF.getFunction().getContext(); |
63 | |
64 | // Only emit it if its hotness meets the threshold. |
65 | if (OptDiag.getHotness().value_or(u: 0) < Ctx.getDiagnosticsHotnessThreshold()) |
66 | return; |
67 | |
68 | Ctx.diagnose(DI: OptDiag); |
69 | } |
70 | |
71 | MachineOptimizationRemarkEmitterPass::() |
72 | : MachineFunctionPass(ID) { |
73 | initializeMachineOptimizationRemarkEmitterPassPass( |
74 | *PassRegistry::getPassRegistry()); |
75 | } |
76 | |
77 | bool MachineOptimizationRemarkEmitterPass::( |
78 | MachineFunction &MF) { |
79 | MachineBlockFrequencyInfo *MBFI; |
80 | |
81 | if (MF.getFunction().getContext().getDiagnosticsHotnessRequested()) |
82 | MBFI = &getAnalysis<LazyMachineBlockFrequencyInfoPass>().getBFI(); |
83 | else |
84 | MBFI = nullptr; |
85 | |
86 | ORE = std::make_unique<MachineOptimizationRemarkEmitter>(args&: MF, args&: MBFI); |
87 | return false; |
88 | } |
89 | |
90 | void MachineOptimizationRemarkEmitterPass::( |
91 | AnalysisUsage &AU) const { |
92 | AU.addRequired<LazyMachineBlockFrequencyInfoPass>(); |
93 | AU.setPreservesAll(); |
94 | MachineFunctionPass::getAnalysisUsage(AU); |
95 | } |
96 | |
97 | AnalysisKey MachineOptimizationRemarkEmitterAnalysis::; |
98 | |
99 | MachineOptimizationRemarkEmitterAnalysis::Result |
100 | MachineOptimizationRemarkEmitterAnalysis::( |
101 | MachineFunction &MF, MachineFunctionAnalysisManager &MFAM) { |
102 | MachineBlockFrequencyInfo *MBFI = |
103 | MF.getFunction().getContext().getDiagnosticsHotnessRequested() |
104 | ? &MFAM.getResult<MachineBlockFrequencyAnalysis>(IR&: MF) |
105 | : nullptr; |
106 | return Result(MF, MBFI); |
107 | } |
108 | |
109 | char MachineOptimizationRemarkEmitterPass:: = 0; |
110 | static const char ore_name[] = "Machine Optimization Remark Emitter" ; |
111 | #define ORE_NAME "machine-opt-remark-emitter" |
112 | |
113 | INITIALIZE_PASS_BEGIN(MachineOptimizationRemarkEmitterPass, ORE_NAME, ore_name, |
114 | true, true) |
115 | INITIALIZE_PASS_DEPENDENCY(LazyMachineBlockFrequencyInfoPass) |
116 | INITIALIZE_PASS_END(MachineOptimizationRemarkEmitterPass, ORE_NAME, ore_name, |
117 | true, true) |
118 | |