1 ///===- MachineOptimizationRemarkEmitter.cpp - Opt Diagnostic -*- C++ -*---===// 2 /// 3 /// The LLVM Compiler Infrastructure 4 /// 5 /// This file is distributed under the University of Illinois Open Source 6 /// License. See LICENSE.TXT for details. 7 /// 8 ///===---------------------------------------------------------------------===// 9 /// \file 10 /// Optimization diagnostic interfaces for machine passes. It's packaged as an 11 /// analysis pass so that by using this service passes become dependent on MBFI 12 /// as well. MBFI is used to compute the "hotness" of the diagnostic message. 13 /// 14 ///===---------------------------------------------------------------------===// 15 16 #include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h" 17 #include "llvm/CodeGen/LazyMachineBlockFrequencyInfo.h" 18 #include "llvm/CodeGen/MachineInstr.h" 19 #include "llvm/IR/DiagnosticInfo.h" 20 #include "llvm/IR/LLVMContext.h" 21 22 using namespace llvm; 23 24 DiagnosticInfoMIROptimization::MachineArgument::MachineArgument( 25 StringRef MKey, const MachineInstr &MI) 26 : Argument() { 27 Key = MKey; 28 29 raw_string_ostream OS(Val); 30 MI.print(OS, /*SkipOpers=*/false, /*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 = llvm::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