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 #include <optional> 22 23 using namespace llvm; 24 25 DiagnosticInfoMIROptimization::MachineArgument::MachineArgument( 26 StringRef MKey, const MachineInstr &MI) { 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 bool MachineOptimizationRemarkEmitter::invalidate( 35 MachineFunction &MF, const PreservedAnalyses &PA, 36 MachineFunctionAnalysisManager::Invalidator &Inv) { 37 // This analysis has no state and so can be trivially preserved but it needs 38 // a fresh view of BFI if it was constructed with one. 39 return MBFI && Inv.invalidate<MachineBlockFrequencyAnalysis>(MF, PA); 40 } 41 42 std::optional<uint64_t> 43 MachineOptimizationRemarkEmitter::computeHotness(const MachineBasicBlock &MBB) { 44 if (!MBFI) 45 return std::nullopt; 46 47 return MBFI->getBlockProfileCount(&MBB); 48 } 49 50 void MachineOptimizationRemarkEmitter::computeHotness( 51 DiagnosticInfoMIROptimization &Remark) { 52 const MachineBasicBlock *MBB = Remark.getBlock(); 53 if (MBB) 54 Remark.setHotness(computeHotness(*MBB)); 55 } 56 57 void MachineOptimizationRemarkEmitter::emit( 58 DiagnosticInfoOptimizationBase &OptDiagCommon) { 59 auto &OptDiag = cast<DiagnosticInfoMIROptimization>(OptDiagCommon); 60 computeHotness(OptDiag); 61 62 LLVMContext &Ctx = MF.getFunction().getContext(); 63 64 // Only emit it if its hotness meets the threshold. 65 if (OptDiag.getHotness().value_or(0) < Ctx.getDiagnosticsHotnessThreshold()) 66 return; 67 68 Ctx.diagnose(OptDiag); 69 } 70 71 MachineOptimizationRemarkEmitterPass::MachineOptimizationRemarkEmitterPass() 72 : MachineFunctionPass(ID) { 73 initializeMachineOptimizationRemarkEmitterPassPass( 74 *PassRegistry::getPassRegistry()); 75 } 76 77 bool MachineOptimizationRemarkEmitterPass::runOnMachineFunction( 78 MachineFunction &MF) { 79 MachineBlockFrequencyInfo *MBFI; 80 81 if (MF.getFunction().getContext().getDiagnosticsHotnessRequested()) 82 MBFI = &getAnalysis<LazyMachineBlockFrequencyInfoPass>().getBFI(); 83 else 84 MBFI = nullptr; 85 86 ORE = std::make_unique<MachineOptimizationRemarkEmitter>(MF, MBFI); 87 return false; 88 } 89 90 void MachineOptimizationRemarkEmitterPass::getAnalysisUsage( 91 AnalysisUsage &AU) const { 92 AU.addRequired<LazyMachineBlockFrequencyInfoPass>(); 93 AU.setPreservesAll(); 94 MachineFunctionPass::getAnalysisUsage(AU); 95 } 96 97 AnalysisKey MachineOptimizationRemarkEmitterAnalysis::Key; 98 99 MachineOptimizationRemarkEmitterAnalysis::Result 100 MachineOptimizationRemarkEmitterAnalysis::run( 101 MachineFunction &MF, MachineFunctionAnalysisManager &MFAM) { 102 MachineBlockFrequencyInfo *MBFI = 103 MF.getFunction().getContext().getDiagnosticsHotnessRequested() 104 ? &MFAM.getResult<MachineBlockFrequencyAnalysis>(MF) 105 : nullptr; 106 return Result(MF, MBFI); 107 } 108 109 char MachineOptimizationRemarkEmitterPass::ID = 0; 110 static const char ore_name[] = "Machine Optimization Remark Emitter"; 111 #define ORE_NAME "machine-opt-remark-emitter" 112 113 INITIALIZE_PASS_BEGIN(MachineOptimizationRemarkEmitterPass, ORE_NAME, ore_name, 114 true, true) 115 INITIALIZE_PASS_DEPENDENCY(LazyMachineBlockFrequencyInfoPass) 116 INITIALIZE_PASS_END(MachineOptimizationRemarkEmitterPass, ORE_NAME, ore_name, 117 true, true) 118