xref: /freebsd/contrib/llvm-project/llvm/lib/Analysis/BlockFrequencyInfo.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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 
getGVDT()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 
getEntryNodellvm::GraphTraits1040b57cec5SDimitry Andric   static NodeRef getEntryNode(const BlockFrequencyInfo *G) {
1050b57cec5SDimitry Andric     return &G->getFunction()->front();
1060b57cec5SDimitry Andric   }
1070b57cec5SDimitry Andric 
child_beginllvm::GraphTraits1080b57cec5SDimitry Andric   static ChildIteratorType child_begin(const NodeRef N) {
1090b57cec5SDimitry Andric     return succ_begin(N);
1100b57cec5SDimitry Andric   }
1110b57cec5SDimitry Andric 
child_endllvm::GraphTraits1120b57cec5SDimitry Andric   static ChildIteratorType child_end(const NodeRef N) { return succ_end(N); }
1130b57cec5SDimitry Andric 
nodes_beginllvm::GraphTraits1140b57cec5SDimitry Andric   static nodes_iterator nodes_begin(const BlockFrequencyInfo *G) {
1150b57cec5SDimitry Andric     return nodes_iterator(G->getFunction()->begin());
1160b57cec5SDimitry Andric   }
1170b57cec5SDimitry Andric 
nodes_endllvm::GraphTraits1180b57cec5SDimitry 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 {
DOTGraphTraitsllvm::DOTGraphTraits1280b57cec5SDimitry Andric   explicit DOTGraphTraits(bool isSimple = false)
1290b57cec5SDimitry Andric       : BFIDOTGTraitsBase(isSimple) {}
1300b57cec5SDimitry Andric 
getNodeLabelllvm::DOTGraphTraits1310b57cec5SDimitry 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 
getNodeAttributesllvm::DOTGraphTraits1370b57cec5SDimitry 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 
getEdgeAttributesllvm::DOTGraphTraits1430b57cec5SDimitry 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 
BlockFrequencyInfo(const Function & F,const BranchProbabilityInfo & BPI,const LoopInfo & LI)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 
BlockFrequencyInfo(BlockFrequencyInfo && Arg)1600b57cec5SDimitry Andric BlockFrequencyInfo::BlockFrequencyInfo(BlockFrequencyInfo &&Arg)
1610b57cec5SDimitry Andric     : BFI(std::move(Arg.BFI)) {}
1620b57cec5SDimitry Andric 
operator =(BlockFrequencyInfo && RHS)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 
invalidate(Function & F,const PreservedAnalyses & PA,FunctionAnalysisManager::Invalidator &)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 
calculate(const Function & F,const BranchProbabilityInfo & BPI,const LoopInfo & LI)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 
getBlockFreq(const BasicBlock * BB) const2000b57cec5SDimitry 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>
getBlockProfileCount(const BasicBlock * BB,bool AllowSynthetic) const2050b57cec5SDimitry 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>
getProfileCountFromFreq(BlockFrequency Freq) const2145f757f3fSDimitry 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 
isIrrLoopHeader(const BasicBlock * BB)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 
setBlockFreq(const BasicBlock * BB,BlockFrequency Freq)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 
setBlockFreqAndScale(const BasicBlock * ReferenceBB,BlockFrequency Freq,SmallPtrSetImpl<BasicBlock * > & BlocksToScale)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.
view(StringRef title) const2550b57cec5SDimitry Andric void BlockFrequencyInfo::view(StringRef title) const {
2560b57cec5SDimitry Andric   ViewGraph(const_cast<BlockFrequencyInfo *>(this), title);
2570b57cec5SDimitry Andric }
2580b57cec5SDimitry Andric 
getFunction() const2590b57cec5SDimitry Andric const Function *BlockFrequencyInfo::getFunction() const {
2600b57cec5SDimitry Andric   return BFI ? BFI->getFunction() : nullptr;
2610b57cec5SDimitry Andric }
2620b57cec5SDimitry Andric 
getBPI() const2630b57cec5SDimitry Andric const BranchProbabilityInfo *BlockFrequencyInfo::getBPI() const {
2640b57cec5SDimitry Andric   return BFI ? &BFI->getBPI() : nullptr;
2650b57cec5SDimitry Andric }
2660b57cec5SDimitry Andric 
getEntryFreq() const2675f757f3fSDimitry Andric BlockFrequency BlockFrequencyInfo::getEntryFreq() const {
2685f757f3fSDimitry Andric   return BFI ? BFI->getEntryFreq() : BlockFrequency(0);
2690b57cec5SDimitry Andric }
2700b57cec5SDimitry Andric 
releaseMemory()2710b57cec5SDimitry Andric void BlockFrequencyInfo::releaseMemory() { BFI.reset(); }
2720b57cec5SDimitry Andric 
print(raw_ostream & OS) const2730b57cec5SDimitry Andric void BlockFrequencyInfo::print(raw_ostream &OS) const {
2740b57cec5SDimitry Andric   if (BFI)
2750b57cec5SDimitry Andric     BFI->print(OS);
2760b57cec5SDimitry Andric }
2770b57cec5SDimitry Andric 
verifyMatch(BlockFrequencyInfo & Other) const2785ffd83dbSDimitry Andric void BlockFrequencyInfo::verifyMatch(BlockFrequencyInfo &Other) const {
2795ffd83dbSDimitry Andric   if (BFI)
2805ffd83dbSDimitry Andric     BFI->verifyMatch(*Other.BFI);
2815ffd83dbSDimitry Andric }
2825ffd83dbSDimitry Andric 
printBlockFreq(const BlockFrequencyInfo & BFI,BlockFrequency Freq)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 
printBlockFreq(const BlockFrequencyInfo & BFI,const BasicBlock & BB)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 
BlockFrequencyInfoWrapperPass()3040b57cec5SDimitry Andric BlockFrequencyInfoWrapperPass::BlockFrequencyInfoWrapperPass()
3050b57cec5SDimitry Andric     : FunctionPass(ID) {
3060b57cec5SDimitry Andric   initializeBlockFrequencyInfoWrapperPassPass(*PassRegistry::getPassRegistry());
3070b57cec5SDimitry Andric }
3080b57cec5SDimitry Andric 
3090b57cec5SDimitry Andric BlockFrequencyInfoWrapperPass::~BlockFrequencyInfoWrapperPass() = default;
3100b57cec5SDimitry Andric 
print(raw_ostream & OS,const Module *) const3110b57cec5SDimitry Andric void BlockFrequencyInfoWrapperPass::print(raw_ostream &OS,
3120b57cec5SDimitry Andric                                           const Module *) const {
3130b57cec5SDimitry Andric   BFI.print(OS);
3140b57cec5SDimitry Andric }
3150b57cec5SDimitry Andric 
getAnalysisUsage(AnalysisUsage & AU) const3160b57cec5SDimitry 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 
releaseMemory()3220b57cec5SDimitry Andric void BlockFrequencyInfoWrapperPass::releaseMemory() { BFI.releaseMemory(); }
3230b57cec5SDimitry Andric 
runOnFunction(Function & F)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;
run(Function & F,FunctionAnalysisManager & AM)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
run(Function & F,FunctionAnalysisManager & AM)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