xref: /aosp_15_r20/external/llvm/lib/CodeGen/MachineDominators.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
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