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 | std::optional<uint64_t> |
35 | MachineOptimizationRemarkEmitter::(const MachineBasicBlock &MBB) { |
36 | if (!MBFI) |
37 | return std::nullopt; |
38 | |
39 | return MBFI->getBlockProfileCount(MBB: &MBB); |
40 | } |
41 | |
42 | void MachineOptimizationRemarkEmitter::( |
43 | DiagnosticInfoMIROptimization &) { |
44 | const MachineBasicBlock *MBB = Remark.getBlock(); |
45 | if (MBB) |
46 | Remark.setHotness(computeHotness(MBB: *MBB)); |
47 | } |
48 | |
49 | void MachineOptimizationRemarkEmitter::( |
50 | DiagnosticInfoOptimizationBase &OptDiagCommon) { |
51 | auto &OptDiag = cast<DiagnosticInfoMIROptimization>(Val&: OptDiagCommon); |
52 | computeHotness(Remark&: OptDiag); |
53 | |
54 | LLVMContext &Ctx = MF.getFunction().getContext(); |
55 | |
56 | // Only emit it if its hotness meets the threshold. |
57 | if (OptDiag.getHotness().value_or(u: 0) < Ctx.getDiagnosticsHotnessThreshold()) |
58 | return; |
59 | |
60 | Ctx.diagnose(DI: OptDiag); |
61 | } |
62 | |
63 | MachineOptimizationRemarkEmitterPass::() |
64 | : MachineFunctionPass(ID) { |
65 | initializeMachineOptimizationRemarkEmitterPassPass( |
66 | *PassRegistry::getPassRegistry()); |
67 | } |
68 | |
69 | bool MachineOptimizationRemarkEmitterPass::( |
70 | MachineFunction &MF) { |
71 | MachineBlockFrequencyInfo *MBFI; |
72 | |
73 | if (MF.getFunction().getContext().getDiagnosticsHotnessRequested()) |
74 | MBFI = &getAnalysis<LazyMachineBlockFrequencyInfoPass>().getBFI(); |
75 | else |
76 | MBFI = nullptr; |
77 | |
78 | ORE = std::make_unique<MachineOptimizationRemarkEmitter>(args&: MF, args&: MBFI); |
79 | return false; |
80 | } |
81 | |
82 | void MachineOptimizationRemarkEmitterPass::( |
83 | AnalysisUsage &AU) const { |
84 | AU.addRequired<LazyMachineBlockFrequencyInfoPass>(); |
85 | AU.setPreservesAll(); |
86 | MachineFunctionPass::getAnalysisUsage(AU); |
87 | } |
88 | |
89 | char MachineOptimizationRemarkEmitterPass:: = 0; |
90 | static const char ore_name[] = "Machine Optimization Remark Emitter" ; |
91 | #define ORE_NAME "machine-opt-remark-emitter" |
92 | |
93 | INITIALIZE_PASS_BEGIN(MachineOptimizationRemarkEmitterPass, ORE_NAME, ore_name, |
94 | true, true) |
95 | INITIALIZE_PASS_DEPENDENCY(LazyMachineBlockFrequencyInfoPass) |
96 | INITIALIZE_PASS_END(MachineOptimizationRemarkEmitterPass, ORE_NAME, ore_name, |
97 | true, true) |
98 | |