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