1a9640667SAdam Nemet ///===- MachineOptimizationRemarkEmitter.cpp - Opt Diagnostic -*- C++ -*---===// 2a9640667SAdam Nemet /// 3a9640667SAdam Nemet /// The LLVM Compiler Infrastructure 4a9640667SAdam Nemet /// 5a9640667SAdam Nemet /// This file is distributed under the University of Illinois Open Source 6a9640667SAdam Nemet /// License. See LICENSE.TXT for details. 7a9640667SAdam Nemet /// 8a9640667SAdam Nemet ///===---------------------------------------------------------------------===// 9a9640667SAdam Nemet /// \file 10a9640667SAdam Nemet /// Optimization diagnostic interfaces for machine passes. It's packaged as an 11a9640667SAdam Nemet /// analysis pass so that by using this service passes become dependent on MBFI 12a9640667SAdam Nemet /// as well. MBFI is used to compute the "hotness" of the diagnostic message. 13a9640667SAdam Nemet /// 14a9640667SAdam Nemet ///===---------------------------------------------------------------------===// 15a9640667SAdam Nemet 16a9640667SAdam Nemet #include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h" 17bbb141c7SAdam Nemet #include "llvm/CodeGen/LazyMachineBlockFrequencyInfo.h" 1827273975SAhmed Bougacha #include "llvm/CodeGen/MachineInstr.h" 19a9640667SAdam Nemet #include "llvm/IR/DebugInfo.h" 20a9640667SAdam Nemet #include "llvm/IR/DiagnosticInfo.h" 21a9640667SAdam Nemet #include "llvm/IR/LLVMContext.h" 22a9640667SAdam Nemet 23a9640667SAdam Nemet using namespace llvm; 24a9640667SAdam Nemet 2527273975SAhmed Bougacha DiagnosticInfoMIROptimization::MachineArgument::MachineArgument( 2627273975SAhmed Bougacha StringRef MKey, const MachineInstr &MI) 2727273975SAhmed Bougacha : Argument() { 2827273975SAhmed Bougacha Key = MKey; 2927273975SAhmed Bougacha 3027273975SAhmed Bougacha raw_string_ostream OS(Val); 3127273975SAhmed Bougacha MI.print(OS, /*SkipOpers=*/false, /*SkipDebugLoc=*/true); 3227273975SAhmed Bougacha } 3327273975SAhmed Bougacha 34a9640667SAdam Nemet Optional<uint64_t> 35a9640667SAdam Nemet MachineOptimizationRemarkEmitter::computeHotness(const MachineBasicBlock &MBB) { 36a9640667SAdam Nemet if (!MBFI) 37a9640667SAdam Nemet return None; 38a9640667SAdam Nemet 39a9640667SAdam Nemet return MBFI->getBlockProfileCount(&MBB); 40a9640667SAdam Nemet } 41a9640667SAdam Nemet 42a9640667SAdam Nemet void MachineOptimizationRemarkEmitter::computeHotness( 43a9640667SAdam Nemet DiagnosticInfoMIROptimization &Remark) { 44a9640667SAdam Nemet const MachineBasicBlock *MBB = Remark.getBlock(); 45a9640667SAdam Nemet if (MBB) 46a9640667SAdam Nemet Remark.setHotness(computeHotness(*MBB)); 47a9640667SAdam Nemet } 48a9640667SAdam Nemet 49a9640667SAdam Nemet void MachineOptimizationRemarkEmitter::emit( 50a9640667SAdam Nemet DiagnosticInfoOptimizationBase &OptDiagCommon) { 51a9640667SAdam Nemet auto &OptDiag = cast<DiagnosticInfoMIROptimization>(OptDiagCommon); 52a9640667SAdam Nemet computeHotness(OptDiag); 53a9640667SAdam Nemet 54a9640667SAdam Nemet LLVMContext &Ctx = MF.getFunction()->getContext(); 55*4ef3daafSBrian Gesiak 56*4ef3daafSBrian Gesiak // If a diagnostic has a hotness value, then only emit it if its hotness 57*4ef3daafSBrian Gesiak // meets the threshold. 58*4ef3daafSBrian Gesiak if (OptDiag.getHotness() && 59*4ef3daafSBrian Gesiak *OptDiag.getHotness() < Ctx.getDiagnosticsHotnessThreshold()) { 60*4ef3daafSBrian Gesiak return; 61*4ef3daafSBrian Gesiak } 62*4ef3daafSBrian Gesiak 63a9640667SAdam Nemet yaml::Output *Out = Ctx.getDiagnosticsOutputFile(); 64a9640667SAdam Nemet if (Out) { 65a9640667SAdam Nemet auto *P = &const_cast<DiagnosticInfoOptimizationBase &>(OptDiagCommon); 66a9640667SAdam Nemet *Out << P; 67a9640667SAdam Nemet } 68a9640667SAdam Nemet // FIXME: now that IsVerbose is part of DI, filtering for this will be moved 69a9640667SAdam Nemet // from here to clang. 70a9640667SAdam Nemet if (!OptDiag.isVerbose() || shouldEmitVerbose()) 71a9640667SAdam Nemet Ctx.diagnose(OptDiag); 72a9640667SAdam Nemet } 73a9640667SAdam Nemet 74a9640667SAdam Nemet MachineOptimizationRemarkEmitterPass::MachineOptimizationRemarkEmitterPass() 75a9640667SAdam Nemet : MachineFunctionPass(ID) { 76a9640667SAdam Nemet initializeMachineOptimizationRemarkEmitterPassPass( 77a9640667SAdam Nemet *PassRegistry::getPassRegistry()); 78a9640667SAdam Nemet } 79a9640667SAdam Nemet 80a9640667SAdam Nemet bool MachineOptimizationRemarkEmitterPass::runOnMachineFunction( 81a9640667SAdam Nemet MachineFunction &MF) { 82a9640667SAdam Nemet MachineBlockFrequencyInfo *MBFI; 83a9640667SAdam Nemet 8444e5f6c4SBrian Gesiak if (MF.getFunction()->getContext().getDiagnosticsHotnessRequested()) 85bbb141c7SAdam Nemet MBFI = &getAnalysis<LazyMachineBlockFrequencyInfoPass>().getBFI(); 86a9640667SAdam Nemet else 87a9640667SAdam Nemet MBFI = nullptr; 88a9640667SAdam Nemet 89a9640667SAdam Nemet ORE = llvm::make_unique<MachineOptimizationRemarkEmitter>(MF, MBFI); 90a9640667SAdam Nemet return false; 91a9640667SAdam Nemet } 92a9640667SAdam Nemet 93a9640667SAdam Nemet void MachineOptimizationRemarkEmitterPass::getAnalysisUsage( 94a9640667SAdam Nemet AnalysisUsage &AU) const { 95b516cf3fSAdam Nemet AU.addRequired<LazyMachineBlockFrequencyInfoPass>(); 96a9640667SAdam Nemet AU.setPreservesAll(); 97a9640667SAdam Nemet MachineFunctionPass::getAnalysisUsage(AU); 98a9640667SAdam Nemet } 99a9640667SAdam Nemet 100a9640667SAdam Nemet char MachineOptimizationRemarkEmitterPass::ID = 0; 101a9640667SAdam Nemet static const char ore_name[] = "Machine Optimization Remark Emitter"; 102a9640667SAdam Nemet #define ORE_NAME "machine-opt-remark-emitter" 103a9640667SAdam Nemet 104a9640667SAdam Nemet INITIALIZE_PASS_BEGIN(MachineOptimizationRemarkEmitterPass, ORE_NAME, ore_name, 105a9640667SAdam Nemet false, true) 106b516cf3fSAdam Nemet INITIALIZE_PASS_DEPENDENCY(LazyMachineBlockFrequencyInfoPass) 107a9640667SAdam Nemet INITIALIZE_PASS_END(MachineOptimizationRemarkEmitterPass, ORE_NAME, ore_name, 108a9640667SAdam Nemet false, true) 109