171d5a254SDimitry Andric ///===- LazyMachineBlockFrequencyInfo.cpp - Lazy Machine Block Frequency --===//
271d5a254SDimitry Andric ///
3e6d15924SDimitry Andric /// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e6d15924SDimitry Andric /// See https://llvm.org/LICENSE.txt for license information.
5e6d15924SDimitry Andric /// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
671d5a254SDimitry Andric ///
771d5a254SDimitry Andric ///===---------------------------------------------------------------------===//
871d5a254SDimitry Andric /// \file
971d5a254SDimitry Andric /// This is an alternative analysis pass to MachineBlockFrequencyInfo. The
1071d5a254SDimitry Andric /// difference is that with this pass the block frequencies are not computed
1171d5a254SDimitry Andric /// when the analysis pass is executed but rather when the BFI result is
1271d5a254SDimitry Andric /// explicitly requested by the analysis client.
1371d5a254SDimitry Andric ///
1471d5a254SDimitry Andric ///===---------------------------------------------------------------------===//
1571d5a254SDimitry Andric
1671d5a254SDimitry Andric #include "llvm/CodeGen/LazyMachineBlockFrequencyInfo.h"
17145449b1SDimitry Andric #include "llvm/CodeGen/MachineBranchProbabilityInfo.h"
18706b4fc4SDimitry Andric #include "llvm/InitializePasses.h"
1971d5a254SDimitry Andric
2071d5a254SDimitry Andric using namespace llvm;
2171d5a254SDimitry Andric
2271d5a254SDimitry Andric #define DEBUG_TYPE "lazy-machine-block-freq"
2371d5a254SDimitry Andric
2471d5a254SDimitry Andric INITIALIZE_PASS_BEGIN(LazyMachineBlockFrequencyInfoPass, DEBUG_TYPE,
2571d5a254SDimitry Andric "Lazy Machine Block Frequency Analysis", true, true)
26ac9a064cSDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineBranchProbabilityInfoWrapperPass)
27ac9a064cSDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineLoopInfoWrapperPass)
2871d5a254SDimitry Andric INITIALIZE_PASS_END(LazyMachineBlockFrequencyInfoPass, DEBUG_TYPE,
2971d5a254SDimitry Andric "Lazy Machine Block Frequency Analysis", true, true)
3071d5a254SDimitry Andric
3171d5a254SDimitry Andric char LazyMachineBlockFrequencyInfoPass::ID = 0;
3271d5a254SDimitry Andric
LazyMachineBlockFrequencyInfoPass()3371d5a254SDimitry Andric LazyMachineBlockFrequencyInfoPass::LazyMachineBlockFrequencyInfoPass()
3471d5a254SDimitry Andric : MachineFunctionPass(ID) {
3571d5a254SDimitry Andric initializeLazyMachineBlockFrequencyInfoPassPass(
3671d5a254SDimitry Andric *PassRegistry::getPassRegistry());
3771d5a254SDimitry Andric }
3871d5a254SDimitry Andric
getAnalysisUsage(AnalysisUsage & AU) const3971d5a254SDimitry Andric void LazyMachineBlockFrequencyInfoPass::getAnalysisUsage(
4071d5a254SDimitry Andric AnalysisUsage &AU) const {
41ac9a064cSDimitry Andric AU.addRequired<MachineBranchProbabilityInfoWrapperPass>();
4271d5a254SDimitry Andric AU.setPreservesAll();
4371d5a254SDimitry Andric MachineFunctionPass::getAnalysisUsage(AU);
4471d5a254SDimitry Andric }
4571d5a254SDimitry Andric
releaseMemory()4671d5a254SDimitry Andric void LazyMachineBlockFrequencyInfoPass::releaseMemory() {
4771d5a254SDimitry Andric OwnedMBFI.reset();
4871d5a254SDimitry Andric OwnedMLI.reset();
4971d5a254SDimitry Andric OwnedMDT.reset();
5071d5a254SDimitry Andric }
5171d5a254SDimitry Andric
5271d5a254SDimitry Andric MachineBlockFrequencyInfo &
calculateIfNotAvailable() const5371d5a254SDimitry Andric LazyMachineBlockFrequencyInfoPass::calculateIfNotAvailable() const {
54ac9a064cSDimitry Andric auto *MBFIWrapper =
55ac9a064cSDimitry Andric getAnalysisIfAvailable<MachineBlockFrequencyInfoWrapperPass>();
56ac9a064cSDimitry Andric if (MBFIWrapper) {
57eb11fae6SDimitry Andric LLVM_DEBUG(dbgs() << "MachineBlockFrequencyInfo is available\n");
58ac9a064cSDimitry Andric return MBFIWrapper->getMBFI();
5971d5a254SDimitry Andric }
6071d5a254SDimitry Andric
61ac9a064cSDimitry Andric auto &MBPI = getAnalysis<MachineBranchProbabilityInfoWrapperPass>().getMBPI();
62ac9a064cSDimitry Andric auto *MLIWrapper = getAnalysisIfAvailable<MachineLoopInfoWrapperPass>();
63ac9a064cSDimitry Andric auto *MLI = MLIWrapper ? &MLIWrapper->getLI() : nullptr;
64ac9a064cSDimitry Andric auto *MDTWrapper = getAnalysisIfAvailable<MachineDominatorTreeWrapperPass>();
65ac9a064cSDimitry Andric auto *MDT = MDTWrapper ? &MDTWrapper->getDomTree() : nullptr;
66eb11fae6SDimitry Andric LLVM_DEBUG(dbgs() << "Building MachineBlockFrequencyInfo on the fly\n");
67eb11fae6SDimitry Andric LLVM_DEBUG(if (MLI) dbgs() << "LoopInfo is available\n");
6871d5a254SDimitry Andric
6971d5a254SDimitry Andric if (!MLI) {
70eb11fae6SDimitry Andric LLVM_DEBUG(dbgs() << "Building LoopInfo on the fly\n");
7171d5a254SDimitry Andric // First create a dominator tree.
72eb11fae6SDimitry Andric LLVM_DEBUG(if (MDT) dbgs() << "DominatorTree is available\n");
7371d5a254SDimitry Andric
7471d5a254SDimitry Andric if (!MDT) {
75eb11fae6SDimitry Andric LLVM_DEBUG(dbgs() << "Building DominatorTree on the fly\n");
761d5ae102SDimitry Andric OwnedMDT = std::make_unique<MachineDominatorTree>();
7771d5a254SDimitry Andric OwnedMDT->getBase().recalculate(*MF);
7871d5a254SDimitry Andric MDT = OwnedMDT.get();
7971d5a254SDimitry Andric }
8071d5a254SDimitry Andric
8171d5a254SDimitry Andric // Generate LoopInfo from it.
821d5ae102SDimitry Andric OwnedMLI = std::make_unique<MachineLoopInfo>();
83ac9a064cSDimitry Andric OwnedMLI->analyze(MDT->getBase());
8471d5a254SDimitry Andric MLI = OwnedMLI.get();
8571d5a254SDimitry Andric }
8671d5a254SDimitry Andric
871d5ae102SDimitry Andric OwnedMBFI = std::make_unique<MachineBlockFrequencyInfo>();
8871d5a254SDimitry Andric OwnedMBFI->calculate(*MF, MBPI, *MLI);
89145449b1SDimitry Andric return *OwnedMBFI;
9071d5a254SDimitry Andric }
9171d5a254SDimitry Andric
runOnMachineFunction(MachineFunction & F)9271d5a254SDimitry Andric bool LazyMachineBlockFrequencyInfoPass::runOnMachineFunction(
9371d5a254SDimitry Andric MachineFunction &F) {
9471d5a254SDimitry Andric MF = &F;
9571d5a254SDimitry Andric return false;
9671d5a254SDimitry Andric }
97