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 22 using namespace llvm; 23 24 DiagnosticInfoMIROptimization::MachineArgument::MachineArgument( 25 StringRef MKey, const MachineInstr &MI) 26 : Argument() { 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 Optional<uint64_t> 35 MachineOptimizationRemarkEmitter::computeHotness(const MachineBasicBlock &MBB) { 36 if (!MBFI) 37 return None; 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().getValueOr(0) < 58 Ctx.getDiagnosticsHotnessThreshold()) { 59 return; 60 } 61 62 Ctx.diagnose(OptDiag); 63 } 64 65 MachineOptimizationRemarkEmitterPass::MachineOptimizationRemarkEmitterPass() 66 : MachineFunctionPass(ID) { 67 initializeMachineOptimizationRemarkEmitterPassPass( 68 *PassRegistry::getPassRegistry()); 69 } 70 71 bool MachineOptimizationRemarkEmitterPass::runOnMachineFunction( 72 MachineFunction &MF) { 73 MachineBlockFrequencyInfo *MBFI; 74 75 if (MF.getFunction().getContext().getDiagnosticsHotnessRequested()) 76 MBFI = &getAnalysis<LazyMachineBlockFrequencyInfoPass>().getBFI(); 77 else 78 MBFI = nullptr; 79 80 ORE = std::make_unique<MachineOptimizationRemarkEmitter>(MF, MBFI); 81 return false; 82 } 83 84 void MachineOptimizationRemarkEmitterPass::getAnalysisUsage( 85 AnalysisUsage &AU) const { 86 AU.addRequired<LazyMachineBlockFrequencyInfoPass>(); 87 AU.setPreservesAll(); 88 MachineFunctionPass::getAnalysisUsage(AU); 89 } 90 91 char MachineOptimizationRemarkEmitterPass::ID = 0; 92 static const char ore_name[] = "Machine Optimization Remark Emitter"; 93 #define ORE_NAME "machine-opt-remark-emitter" 94 95 INITIALIZE_PASS_BEGIN(MachineOptimizationRemarkEmitterPass, ORE_NAME, ore_name, 96 false, true) 97 INITIALIZE_PASS_DEPENDENCY(LazyMachineBlockFrequencyInfoPass) 98 INITIALIZE_PASS_END(MachineOptimizationRemarkEmitterPass, ORE_NAME, ore_name, 99 false, true) 100