17a7e6055SDimitry Andric ///===- MachineOptimizationRemarkEmitter.cpp - Opt Diagnostic -*- C++ -*---===//
27a7e6055SDimitry Andric ///
37a7e6055SDimitry Andric /// The LLVM Compiler Infrastructure
47a7e6055SDimitry Andric ///
57a7e6055SDimitry Andric /// This file is distributed under the University of Illinois Open Source
67a7e6055SDimitry Andric /// License. See LICENSE.TXT for details.
77a7e6055SDimitry Andric ///
87a7e6055SDimitry Andric ///===---------------------------------------------------------------------===//
97a7e6055SDimitry Andric /// \file
107a7e6055SDimitry Andric /// Optimization diagnostic interfaces for machine passes. It's packaged as an
117a7e6055SDimitry Andric /// analysis pass so that by using this service passes become dependent on MBFI
127a7e6055SDimitry Andric /// as well. MBFI is used to compute the "hotness" of the diagnostic message.
137a7e6055SDimitry Andric ///
147a7e6055SDimitry Andric ///===---------------------------------------------------------------------===//
157a7e6055SDimitry Andric
167a7e6055SDimitry Andric #include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
177a7e6055SDimitry Andric #include "llvm/CodeGen/LazyMachineBlockFrequencyInfo.h"
187a7e6055SDimitry Andric #include "llvm/CodeGen/MachineInstr.h"
197a7e6055SDimitry Andric #include "llvm/IR/DiagnosticInfo.h"
207a7e6055SDimitry Andric #include "llvm/IR/LLVMContext.h"
217a7e6055SDimitry Andric
227a7e6055SDimitry Andric using namespace llvm;
237a7e6055SDimitry Andric
MachineArgument(StringRef MKey,const MachineInstr & MI)247a7e6055SDimitry Andric DiagnosticInfoMIROptimization::MachineArgument::MachineArgument(
257a7e6055SDimitry Andric StringRef MKey, const MachineInstr &MI)
267a7e6055SDimitry Andric : Argument() {
277a7e6055SDimitry Andric Key = MKey;
287a7e6055SDimitry Andric
297a7e6055SDimitry Andric raw_string_ostream OS(Val);
30*4ba319b5SDimitry Andric MI.print(OS, /*IsStandalone=*/true, /*SkipOpers=*/false,
31*4ba319b5SDimitry Andric /*SkipDebugLoc=*/true);
327a7e6055SDimitry Andric }
337a7e6055SDimitry Andric
347a7e6055SDimitry Andric Optional<uint64_t>
computeHotness(const MachineBasicBlock & MBB)357a7e6055SDimitry Andric MachineOptimizationRemarkEmitter::computeHotness(const MachineBasicBlock &MBB) {
367a7e6055SDimitry Andric if (!MBFI)
377a7e6055SDimitry Andric return None;
387a7e6055SDimitry Andric
397a7e6055SDimitry Andric return MBFI->getBlockProfileCount(&MBB);
407a7e6055SDimitry Andric }
417a7e6055SDimitry Andric
computeHotness(DiagnosticInfoMIROptimization & Remark)427a7e6055SDimitry Andric void MachineOptimizationRemarkEmitter::computeHotness(
437a7e6055SDimitry Andric DiagnosticInfoMIROptimization &Remark) {
447a7e6055SDimitry Andric const MachineBasicBlock *MBB = Remark.getBlock();
457a7e6055SDimitry Andric if (MBB)
467a7e6055SDimitry Andric Remark.setHotness(computeHotness(*MBB));
477a7e6055SDimitry Andric }
487a7e6055SDimitry Andric
emit(DiagnosticInfoOptimizationBase & OptDiagCommon)497a7e6055SDimitry Andric void MachineOptimizationRemarkEmitter::emit(
507a7e6055SDimitry Andric DiagnosticInfoOptimizationBase &OptDiagCommon) {
517a7e6055SDimitry Andric auto &OptDiag = cast<DiagnosticInfoMIROptimization>(OptDiagCommon);
527a7e6055SDimitry Andric computeHotness(OptDiag);
537a7e6055SDimitry Andric
542cab237bSDimitry Andric LLVMContext &Ctx = MF.getFunction().getContext();
55a580b014SDimitry Andric
562cab237bSDimitry Andric // Only emit it if its hotness meets the threshold.
572cab237bSDimitry Andric if (OptDiag.getHotness().getValueOr(0) <
582cab237bSDimitry Andric Ctx.getDiagnosticsHotnessThreshold()) {
59a580b014SDimitry Andric return;
60a580b014SDimitry Andric }
61a580b014SDimitry Andric
627a7e6055SDimitry Andric Ctx.diagnose(OptDiag);
637a7e6055SDimitry Andric }
647a7e6055SDimitry Andric
MachineOptimizationRemarkEmitterPass()657a7e6055SDimitry Andric MachineOptimizationRemarkEmitterPass::MachineOptimizationRemarkEmitterPass()
667a7e6055SDimitry Andric : MachineFunctionPass(ID) {
677a7e6055SDimitry Andric initializeMachineOptimizationRemarkEmitterPassPass(
687a7e6055SDimitry Andric *PassRegistry::getPassRegistry());
697a7e6055SDimitry Andric }
707a7e6055SDimitry Andric
runOnMachineFunction(MachineFunction & MF)717a7e6055SDimitry Andric bool MachineOptimizationRemarkEmitterPass::runOnMachineFunction(
727a7e6055SDimitry Andric MachineFunction &MF) {
737a7e6055SDimitry Andric MachineBlockFrequencyInfo *MBFI;
747a7e6055SDimitry Andric
752cab237bSDimitry Andric if (MF.getFunction().getContext().getDiagnosticsHotnessRequested())
767a7e6055SDimitry Andric MBFI = &getAnalysis<LazyMachineBlockFrequencyInfoPass>().getBFI();
777a7e6055SDimitry Andric else
787a7e6055SDimitry Andric MBFI = nullptr;
797a7e6055SDimitry Andric
807a7e6055SDimitry Andric ORE = llvm::make_unique<MachineOptimizationRemarkEmitter>(MF, MBFI);
817a7e6055SDimitry Andric return false;
827a7e6055SDimitry Andric }
837a7e6055SDimitry Andric
getAnalysisUsage(AnalysisUsage & AU) const847a7e6055SDimitry Andric void MachineOptimizationRemarkEmitterPass::getAnalysisUsage(
857a7e6055SDimitry Andric AnalysisUsage &AU) const {
867a7e6055SDimitry Andric AU.addRequired<LazyMachineBlockFrequencyInfoPass>();
877a7e6055SDimitry Andric AU.setPreservesAll();
887a7e6055SDimitry Andric MachineFunctionPass::getAnalysisUsage(AU);
897a7e6055SDimitry Andric }
907a7e6055SDimitry Andric
917a7e6055SDimitry Andric char MachineOptimizationRemarkEmitterPass::ID = 0;
927a7e6055SDimitry Andric static const char ore_name[] = "Machine Optimization Remark Emitter";
937a7e6055SDimitry Andric #define ORE_NAME "machine-opt-remark-emitter"
947a7e6055SDimitry Andric
957a7e6055SDimitry Andric INITIALIZE_PASS_BEGIN(MachineOptimizationRemarkEmitterPass, ORE_NAME, ore_name,
967a7e6055SDimitry Andric false, true)
977a7e6055SDimitry Andric INITIALIZE_PASS_DEPENDENCY(LazyMachineBlockFrequencyInfoPass)
987a7e6055SDimitry Andric INITIALIZE_PASS_END(MachineOptimizationRemarkEmitterPass, ORE_NAME, ore_name,
997a7e6055SDimitry Andric false, true)
100