1*9880d681SAndroid Build Coastguard Worker //===- MachineBlockFrequencyInfo.cpp - MBB Frequency Analysis -------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // Loops should be simplified before this analysis.
11*9880d681SAndroid Build Coastguard Worker //
12*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
13*9880d681SAndroid Build Coastguard Worker
14*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
15*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/BlockFrequencyInfoImpl.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineBranchProbabilityInfo.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFunction.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineLoopInfo.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/Passes.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/InitializePasses.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/CommandLine.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Format.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/GraphWriter.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
26*9880d681SAndroid Build Coastguard Worker
27*9880d681SAndroid Build Coastguard Worker using namespace llvm;
28*9880d681SAndroid Build Coastguard Worker
29*9880d681SAndroid Build Coastguard Worker #define DEBUG_TYPE "block-freq"
30*9880d681SAndroid Build Coastguard Worker
31*9880d681SAndroid Build Coastguard Worker #ifndef NDEBUG
32*9880d681SAndroid Build Coastguard Worker
33*9880d681SAndroid Build Coastguard Worker static cl::opt<GVDAGType> ViewMachineBlockFreqPropagationDAG(
34*9880d681SAndroid Build Coastguard Worker "view-machine-block-freq-propagation-dags", cl::Hidden,
35*9880d681SAndroid Build Coastguard Worker cl::desc("Pop up a window to show a dag displaying how machine block "
36*9880d681SAndroid Build Coastguard Worker "frequencies propagate through the CFG."),
37*9880d681SAndroid Build Coastguard Worker cl::values(clEnumValN(GVDT_None, "none", "do not display graphs."),
38*9880d681SAndroid Build Coastguard Worker clEnumValN(GVDT_Fraction, "fraction",
39*9880d681SAndroid Build Coastguard Worker "display a graph using the "
40*9880d681SAndroid Build Coastguard Worker "fractional block frequency representation."),
41*9880d681SAndroid Build Coastguard Worker clEnumValN(GVDT_Integer, "integer",
42*9880d681SAndroid Build Coastguard Worker "display a graph using the raw "
43*9880d681SAndroid Build Coastguard Worker "integer fractional block frequency representation."),
44*9880d681SAndroid Build Coastguard Worker clEnumValN(GVDT_Count, "count", "display a graph using the real "
45*9880d681SAndroid Build Coastguard Worker "profile count if available."),
46*9880d681SAndroid Build Coastguard Worker
47*9880d681SAndroid Build Coastguard Worker clEnumValEnd));
48*9880d681SAndroid Build Coastguard Worker
49*9880d681SAndroid Build Coastguard Worker extern cl::opt<std::string> ViewBlockFreqFuncName;
50*9880d681SAndroid Build Coastguard Worker extern cl::opt<unsigned> ViewHotFreqPercent;
51*9880d681SAndroid Build Coastguard Worker
52*9880d681SAndroid Build Coastguard Worker namespace llvm {
53*9880d681SAndroid Build Coastguard Worker
54*9880d681SAndroid Build Coastguard Worker template <> struct GraphTraits<MachineBlockFrequencyInfo *> {
55*9880d681SAndroid Build Coastguard Worker typedef const MachineBasicBlock NodeType;
56*9880d681SAndroid Build Coastguard Worker typedef MachineBasicBlock::const_succ_iterator ChildIteratorType;
57*9880d681SAndroid Build Coastguard Worker typedef MachineFunction::const_iterator nodes_iterator;
58*9880d681SAndroid Build Coastguard Worker
59*9880d681SAndroid Build Coastguard Worker static inline const NodeType *
getEntryNodellvm::GraphTraits60*9880d681SAndroid Build Coastguard Worker getEntryNode(const MachineBlockFrequencyInfo *G) {
61*9880d681SAndroid Build Coastguard Worker return &G->getFunction()->front();
62*9880d681SAndroid Build Coastguard Worker }
63*9880d681SAndroid Build Coastguard Worker
child_beginllvm::GraphTraits64*9880d681SAndroid Build Coastguard Worker static ChildIteratorType child_begin(const NodeType *N) {
65*9880d681SAndroid Build Coastguard Worker return N->succ_begin();
66*9880d681SAndroid Build Coastguard Worker }
67*9880d681SAndroid Build Coastguard Worker
child_endllvm::GraphTraits68*9880d681SAndroid Build Coastguard Worker static ChildIteratorType child_end(const NodeType *N) {
69*9880d681SAndroid Build Coastguard Worker return N->succ_end();
70*9880d681SAndroid Build Coastguard Worker }
71*9880d681SAndroid Build Coastguard Worker
nodes_beginllvm::GraphTraits72*9880d681SAndroid Build Coastguard Worker static nodes_iterator nodes_begin(const MachineBlockFrequencyInfo *G) {
73*9880d681SAndroid Build Coastguard Worker return G->getFunction()->begin();
74*9880d681SAndroid Build Coastguard Worker }
75*9880d681SAndroid Build Coastguard Worker
nodes_endllvm::GraphTraits76*9880d681SAndroid Build Coastguard Worker static nodes_iterator nodes_end(const MachineBlockFrequencyInfo *G) {
77*9880d681SAndroid Build Coastguard Worker return G->getFunction()->end();
78*9880d681SAndroid Build Coastguard Worker }
79*9880d681SAndroid Build Coastguard Worker };
80*9880d681SAndroid Build Coastguard Worker
81*9880d681SAndroid Build Coastguard Worker typedef BFIDOTGraphTraitsBase<MachineBlockFrequencyInfo,
82*9880d681SAndroid Build Coastguard Worker MachineBranchProbabilityInfo>
83*9880d681SAndroid Build Coastguard Worker MBFIDOTGraphTraitsBase;
84*9880d681SAndroid Build Coastguard Worker template <>
85*9880d681SAndroid Build Coastguard Worker struct DOTGraphTraits<MachineBlockFrequencyInfo *>
86*9880d681SAndroid Build Coastguard Worker : public MBFIDOTGraphTraitsBase {
DOTGraphTraitsllvm::DOTGraphTraits87*9880d681SAndroid Build Coastguard Worker explicit DOTGraphTraits(bool isSimple = false)
88*9880d681SAndroid Build Coastguard Worker : MBFIDOTGraphTraitsBase(isSimple) {}
89*9880d681SAndroid Build Coastguard Worker
getNodeLabelllvm::DOTGraphTraits90*9880d681SAndroid Build Coastguard Worker std::string getNodeLabel(const MachineBasicBlock *Node,
91*9880d681SAndroid Build Coastguard Worker const MachineBlockFrequencyInfo *Graph) {
92*9880d681SAndroid Build Coastguard Worker return MBFIDOTGraphTraitsBase::getNodeLabel(
93*9880d681SAndroid Build Coastguard Worker Node, Graph, ViewMachineBlockFreqPropagationDAG);
94*9880d681SAndroid Build Coastguard Worker }
95*9880d681SAndroid Build Coastguard Worker
getNodeAttributesllvm::DOTGraphTraits96*9880d681SAndroid Build Coastguard Worker std::string getNodeAttributes(const MachineBasicBlock *Node,
97*9880d681SAndroid Build Coastguard Worker const MachineBlockFrequencyInfo *Graph) {
98*9880d681SAndroid Build Coastguard Worker return MBFIDOTGraphTraitsBase::getNodeAttributes(Node, Graph,
99*9880d681SAndroid Build Coastguard Worker ViewHotFreqPercent);
100*9880d681SAndroid Build Coastguard Worker }
101*9880d681SAndroid Build Coastguard Worker
getEdgeAttributesllvm::DOTGraphTraits102*9880d681SAndroid Build Coastguard Worker std::string getEdgeAttributes(const MachineBasicBlock *Node, EdgeIter EI,
103*9880d681SAndroid Build Coastguard Worker const MachineBlockFrequencyInfo *MBFI) {
104*9880d681SAndroid Build Coastguard Worker return MBFIDOTGraphTraitsBase::getEdgeAttributes(
105*9880d681SAndroid Build Coastguard Worker Node, EI, MBFI, MBFI->getMBPI(), ViewHotFreqPercent);
106*9880d681SAndroid Build Coastguard Worker }
107*9880d681SAndroid Build Coastguard Worker };
108*9880d681SAndroid Build Coastguard Worker
109*9880d681SAndroid Build Coastguard Worker } // end namespace llvm
110*9880d681SAndroid Build Coastguard Worker #endif
111*9880d681SAndroid Build Coastguard Worker
112*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS_BEGIN(MachineBlockFrequencyInfo, "machine-block-freq",
113*9880d681SAndroid Build Coastguard Worker "Machine Block Frequency Analysis", true, true)
114*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS_DEPENDENCY(MachineBranchProbabilityInfo)
115*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo)
116*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS_END(MachineBlockFrequencyInfo, "machine-block-freq",
117*9880d681SAndroid Build Coastguard Worker "Machine Block Frequency Analysis", true, true)
118*9880d681SAndroid Build Coastguard Worker
119*9880d681SAndroid Build Coastguard Worker char MachineBlockFrequencyInfo::ID = 0;
120*9880d681SAndroid Build Coastguard Worker
MachineBlockFrequencyInfo()121*9880d681SAndroid Build Coastguard Worker MachineBlockFrequencyInfo::MachineBlockFrequencyInfo()
122*9880d681SAndroid Build Coastguard Worker : MachineFunctionPass(ID) {
123*9880d681SAndroid Build Coastguard Worker initializeMachineBlockFrequencyInfoPass(*PassRegistry::getPassRegistry());
124*9880d681SAndroid Build Coastguard Worker }
125*9880d681SAndroid Build Coastguard Worker
~MachineBlockFrequencyInfo()126*9880d681SAndroid Build Coastguard Worker MachineBlockFrequencyInfo::~MachineBlockFrequencyInfo() {}
127*9880d681SAndroid Build Coastguard Worker
getAnalysisUsage(AnalysisUsage & AU) const128*9880d681SAndroid Build Coastguard Worker void MachineBlockFrequencyInfo::getAnalysisUsage(AnalysisUsage &AU) const {
129*9880d681SAndroid Build Coastguard Worker AU.addRequired<MachineBranchProbabilityInfo>();
130*9880d681SAndroid Build Coastguard Worker AU.addRequired<MachineLoopInfo>();
131*9880d681SAndroid Build Coastguard Worker AU.setPreservesAll();
132*9880d681SAndroid Build Coastguard Worker MachineFunctionPass::getAnalysisUsage(AU);
133*9880d681SAndroid Build Coastguard Worker }
134*9880d681SAndroid Build Coastguard Worker
runOnMachineFunction(MachineFunction & F)135*9880d681SAndroid Build Coastguard Worker bool MachineBlockFrequencyInfo::runOnMachineFunction(MachineFunction &F) {
136*9880d681SAndroid Build Coastguard Worker MachineBranchProbabilityInfo &MBPI =
137*9880d681SAndroid Build Coastguard Worker getAnalysis<MachineBranchProbabilityInfo>();
138*9880d681SAndroid Build Coastguard Worker MachineLoopInfo &MLI = getAnalysis<MachineLoopInfo>();
139*9880d681SAndroid Build Coastguard Worker if (!MBFI)
140*9880d681SAndroid Build Coastguard Worker MBFI.reset(new ImplType);
141*9880d681SAndroid Build Coastguard Worker MBFI->calculate(F, MBPI, MLI);
142*9880d681SAndroid Build Coastguard Worker #ifndef NDEBUG
143*9880d681SAndroid Build Coastguard Worker if (ViewMachineBlockFreqPropagationDAG != GVDT_None &&
144*9880d681SAndroid Build Coastguard Worker (ViewBlockFreqFuncName.empty() ||
145*9880d681SAndroid Build Coastguard Worker F.getName().equals(ViewBlockFreqFuncName))) {
146*9880d681SAndroid Build Coastguard Worker view();
147*9880d681SAndroid Build Coastguard Worker }
148*9880d681SAndroid Build Coastguard Worker #endif
149*9880d681SAndroid Build Coastguard Worker return false;
150*9880d681SAndroid Build Coastguard Worker }
151*9880d681SAndroid Build Coastguard Worker
releaseMemory()152*9880d681SAndroid Build Coastguard Worker void MachineBlockFrequencyInfo::releaseMemory() { MBFI.reset(); }
153*9880d681SAndroid Build Coastguard Worker
154*9880d681SAndroid Build Coastguard Worker /// Pop up a ghostview window with the current block frequency propagation
155*9880d681SAndroid Build Coastguard Worker /// rendered using dot.
view() const156*9880d681SAndroid Build Coastguard Worker void MachineBlockFrequencyInfo::view() const {
157*9880d681SAndroid Build Coastguard Worker // This code is only for debugging.
158*9880d681SAndroid Build Coastguard Worker #ifndef NDEBUG
159*9880d681SAndroid Build Coastguard Worker ViewGraph(const_cast<MachineBlockFrequencyInfo *>(this),
160*9880d681SAndroid Build Coastguard Worker "MachineBlockFrequencyDAGs");
161*9880d681SAndroid Build Coastguard Worker #else
162*9880d681SAndroid Build Coastguard Worker errs() << "MachineBlockFrequencyInfo::view is only available in debug builds "
163*9880d681SAndroid Build Coastguard Worker "on systems with Graphviz or gv!\n";
164*9880d681SAndroid Build Coastguard Worker #endif // NDEBUG
165*9880d681SAndroid Build Coastguard Worker }
166*9880d681SAndroid Build Coastguard Worker
167*9880d681SAndroid Build Coastguard Worker BlockFrequency
getBlockFreq(const MachineBasicBlock * MBB) const168*9880d681SAndroid Build Coastguard Worker MachineBlockFrequencyInfo::getBlockFreq(const MachineBasicBlock *MBB) const {
169*9880d681SAndroid Build Coastguard Worker return MBFI ? MBFI->getBlockFreq(MBB) : 0;
170*9880d681SAndroid Build Coastguard Worker }
171*9880d681SAndroid Build Coastguard Worker
getBlockProfileCount(const MachineBasicBlock * MBB) const172*9880d681SAndroid Build Coastguard Worker Optional<uint64_t> MachineBlockFrequencyInfo::getBlockProfileCount(
173*9880d681SAndroid Build Coastguard Worker const MachineBasicBlock *MBB) const {
174*9880d681SAndroid Build Coastguard Worker const Function *F = MBFI->getFunction()->getFunction();
175*9880d681SAndroid Build Coastguard Worker return MBFI ? MBFI->getBlockProfileCount(*F, MBB) : None;
176*9880d681SAndroid Build Coastguard Worker }
177*9880d681SAndroid Build Coastguard Worker
getFunction() const178*9880d681SAndroid Build Coastguard Worker const MachineFunction *MachineBlockFrequencyInfo::getFunction() const {
179*9880d681SAndroid Build Coastguard Worker return MBFI ? MBFI->getFunction() : nullptr;
180*9880d681SAndroid Build Coastguard Worker }
181*9880d681SAndroid Build Coastguard Worker
getMBPI() const182*9880d681SAndroid Build Coastguard Worker const MachineBranchProbabilityInfo *MachineBlockFrequencyInfo::getMBPI() const {
183*9880d681SAndroid Build Coastguard Worker return MBFI ? &MBFI->getBPI() : nullptr;
184*9880d681SAndroid Build Coastguard Worker }
185*9880d681SAndroid Build Coastguard Worker
186*9880d681SAndroid Build Coastguard Worker raw_ostream &
printBlockFreq(raw_ostream & OS,const BlockFrequency Freq) const187*9880d681SAndroid Build Coastguard Worker MachineBlockFrequencyInfo::printBlockFreq(raw_ostream &OS,
188*9880d681SAndroid Build Coastguard Worker const BlockFrequency Freq) const {
189*9880d681SAndroid Build Coastguard Worker return MBFI ? MBFI->printBlockFreq(OS, Freq) : OS;
190*9880d681SAndroid Build Coastguard Worker }
191*9880d681SAndroid Build Coastguard Worker
192*9880d681SAndroid Build Coastguard Worker raw_ostream &
printBlockFreq(raw_ostream & OS,const MachineBasicBlock * MBB) const193*9880d681SAndroid Build Coastguard Worker MachineBlockFrequencyInfo::printBlockFreq(raw_ostream &OS,
194*9880d681SAndroid Build Coastguard Worker const MachineBasicBlock *MBB) const {
195*9880d681SAndroid Build Coastguard Worker return MBFI ? MBFI->printBlockFreq(OS, MBB) : OS;
196*9880d681SAndroid Build Coastguard Worker }
197*9880d681SAndroid Build Coastguard Worker
getEntryFreq() const198*9880d681SAndroid Build Coastguard Worker uint64_t MachineBlockFrequencyInfo::getEntryFreq() const {
199*9880d681SAndroid Build Coastguard Worker return MBFI ? MBFI->getEntryFreq() : 0;
200*9880d681SAndroid Build Coastguard Worker }
201