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::computeHotness(const MachineBasicBlock &MBB) { 36 if (!MBFI) 37 return std::nullopt; 38 39 return MBFI->getBlockProfileCount(&MBB); 40 } 41 42 void MachineOptimizationRemarkEmitter::computeHotness( 43 DiagnosticInfoMIROptimization &Remark) { 44 const MachineBasicBlock *MBB = Remark.getBlock(); 45 if (MBB) 46 Remark.setHotness(computeHotness(*MBB)); 47 } 48 49 void MachineOptimizationRemarkEmitter::emit( 50 DiagnosticInfoOptimizationBase &OptDiagCommon) { 51 auto &OptDiag = cast<DiagnosticInfoMIROptimization>(OptDiagCommon); 52 computeHotness(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(0) < Ctx.getDiagnosticsHotnessThreshold()) 58 return; 59 60 Ctx.diagnose(OptDiag); 61 } 62 63 MachineOptimizationRemarkEmitterPass::MachineOptimizationRemarkEmitterPass() 64 : MachineFunctionPass(ID) { 65 initializeMachineOptimizationRemarkEmitterPassPass( 66 *PassRegistry::getPassRegistry()); 67 } 68 69 bool MachineOptimizationRemarkEmitterPass::runOnMachineFunction( 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>(MF, MBFI); 79 return false; 80 } 81 82 void MachineOptimizationRemarkEmitterPass::getAnalysisUsage( 83 AnalysisUsage &AU) const { 84 AU.addRequired<LazyMachineBlockFrequencyInfoPass>(); 85 AU.setPreservesAll(); 86 MachineFunctionPass::getAnalysisUsage(AU); 87 } 88 89 char MachineOptimizationRemarkEmitterPass::ID = 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