1*9880d681SAndroid Build Coastguard Worker //===- MachineDominators.cpp - Machine Dominator Calculation --------------===//
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 // This file implements simple dominator construction algorithms for finding
11*9880d681SAndroid Build Coastguard Worker // forward dominators on machine functions.
12*9880d681SAndroid Build Coastguard Worker //
13*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
14*9880d681SAndroid Build Coastguard Worker
15*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineDominators.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/Passes.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/SmallBitVector.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/CommandLine.h"
19*9880d681SAndroid Build Coastguard Worker
20*9880d681SAndroid Build Coastguard Worker using namespace llvm;
21*9880d681SAndroid Build Coastguard Worker
22*9880d681SAndroid Build Coastguard Worker // Always verify dominfo if expensive checking is enabled.
23*9880d681SAndroid Build Coastguard Worker #ifdef EXPENSIVE_CHECKS
24*9880d681SAndroid Build Coastguard Worker static bool VerifyMachineDomInfo = true;
25*9880d681SAndroid Build Coastguard Worker #else
26*9880d681SAndroid Build Coastguard Worker static bool VerifyMachineDomInfo = false;
27*9880d681SAndroid Build Coastguard Worker #endif
28*9880d681SAndroid Build Coastguard Worker static cl::opt<bool, true> VerifyMachineDomInfoX(
29*9880d681SAndroid Build Coastguard Worker "verify-machine-dom-info", cl::location(VerifyMachineDomInfo),
30*9880d681SAndroid Build Coastguard Worker cl::desc("Verify machine dominator info (time consuming)"));
31*9880d681SAndroid Build Coastguard Worker
32*9880d681SAndroid Build Coastguard Worker namespace llvm {
33*9880d681SAndroid Build Coastguard Worker template class DomTreeNodeBase<MachineBasicBlock>;
34*9880d681SAndroid Build Coastguard Worker template class DominatorTreeBase<MachineBasicBlock>;
35*9880d681SAndroid Build Coastguard Worker }
36*9880d681SAndroid Build Coastguard Worker
37*9880d681SAndroid Build Coastguard Worker char MachineDominatorTree::ID = 0;
38*9880d681SAndroid Build Coastguard Worker
39*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS(MachineDominatorTree, "machinedomtree",
40*9880d681SAndroid Build Coastguard Worker "MachineDominator Tree Construction", true, true)
41*9880d681SAndroid Build Coastguard Worker
42*9880d681SAndroid Build Coastguard Worker char &llvm::MachineDominatorsID = MachineDominatorTree::ID;
43*9880d681SAndroid Build Coastguard Worker
getAnalysisUsage(AnalysisUsage & AU) const44*9880d681SAndroid Build Coastguard Worker void MachineDominatorTree::getAnalysisUsage(AnalysisUsage &AU) const {
45*9880d681SAndroid Build Coastguard Worker AU.setPreservesAll();
46*9880d681SAndroid Build Coastguard Worker MachineFunctionPass::getAnalysisUsage(AU);
47*9880d681SAndroid Build Coastguard Worker }
48*9880d681SAndroid Build Coastguard Worker
runOnMachineFunction(MachineFunction & F)49*9880d681SAndroid Build Coastguard Worker bool MachineDominatorTree::runOnMachineFunction(MachineFunction &F) {
50*9880d681SAndroid Build Coastguard Worker CriticalEdgesToSplit.clear();
51*9880d681SAndroid Build Coastguard Worker NewBBs.clear();
52*9880d681SAndroid Build Coastguard Worker DT->recalculate(F);
53*9880d681SAndroid Build Coastguard Worker
54*9880d681SAndroid Build Coastguard Worker return false;
55*9880d681SAndroid Build Coastguard Worker }
56*9880d681SAndroid Build Coastguard Worker
MachineDominatorTree()57*9880d681SAndroid Build Coastguard Worker MachineDominatorTree::MachineDominatorTree()
58*9880d681SAndroid Build Coastguard Worker : MachineFunctionPass(ID) {
59*9880d681SAndroid Build Coastguard Worker initializeMachineDominatorTreePass(*PassRegistry::getPassRegistry());
60*9880d681SAndroid Build Coastguard Worker DT = new DominatorTreeBase<MachineBasicBlock>(false);
61*9880d681SAndroid Build Coastguard Worker }
62*9880d681SAndroid Build Coastguard Worker
~MachineDominatorTree()63*9880d681SAndroid Build Coastguard Worker MachineDominatorTree::~MachineDominatorTree() {
64*9880d681SAndroid Build Coastguard Worker delete DT;
65*9880d681SAndroid Build Coastguard Worker }
66*9880d681SAndroid Build Coastguard Worker
releaseMemory()67*9880d681SAndroid Build Coastguard Worker void MachineDominatorTree::releaseMemory() {
68*9880d681SAndroid Build Coastguard Worker DT->releaseMemory();
69*9880d681SAndroid Build Coastguard Worker }
70*9880d681SAndroid Build Coastguard Worker
verifyAnalysis() const71*9880d681SAndroid Build Coastguard Worker void MachineDominatorTree::verifyAnalysis() const {
72*9880d681SAndroid Build Coastguard Worker if (VerifyMachineDomInfo)
73*9880d681SAndroid Build Coastguard Worker verifyDomTree();
74*9880d681SAndroid Build Coastguard Worker }
75*9880d681SAndroid Build Coastguard Worker
print(raw_ostream & OS,const Module *) const76*9880d681SAndroid Build Coastguard Worker void MachineDominatorTree::print(raw_ostream &OS, const Module*) const {
77*9880d681SAndroid Build Coastguard Worker DT->print(OS);
78*9880d681SAndroid Build Coastguard Worker }
79*9880d681SAndroid Build Coastguard Worker
applySplitCriticalEdges() const80*9880d681SAndroid Build Coastguard Worker void MachineDominatorTree::applySplitCriticalEdges() const {
81*9880d681SAndroid Build Coastguard Worker // Bail out early if there is nothing to do.
82*9880d681SAndroid Build Coastguard Worker if (CriticalEdgesToSplit.empty())
83*9880d681SAndroid Build Coastguard Worker return;
84*9880d681SAndroid Build Coastguard Worker
85*9880d681SAndroid Build Coastguard Worker // For each element in CriticalEdgesToSplit, remember whether or not element
86*9880d681SAndroid Build Coastguard Worker // is the new immediate domminator of its successor. The mapping is done by
87*9880d681SAndroid Build Coastguard Worker // index, i.e., the information for the ith element of CriticalEdgesToSplit is
88*9880d681SAndroid Build Coastguard Worker // the ith element of IsNewIDom.
89*9880d681SAndroid Build Coastguard Worker SmallBitVector IsNewIDom(CriticalEdgesToSplit.size(), true);
90*9880d681SAndroid Build Coastguard Worker size_t Idx = 0;
91*9880d681SAndroid Build Coastguard Worker
92*9880d681SAndroid Build Coastguard Worker // Collect all the dominance properties info, before invalidating
93*9880d681SAndroid Build Coastguard Worker // the underlying DT.
94*9880d681SAndroid Build Coastguard Worker for (CriticalEdge &Edge : CriticalEdgesToSplit) {
95*9880d681SAndroid Build Coastguard Worker // Update dominator information.
96*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *Succ = Edge.ToBB;
97*9880d681SAndroid Build Coastguard Worker MachineDomTreeNode *SuccDTNode = DT->getNode(Succ);
98*9880d681SAndroid Build Coastguard Worker
99*9880d681SAndroid Build Coastguard Worker for (MachineBasicBlock *PredBB : Succ->predecessors()) {
100*9880d681SAndroid Build Coastguard Worker if (PredBB == Edge.NewBB)
101*9880d681SAndroid Build Coastguard Worker continue;
102*9880d681SAndroid Build Coastguard Worker // If we are in this situation:
103*9880d681SAndroid Build Coastguard Worker // FromBB1 FromBB2
104*9880d681SAndroid Build Coastguard Worker // + +
105*9880d681SAndroid Build Coastguard Worker // + + + +
106*9880d681SAndroid Build Coastguard Worker // + + + +
107*9880d681SAndroid Build Coastguard Worker // ... Split1 Split2 ...
108*9880d681SAndroid Build Coastguard Worker // + +
109*9880d681SAndroid Build Coastguard Worker // + +
110*9880d681SAndroid Build Coastguard Worker // +
111*9880d681SAndroid Build Coastguard Worker // Succ
112*9880d681SAndroid Build Coastguard Worker // Instead of checking the domiance property with Split2, we check it with
113*9880d681SAndroid Build Coastguard Worker // FromBB2 since Split2 is still unknown of the underlying DT structure.
114*9880d681SAndroid Build Coastguard Worker if (NewBBs.count(PredBB)) {
115*9880d681SAndroid Build Coastguard Worker assert(PredBB->pred_size() == 1 && "A basic block resulting from a "
116*9880d681SAndroid Build Coastguard Worker "critical edge split has more "
117*9880d681SAndroid Build Coastguard Worker "than one predecessor!");
118*9880d681SAndroid Build Coastguard Worker PredBB = *PredBB->pred_begin();
119*9880d681SAndroid Build Coastguard Worker }
120*9880d681SAndroid Build Coastguard Worker if (!DT->dominates(SuccDTNode, DT->getNode(PredBB))) {
121*9880d681SAndroid Build Coastguard Worker IsNewIDom[Idx] = false;
122*9880d681SAndroid Build Coastguard Worker break;
123*9880d681SAndroid Build Coastguard Worker }
124*9880d681SAndroid Build Coastguard Worker }
125*9880d681SAndroid Build Coastguard Worker ++Idx;
126*9880d681SAndroid Build Coastguard Worker }
127*9880d681SAndroid Build Coastguard Worker
128*9880d681SAndroid Build Coastguard Worker // Now, update DT with the collected dominance properties info.
129*9880d681SAndroid Build Coastguard Worker Idx = 0;
130*9880d681SAndroid Build Coastguard Worker for (CriticalEdge &Edge : CriticalEdgesToSplit) {
131*9880d681SAndroid Build Coastguard Worker // We know FromBB dominates NewBB.
132*9880d681SAndroid Build Coastguard Worker MachineDomTreeNode *NewDTNode = DT->addNewBlock(Edge.NewBB, Edge.FromBB);
133*9880d681SAndroid Build Coastguard Worker
134*9880d681SAndroid Build Coastguard Worker // If all the other predecessors of "Succ" are dominated by "Succ" itself
135*9880d681SAndroid Build Coastguard Worker // then the new block is the new immediate dominator of "Succ". Otherwise,
136*9880d681SAndroid Build Coastguard Worker // the new block doesn't dominate anything.
137*9880d681SAndroid Build Coastguard Worker if (IsNewIDom[Idx])
138*9880d681SAndroid Build Coastguard Worker DT->changeImmediateDominator(DT->getNode(Edge.ToBB), NewDTNode);
139*9880d681SAndroid Build Coastguard Worker ++Idx;
140*9880d681SAndroid Build Coastguard Worker }
141*9880d681SAndroid Build Coastguard Worker NewBBs.clear();
142*9880d681SAndroid Build Coastguard Worker CriticalEdgesToSplit.clear();
143*9880d681SAndroid Build Coastguard Worker }
144*9880d681SAndroid Build Coastguard Worker
verifyDomTree() const145*9880d681SAndroid Build Coastguard Worker void MachineDominatorTree::verifyDomTree() const {
146*9880d681SAndroid Build Coastguard Worker MachineFunction &F = *getRoot()->getParent();
147*9880d681SAndroid Build Coastguard Worker
148*9880d681SAndroid Build Coastguard Worker MachineDominatorTree OtherDT;
149*9880d681SAndroid Build Coastguard Worker OtherDT.DT->recalculate(F);
150*9880d681SAndroid Build Coastguard Worker if (compare(OtherDT)) {
151*9880d681SAndroid Build Coastguard Worker errs() << "MachineDominatorTree is not up to date!\nComputed:\n";
152*9880d681SAndroid Build Coastguard Worker print(errs(), nullptr);
153*9880d681SAndroid Build Coastguard Worker errs() << "\nActual:\n";
154*9880d681SAndroid Build Coastguard Worker OtherDT.print(errs(), nullptr);
155*9880d681SAndroid Build Coastguard Worker abort();
156*9880d681SAndroid Build Coastguard Worker }
157*9880d681SAndroid Build Coastguard Worker }
158