10b57cec5SDimitry Andric //===- MachineBlockFrequencyInfo.cpp - MBB Frequency Analysis -------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // Loops should be simplified before this analysis.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric
130b57cec5SDimitry Andric #include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
140b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h"
150b57cec5SDimitry Andric #include "llvm/ADT/iterator.h"
160b57cec5SDimitry Andric #include "llvm/Analysis/BlockFrequencyInfoImpl.h"
170b57cec5SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h"
180b57cec5SDimitry Andric #include "llvm/CodeGen/MachineBranchProbabilityInfo.h"
190b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
200b57cec5SDimitry Andric #include "llvm/CodeGen/MachineLoopInfo.h"
21480093f4SDimitry Andric #include "llvm/InitializePasses.h"
220b57cec5SDimitry Andric #include "llvm/Pass.h"
230b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h"
240b57cec5SDimitry Andric #include "llvm/Support/GraphWriter.h"
25bdd1243dSDimitry Andric #include <optional>
260b57cec5SDimitry Andric #include <string>
270b57cec5SDimitry Andric
280b57cec5SDimitry Andric using namespace llvm;
290b57cec5SDimitry Andric
300b57cec5SDimitry Andric #define DEBUG_TYPE "machine-block-freq"
310b57cec5SDimitry Andric
32fe6060f1SDimitry Andric namespace llvm {
330b57cec5SDimitry Andric static cl::opt<GVDAGType> ViewMachineBlockFreqPropagationDAG(
340b57cec5SDimitry Andric "view-machine-block-freq-propagation-dags", cl::Hidden,
350b57cec5SDimitry Andric cl::desc("Pop up a window to show a dag displaying how machine block "
360b57cec5SDimitry Andric "frequencies propagate through the CFG."),
370b57cec5SDimitry Andric cl::values(clEnumValN(GVDT_None, "none", "do not display graphs."),
380b57cec5SDimitry Andric clEnumValN(GVDT_Fraction, "fraction",
390b57cec5SDimitry Andric "display a graph using the "
400b57cec5SDimitry Andric "fractional block frequency representation."),
410b57cec5SDimitry Andric clEnumValN(GVDT_Integer, "integer",
420b57cec5SDimitry Andric "display a graph using the raw "
430b57cec5SDimitry Andric "integer fractional block frequency representation."),
440b57cec5SDimitry Andric clEnumValN(GVDT_Count, "count", "display a graph using the real "
450b57cec5SDimitry Andric "profile count if available.")));
460b57cec5SDimitry Andric
470b57cec5SDimitry Andric // Similar option above, but used to control BFI display only after MBP pass
480b57cec5SDimitry Andric cl::opt<GVDAGType> ViewBlockLayoutWithBFI(
490b57cec5SDimitry Andric "view-block-layout-with-bfi", cl::Hidden,
500b57cec5SDimitry Andric cl::desc(
510b57cec5SDimitry Andric "Pop up a window to show a dag displaying MBP layout and associated "
520b57cec5SDimitry Andric "block frequencies of the CFG."),
530b57cec5SDimitry Andric cl::values(clEnumValN(GVDT_None, "none", "do not display graphs."),
540b57cec5SDimitry Andric clEnumValN(GVDT_Fraction, "fraction",
550b57cec5SDimitry Andric "display a graph using the "
560b57cec5SDimitry Andric "fractional block frequency representation."),
570b57cec5SDimitry Andric clEnumValN(GVDT_Integer, "integer",
580b57cec5SDimitry Andric "display a graph using the raw "
590b57cec5SDimitry Andric "integer fractional block frequency representation."),
600b57cec5SDimitry Andric clEnumValN(GVDT_Count, "count",
610b57cec5SDimitry Andric "display a graph using the real "
620b57cec5SDimitry Andric "profile count if available.")));
630b57cec5SDimitry Andric
640b57cec5SDimitry Andric // Command line option to specify the name of the function for CFG dump
650b57cec5SDimitry Andric // Defined in Analysis/BlockFrequencyInfo.cpp: -view-bfi-func-name=
660b57cec5SDimitry Andric extern cl::opt<std::string> ViewBlockFreqFuncName;
670b57cec5SDimitry Andric
680b57cec5SDimitry Andric // Command line option to specify hot frequency threshold.
690b57cec5SDimitry Andric // Defined in Analysis/BlockFrequencyInfo.cpp: -view-hot-freq-perc=
700b57cec5SDimitry Andric extern cl::opt<unsigned> ViewHotFreqPercent;
710b57cec5SDimitry Andric
720b57cec5SDimitry Andric static cl::opt<bool> PrintMachineBlockFreq(
730b57cec5SDimitry Andric "print-machine-bfi", cl::init(false), cl::Hidden,
740b57cec5SDimitry Andric cl::desc("Print the machine block frequency info."));
750b57cec5SDimitry Andric
760b57cec5SDimitry Andric // Command line option to specify the name of the function for block frequency
770b57cec5SDimitry Andric // dump. Defined in Analysis/BlockFrequencyInfo.cpp.
785f757f3fSDimitry Andric extern cl::opt<std::string> PrintBFIFuncName;
79fe6060f1SDimitry Andric } // namespace llvm
800b57cec5SDimitry Andric
getGVDT()810b57cec5SDimitry Andric static GVDAGType getGVDT() {
820b57cec5SDimitry Andric if (ViewBlockLayoutWithBFI != GVDT_None)
830b57cec5SDimitry Andric return ViewBlockLayoutWithBFI;
840b57cec5SDimitry Andric
850b57cec5SDimitry Andric return ViewMachineBlockFreqPropagationDAG;
860b57cec5SDimitry Andric }
870b57cec5SDimitry Andric
880b57cec5SDimitry Andric namespace llvm {
890b57cec5SDimitry Andric
900b57cec5SDimitry Andric template <> struct GraphTraits<MachineBlockFrequencyInfo *> {
910b57cec5SDimitry Andric using NodeRef = const MachineBasicBlock *;
920b57cec5SDimitry Andric using ChildIteratorType = MachineBasicBlock::const_succ_iterator;
930b57cec5SDimitry Andric using nodes_iterator = pointer_iterator<MachineFunction::const_iterator>;
940b57cec5SDimitry Andric
getEntryNodellvm::GraphTraits950b57cec5SDimitry Andric static NodeRef getEntryNode(const MachineBlockFrequencyInfo *G) {
960b57cec5SDimitry Andric return &G->getFunction()->front();
970b57cec5SDimitry Andric }
980b57cec5SDimitry Andric
child_beginllvm::GraphTraits990b57cec5SDimitry Andric static ChildIteratorType child_begin(const NodeRef N) {
1000b57cec5SDimitry Andric return N->succ_begin();
1010b57cec5SDimitry Andric }
1020b57cec5SDimitry Andric
child_endllvm::GraphTraits1030b57cec5SDimitry Andric static ChildIteratorType child_end(const NodeRef N) { return N->succ_end(); }
1040b57cec5SDimitry Andric
nodes_beginllvm::GraphTraits1050b57cec5SDimitry Andric static nodes_iterator nodes_begin(const MachineBlockFrequencyInfo *G) {
1060b57cec5SDimitry Andric return nodes_iterator(G->getFunction()->begin());
1070b57cec5SDimitry Andric }
1080b57cec5SDimitry Andric
nodes_endllvm::GraphTraits1090b57cec5SDimitry Andric static nodes_iterator nodes_end(const MachineBlockFrequencyInfo *G) {
1100b57cec5SDimitry Andric return nodes_iterator(G->getFunction()->end());
1110b57cec5SDimitry Andric }
1120b57cec5SDimitry Andric };
1130b57cec5SDimitry Andric
1140b57cec5SDimitry Andric using MBFIDOTGraphTraitsBase =
1150b57cec5SDimitry Andric BFIDOTGraphTraitsBase<MachineBlockFrequencyInfo,
1160b57cec5SDimitry Andric MachineBranchProbabilityInfo>;
1170b57cec5SDimitry Andric
1180b57cec5SDimitry Andric template <>
1190b57cec5SDimitry Andric struct DOTGraphTraits<MachineBlockFrequencyInfo *>
1200b57cec5SDimitry Andric : public MBFIDOTGraphTraitsBase {
1210b57cec5SDimitry Andric const MachineFunction *CurFunc = nullptr;
1220b57cec5SDimitry Andric DenseMap<const MachineBasicBlock *, int> LayoutOrderMap;
1230b57cec5SDimitry Andric
DOTGraphTraitsllvm::DOTGraphTraits1240b57cec5SDimitry Andric explicit DOTGraphTraits(bool isSimple = false)
1250b57cec5SDimitry Andric : MBFIDOTGraphTraitsBase(isSimple) {}
1260b57cec5SDimitry Andric
getNodeLabelllvm::DOTGraphTraits1270b57cec5SDimitry Andric std::string getNodeLabel(const MachineBasicBlock *Node,
1280b57cec5SDimitry Andric const MachineBlockFrequencyInfo *Graph) {
1290b57cec5SDimitry Andric int layout_order = -1;
1300b57cec5SDimitry Andric // Attach additional ordering information if 'isSimple' is false.
1310b57cec5SDimitry Andric if (!isSimple()) {
1320b57cec5SDimitry Andric const MachineFunction *F = Node->getParent();
1330b57cec5SDimitry Andric if (!CurFunc || F != CurFunc) {
1340b57cec5SDimitry Andric if (CurFunc)
1350b57cec5SDimitry Andric LayoutOrderMap.clear();
1360b57cec5SDimitry Andric
1370b57cec5SDimitry Andric CurFunc = F;
1380b57cec5SDimitry Andric int O = 0;
1390b57cec5SDimitry Andric for (auto MBI = F->begin(); MBI != F->end(); ++MBI, ++O) {
1400b57cec5SDimitry Andric LayoutOrderMap[&*MBI] = O;
1410b57cec5SDimitry Andric }
1420b57cec5SDimitry Andric }
1430b57cec5SDimitry Andric layout_order = LayoutOrderMap[Node];
1440b57cec5SDimitry Andric }
1450b57cec5SDimitry Andric return MBFIDOTGraphTraitsBase::getNodeLabel(Node, Graph, getGVDT(),
1460b57cec5SDimitry Andric layout_order);
1470b57cec5SDimitry Andric }
1480b57cec5SDimitry Andric
getNodeAttributesllvm::DOTGraphTraits1490b57cec5SDimitry Andric std::string getNodeAttributes(const MachineBasicBlock *Node,
1500b57cec5SDimitry Andric const MachineBlockFrequencyInfo *Graph) {
1510b57cec5SDimitry Andric return MBFIDOTGraphTraitsBase::getNodeAttributes(Node, Graph,
1520b57cec5SDimitry Andric ViewHotFreqPercent);
1530b57cec5SDimitry Andric }
1540b57cec5SDimitry Andric
getEdgeAttributesllvm::DOTGraphTraits1550b57cec5SDimitry Andric std::string getEdgeAttributes(const MachineBasicBlock *Node, EdgeIter EI,
1560b57cec5SDimitry Andric const MachineBlockFrequencyInfo *MBFI) {
1570b57cec5SDimitry Andric return MBFIDOTGraphTraitsBase::getEdgeAttributes(
1580b57cec5SDimitry Andric Node, EI, MBFI, MBFI->getMBPI(), ViewHotFreqPercent);
1590b57cec5SDimitry Andric }
1600b57cec5SDimitry Andric };
1610b57cec5SDimitry Andric
1620b57cec5SDimitry Andric } // end namespace llvm
1630b57cec5SDimitry Andric
164*0fca6ea1SDimitry Andric AnalysisKey MachineBlockFrequencyAnalysis::Key;
1650b57cec5SDimitry Andric
166*0fca6ea1SDimitry Andric MachineBlockFrequencyAnalysis::Result
run(MachineFunction & MF,MachineFunctionAnalysisManager & MFAM)167*0fca6ea1SDimitry Andric MachineBlockFrequencyAnalysis::run(MachineFunction &MF,
168*0fca6ea1SDimitry Andric MachineFunctionAnalysisManager &MFAM) {
169*0fca6ea1SDimitry Andric auto &MBPI = MFAM.getResult<MachineBranchProbabilityAnalysis>(MF);
170*0fca6ea1SDimitry Andric auto &MLI = MFAM.getResult<MachineLoopAnalysis>(MF);
171*0fca6ea1SDimitry Andric return Result(MF, MBPI, MLI);
1720b57cec5SDimitry Andric }
1730b57cec5SDimitry Andric
174*0fca6ea1SDimitry Andric PreservedAnalyses
run(MachineFunction & MF,MachineFunctionAnalysisManager & MFAM)175*0fca6ea1SDimitry Andric MachineBlockFrequencyPrinterPass::run(MachineFunction &MF,
176*0fca6ea1SDimitry Andric MachineFunctionAnalysisManager &MFAM) {
177*0fca6ea1SDimitry Andric auto &MBFI = MFAM.getResult<MachineBlockFrequencyAnalysis>(MF);
178*0fca6ea1SDimitry Andric OS << "Machine block frequency for machine function: " << MF.getName()
179*0fca6ea1SDimitry Andric << '\n';
180*0fca6ea1SDimitry Andric MBFI.print(OS);
181*0fca6ea1SDimitry Andric return PreservedAnalyses::all();
182*0fca6ea1SDimitry Andric }
183*0fca6ea1SDimitry Andric
184*0fca6ea1SDimitry Andric INITIALIZE_PASS_BEGIN(MachineBlockFrequencyInfoWrapperPass, DEBUG_TYPE,
185*0fca6ea1SDimitry Andric "Machine Block Frequency Analysis", true, true)
186*0fca6ea1SDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineBranchProbabilityInfoWrapperPass)
187*0fca6ea1SDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineLoopInfoWrapperPass)
188*0fca6ea1SDimitry Andric INITIALIZE_PASS_END(MachineBlockFrequencyInfoWrapperPass, DEBUG_TYPE,
189*0fca6ea1SDimitry Andric "Machine Block Frequency Analysis", true, true)
190*0fca6ea1SDimitry Andric
191*0fca6ea1SDimitry Andric char MachineBlockFrequencyInfoWrapperPass::ID = 0;
192*0fca6ea1SDimitry Andric
MachineBlockFrequencyInfoWrapperPass()193*0fca6ea1SDimitry Andric MachineBlockFrequencyInfoWrapperPass::MachineBlockFrequencyInfoWrapperPass()
194*0fca6ea1SDimitry Andric : MachineFunctionPass(ID) {
195*0fca6ea1SDimitry Andric initializeMachineBlockFrequencyInfoWrapperPassPass(
196*0fca6ea1SDimitry Andric *PassRegistry::getPassRegistry());
197*0fca6ea1SDimitry Andric }
198*0fca6ea1SDimitry Andric
199*0fca6ea1SDimitry Andric MachineBlockFrequencyInfo::MachineBlockFrequencyInfo() = default;
200*0fca6ea1SDimitry Andric
201480093f4SDimitry Andric MachineBlockFrequencyInfo::MachineBlockFrequencyInfo(
202*0fca6ea1SDimitry Andric MachineBlockFrequencyInfo &&) = default;
203*0fca6ea1SDimitry Andric
MachineBlockFrequencyInfo(MachineFunction & F,MachineBranchProbabilityInfo & MBPI,MachineLoopInfo & MLI)204*0fca6ea1SDimitry Andric MachineBlockFrequencyInfo::MachineBlockFrequencyInfo(
205*0fca6ea1SDimitry Andric MachineFunction &F, MachineBranchProbabilityInfo &MBPI,
206*0fca6ea1SDimitry Andric MachineLoopInfo &MLI) {
207480093f4SDimitry Andric calculate(F, MBPI, MLI);
208480093f4SDimitry Andric }
209480093f4SDimitry Andric
2100b57cec5SDimitry Andric MachineBlockFrequencyInfo::~MachineBlockFrequencyInfo() = default;
2110b57cec5SDimitry Andric
invalidate(MachineFunction & MF,const PreservedAnalyses & PA,MachineFunctionAnalysisManager::Invalidator &)212*0fca6ea1SDimitry Andric bool MachineBlockFrequencyInfo::invalidate(
213*0fca6ea1SDimitry Andric MachineFunction &MF, const PreservedAnalyses &PA,
214*0fca6ea1SDimitry Andric MachineFunctionAnalysisManager::Invalidator &) {
215*0fca6ea1SDimitry Andric // Check whether the analysis, all analyses on machine functions, or the
216*0fca6ea1SDimitry Andric // machine function's CFG have been preserved.
217*0fca6ea1SDimitry Andric auto PAC = PA.getChecker<MachineBlockFrequencyAnalysis>();
218*0fca6ea1SDimitry Andric return !PAC.preserved() &&
219*0fca6ea1SDimitry Andric !PAC.preservedSet<AllAnalysesOn<MachineFunction>>() &&
220*0fca6ea1SDimitry Andric !PAC.preservedSet<CFGAnalyses>();
221*0fca6ea1SDimitry Andric }
222*0fca6ea1SDimitry Andric
getAnalysisUsage(AnalysisUsage & AU) const223*0fca6ea1SDimitry Andric void MachineBlockFrequencyInfoWrapperPass::getAnalysisUsage(
224*0fca6ea1SDimitry Andric AnalysisUsage &AU) const {
225*0fca6ea1SDimitry Andric AU.addRequired<MachineBranchProbabilityInfoWrapperPass>();
226*0fca6ea1SDimitry Andric AU.addRequired<MachineLoopInfoWrapperPass>();
2270b57cec5SDimitry Andric AU.setPreservesAll();
2280b57cec5SDimitry Andric MachineFunctionPass::getAnalysisUsage(AU);
2290b57cec5SDimitry Andric }
2300b57cec5SDimitry Andric
calculate(const MachineFunction & F,const MachineBranchProbabilityInfo & MBPI,const MachineLoopInfo & MLI)2310b57cec5SDimitry Andric void MachineBlockFrequencyInfo::calculate(
2320b57cec5SDimitry Andric const MachineFunction &F, const MachineBranchProbabilityInfo &MBPI,
2330b57cec5SDimitry Andric const MachineLoopInfo &MLI) {
2340b57cec5SDimitry Andric if (!MBFI)
2350b57cec5SDimitry Andric MBFI.reset(new ImplType);
2360b57cec5SDimitry Andric MBFI->calculate(F, MBPI, MLI);
2370b57cec5SDimitry Andric if (ViewMachineBlockFreqPropagationDAG != GVDT_None &&
238*0fca6ea1SDimitry Andric (ViewBlockFreqFuncName.empty() || F.getName() == ViewBlockFreqFuncName)) {
2390b57cec5SDimitry Andric view("MachineBlockFrequencyDAGS." + F.getName());
2400b57cec5SDimitry Andric }
2410b57cec5SDimitry Andric if (PrintMachineBlockFreq &&
242*0fca6ea1SDimitry Andric (PrintBFIFuncName.empty() || F.getName() == PrintBFIFuncName)) {
2430b57cec5SDimitry Andric MBFI->print(dbgs());
2440b57cec5SDimitry Andric }
2450b57cec5SDimitry Andric }
2460b57cec5SDimitry Andric
runOnMachineFunction(MachineFunction & F)247*0fca6ea1SDimitry Andric bool MachineBlockFrequencyInfoWrapperPass::runOnMachineFunction(
248*0fca6ea1SDimitry Andric MachineFunction &F) {
2490b57cec5SDimitry Andric MachineBranchProbabilityInfo &MBPI =
250*0fca6ea1SDimitry Andric getAnalysis<MachineBranchProbabilityInfoWrapperPass>().getMBPI();
251*0fca6ea1SDimitry Andric MachineLoopInfo &MLI = getAnalysis<MachineLoopInfoWrapperPass>().getLI();
252*0fca6ea1SDimitry Andric MBFI.calculate(F, MBPI, MLI);
2530b57cec5SDimitry Andric return false;
2540b57cec5SDimitry Andric }
2550b57cec5SDimitry Andric
print(raw_ostream & OS)256*0fca6ea1SDimitry Andric void MachineBlockFrequencyInfo::print(raw_ostream &OS) { MBFI->print(OS); }
257*0fca6ea1SDimitry Andric
releaseMemory()2580b57cec5SDimitry Andric void MachineBlockFrequencyInfo::releaseMemory() { MBFI.reset(); }
2590b57cec5SDimitry Andric
2600b57cec5SDimitry Andric /// Pop up a ghostview window with the current block frequency propagation
2610b57cec5SDimitry Andric /// rendered using dot.
view(const Twine & Name,bool isSimple) const2620b57cec5SDimitry Andric void MachineBlockFrequencyInfo::view(const Twine &Name, bool isSimple) const {
2630b57cec5SDimitry Andric // This code is only for debugging.
2640b57cec5SDimitry Andric ViewGraph(const_cast<MachineBlockFrequencyInfo *>(this), Name, isSimple);
2650b57cec5SDimitry Andric }
2660b57cec5SDimitry Andric
2670b57cec5SDimitry Andric BlockFrequency
getBlockFreq(const MachineBasicBlock * MBB) const2680b57cec5SDimitry Andric MachineBlockFrequencyInfo::getBlockFreq(const MachineBasicBlock *MBB) const {
2695f757f3fSDimitry Andric return MBFI ? MBFI->getBlockFreq(MBB) : BlockFrequency(0);
2700b57cec5SDimitry Andric }
2710b57cec5SDimitry Andric
getBlockProfileCount(const MachineBasicBlock * MBB) const272bdd1243dSDimitry Andric std::optional<uint64_t> MachineBlockFrequencyInfo::getBlockProfileCount(
2730b57cec5SDimitry Andric const MachineBasicBlock *MBB) const {
274fe6060f1SDimitry Andric if (!MBFI)
275bdd1243dSDimitry Andric return std::nullopt;
276fe6060f1SDimitry Andric
2770b57cec5SDimitry Andric const Function &F = MBFI->getFunction()->getFunction();
278fe6060f1SDimitry Andric return MBFI->getBlockProfileCount(F, MBB);
2790b57cec5SDimitry Andric }
2800b57cec5SDimitry Andric
281bdd1243dSDimitry Andric std::optional<uint64_t>
getProfileCountFromFreq(BlockFrequency Freq) const2825f757f3fSDimitry Andric MachineBlockFrequencyInfo::getProfileCountFromFreq(BlockFrequency Freq) const {
283fe6060f1SDimitry Andric if (!MBFI)
284bdd1243dSDimitry Andric return std::nullopt;
285fe6060f1SDimitry Andric
2860b57cec5SDimitry Andric const Function &F = MBFI->getFunction()->getFunction();
287fe6060f1SDimitry Andric return MBFI->getProfileCountFromFreq(F, Freq);
2880b57cec5SDimitry Andric }
2890b57cec5SDimitry Andric
isIrrLoopHeader(const MachineBasicBlock * MBB) const290e8d8bef9SDimitry Andric bool MachineBlockFrequencyInfo::isIrrLoopHeader(
291e8d8bef9SDimitry Andric const MachineBasicBlock *MBB) const {
2920b57cec5SDimitry Andric assert(MBFI && "Expected analysis to be available");
2930b57cec5SDimitry Andric return MBFI->isIrrLoopHeader(MBB);
2940b57cec5SDimitry Andric }
2950b57cec5SDimitry Andric
onEdgeSplit(const MachineBasicBlock & NewPredecessor,const MachineBasicBlock & NewSuccessor,const MachineBranchProbabilityInfo & MBPI)296e8d8bef9SDimitry Andric void MachineBlockFrequencyInfo::onEdgeSplit(
297e8d8bef9SDimitry Andric const MachineBasicBlock &NewPredecessor,
298e8d8bef9SDimitry Andric const MachineBasicBlock &NewSuccessor,
299e8d8bef9SDimitry Andric const MachineBranchProbabilityInfo &MBPI) {
3005ffd83dbSDimitry Andric assert(MBFI && "Expected analysis to be available");
301e8d8bef9SDimitry Andric auto NewSuccFreq = MBFI->getBlockFreq(&NewPredecessor) *
302e8d8bef9SDimitry Andric MBPI.getEdgeProbability(&NewPredecessor, &NewSuccessor);
303e8d8bef9SDimitry Andric
3045f757f3fSDimitry Andric MBFI->setBlockFreq(&NewSuccessor, NewSuccFreq);
3055ffd83dbSDimitry Andric }
3065ffd83dbSDimitry Andric
getFunction() const3070b57cec5SDimitry Andric const MachineFunction *MachineBlockFrequencyInfo::getFunction() const {
3080b57cec5SDimitry Andric return MBFI ? MBFI->getFunction() : nullptr;
3090b57cec5SDimitry Andric }
3100b57cec5SDimitry Andric
getMBPI() const3110b57cec5SDimitry Andric const MachineBranchProbabilityInfo *MachineBlockFrequencyInfo::getMBPI() const {
3120b57cec5SDimitry Andric return MBFI ? &MBFI->getBPI() : nullptr;
3130b57cec5SDimitry Andric }
3140b57cec5SDimitry Andric
getEntryFreq() const3155f757f3fSDimitry Andric BlockFrequency MachineBlockFrequencyInfo::getEntryFreq() const {
3165f757f3fSDimitry Andric return MBFI ? MBFI->getEntryFreq() : BlockFrequency(0);
3170b57cec5SDimitry Andric }
3180b57cec5SDimitry Andric
printBlockFreq(const MachineBlockFrequencyInfo & MBFI,BlockFrequency Freq)3195f757f3fSDimitry Andric Printable llvm::printBlockFreq(const MachineBlockFrequencyInfo &MBFI,
3205f757f3fSDimitry Andric BlockFrequency Freq) {
3215f757f3fSDimitry Andric return Printable([&MBFI, Freq](raw_ostream &OS) {
322*0fca6ea1SDimitry Andric printRelativeBlockFreq(OS, MBFI.getEntryFreq(), Freq);
3235f757f3fSDimitry Andric });
3240b57cec5SDimitry Andric }
3250b57cec5SDimitry Andric
printBlockFreq(const MachineBlockFrequencyInfo & MBFI,const MachineBasicBlock & MBB)3265f757f3fSDimitry Andric Printable llvm::printBlockFreq(const MachineBlockFrequencyInfo &MBFI,
3275f757f3fSDimitry Andric const MachineBasicBlock &MBB) {
3285f757f3fSDimitry Andric return printBlockFreq(MBFI, MBFI.getBlockFreq(&MBB));
3290b57cec5SDimitry Andric }
330