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 Key = std::string(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().value_or(0) < Ctx.getDiagnosticsHotnessThreshold()) 57 return; 58 59 Ctx.diagnose(OptDiag); 60 } 61 62 MachineOptimizationRemarkEmitterPass::MachineOptimizationRemarkEmitterPass() 63 : MachineFunctionPass(ID) { 64 initializeMachineOptimizationRemarkEmitterPassPass( 65 *PassRegistry::getPassRegistry()); 66 } 67 68 bool MachineOptimizationRemarkEmitterPass::runOnMachineFunction( 69 MachineFunction &MF) { 70 MachineBlockFrequencyInfo *MBFI; 71 72 if (MF.getFunction().getContext().getDiagnosticsHotnessRequested()) 73 MBFI = &getAnalysis<LazyMachineBlockFrequencyInfoPass>().getBFI(); 74 else 75 MBFI = nullptr; 76 77 ORE = std::make_unique<MachineOptimizationRemarkEmitter>(MF, MBFI); 78 return false; 79 } 80 81 void MachineOptimizationRemarkEmitterPass::getAnalysisUsage( 82 AnalysisUsage &AU) const { 83 AU.addRequired<LazyMachineBlockFrequencyInfoPass>(); 84 AU.setPreservesAll(); 85 MachineFunctionPass::getAnalysisUsage(AU); 86 } 87 88 char MachineOptimizationRemarkEmitterPass::ID = 0; 89 static const char ore_name[] = "Machine Optimization Remark Emitter"; 90 #define ORE_NAME "machine-opt-remark-emitter" 91 92 INITIALIZE_PASS_BEGIN(MachineOptimizationRemarkEmitterPass, ORE_NAME, ore_name, 93 true, true) 94 INITIALIZE_PASS_DEPENDENCY(LazyMachineBlockFrequencyInfoPass) 95 INITIALIZE_PASS_END(MachineOptimizationRemarkEmitterPass, ORE_NAME, ore_name, 96 true, true) 97