| Owen Anderson | 9b8f34f | 2007-10-31 03:30:14 +0000 | [diff] [blame] | 1 | //===- MachineDominators.cpp - Machine Dominator Calculation --------------===// | 
|  | 2 | // | 
| Chandler Carruth | 2946cd7 | 2019-01-19 08:50:56 +0000 | [diff] [blame] | 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | 
|  | 4 | // See https://llvm.org/LICENSE.txt for license information. | 
|  | 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | 
| Owen Anderson | 9b8f34f | 2007-10-31 03:30:14 +0000 | [diff] [blame] | 6 | // | 
|  | 7 | //===----------------------------------------------------------------------===// | 
|  | 8 | // | 
|  | 9 | // This file implements simple dominator construction algorithms for finding | 
|  | 10 | // forward dominators on machine functions. | 
|  | 11 | // | 
|  | 12 | //===----------------------------------------------------------------------===// | 
|  | 13 |  | 
|  | 14 | #include "llvm/CodeGen/MachineDominators.h" | 
| Benjamin Kramer | 012b151 | 2015-02-27 23:13:13 +0000 | [diff] [blame] | 15 | #include "llvm/ADT/SmallBitVector.h" | 
| Chandler Carruth | 6bda14b | 2017-06-06 11:49:48 +0000 | [diff] [blame] | 16 | #include "llvm/CodeGen/Passes.h" | 
| Reid Kleckner | 05da2fe | 2019-11-13 13:15:01 -0800 | [diff] [blame] | 17 | #include "llvm/InitializePasses.h" | 
| Chad Rosier | fd342808 | 2016-06-24 13:32:22 +0000 | [diff] [blame] | 18 | #include "llvm/Support/CommandLine.h" | 
| Owen Anderson | 9b8f34f | 2007-10-31 03:30:14 +0000 | [diff] [blame] | 19 |  | 
|  | 20 | using namespace llvm; | 
|  | 21 |  | 
| Jakub Kuderski | 56b52a2 | 2019-10-01 15:23:27 +0000 | [diff] [blame] | 22 | namespace llvm { | 
| Chad Rosier | e2185fd | 2016-06-24 17:15:04 +0000 | [diff] [blame] | 23 | // Always verify dominfo if expensive checking is enabled. | 
| Chad Rosier | fd342808 | 2016-06-24 13:32:22 +0000 | [diff] [blame] | 24 | #ifdef EXPENSIVE_CHECKS | 
| Jakub Kuderski | 56b52a2 | 2019-10-01 15:23:27 +0000 | [diff] [blame] | 25 | bool VerifyMachineDomInfo = true; | 
| Chad Rosier | fd342808 | 2016-06-24 13:32:22 +0000 | [diff] [blame] | 26 | #else | 
| Jakub Kuderski | 56b52a2 | 2019-10-01 15:23:27 +0000 | [diff] [blame] | 27 | bool VerifyMachineDomInfo = false; | 
| Chad Rosier | fd342808 | 2016-06-24 13:32:22 +0000 | [diff] [blame] | 28 | #endif | 
| Jakub Kuderski | 56b52a2 | 2019-10-01 15:23:27 +0000 | [diff] [blame] | 29 | } // namespace llvm | 
|  | 30 |  | 
| Chad Rosier | fd342808 | 2016-06-24 13:32:22 +0000 | [diff] [blame] | 31 | static cl::opt<bool, true> VerifyMachineDomInfoX( | 
| Zachary Turner | 8065f0b | 2017-12-01 00:53:10 +0000 | [diff] [blame] | 32 | "verify-machine-dom-info", cl::location(VerifyMachineDomInfo), cl::Hidden, | 
| Chad Rosier | fd342808 | 2016-06-24 13:32:22 +0000 | [diff] [blame] | 33 | cl::desc("Verify machine dominator info (time consuming)")); | 
|  | 34 |  | 
| John McCall | 323c30c | 2009-12-16 00:13:24 +0000 | [diff] [blame] | 35 | namespace llvm { | 
| Benjamin Kramer | a667d1a | 2015-07-13 17:21:31 +0000 | [diff] [blame] | 36 | template class DomTreeNodeBase<MachineBasicBlock>; | 
| Jakub Kuderski | b292c22 | 2017-07-14 18:26:09 +0000 | [diff] [blame] | 37 | template class DominatorTreeBase<MachineBasicBlock, false>; // DomTreeBase | 
| John McCall | 323c30c | 2009-12-16 00:13:24 +0000 | [diff] [blame] | 38 | } | 
| Owen Anderson | 9b8f34f | 2007-10-31 03:30:14 +0000 | [diff] [blame] | 39 |  | 
| Chris Lattner | 647e61a | 2008-01-05 20:15:42 +0000 | [diff] [blame] | 40 | char MachineDominatorTree::ID = 0; | 
|  | 41 |  | 
| Owen Anderson | d31d82d | 2010-08-23 17:52:01 +0000 | [diff] [blame] | 42 | INITIALIZE_PASS(MachineDominatorTree, "machinedomtree", | 
| Owen Anderson | df7a4f2 | 2010-10-07 22:25:06 +0000 | [diff] [blame] | 43 | "MachineDominator Tree Construction", true, true) | 
| Bill Wendling | 0c20943 | 2008-01-04 20:54:55 +0000 | [diff] [blame] | 44 |  | 
| Owen Anderson | a7aed18 | 2010-08-06 18:33:48 +0000 | [diff] [blame] | 45 | char &llvm::MachineDominatorsID = MachineDominatorTree::ID; | 
| Dan Gohman | 906152a | 2009-01-05 17:59:02 +0000 | [diff] [blame] | 46 |  | 
|  | 47 | void MachineDominatorTree::getAnalysisUsage(AnalysisUsage &AU) const { | 
|  | 48 | AU.setPreservesAll(); | 
|  | 49 | MachineFunctionPass::getAnalysisUsage(AU); | 
|  | 50 | } | 
|  | 51 |  | 
|  | 52 | bool MachineDominatorTree::runOnMachineFunction(MachineFunction &F) { | 
| Hiroshi Yamauchi | 75f72f6 | 2019-10-28 12:35:34 -0700 | [diff] [blame] | 53 | calculate(F); | 
|  | 54 | return false; | 
|  | 55 | } | 
|  | 56 |  | 
|  | 57 | void MachineDominatorTree::calculate(MachineFunction &F) { | 
| Quentin Colombet | abea99f | 2014-08-13 21:00:07 +0000 | [diff] [blame] | 58 | CriticalEdgesToSplit.clear(); | 
|  | 59 | NewBBs.clear(); | 
| Jakub Kuderski | b292c22 | 2017-07-14 18:26:09 +0000 | [diff] [blame] | 60 | DT.reset(new DomTreeBase<MachineBasicBlock>()); | 
| Dan Gohman | 906152a | 2009-01-05 17:59:02 +0000 | [diff] [blame] | 61 | DT->recalculate(F); | 
| Dan Gohman | 906152a | 2009-01-05 17:59:02 +0000 | [diff] [blame] | 62 | } | 
|  | 63 |  | 
|  | 64 | MachineDominatorTree::MachineDominatorTree() | 
| Owen Anderson | a7aed18 | 2010-08-06 18:33:48 +0000 | [diff] [blame] | 65 | : MachineFunctionPass(ID) { | 
| Owen Anderson | 6c18d1a | 2010-10-19 17:21:58 +0000 | [diff] [blame] | 66 | initializeMachineDominatorTreePass(*PassRegistry::getPassRegistry()); | 
| Dan Gohman | 906152a | 2009-01-05 17:59:02 +0000 | [diff] [blame] | 67 | } | 
|  | 68 |  | 
|  | 69 | void MachineDominatorTree::releaseMemory() { | 
| Serge Pavlov | e2bf697 | 2017-03-02 12:00:10 +0000 | [diff] [blame] | 70 | CriticalEdgesToSplit.clear(); | 
|  | 71 | DT.reset(nullptr); | 
| Dan Gohman | 906152a | 2009-01-05 17:59:02 +0000 | [diff] [blame] | 72 | } | 
| Chris Lattner | b1d782b | 2009-08-23 05:17:37 +0000 | [diff] [blame] | 73 |  | 
| Chad Rosier | fd342808 | 2016-06-24 13:32:22 +0000 | [diff] [blame] | 74 | void MachineDominatorTree::verifyAnalysis() const { | 
| Jakub Kuderski | 925c285 | 2019-10-01 18:27:14 +0000 | [diff] [blame] | 75 | if (DT && VerifyMachineDomInfo) | 
|  | 76 | if (!DT->verify(DomTreeT::VerificationLevel::Basic)) { | 
|  | 77 | errs() << "MachineDominatorTree verification failed\n"; | 
| David Green | 7c35de1 | 2018-02-28 11:00:08 +0000 | [diff] [blame] | 78 | abort(); | 
|  | 79 | } | 
| Chad Rosier | fd342808 | 2016-06-24 13:32:22 +0000 | [diff] [blame] | 80 | } | 
|  | 81 |  | 
| Chris Lattner | 1362602 | 2009-08-23 06:03:38 +0000 | [diff] [blame] | 82 | void MachineDominatorTree::print(raw_ostream &OS, const Module*) const { | 
| Serge Pavlov | e2bf697 | 2017-03-02 12:00:10 +0000 | [diff] [blame] | 83 | if (DT) | 
|  | 84 | DT->print(OS); | 
| Chris Lattner | b1d782b | 2009-08-23 05:17:37 +0000 | [diff] [blame] | 85 | } | 
| Benjamin Kramer | 012b151 | 2015-02-27 23:13:13 +0000 | [diff] [blame] | 86 |  | 
|  | 87 | void MachineDominatorTree::applySplitCriticalEdges() const { | 
|  | 88 | // Bail out early if there is nothing to do. | 
|  | 89 | if (CriticalEdgesToSplit.empty()) | 
|  | 90 | return; | 
|  | 91 |  | 
|  | 92 | // For each element in CriticalEdgesToSplit, remember whether or not element | 
|  | 93 | // is the new immediate domminator of its successor. The mapping is done by | 
|  | 94 | // index, i.e., the information for the ith element of CriticalEdgesToSplit is | 
|  | 95 | // the ith element of IsNewIDom. | 
|  | 96 | SmallBitVector IsNewIDom(CriticalEdgesToSplit.size(), true); | 
|  | 97 | size_t Idx = 0; | 
|  | 98 |  | 
|  | 99 | // Collect all the dominance properties info, before invalidating | 
|  | 100 | // the underlying DT. | 
|  | 101 | for (CriticalEdge &Edge : CriticalEdgesToSplit) { | 
|  | 102 | // Update dominator information. | 
|  | 103 | MachineBasicBlock *Succ = Edge.ToBB; | 
|  | 104 | MachineDomTreeNode *SuccDTNode = DT->getNode(Succ); | 
|  | 105 |  | 
|  | 106 | for (MachineBasicBlock *PredBB : Succ->predecessors()) { | 
|  | 107 | if (PredBB == Edge.NewBB) | 
|  | 108 | continue; | 
|  | 109 | // If we are in this situation: | 
|  | 110 | // FromBB1        FromBB2 | 
|  | 111 | //    +              + | 
|  | 112 | //   + +            + + | 
|  | 113 | //  +   +          +   + | 
|  | 114 | // ...  Split1  Split2 ... | 
|  | 115 | //           +   + | 
|  | 116 | //            + + | 
|  | 117 | //             + | 
|  | 118 | //            Succ | 
|  | 119 | // Instead of checking the domiance property with Split2, we check it with | 
|  | 120 | // FromBB2 since Split2 is still unknown of the underlying DT structure. | 
|  | 121 | if (NewBBs.count(PredBB)) { | 
|  | 122 | assert(PredBB->pred_size() == 1 && "A basic block resulting from a " | 
|  | 123 | "critical edge split has more " | 
|  | 124 | "than one predecessor!"); | 
|  | 125 | PredBB = *PredBB->pred_begin(); | 
|  | 126 | } | 
|  | 127 | if (!DT->dominates(SuccDTNode, DT->getNode(PredBB))) { | 
|  | 128 | IsNewIDom[Idx] = false; | 
|  | 129 | break; | 
|  | 130 | } | 
|  | 131 | } | 
|  | 132 | ++Idx; | 
|  | 133 | } | 
|  | 134 |  | 
|  | 135 | // Now, update DT with the collected dominance properties info. | 
|  | 136 | Idx = 0; | 
|  | 137 | for (CriticalEdge &Edge : CriticalEdgesToSplit) { | 
|  | 138 | // We know FromBB dominates NewBB. | 
|  | 139 | MachineDomTreeNode *NewDTNode = DT->addNewBlock(Edge.NewBB, Edge.FromBB); | 
|  | 140 |  | 
|  | 141 | // If all the other predecessors of "Succ" are dominated by "Succ" itself | 
|  | 142 | // then the new block is the new immediate dominator of "Succ". Otherwise, | 
|  | 143 | // the new block doesn't dominate anything. | 
|  | 144 | if (IsNewIDom[Idx]) | 
|  | 145 | DT->changeImmediateDominator(DT->getNode(Edge.ToBB), NewDTNode); | 
|  | 146 | ++Idx; | 
|  | 147 | } | 
|  | 148 | NewBBs.clear(); | 
|  | 149 | CriticalEdgesToSplit.clear(); | 
|  | 150 | } |