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/DebugInfo.h" 20 #include "llvm/IR/DiagnosticInfo.h" 21 #include "llvm/IR/LLVMContext.h" 22 23 using namespace llvm; 24 25 DiagnosticInfoMIROptimization::MachineArgument::MachineArgument( 26 StringRef MKey, const MachineInstr &MI) 27 : Argument() { 28 Key = MKey; 29 30 raw_string_ostream OS(Val); 31 MI.print(OS, /*SkipOpers=*/false, /*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 // If a diagnostic has a hotness value, then only emit it if its hotness 57 // meets the threshold. 58 if (OptDiag.getHotness() && 59 *OptDiag.getHotness() < Ctx.getDiagnosticsHotnessThreshold()) { 60 return; 61 } 62 63 yaml::Output *Out = Ctx.getDiagnosticsOutputFile(); 64 if (Out) { 65 auto *P = &const_cast<DiagnosticInfoOptimizationBase &>(OptDiagCommon); 66 *Out << P; 67 } 68 // FIXME: now that IsVerbose is part of DI, filtering for this will be moved 69 // from here to clang. 70 if (!OptDiag.isVerbose() || shouldEmitVerbose()) 71 Ctx.diagnose(OptDiag); 72 } 73 74 MachineOptimizationRemarkEmitterPass::MachineOptimizationRemarkEmitterPass() 75 : MachineFunctionPass(ID) { 76 initializeMachineOptimizationRemarkEmitterPassPass( 77 *PassRegistry::getPassRegistry()); 78 } 79 80 bool MachineOptimizationRemarkEmitterPass::runOnMachineFunction( 81 MachineFunction &MF) { 82 MachineBlockFrequencyInfo *MBFI; 83 84 if (MF.getFunction()->getContext().getDiagnosticsHotnessRequested()) 85 MBFI = &getAnalysis<LazyMachineBlockFrequencyInfoPass>().getBFI(); 86 else 87 MBFI = nullptr; 88 89 ORE = llvm::make_unique<MachineOptimizationRemarkEmitter>(MF, MBFI); 90 return false; 91 } 92 93 void MachineOptimizationRemarkEmitterPass::getAnalysisUsage( 94 AnalysisUsage &AU) const { 95 AU.addRequired<LazyMachineBlockFrequencyInfoPass>(); 96 AU.setPreservesAll(); 97 MachineFunctionPass::getAnalysisUsage(AU); 98 } 99 100 char MachineOptimizationRemarkEmitterPass::ID = 0; 101 static const char ore_name[] = "Machine Optimization Remark Emitter"; 102 #define ORE_NAME "machine-opt-remark-emitter" 103 104 INITIALIZE_PASS_BEGIN(MachineOptimizationRemarkEmitterPass, ORE_NAME, ore_name, 105 false, true) 106 INITIALIZE_PASS_DEPENDENCY(LazyMachineBlockFrequencyInfoPass) 107 INITIALIZE_PASS_END(MachineOptimizationRemarkEmitterPass, ORE_NAME, ore_name, 108 false, true) 109