1*0b57cec5SDimitry Andric ///===- LazyMachineBlockFrequencyInfo.cpp - Lazy Machine Block Frequency --===// 2*0b57cec5SDimitry Andric /// 3*0b57cec5SDimitry Andric /// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric /// See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric /// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric /// 7*0b57cec5SDimitry Andric ///===---------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric /// \file 9*0b57cec5SDimitry Andric /// This is an alternative analysis pass to MachineBlockFrequencyInfo. The 10*0b57cec5SDimitry Andric /// difference is that with this pass the block frequencies are not computed 11*0b57cec5SDimitry Andric /// when the analysis pass is executed but rather when the BFI result is 12*0b57cec5SDimitry Andric /// explicitly requested by the analysis client. 13*0b57cec5SDimitry Andric /// 14*0b57cec5SDimitry Andric ///===---------------------------------------------------------------------===// 15*0b57cec5SDimitry Andric 16*0b57cec5SDimitry Andric #include "llvm/CodeGen/LazyMachineBlockFrequencyInfo.h" 17*0b57cec5SDimitry Andric 18*0b57cec5SDimitry Andric using namespace llvm; 19*0b57cec5SDimitry Andric 20*0b57cec5SDimitry Andric #define DEBUG_TYPE "lazy-machine-block-freq" 21*0b57cec5SDimitry Andric 22*0b57cec5SDimitry Andric INITIALIZE_PASS_BEGIN(LazyMachineBlockFrequencyInfoPass, DEBUG_TYPE, 23*0b57cec5SDimitry Andric "Lazy Machine Block Frequency Analysis", true, true) 24*0b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineBranchProbabilityInfo) 25*0b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo) 26*0b57cec5SDimitry Andric INITIALIZE_PASS_END(LazyMachineBlockFrequencyInfoPass, DEBUG_TYPE, 27*0b57cec5SDimitry Andric "Lazy Machine Block Frequency Analysis", true, true) 28*0b57cec5SDimitry Andric 29*0b57cec5SDimitry Andric char LazyMachineBlockFrequencyInfoPass::ID = 0; 30*0b57cec5SDimitry Andric 31*0b57cec5SDimitry Andric LazyMachineBlockFrequencyInfoPass::LazyMachineBlockFrequencyInfoPass() 32*0b57cec5SDimitry Andric : MachineFunctionPass(ID) { 33*0b57cec5SDimitry Andric initializeLazyMachineBlockFrequencyInfoPassPass( 34*0b57cec5SDimitry Andric *PassRegistry::getPassRegistry()); 35*0b57cec5SDimitry Andric } 36*0b57cec5SDimitry Andric 37*0b57cec5SDimitry Andric void LazyMachineBlockFrequencyInfoPass::print(raw_ostream &OS, 38*0b57cec5SDimitry Andric const Module *M) const { 39*0b57cec5SDimitry Andric getBFI().print(OS, M); 40*0b57cec5SDimitry Andric } 41*0b57cec5SDimitry Andric 42*0b57cec5SDimitry Andric void LazyMachineBlockFrequencyInfoPass::getAnalysisUsage( 43*0b57cec5SDimitry Andric AnalysisUsage &AU) const { 44*0b57cec5SDimitry Andric AU.addRequired<MachineBranchProbabilityInfo>(); 45*0b57cec5SDimitry Andric AU.setPreservesAll(); 46*0b57cec5SDimitry Andric MachineFunctionPass::getAnalysisUsage(AU); 47*0b57cec5SDimitry Andric } 48*0b57cec5SDimitry Andric 49*0b57cec5SDimitry Andric void LazyMachineBlockFrequencyInfoPass::releaseMemory() { 50*0b57cec5SDimitry Andric OwnedMBFI.reset(); 51*0b57cec5SDimitry Andric OwnedMLI.reset(); 52*0b57cec5SDimitry Andric OwnedMDT.reset(); 53*0b57cec5SDimitry Andric } 54*0b57cec5SDimitry Andric 55*0b57cec5SDimitry Andric MachineBlockFrequencyInfo & 56*0b57cec5SDimitry Andric LazyMachineBlockFrequencyInfoPass::calculateIfNotAvailable() const { 57*0b57cec5SDimitry Andric auto *MBFI = getAnalysisIfAvailable<MachineBlockFrequencyInfo>(); 58*0b57cec5SDimitry Andric if (MBFI) { 59*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "MachineBlockFrequencyInfo is available\n"); 60*0b57cec5SDimitry Andric return *MBFI; 61*0b57cec5SDimitry Andric } 62*0b57cec5SDimitry Andric 63*0b57cec5SDimitry Andric auto &MBPI = getAnalysis<MachineBranchProbabilityInfo>(); 64*0b57cec5SDimitry Andric auto *MLI = getAnalysisIfAvailable<MachineLoopInfo>(); 65*0b57cec5SDimitry Andric auto *MDT = getAnalysisIfAvailable<MachineDominatorTree>(); 66*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Building MachineBlockFrequencyInfo on the fly\n"); 67*0b57cec5SDimitry Andric LLVM_DEBUG(if (MLI) dbgs() << "LoopInfo is available\n"); 68*0b57cec5SDimitry Andric 69*0b57cec5SDimitry Andric if (!MLI) { 70*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Building LoopInfo on the fly\n"); 71*0b57cec5SDimitry Andric // First create a dominator tree. 72*0b57cec5SDimitry Andric LLVM_DEBUG(if (MDT) dbgs() << "DominatorTree is available\n"); 73*0b57cec5SDimitry Andric 74*0b57cec5SDimitry Andric if (!MDT) { 75*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Building DominatorTree on the fly\n"); 76*0b57cec5SDimitry Andric OwnedMDT = make_unique<MachineDominatorTree>(); 77*0b57cec5SDimitry Andric OwnedMDT->getBase().recalculate(*MF); 78*0b57cec5SDimitry Andric MDT = OwnedMDT.get(); 79*0b57cec5SDimitry Andric } 80*0b57cec5SDimitry Andric 81*0b57cec5SDimitry Andric // Generate LoopInfo from it. 82*0b57cec5SDimitry Andric OwnedMLI = make_unique<MachineLoopInfo>(); 83*0b57cec5SDimitry Andric OwnedMLI->getBase().analyze(MDT->getBase()); 84*0b57cec5SDimitry Andric MLI = OwnedMLI.get(); 85*0b57cec5SDimitry Andric } 86*0b57cec5SDimitry Andric 87*0b57cec5SDimitry Andric OwnedMBFI = make_unique<MachineBlockFrequencyInfo>(); 88*0b57cec5SDimitry Andric OwnedMBFI->calculate(*MF, MBPI, *MLI); 89*0b57cec5SDimitry Andric return *OwnedMBFI.get(); 90*0b57cec5SDimitry Andric } 91*0b57cec5SDimitry Andric 92*0b57cec5SDimitry Andric bool LazyMachineBlockFrequencyInfoPass::runOnMachineFunction( 93*0b57cec5SDimitry Andric MachineFunction &F) { 94*0b57cec5SDimitry Andric MF = &F; 95*0b57cec5SDimitry Andric return false; 96*0b57cec5SDimitry Andric } 97