1f22ef01cSRoman Divacky //===- MachineDominators.cpp - Machine Dominator Calculation --------------===//
2f22ef01cSRoman Divacky //
3f22ef01cSRoman Divacky //                     The LLVM Compiler Infrastructure
4f22ef01cSRoman Divacky //
5f22ef01cSRoman Divacky // This file is distributed under the University of Illinois Open Source
6f22ef01cSRoman Divacky // License. See LICENSE.TXT for details.
7f22ef01cSRoman Divacky //
8f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
9f22ef01cSRoman Divacky //
10f22ef01cSRoman Divacky // This file implements simple dominator construction algorithms for finding
11f22ef01cSRoman Divacky // forward dominators on machine functions.
12f22ef01cSRoman Divacky //
13f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
14f22ef01cSRoman Divacky 
15f22ef01cSRoman Divacky #include "llvm/CodeGen/MachineDominators.h"
16ff0cc061SDimitry Andric #include "llvm/ADT/SmallBitVector.h"
17db17bf38SDimitry Andric #include "llvm/CodeGen/Passes.h"
183ca95b02SDimitry Andric #include "llvm/Support/CommandLine.h"
19f22ef01cSRoman Divacky 
20f22ef01cSRoman Divacky using namespace llvm;
21f22ef01cSRoman Divacky 
223ca95b02SDimitry Andric // Always verify dominfo if expensive checking is enabled.
233ca95b02SDimitry Andric #ifdef EXPENSIVE_CHECKS
243ca95b02SDimitry Andric static bool VerifyMachineDomInfo = true;
253ca95b02SDimitry Andric #else
263ca95b02SDimitry Andric static bool VerifyMachineDomInfo = false;
273ca95b02SDimitry Andric #endif
283ca95b02SDimitry Andric static cl::opt<bool, true> VerifyMachineDomInfoX(
292cab237bSDimitry Andric     "verify-machine-dom-info", cl::location(VerifyMachineDomInfo), cl::Hidden,
303ca95b02SDimitry Andric     cl::desc("Verify machine dominator info (time consuming)"));
313ca95b02SDimitry Andric 
32f22ef01cSRoman Divacky namespace llvm {
33875ed548SDimitry Andric template class DomTreeNodeBase<MachineBasicBlock>;
34b40b48b8SDimitry Andric template class DominatorTreeBase<MachineBasicBlock, false>; // DomTreeBase
35f22ef01cSRoman Divacky }
36f22ef01cSRoman Divacky 
37f22ef01cSRoman Divacky char MachineDominatorTree::ID = 0;
38f22ef01cSRoman Divacky 
39e580952dSDimitry Andric INITIALIZE_PASS(MachineDominatorTree, "machinedomtree",
402754fe60SDimitry Andric                 "MachineDominator Tree Construction", true, true)
41f22ef01cSRoman Divacky 
42e580952dSDimitry Andric char &llvm::MachineDominatorsID = MachineDominatorTree::ID;
43f22ef01cSRoman Divacky 
getAnalysisUsage(AnalysisUsage & AU) const44f22ef01cSRoman Divacky void MachineDominatorTree::getAnalysisUsage(AnalysisUsage &AU) const {
45f22ef01cSRoman Divacky   AU.setPreservesAll();
46f22ef01cSRoman Divacky   MachineFunctionPass::getAnalysisUsage(AU);
47f22ef01cSRoman Divacky }
48f22ef01cSRoman Divacky 
runOnMachineFunction(MachineFunction & F)49f22ef01cSRoman Divacky bool MachineDominatorTree::runOnMachineFunction(MachineFunction &F) {
5039d628a0SDimitry Andric   CriticalEdgesToSplit.clear();
5139d628a0SDimitry Andric   NewBBs.clear();
52b40b48b8SDimitry Andric   DT.reset(new DomTreeBase<MachineBasicBlock>());
53f22ef01cSRoman Divacky   DT->recalculate(F);
54f22ef01cSRoman Divacky   return false;
55f22ef01cSRoman Divacky }
56f22ef01cSRoman Divacky 
MachineDominatorTree()57f22ef01cSRoman Divacky MachineDominatorTree::MachineDominatorTree()
58e580952dSDimitry Andric     : MachineFunctionPass(ID) {
592754fe60SDimitry Andric   initializeMachineDominatorTreePass(*PassRegistry::getPassRegistry());
60f22ef01cSRoman Divacky }
61f22ef01cSRoman Divacky 
releaseMemory()62f22ef01cSRoman Divacky void MachineDominatorTree::releaseMemory() {
637a7e6055SDimitry Andric   CriticalEdgesToSplit.clear();
647a7e6055SDimitry Andric   DT.reset(nullptr);
65f22ef01cSRoman Divacky }
66f22ef01cSRoman Divacky 
verifyAnalysis() const673ca95b02SDimitry Andric void MachineDominatorTree::verifyAnalysis() const {
68*4ba319b5SDimitry Andric   if (DT && VerifyMachineDomInfo) {
69*4ba319b5SDimitry Andric     MachineFunction &F = *getRoot()->getParent();
70*4ba319b5SDimitry Andric 
71*4ba319b5SDimitry Andric     DomTreeBase<MachineBasicBlock> OtherDT;
72*4ba319b5SDimitry Andric     OtherDT.recalculate(F);
73*4ba319b5SDimitry Andric     if (getRootNode()->getBlock() != OtherDT.getRootNode()->getBlock() ||
74*4ba319b5SDimitry Andric         DT->compare(OtherDT)) {
75*4ba319b5SDimitry Andric       errs() << "MachineDominatorTree for function " << F.getName()
76*4ba319b5SDimitry Andric             << " is not up to date!\nComputed:\n";
77*4ba319b5SDimitry Andric       DT->print(errs());
78*4ba319b5SDimitry Andric       errs() << "\nActual:\n";
79*4ba319b5SDimitry Andric       OtherDT.print(errs());
80*4ba319b5SDimitry Andric       abort();
81*4ba319b5SDimitry Andric     }
82*4ba319b5SDimitry Andric   }
833ca95b02SDimitry Andric }
843ca95b02SDimitry Andric 
print(raw_ostream & OS,const Module *) const85f22ef01cSRoman Divacky void MachineDominatorTree::print(raw_ostream &OS, const Module*) const {
867a7e6055SDimitry Andric   if (DT)
87f22ef01cSRoman Divacky     DT->print(OS);
88f22ef01cSRoman Divacky }
89ff0cc061SDimitry Andric 
applySplitCriticalEdges() const90ff0cc061SDimitry Andric void MachineDominatorTree::applySplitCriticalEdges() const {
91ff0cc061SDimitry Andric   // Bail out early if there is nothing to do.
92ff0cc061SDimitry Andric   if (CriticalEdgesToSplit.empty())
93ff0cc061SDimitry Andric     return;
94ff0cc061SDimitry Andric 
95ff0cc061SDimitry Andric   // For each element in CriticalEdgesToSplit, remember whether or not element
96ff0cc061SDimitry Andric   // is the new immediate domminator of its successor. The mapping is done by
97ff0cc061SDimitry Andric   // index, i.e., the information for the ith element of CriticalEdgesToSplit is
98ff0cc061SDimitry Andric   // the ith element of IsNewIDom.
99ff0cc061SDimitry Andric   SmallBitVector IsNewIDom(CriticalEdgesToSplit.size(), true);
100ff0cc061SDimitry Andric   size_t Idx = 0;
101ff0cc061SDimitry Andric 
102ff0cc061SDimitry Andric   // Collect all the dominance properties info, before invalidating
103ff0cc061SDimitry Andric   // the underlying DT.
104ff0cc061SDimitry Andric   for (CriticalEdge &Edge : CriticalEdgesToSplit) {
105ff0cc061SDimitry Andric     // Update dominator information.
106ff0cc061SDimitry Andric     MachineBasicBlock *Succ = Edge.ToBB;
107ff0cc061SDimitry Andric     MachineDomTreeNode *SuccDTNode = DT->getNode(Succ);
108ff0cc061SDimitry Andric 
109ff0cc061SDimitry Andric     for (MachineBasicBlock *PredBB : Succ->predecessors()) {
110ff0cc061SDimitry Andric       if (PredBB == Edge.NewBB)
111ff0cc061SDimitry Andric         continue;
112ff0cc061SDimitry Andric       // If we are in this situation:
113ff0cc061SDimitry Andric       // FromBB1        FromBB2
114ff0cc061SDimitry Andric       //    +              +
115ff0cc061SDimitry Andric       //   + +            + +
116ff0cc061SDimitry Andric       //  +   +          +   +
117ff0cc061SDimitry Andric       // ...  Split1  Split2 ...
118ff0cc061SDimitry Andric       //           +   +
119ff0cc061SDimitry Andric       //            + +
120ff0cc061SDimitry Andric       //             +
121ff0cc061SDimitry Andric       //            Succ
122ff0cc061SDimitry Andric       // Instead of checking the domiance property with Split2, we check it with
123ff0cc061SDimitry Andric       // FromBB2 since Split2 is still unknown of the underlying DT structure.
124ff0cc061SDimitry Andric       if (NewBBs.count(PredBB)) {
125ff0cc061SDimitry Andric         assert(PredBB->pred_size() == 1 && "A basic block resulting from a "
126ff0cc061SDimitry Andric                                            "critical edge split has more "
127ff0cc061SDimitry Andric                                            "than one predecessor!");
128ff0cc061SDimitry Andric         PredBB = *PredBB->pred_begin();
129ff0cc061SDimitry Andric       }
130ff0cc061SDimitry Andric       if (!DT->dominates(SuccDTNode, DT->getNode(PredBB))) {
131ff0cc061SDimitry Andric         IsNewIDom[Idx] = false;
132ff0cc061SDimitry Andric         break;
133ff0cc061SDimitry Andric       }
134ff0cc061SDimitry Andric     }
135ff0cc061SDimitry Andric     ++Idx;
136ff0cc061SDimitry Andric   }
137ff0cc061SDimitry Andric 
138ff0cc061SDimitry Andric   // Now, update DT with the collected dominance properties info.
139ff0cc061SDimitry Andric   Idx = 0;
140ff0cc061SDimitry Andric   for (CriticalEdge &Edge : CriticalEdgesToSplit) {
141ff0cc061SDimitry Andric     // We know FromBB dominates NewBB.
142ff0cc061SDimitry Andric     MachineDomTreeNode *NewDTNode = DT->addNewBlock(Edge.NewBB, Edge.FromBB);
143ff0cc061SDimitry Andric 
144ff0cc061SDimitry Andric     // If all the other predecessors of "Succ" are dominated by "Succ" itself
145ff0cc061SDimitry Andric     // then the new block is the new immediate dominator of "Succ". Otherwise,
146ff0cc061SDimitry Andric     // the new block doesn't dominate anything.
147ff0cc061SDimitry Andric     if (IsNewIDom[Idx])
148ff0cc061SDimitry Andric       DT->changeImmediateDominator(DT->getNode(Edge.ToBB), NewDTNode);
149ff0cc061SDimitry Andric     ++Idx;
150ff0cc061SDimitry Andric   }
151ff0cc061SDimitry Andric   NewBBs.clear();
152ff0cc061SDimitry Andric   CriticalEdgesToSplit.clear();
153ff0cc061SDimitry Andric }
154