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