1689a5073SDuncan P. N. Exon Smith //===- MachineBlockFrequencyInfo.cpp - MBB Frequency Analysis -------------===//
2875ebd5fSJakub Staszak //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6875ebd5fSJakub Staszak //
7875ebd5fSJakub Staszak //===----------------------------------------------------------------------===//
8875ebd5fSJakub Staszak //
9875ebd5fSJakub Staszak // Loops should be simplified before this analysis.
10875ebd5fSJakub Staszak //
11875ebd5fSJakub Staszak //===----------------------------------------------------------------------===//
12875ebd5fSJakub Staszak
13875ebd5fSJakub Staszak #include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
145df3d890SEugene Zelenko #include "llvm/ADT/DenseMap.h"
155df3d890SEugene Zelenko #include "llvm/ADT/None.h"
165df3d890SEugene Zelenko #include "llvm/ADT/iterator.h"
17689a5073SDuncan P. N. Exon Smith #include "llvm/Analysis/BlockFrequencyInfoImpl.h"
185df3d890SEugene Zelenko #include "llvm/CodeGen/MachineBasicBlock.h"
19875ebd5fSJakub Staszak #include "llvm/CodeGen/MachineBranchProbabilityInfo.h"
2010be9a88SDuncan P. N. Exon Smith #include "llvm/CodeGen/MachineFunction.h"
2110be9a88SDuncan P. N. Exon Smith #include "llvm/CodeGen/MachineLoopInfo.h"
2205da2fe5SReid Kleckner #include "llvm/InitializePasses.h"
235df3d890SEugene Zelenko #include "llvm/Pass.h"
2465bbcdfaSMichael Gottesman #include "llvm/Support/CommandLine.h"
2565bbcdfaSMichael Gottesman #include "llvm/Support/GraphWriter.h"
265df3d890SEugene Zelenko #include <string>
27875ebd5fSJakub Staszak
28875ebd5fSJakub Staszak using namespace llvm;
29875ebd5fSJakub Staszak
301527baabSMatthias Braun #define DEBUG_TYPE "machine-block-freq"
311b9dde08SChandler Carruth
32d8aba75aSFangrui Song namespace llvm {
33bc157084SXinliang David Li static cl::opt<GVDAGType> ViewMachineBlockFreqPropagationDAG(
34bc157084SXinliang David Li "view-machine-block-freq-propagation-dags", cl::Hidden,
3565bbcdfaSMichael Gottesman cl::desc("Pop up a window to show a dag displaying how machine block "
36748fe483SMichael Gottesman "frequencies propagate through the CFG."),
37bc157084SXinliang David Li cl::values(clEnumValN(GVDT_None, "none", "do not display graphs."),
38bc157084SXinliang David Li clEnumValN(GVDT_Fraction, "fraction",
39bc157084SXinliang David Li "display a graph using the "
4065bbcdfaSMichael Gottesman "fractional block frequency representation."),
41bc157084SXinliang David Li clEnumValN(GVDT_Integer, "integer",
42bc157084SXinliang David Li "display a graph using the raw "
4365bbcdfaSMichael Gottesman "integer fractional block frequency representation."),
4430c50f3cSXinliang David Li clEnumValN(GVDT_Count, "count", "display a graph using the real "
45732afdd0SMehdi Amini "profile count if available.")));
465df3d890SEugene Zelenko
47fd3f645fSXinliang David Li // Similar option above, but used to control BFI display only after MBP pass
48fd3f645fSXinliang David Li cl::opt<GVDAGType> ViewBlockLayoutWithBFI(
49fd3f645fSXinliang David Li "view-block-layout-with-bfi", cl::Hidden,
50fd3f645fSXinliang David Li cl::desc(
51fd3f645fSXinliang David Li "Pop up a window to show a dag displaying MBP layout and associated "
52fd3f645fSXinliang David Li "block frequencies of the CFG."),
53fd3f645fSXinliang David Li cl::values(clEnumValN(GVDT_None, "none", "do not display graphs."),
54fd3f645fSXinliang David Li clEnumValN(GVDT_Fraction, "fraction",
55fd3f645fSXinliang David Li "display a graph using the "
56fd3f645fSXinliang David Li "fractional block frequency representation."),
57fd3f645fSXinliang David Li clEnumValN(GVDT_Integer, "integer",
58fd3f645fSXinliang David Li "display a graph using the raw "
59fd3f645fSXinliang David Li "integer fractional block frequency representation."),
60fd3f645fSXinliang David Li clEnumValN(GVDT_Count, "count",
61fd3f645fSXinliang David Li "display a graph using the real "
62fd3f645fSXinliang David Li "profile count if available.")));
6365bbcdfaSMichael Gottesman
6458fcc9bdSXinliang David Li // Command line option to specify the name of the function for CFG dump
6558fcc9bdSXinliang David Li // Defined in Analysis/BlockFrequencyInfo.cpp: -view-bfi-func-name=
668dd5ce97SXinliang David Li extern cl::opt<std::string> ViewBlockFreqFuncName;
675df3d890SEugene Zelenko
6858fcc9bdSXinliang David Li // Command line option to specify hot frequency threshold.
6958fcc9bdSXinliang David Li // Defined in Analysis/BlockFrequencyInfo.cpp: -view-hot-freq-perc=
702d531580SSimon Pilgrim extern cl::opt<unsigned> ViewHotFreqPercent;
7180457ce5SXinliang David Li
7263e17ebfSHiroshi Yamauchi static cl::opt<bool> PrintMachineBlockFreq(
7363e17ebfSHiroshi Yamauchi "print-machine-bfi", cl::init(false), cl::Hidden,
7463e17ebfSHiroshi Yamauchi cl::desc("Print the machine block frequency info."));
7563e17ebfSHiroshi Yamauchi
7663e17ebfSHiroshi Yamauchi // Command line option to specify the name of the function for block frequency
7763e17ebfSHiroshi Yamauchi // dump. Defined in Analysis/BlockFrequencyInfo.cpp.
7863e17ebfSHiroshi Yamauchi extern cl::opt<std::string> PrintBlockFreqFuncName;
79d8aba75aSFangrui Song } // namespace llvm
8063e17ebfSHiroshi Yamauchi
getGVDT()81fd3f645fSXinliang David Li static GVDAGType getGVDT() {
82fd3f645fSXinliang David Li if (ViewBlockLayoutWithBFI != GVDT_None)
83fd3f645fSXinliang David Li return ViewBlockLayoutWithBFI;
84fd3f645fSXinliang David Li
85fd3f645fSXinliang David Li return ViewMachineBlockFreqPropagationDAG;
86fd3f645fSXinliang David Li }
87fd3f645fSXinliang David Li
8865bbcdfaSMichael Gottesman namespace llvm {
8965bbcdfaSMichael Gottesman
90bc157084SXinliang David Li template <> struct GraphTraits<MachineBlockFrequencyInfo *> {
915df3d890SEugene Zelenko using NodeRef = const MachineBasicBlock *;
925df3d890SEugene Zelenko using ChildIteratorType = MachineBasicBlock::const_succ_iterator;
935df3d890SEugene Zelenko using nodes_iterator = pointer_iterator<MachineFunction::const_iterator>;
9465bbcdfaSMichael Gottesman
getEntryNodellvm::GraphTraits9548f814e8STim Shen static NodeRef getEntryNode(const MachineBlockFrequencyInfo *G) {
960ac8eb91SDuncan P. N. Exon Smith return &G->getFunction()->front();
9765bbcdfaSMichael Gottesman }
98748fe483SMichael Gottesman
child_beginllvm::GraphTraits99f2187ed3STim Shen static ChildIteratorType child_begin(const NodeRef N) {
10065bbcdfaSMichael Gottesman return N->succ_begin();
10165bbcdfaSMichael Gottesman }
102748fe483SMichael Gottesman
child_endllvm::GraphTraits103f2187ed3STim Shen static ChildIteratorType child_end(const NodeRef N) { return N->succ_end(); }
104748fe483SMichael Gottesman
nodes_beginllvm::GraphTraits10565bbcdfaSMichael Gottesman static nodes_iterator nodes_begin(const MachineBlockFrequencyInfo *G) {
106b5e0f5acSTim Shen return nodes_iterator(G->getFunction()->begin());
10765bbcdfaSMichael Gottesman }
108748fe483SMichael Gottesman
nodes_endllvm::GraphTraits10965bbcdfaSMichael Gottesman static nodes_iterator nodes_end(const MachineBlockFrequencyInfo *G) {
110b5e0f5acSTim Shen return nodes_iterator(G->getFunction()->end());
11165bbcdfaSMichael Gottesman }
11265bbcdfaSMichael Gottesman };
11365bbcdfaSMichael Gottesman
1145df3d890SEugene Zelenko using MBFIDOTGraphTraitsBase =
1155df3d890SEugene Zelenko BFIDOTGraphTraitsBase<MachineBlockFrequencyInfo,
1165df3d890SEugene Zelenko MachineBranchProbabilityInfo>;
1175df3d890SEugene Zelenko
11865bbcdfaSMichael Gottesman template <>
119bc157084SXinliang David Li struct DOTGraphTraits<MachineBlockFrequencyInfo *>
12055415f25SXinliang David Li : public MBFIDOTGraphTraitsBase {
1215df3d890SEugene Zelenko const MachineFunction *CurFunc = nullptr;
122fd3f645fSXinliang David Li DenseMap<const MachineBasicBlock *, int> LayoutOrderMap;
12365bbcdfaSMichael Gottesman
DOTGraphTraitsllvm::DOTGraphTraits1245df3d890SEugene Zelenko explicit DOTGraphTraits(bool isSimple = false)
1255df3d890SEugene Zelenko : MBFIDOTGraphTraitsBase(isSimple) {}
1265df3d890SEugene Zelenko
getNodeLabelllvm::DOTGraphTraits12765bbcdfaSMichael Gottesman std::string getNodeLabel(const MachineBasicBlock *Node,
12865bbcdfaSMichael Gottesman const MachineBlockFrequencyInfo *Graph) {
129fd3f645fSXinliang David Li int layout_order = -1;
130fd3f645fSXinliang David Li // Attach additional ordering information if 'isSimple' is false.
131fd3f645fSXinliang David Li if (!isSimple()) {
132fd3f645fSXinliang David Li const MachineFunction *F = Node->getParent();
133fd3f645fSXinliang David Li if (!CurFunc || F != CurFunc) {
134fd3f645fSXinliang David Li if (CurFunc)
135fd3f645fSXinliang David Li LayoutOrderMap.clear();
136fd3f645fSXinliang David Li
137fd3f645fSXinliang David Li CurFunc = F;
138fd3f645fSXinliang David Li int O = 0;
139fd3f645fSXinliang David Li for (auto MBI = F->begin(); MBI != F->end(); ++MBI, ++O) {
140fd3f645fSXinliang David Li LayoutOrderMap[&*MBI] = O;
141fd3f645fSXinliang David Li }
142fd3f645fSXinliang David Li }
143fd3f645fSXinliang David Li layout_order = LayoutOrderMap[Node];
144fd3f645fSXinliang David Li }
145fd3f645fSXinliang David Li return MBFIDOTGraphTraitsBase::getNodeLabel(Node, Graph, getGVDT(),
146fd3f645fSXinliang David Li layout_order);
14755415f25SXinliang David Li }
14865bbcdfaSMichael Gottesman
getNodeAttributesllvm::DOTGraphTraits1493e176c77SXinliang David Li std::string getNodeAttributes(const MachineBasicBlock *Node,
1503e176c77SXinliang David Li const MachineBlockFrequencyInfo *Graph) {
1513e176c77SXinliang David Li return MBFIDOTGraphTraitsBase::getNodeAttributes(Node, Graph,
1523e176c77SXinliang David Li ViewHotFreqPercent);
1533e176c77SXinliang David Li }
1543e176c77SXinliang David Li
getEdgeAttributesllvm::DOTGraphTraits15555415f25SXinliang David Li std::string getEdgeAttributes(const MachineBasicBlock *Node, EdgeIter EI,
15669317f2eSXinliang David Li const MachineBlockFrequencyInfo *MBFI) {
1573e176c77SXinliang David Li return MBFIDOTGraphTraitsBase::getEdgeAttributes(
1583e176c77SXinliang David Li Node, EI, MBFI, MBFI->getMBPI(), ViewHotFreqPercent);
15969317f2eSXinliang David Li }
16065bbcdfaSMichael Gottesman };
16165bbcdfaSMichael Gottesman
16265bbcdfaSMichael Gottesman } // end namespace llvm
16365bbcdfaSMichael Gottesman
1641527baabSMatthias Braun INITIALIZE_PASS_BEGIN(MachineBlockFrequencyInfo, DEBUG_TYPE,
165875ebd5fSJakub Staszak "Machine Block Frequency Analysis", true, true)
166875ebd5fSJakub Staszak INITIALIZE_PASS_DEPENDENCY(MachineBranchProbabilityInfo)
16710be9a88SDuncan P. N. Exon Smith INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo)
1681527baabSMatthias Braun INITIALIZE_PASS_END(MachineBlockFrequencyInfo, DEBUG_TYPE,
169875ebd5fSJakub Staszak "Machine Block Frequency Analysis", true, true)
170875ebd5fSJakub Staszak
171875ebd5fSJakub Staszak char MachineBlockFrequencyInfo::ID = 0;
172875ebd5fSJakub Staszak
MachineBlockFrequencyInfo()173bc157084SXinliang David Li MachineBlockFrequencyInfo::MachineBlockFrequencyInfo()
174bc157084SXinliang David Li : MachineFunctionPass(ID) {
175875ebd5fSJakub Staszak initializeMachineBlockFrequencyInfoPass(*PassRegistry::getPassRegistry());
176875ebd5fSJakub Staszak }
177875ebd5fSJakub Staszak
MachineBlockFrequencyInfo(MachineFunction & F,MachineBranchProbabilityInfo & MBPI,MachineLoopInfo & MLI)17875f72f6bSHiroshi Yamauchi MachineBlockFrequencyInfo::MachineBlockFrequencyInfo(
17975f72f6bSHiroshi Yamauchi MachineFunction &F,
18075f72f6bSHiroshi Yamauchi MachineBranchProbabilityInfo &MBPI,
18175f72f6bSHiroshi Yamauchi MachineLoopInfo &MLI) : MachineFunctionPass(ID) {
18275f72f6bSHiroshi Yamauchi calculate(F, MBPI, MLI);
18375f72f6bSHiroshi Yamauchi }
18475f72f6bSHiroshi Yamauchi
1855df3d890SEugene Zelenko MachineBlockFrequencyInfo::~MachineBlockFrequencyInfo() = default;
186875ebd5fSJakub Staszak
getAnalysisUsage(AnalysisUsage & AU) const187875ebd5fSJakub Staszak void MachineBlockFrequencyInfo::getAnalysisUsage(AnalysisUsage &AU) const {
188875ebd5fSJakub Staszak AU.addRequired<MachineBranchProbabilityInfo>();
18910be9a88SDuncan P. N. Exon Smith AU.addRequired<MachineLoopInfo>();
190875ebd5fSJakub Staszak AU.setPreservesAll();
191875ebd5fSJakub Staszak MachineFunctionPass::getAnalysisUsage(AU);
192875ebd5fSJakub Staszak }
193875ebd5fSJakub Staszak
calculate(const MachineFunction & F,const MachineBranchProbabilityInfo & MBPI,const MachineLoopInfo & MLI)194bbb141c7SAdam Nemet void MachineBlockFrequencyInfo::calculate(
195bbb141c7SAdam Nemet const MachineFunction &F, const MachineBranchProbabilityInfo &MBPI,
196bbb141c7SAdam Nemet const MachineLoopInfo &MLI) {
1973dbe1050SDuncan P. N. Exon Smith if (!MBFI)
1983dbe1050SDuncan P. N. Exon Smith MBFI.reset(new ImplType);
1995e67b666SCong Hou MBFI->calculate(F, MBPI, MLI);
20080457ce5SXinliang David Li if (ViewMachineBlockFreqPropagationDAG != GVDT_None &&
2018dd5ce97SXinliang David Li (ViewBlockFreqFuncName.empty() ||
2028dd5ce97SXinliang David Li F.getName().equals(ViewBlockFreqFuncName))) {
203538d6668SXinliang David Li view("MachineBlockFrequencyDAGS." + F.getName());
20465bbcdfaSMichael Gottesman }
20563e17ebfSHiroshi Yamauchi if (PrintMachineBlockFreq &&
20663e17ebfSHiroshi Yamauchi (PrintBlockFreqFuncName.empty() ||
20763e17ebfSHiroshi Yamauchi F.getName().equals(PrintBlockFreqFuncName))) {
20863e17ebfSHiroshi Yamauchi MBFI->print(dbgs());
20963e17ebfSHiroshi Yamauchi }
210bbb141c7SAdam Nemet }
211bbb141c7SAdam Nemet
runOnMachineFunction(MachineFunction & F)212bbb141c7SAdam Nemet bool MachineBlockFrequencyInfo::runOnMachineFunction(MachineFunction &F) {
213bbb141c7SAdam Nemet MachineBranchProbabilityInfo &MBPI =
214bbb141c7SAdam Nemet getAnalysis<MachineBranchProbabilityInfo>();
215bbb141c7SAdam Nemet MachineLoopInfo &MLI = getAnalysis<MachineLoopInfo>();
216bbb141c7SAdam Nemet calculate(F, MBPI, MLI);
217875ebd5fSJakub Staszak return false;
218875ebd5fSJakub Staszak }
219875ebd5fSJakub Staszak
releaseMemory()2203dbe1050SDuncan P. N. Exon Smith void MachineBlockFrequencyInfo::releaseMemory() { MBFI.reset(); }
2213dbe1050SDuncan P. N. Exon Smith
22265bbcdfaSMichael Gottesman /// Pop up a ghostview window with the current block frequency propagation
22365bbcdfaSMichael Gottesman /// rendered using dot.
view(const Twine & Name,bool isSimple) const224538d6668SXinliang David Li void MachineBlockFrequencyInfo::view(const Twine &Name, bool isSimple) const {
22565bbcdfaSMichael Gottesman // This code is only for debugging.
226538d6668SXinliang David Li ViewGraph(const_cast<MachineBlockFrequencyInfo *>(this), Name, isSimple);
22765bbcdfaSMichael Gottesman }
22865bbcdfaSMichael Gottesman
229bc157084SXinliang David Li BlockFrequency
getBlockFreq(const MachineBasicBlock * MBB) const230bc157084SXinliang David Li MachineBlockFrequencyInfo::getBlockFreq(const MachineBasicBlock *MBB) const {
2313dbe1050SDuncan P. N. Exon Smith return MBFI ? MBFI->getBlockFreq(MBB) : 0;
232875ebd5fSJakub Staszak }
23365bbcdfaSMichael Gottesman
getBlockProfileCount(const MachineBasicBlock * MBB) const23430c50f3cSXinliang David Li Optional<uint64_t> MachineBlockFrequencyInfo::getBlockProfileCount(
23530c50f3cSXinliang David Li const MachineBasicBlock *MBB) const {
236*bce3cca4SMatt Arsenault if (!MBFI)
237*bce3cca4SMatt Arsenault return None;
238*bce3cca4SMatt Arsenault
239f1caa283SMatthias Braun const Function &F = MBFI->getFunction()->getFunction();
240*bce3cca4SMatt Arsenault return MBFI->getBlockProfileCount(F, MBB);
24130c50f3cSXinliang David Li }
24230c50f3cSXinliang David Li
243f801575fSSean Silva Optional<uint64_t>
getProfileCountFromFreq(uint64_t Freq) const244f801575fSSean Silva MachineBlockFrequencyInfo::getProfileCountFromFreq(uint64_t Freq) const {
245*bce3cca4SMatt Arsenault if (!MBFI)
246*bce3cca4SMatt Arsenault return None;
247*bce3cca4SMatt Arsenault
248f1caa283SMatthias Braun const Function &F = MBFI->getFunction()->getFunction();
249*bce3cca4SMatt Arsenault return MBFI->getProfileCountFromFreq(F, Freq);
250f801575fSSean Silva }
251f801575fSSean Silva
isIrrLoopHeader(const MachineBasicBlock * MBB) const252111a018bSMircea Trofin bool MachineBlockFrequencyInfo::isIrrLoopHeader(
253111a018bSMircea Trofin const MachineBasicBlock *MBB) const {
254dce9def3SHiroshi Yamauchi assert(MBFI && "Expected analysis to be available");
255dce9def3SHiroshi Yamauchi return MBFI->isIrrLoopHeader(MBB);
256dce9def3SHiroshi Yamauchi }
257dce9def3SHiroshi Yamauchi
onEdgeSplit(const MachineBasicBlock & NewPredecessor,const MachineBasicBlock & NewSuccessor,const MachineBranchProbabilityInfo & MBPI)2581e027b77SMircea Trofin void MachineBlockFrequencyInfo::onEdgeSplit(
2591e027b77SMircea Trofin const MachineBasicBlock &NewPredecessor,
2601e027b77SMircea Trofin const MachineBasicBlock &NewSuccessor,
2611e027b77SMircea Trofin const MachineBranchProbabilityInfo &MBPI) {
2620e3e2422SHiroshi Yamauchi assert(MBFI && "Expected analysis to be available");
2631e027b77SMircea Trofin auto NewSuccFreq = MBFI->getBlockFreq(&NewPredecessor) *
2641e027b77SMircea Trofin MBPI.getEdgeProbability(&NewPredecessor, &NewSuccessor);
2651e027b77SMircea Trofin
2661e027b77SMircea Trofin MBFI->setBlockFreq(&NewSuccessor, NewSuccFreq.getFrequency());
2670e3e2422SHiroshi Yamauchi }
2680e3e2422SHiroshi Yamauchi
getFunction() const269936aef92SDuncan P. N. Exon Smith const MachineFunction *MachineBlockFrequencyInfo::getFunction() const {
27010be9a88SDuncan P. N. Exon Smith return MBFI ? MBFI->getFunction() : nullptr;
27165bbcdfaSMichael Gottesman }
272fd5c4b2cSMichael Gottesman
getMBPI() const2733264fdd3SXinliang David Li const MachineBranchProbabilityInfo *MachineBlockFrequencyInfo::getMBPI() const {
2743264fdd3SXinliang David Li return MBFI ? &MBFI->getBPI() : nullptr;
2753264fdd3SXinliang David Li }
2763264fdd3SXinliang David Li
277fd5c4b2cSMichael Gottesman raw_ostream &
printBlockFreq(raw_ostream & OS,const BlockFrequency Freq) const278fd5c4b2cSMichael Gottesman MachineBlockFrequencyInfo::printBlockFreq(raw_ostream &OS,
279fd5c4b2cSMichael Gottesman const BlockFrequency Freq) const {
2803dbe1050SDuncan P. N. Exon Smith return MBFI ? MBFI->printBlockFreq(OS, Freq) : OS;
281fd5c4b2cSMichael Gottesman }
282fd5c4b2cSMichael Gottesman
283fd5c4b2cSMichael Gottesman raw_ostream &
printBlockFreq(raw_ostream & OS,const MachineBasicBlock * MBB) const284fd5c4b2cSMichael Gottesman MachineBlockFrequencyInfo::printBlockFreq(raw_ostream &OS,
285fd5c4b2cSMichael Gottesman const MachineBasicBlock *MBB) const {
2863dbe1050SDuncan P. N. Exon Smith return MBFI ? MBFI->printBlockFreq(OS, MBB) : OS;
287fd5c4b2cSMichael Gottesman }
288fd5c4b2cSMichael Gottesman
getEntryFreq() const2895e985ee5SMichael Gottesman uint64_t MachineBlockFrequencyInfo::getEntryFreq() const {
2903dbe1050SDuncan P. N. Exon Smith return MBFI ? MBFI->getEntryFreq() : 0;
291fd5c4b2cSMichael Gottesman }
292