10b57cec5SDimitry Andric //===- BlockFrequencyInfo.cpp - Block 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/Analysis/BlockFrequencyInfo.h" 140b57cec5SDimitry Andric #include "llvm/ADT/APInt.h" 150b57cec5SDimitry Andric #include "llvm/ADT/iterator.h" 160b57cec5SDimitry Andric #include "llvm/Analysis/BlockFrequencyInfoImpl.h" 170b57cec5SDimitry Andric #include "llvm/Analysis/BranchProbabilityInfo.h" 180b57cec5SDimitry Andric #include "llvm/Analysis/LoopInfo.h" 190b57cec5SDimitry Andric #include "llvm/IR/CFG.h" 200b57cec5SDimitry Andric #include "llvm/IR/Function.h" 210b57cec5SDimitry Andric #include "llvm/IR/PassManager.h" 22480093f4SDimitry Andric #include "llvm/InitializePasses.h" 230b57cec5SDimitry Andric #include "llvm/Pass.h" 240b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h" 250b57cec5SDimitry Andric #include "llvm/Support/GraphWriter.h" 260b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 270b57cec5SDimitry Andric #include <cassert> 28bdd1243dSDimitry Andric #include <optional> 290b57cec5SDimitry Andric #include <string> 300b57cec5SDimitry Andric 310b57cec5SDimitry Andric using namespace llvm; 320b57cec5SDimitry Andric 330b57cec5SDimitry Andric #define DEBUG_TYPE "block-freq" 340b57cec5SDimitry Andric 350b57cec5SDimitry Andric static cl::opt<GVDAGType> ViewBlockFreqPropagationDAG( 360b57cec5SDimitry Andric "view-block-freq-propagation-dags", cl::Hidden, 370b57cec5SDimitry Andric cl::desc("Pop up a window to show a dag displaying how block " 380b57cec5SDimitry Andric "frequencies propagation through the CFG."), 390b57cec5SDimitry Andric cl::values(clEnumValN(GVDT_None, "none", "do not display graphs."), 400b57cec5SDimitry Andric clEnumValN(GVDT_Fraction, "fraction", 410b57cec5SDimitry Andric "display a graph using the " 420b57cec5SDimitry Andric "fractional block frequency representation."), 430b57cec5SDimitry Andric clEnumValN(GVDT_Integer, "integer", 440b57cec5SDimitry Andric "display a graph using the raw " 450b57cec5SDimitry Andric "integer fractional block frequency representation."), 460b57cec5SDimitry Andric clEnumValN(GVDT_Count, "count", "display a graph using the real " 470b57cec5SDimitry Andric "profile count if available."))); 480b57cec5SDimitry Andric 49fe6060f1SDimitry Andric namespace llvm { 500b57cec5SDimitry Andric cl::opt<std::string> 510b57cec5SDimitry Andric ViewBlockFreqFuncName("view-bfi-func-name", cl::Hidden, 520b57cec5SDimitry Andric cl::desc("The option to specify " 530b57cec5SDimitry Andric "the name of the function " 540b57cec5SDimitry Andric "whose CFG will be displayed.")); 550b57cec5SDimitry Andric 560b57cec5SDimitry Andric cl::opt<unsigned> 570b57cec5SDimitry Andric ViewHotFreqPercent("view-hot-freq-percent", cl::init(10), cl::Hidden, 580b57cec5SDimitry Andric cl::desc("An integer in percent used to specify " 590b57cec5SDimitry Andric "the hot blocks/edges to be displayed " 600b57cec5SDimitry Andric "in red: a block or edge whose frequency " 610b57cec5SDimitry Andric "is no less than the max frequency of the " 620b57cec5SDimitry Andric "function multiplied by this percent.")); 630b57cec5SDimitry Andric 640b57cec5SDimitry Andric // Command line option to turn on CFG dot or text dump after profile annotation. 650b57cec5SDimitry Andric cl::opt<PGOViewCountsType> PGOViewCounts( 660b57cec5SDimitry Andric "pgo-view-counts", cl::Hidden, 670b57cec5SDimitry Andric cl::desc("A boolean option to show CFG dag or text with " 680b57cec5SDimitry Andric "block profile counts and branch probabilities " 690b57cec5SDimitry Andric "right after PGO profile annotation step. The " 700b57cec5SDimitry Andric "profile counts are computed using branch " 710b57cec5SDimitry Andric "probabilities from the runtime profile data and " 720b57cec5SDimitry Andric "block frequency propagation algorithm. To view " 730b57cec5SDimitry Andric "the raw counts from the profile, use option " 740b57cec5SDimitry Andric "-pgo-view-raw-counts instead. To limit graph " 750b57cec5SDimitry Andric "display to only one function, use filtering option " 760b57cec5SDimitry Andric "-view-bfi-func-name."), 770b57cec5SDimitry Andric cl::values(clEnumValN(PGOVCT_None, "none", "do not show."), 780b57cec5SDimitry Andric clEnumValN(PGOVCT_Graph, "graph", "show a graph."), 790b57cec5SDimitry Andric clEnumValN(PGOVCT_Text, "text", "show in text."))); 800b57cec5SDimitry Andric 815f757f3fSDimitry Andric static cl::opt<bool> PrintBFI("print-bfi", cl::init(false), cl::Hidden, 820b57cec5SDimitry Andric cl::desc("Print the block frequency info.")); 830b57cec5SDimitry Andric 845f757f3fSDimitry Andric cl::opt<std::string> 855f757f3fSDimitry Andric PrintBFIFuncName("print-bfi-func-name", cl::Hidden, 860b57cec5SDimitry Andric cl::desc("The option to specify the name of the function " 870b57cec5SDimitry Andric "whose block frequency info is printed.")); 88fe6060f1SDimitry Andric } // namespace llvm 890b57cec5SDimitry Andric 900b57cec5SDimitry Andric namespace llvm { 910b57cec5SDimitry Andric 920b57cec5SDimitry Andric static GVDAGType getGVDT() { 930b57cec5SDimitry Andric if (PGOViewCounts == PGOVCT_Graph) 940b57cec5SDimitry Andric return GVDT_Count; 950b57cec5SDimitry Andric return ViewBlockFreqPropagationDAG; 960b57cec5SDimitry Andric } 970b57cec5SDimitry Andric 980b57cec5SDimitry Andric template <> 990b57cec5SDimitry Andric struct GraphTraits<BlockFrequencyInfo *> { 1000b57cec5SDimitry Andric using NodeRef = const BasicBlock *; 1015ffd83dbSDimitry Andric using ChildIteratorType = const_succ_iterator; 1020b57cec5SDimitry Andric using nodes_iterator = pointer_iterator<Function::const_iterator>; 1030b57cec5SDimitry Andric 1040b57cec5SDimitry Andric static NodeRef getEntryNode(const BlockFrequencyInfo *G) { 1050b57cec5SDimitry Andric return &G->getFunction()->front(); 1060b57cec5SDimitry Andric } 1070b57cec5SDimitry Andric 1080b57cec5SDimitry Andric static ChildIteratorType child_begin(const NodeRef N) { 1090b57cec5SDimitry Andric return succ_begin(N); 1100b57cec5SDimitry Andric } 1110b57cec5SDimitry Andric 1120b57cec5SDimitry Andric static ChildIteratorType child_end(const NodeRef N) { return succ_end(N); } 1130b57cec5SDimitry Andric 1140b57cec5SDimitry Andric static nodes_iterator nodes_begin(const BlockFrequencyInfo *G) { 1150b57cec5SDimitry Andric return nodes_iterator(G->getFunction()->begin()); 1160b57cec5SDimitry Andric } 1170b57cec5SDimitry Andric 1180b57cec5SDimitry Andric static nodes_iterator nodes_end(const BlockFrequencyInfo *G) { 1190b57cec5SDimitry Andric return nodes_iterator(G->getFunction()->end()); 1200b57cec5SDimitry Andric } 1210b57cec5SDimitry Andric }; 1220b57cec5SDimitry Andric 1230b57cec5SDimitry Andric using BFIDOTGTraitsBase = 1240b57cec5SDimitry Andric BFIDOTGraphTraitsBase<BlockFrequencyInfo, BranchProbabilityInfo>; 1250b57cec5SDimitry Andric 1260b57cec5SDimitry Andric template <> 1270b57cec5SDimitry Andric struct DOTGraphTraits<BlockFrequencyInfo *> : public BFIDOTGTraitsBase { 1280b57cec5SDimitry Andric explicit DOTGraphTraits(bool isSimple = false) 1290b57cec5SDimitry Andric : BFIDOTGTraitsBase(isSimple) {} 1300b57cec5SDimitry Andric 1310b57cec5SDimitry Andric std::string getNodeLabel(const BasicBlock *Node, 1320b57cec5SDimitry Andric const BlockFrequencyInfo *Graph) { 1330b57cec5SDimitry Andric 1340b57cec5SDimitry Andric return BFIDOTGTraitsBase::getNodeLabel(Node, Graph, getGVDT()); 1350b57cec5SDimitry Andric } 1360b57cec5SDimitry Andric 1370b57cec5SDimitry Andric std::string getNodeAttributes(const BasicBlock *Node, 1380b57cec5SDimitry Andric const BlockFrequencyInfo *Graph) { 1390b57cec5SDimitry Andric return BFIDOTGTraitsBase::getNodeAttributes(Node, Graph, 1400b57cec5SDimitry Andric ViewHotFreqPercent); 1410b57cec5SDimitry Andric } 1420b57cec5SDimitry Andric 1430b57cec5SDimitry Andric std::string getEdgeAttributes(const BasicBlock *Node, EdgeIter EI, 1440b57cec5SDimitry Andric const BlockFrequencyInfo *BFI) { 1450b57cec5SDimitry Andric return BFIDOTGTraitsBase::getEdgeAttributes(Node, EI, BFI, BFI->getBPI(), 1460b57cec5SDimitry Andric ViewHotFreqPercent); 1470b57cec5SDimitry Andric } 1480b57cec5SDimitry Andric }; 1490b57cec5SDimitry Andric 1500b57cec5SDimitry Andric } // end namespace llvm 1510b57cec5SDimitry Andric 1520b57cec5SDimitry Andric BlockFrequencyInfo::BlockFrequencyInfo() = default; 1530b57cec5SDimitry Andric 1540b57cec5SDimitry Andric BlockFrequencyInfo::BlockFrequencyInfo(const Function &F, 1550b57cec5SDimitry Andric const BranchProbabilityInfo &BPI, 1560b57cec5SDimitry Andric const LoopInfo &LI) { 1570b57cec5SDimitry Andric calculate(F, BPI, LI); 1580b57cec5SDimitry Andric } 1590b57cec5SDimitry Andric 1600b57cec5SDimitry Andric BlockFrequencyInfo::BlockFrequencyInfo(BlockFrequencyInfo &&Arg) 1610b57cec5SDimitry Andric : BFI(std::move(Arg.BFI)) {} 1620b57cec5SDimitry Andric 1630b57cec5SDimitry Andric BlockFrequencyInfo &BlockFrequencyInfo::operator=(BlockFrequencyInfo &&RHS) { 1640b57cec5SDimitry Andric releaseMemory(); 1650b57cec5SDimitry Andric BFI = std::move(RHS.BFI); 1660b57cec5SDimitry Andric return *this; 1670b57cec5SDimitry Andric } 1680b57cec5SDimitry Andric 1690b57cec5SDimitry Andric // Explicitly define the default constructor otherwise it would be implicitly 1700b57cec5SDimitry Andric // defined at the first ODR-use which is the BFI member in the 1710b57cec5SDimitry Andric // LazyBlockFrequencyInfo header. The dtor needs the BlockFrequencyInfoImpl 1720b57cec5SDimitry Andric // template instantiated which is not available in the header. 1730b57cec5SDimitry Andric BlockFrequencyInfo::~BlockFrequencyInfo() = default; 1740b57cec5SDimitry Andric 1750b57cec5SDimitry Andric bool BlockFrequencyInfo::invalidate(Function &F, const PreservedAnalyses &PA, 1760b57cec5SDimitry Andric FunctionAnalysisManager::Invalidator &) { 1770b57cec5SDimitry Andric // Check whether the analysis, all analyses on functions, or the function's 1780b57cec5SDimitry Andric // CFG have been preserved. 1790b57cec5SDimitry Andric auto PAC = PA.getChecker<BlockFrequencyAnalysis>(); 1800b57cec5SDimitry Andric return !(PAC.preserved() || PAC.preservedSet<AllAnalysesOn<Function>>() || 1810b57cec5SDimitry Andric PAC.preservedSet<CFGAnalyses>()); 1820b57cec5SDimitry Andric } 1830b57cec5SDimitry Andric 1840b57cec5SDimitry Andric void BlockFrequencyInfo::calculate(const Function &F, 1850b57cec5SDimitry Andric const BranchProbabilityInfo &BPI, 1860b57cec5SDimitry Andric const LoopInfo &LI) { 1870b57cec5SDimitry Andric if (!BFI) 1880b57cec5SDimitry Andric BFI.reset(new ImplType); 1890b57cec5SDimitry Andric BFI->calculate(F, BPI, LI); 1900b57cec5SDimitry Andric if (ViewBlockFreqPropagationDAG != GVDT_None && 191*0fca6ea1SDimitry Andric (ViewBlockFreqFuncName.empty() || F.getName() == ViewBlockFreqFuncName)) { 1920b57cec5SDimitry Andric view(); 1930b57cec5SDimitry Andric } 1945f757f3fSDimitry Andric if (PrintBFI && 195*0fca6ea1SDimitry Andric (PrintBFIFuncName.empty() || F.getName() == PrintBFIFuncName)) { 1960b57cec5SDimitry Andric print(dbgs()); 1970b57cec5SDimitry Andric } 1980b57cec5SDimitry Andric } 1990b57cec5SDimitry Andric 2000b57cec5SDimitry Andric BlockFrequency BlockFrequencyInfo::getBlockFreq(const BasicBlock *BB) const { 2015f757f3fSDimitry Andric return BFI ? BFI->getBlockFreq(BB) : BlockFrequency(0); 2020b57cec5SDimitry Andric } 2030b57cec5SDimitry Andric 204bdd1243dSDimitry Andric std::optional<uint64_t> 2050b57cec5SDimitry Andric BlockFrequencyInfo::getBlockProfileCount(const BasicBlock *BB, 2060b57cec5SDimitry Andric bool AllowSynthetic) const { 2070b57cec5SDimitry Andric if (!BFI) 208bdd1243dSDimitry Andric return std::nullopt; 2090b57cec5SDimitry Andric 2100b57cec5SDimitry Andric return BFI->getBlockProfileCount(*getFunction(), BB, AllowSynthetic); 2110b57cec5SDimitry Andric } 2120b57cec5SDimitry Andric 213bdd1243dSDimitry Andric std::optional<uint64_t> 2145f757f3fSDimitry Andric BlockFrequencyInfo::getProfileCountFromFreq(BlockFrequency Freq) const { 2150b57cec5SDimitry Andric if (!BFI) 216bdd1243dSDimitry Andric return std::nullopt; 2170b57cec5SDimitry Andric return BFI->getProfileCountFromFreq(*getFunction(), Freq); 2180b57cec5SDimitry Andric } 2190b57cec5SDimitry Andric 2200b57cec5SDimitry Andric bool BlockFrequencyInfo::isIrrLoopHeader(const BasicBlock *BB) { 2210b57cec5SDimitry Andric assert(BFI && "Expected analysis to be available"); 2220b57cec5SDimitry Andric return BFI->isIrrLoopHeader(BB); 2230b57cec5SDimitry Andric } 2240b57cec5SDimitry Andric 2255f757f3fSDimitry Andric void BlockFrequencyInfo::setBlockFreq(const BasicBlock *BB, 2265f757f3fSDimitry Andric BlockFrequency Freq) { 2270b57cec5SDimitry Andric assert(BFI && "Expected analysis to be available"); 2280b57cec5SDimitry Andric BFI->setBlockFreq(BB, Freq); 2290b57cec5SDimitry Andric } 2300b57cec5SDimitry Andric 2310b57cec5SDimitry Andric void BlockFrequencyInfo::setBlockFreqAndScale( 2325f757f3fSDimitry Andric const BasicBlock *ReferenceBB, BlockFrequency Freq, 2330b57cec5SDimitry Andric SmallPtrSetImpl<BasicBlock *> &BlocksToScale) { 2340b57cec5SDimitry Andric assert(BFI && "Expected analysis to be available"); 2350b57cec5SDimitry Andric // Use 128 bits APInt to avoid overflow. 2365f757f3fSDimitry Andric APInt NewFreq(128, Freq.getFrequency()); 2370b57cec5SDimitry Andric APInt OldFreq(128, BFI->getBlockFreq(ReferenceBB).getFrequency()); 2380b57cec5SDimitry Andric APInt BBFreq(128, 0); 2390b57cec5SDimitry Andric for (auto *BB : BlocksToScale) { 2400b57cec5SDimitry Andric BBFreq = BFI->getBlockFreq(BB).getFrequency(); 2410b57cec5SDimitry Andric // Multiply first by NewFreq and then divide by OldFreq 2420b57cec5SDimitry Andric // to minimize loss of precision. 2430b57cec5SDimitry Andric BBFreq *= NewFreq; 2440b57cec5SDimitry Andric // udiv is an expensive operation in the general case. If this ends up being 2450b57cec5SDimitry Andric // a hot spot, one of the options proposed in 2460b57cec5SDimitry Andric // https://reviews.llvm.org/D28535#650071 could be used to avoid this. 2470b57cec5SDimitry Andric BBFreq = BBFreq.udiv(OldFreq); 2485f757f3fSDimitry Andric BFI->setBlockFreq(BB, BlockFrequency(BBFreq.getLimitedValue())); 2490b57cec5SDimitry Andric } 2500b57cec5SDimitry Andric BFI->setBlockFreq(ReferenceBB, Freq); 2510b57cec5SDimitry Andric } 2520b57cec5SDimitry Andric 2530b57cec5SDimitry Andric /// Pop up a ghostview window with the current block frequency propagation 2540b57cec5SDimitry Andric /// rendered using dot. 2550b57cec5SDimitry Andric void BlockFrequencyInfo::view(StringRef title) const { 2560b57cec5SDimitry Andric ViewGraph(const_cast<BlockFrequencyInfo *>(this), title); 2570b57cec5SDimitry Andric } 2580b57cec5SDimitry Andric 2590b57cec5SDimitry Andric const Function *BlockFrequencyInfo::getFunction() const { 2600b57cec5SDimitry Andric return BFI ? BFI->getFunction() : nullptr; 2610b57cec5SDimitry Andric } 2620b57cec5SDimitry Andric 2630b57cec5SDimitry Andric const BranchProbabilityInfo *BlockFrequencyInfo::getBPI() const { 2640b57cec5SDimitry Andric return BFI ? &BFI->getBPI() : nullptr; 2650b57cec5SDimitry Andric } 2660b57cec5SDimitry Andric 2675f757f3fSDimitry Andric BlockFrequency BlockFrequencyInfo::getEntryFreq() const { 2685f757f3fSDimitry Andric return BFI ? BFI->getEntryFreq() : BlockFrequency(0); 2690b57cec5SDimitry Andric } 2700b57cec5SDimitry Andric 2710b57cec5SDimitry Andric void BlockFrequencyInfo::releaseMemory() { BFI.reset(); } 2720b57cec5SDimitry Andric 2730b57cec5SDimitry Andric void BlockFrequencyInfo::print(raw_ostream &OS) const { 2740b57cec5SDimitry Andric if (BFI) 2750b57cec5SDimitry Andric BFI->print(OS); 2760b57cec5SDimitry Andric } 2770b57cec5SDimitry Andric 2785ffd83dbSDimitry Andric void BlockFrequencyInfo::verifyMatch(BlockFrequencyInfo &Other) const { 2795ffd83dbSDimitry Andric if (BFI) 2805ffd83dbSDimitry Andric BFI->verifyMatch(*Other.BFI); 2815ffd83dbSDimitry Andric } 2825ffd83dbSDimitry Andric 2835f757f3fSDimitry Andric Printable llvm::printBlockFreq(const BlockFrequencyInfo &BFI, 2845f757f3fSDimitry Andric BlockFrequency Freq) { 2855f757f3fSDimitry Andric return Printable([&BFI, Freq](raw_ostream &OS) { 286*0fca6ea1SDimitry Andric printRelativeBlockFreq(OS, BFI.getEntryFreq(), Freq); 2875f757f3fSDimitry Andric }); 2885f757f3fSDimitry Andric } 2895f757f3fSDimitry Andric 2905f757f3fSDimitry Andric Printable llvm::printBlockFreq(const BlockFrequencyInfo &BFI, 2915f757f3fSDimitry Andric const BasicBlock &BB) { 2925f757f3fSDimitry Andric return printBlockFreq(BFI, BFI.getBlockFreq(&BB)); 2935f757f3fSDimitry Andric } 2945f757f3fSDimitry Andric 2950b57cec5SDimitry Andric INITIALIZE_PASS_BEGIN(BlockFrequencyInfoWrapperPass, "block-freq", 2960b57cec5SDimitry Andric "Block Frequency Analysis", true, true) 2970b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(BranchProbabilityInfoWrapperPass) 2980b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass) 2990b57cec5SDimitry Andric INITIALIZE_PASS_END(BlockFrequencyInfoWrapperPass, "block-freq", 3000b57cec5SDimitry Andric "Block Frequency Analysis", true, true) 3010b57cec5SDimitry Andric 3020b57cec5SDimitry Andric char BlockFrequencyInfoWrapperPass::ID = 0; 3030b57cec5SDimitry Andric 3040b57cec5SDimitry Andric BlockFrequencyInfoWrapperPass::BlockFrequencyInfoWrapperPass() 3050b57cec5SDimitry Andric : FunctionPass(ID) { 3060b57cec5SDimitry Andric initializeBlockFrequencyInfoWrapperPassPass(*PassRegistry::getPassRegistry()); 3070b57cec5SDimitry Andric } 3080b57cec5SDimitry Andric 3090b57cec5SDimitry Andric BlockFrequencyInfoWrapperPass::~BlockFrequencyInfoWrapperPass() = default; 3100b57cec5SDimitry Andric 3110b57cec5SDimitry Andric void BlockFrequencyInfoWrapperPass::print(raw_ostream &OS, 3120b57cec5SDimitry Andric const Module *) const { 3130b57cec5SDimitry Andric BFI.print(OS); 3140b57cec5SDimitry Andric } 3150b57cec5SDimitry Andric 3160b57cec5SDimitry Andric void BlockFrequencyInfoWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const { 3170b57cec5SDimitry Andric AU.addRequired<BranchProbabilityInfoWrapperPass>(); 3180b57cec5SDimitry Andric AU.addRequired<LoopInfoWrapperPass>(); 3190b57cec5SDimitry Andric AU.setPreservesAll(); 3200b57cec5SDimitry Andric } 3210b57cec5SDimitry Andric 3220b57cec5SDimitry Andric void BlockFrequencyInfoWrapperPass::releaseMemory() { BFI.releaseMemory(); } 3230b57cec5SDimitry Andric 3240b57cec5SDimitry Andric bool BlockFrequencyInfoWrapperPass::runOnFunction(Function &F) { 3250b57cec5SDimitry Andric BranchProbabilityInfo &BPI = 3260b57cec5SDimitry Andric getAnalysis<BranchProbabilityInfoWrapperPass>().getBPI(); 3270b57cec5SDimitry Andric LoopInfo &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo(); 3280b57cec5SDimitry Andric BFI.calculate(F, BPI, LI); 3290b57cec5SDimitry Andric return false; 3300b57cec5SDimitry Andric } 3310b57cec5SDimitry Andric 3320b57cec5SDimitry Andric AnalysisKey BlockFrequencyAnalysis::Key; 3330b57cec5SDimitry Andric BlockFrequencyInfo BlockFrequencyAnalysis::run(Function &F, 3340b57cec5SDimitry Andric FunctionAnalysisManager &AM) { 33506c3fb27SDimitry Andric auto &BP = AM.getResult<BranchProbabilityAnalysis>(F); 33606c3fb27SDimitry Andric auto &LI = AM.getResult<LoopAnalysis>(F); 3370b57cec5SDimitry Andric BlockFrequencyInfo BFI; 33806c3fb27SDimitry Andric BFI.calculate(F, BP, LI); 3390b57cec5SDimitry Andric return BFI; 3400b57cec5SDimitry Andric } 3410b57cec5SDimitry Andric 3420b57cec5SDimitry Andric PreservedAnalyses 3430b57cec5SDimitry Andric BlockFrequencyPrinterPass::run(Function &F, FunctionAnalysisManager &AM) { 3440b57cec5SDimitry Andric OS << "Printing analysis results of BFI for function " 3450b57cec5SDimitry Andric << "'" << F.getName() << "':" 3460b57cec5SDimitry Andric << "\n"; 3470b57cec5SDimitry Andric AM.getResult<BlockFrequencyAnalysis>(F).print(OS); 3480b57cec5SDimitry Andric return PreservedAnalyses::all(); 3490b57cec5SDimitry Andric } 350