Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 //===- subzero/src/IceCfg.cpp - Control flow graph implementation ---------===// | 1 //===- subzero/src/IceCfg.cpp - Control flow graph implementation ---------===// |
| 2 // | 2 // |
| 3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
| 4 // | 4 // |
| 5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
| 6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
| 7 // | 7 // |
| 8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
| 9 // | 9 // |
| 10 // This file implements the Cfg class, including constant pool | 10 // This file implements the Cfg class, including constant pool |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 109 for (CfgNode *Node : Nodes) | 109 for (CfgNode *Node : Nodes) |
| 110 Node->placePhiStores(); | 110 Node->placePhiStores(); |
| 111 } | 111 } |
| 112 | 112 |
| 113 void Cfg::deletePhis() { | 113 void Cfg::deletePhis() { |
| 114 TimerMarker T(TimerStack::TT_deletePhis, this); | 114 TimerMarker T(TimerStack::TT_deletePhis, this); |
| 115 for (CfgNode *Node : Nodes) | 115 for (CfgNode *Node : Nodes) |
| 116 Node->deletePhis(); | 116 Node->deletePhis(); |
| 117 } | 117 } |
| 118 | 118 |
| 119 void Cfg::advancedPhiLowering() { | |
| 120 TimerMarker T(TimerStack::TT_advancedPhiLowering, this); | |
| 121 // This splits edges and appends new nodes to the end of the node | |
| 122 // list. This can invalidate iterators, so don't use an iterator. | |
| 123 SizeT NumNodes = getNumNodes(); | |
| 124 for (SizeT I = 0; I < NumNodes; ++I) | |
| 125 Nodes[I]->advancedPhiLowering(); | |
| 126 } | |
| 127 | |
| 128 // Find a reasonable placement for nodes that have not yet been | |
| 129 // placed, while maintaining the same relative ordering among already | |
| 130 // placed nodes. | |
| 131 void Cfg::reorderNodes() { | |
| 132 typedef std::list<CfgNode *> PlacedList; | |
| 133 PlacedList Placed, Unplaced, Extra; | |
| 134 PlacedList::iterator NoPlace = Placed.end(); | |
| 135 // Keep track of where each node has been tentatively placed so that | |
| 136 // we can manage insertions into the middle. | |
| 137 std::vector<PlacedList::iterator> PlaceIndex(Nodes.size(), NoPlace); | |
| 138 for (CfgNode *Node : Nodes) { | |
| 139 // The "do ... while(0);" construct is to factor out the | |
| 140 // --PlaceIndex and assert() statements before moving to the next | |
| 141 // node. | |
| 142 do { | |
| 143 if (!Node->needsPlacement()) { | |
| 144 // Add to the end of the Placed list. | |
| 145 Placed.push_back(Node); | |
| 146 PlaceIndex[Node->getIndex()] = Placed.end(); | |
| 147 continue; | |
| 148 } | |
| 149 Node->setNeedsPlacement(false); | |
| 150 if (Node != getEntryNode() && Node->getInEdges().size() == 0) { | |
| 151 // The node has essentially been deleted since it is not a | |
| 152 // successor of any other node. | |
| 153 Extra.push_back(Node); | |
| 154 PlaceIndex[Node->getIndex()] = Extra.end(); | |
| 155 continue; | |
| 156 } | |
| 157 // Assume for now that the unplaced node is from edge-splitting | |
| 158 // and therefore has 1 in-edge and 1 out-edge (actually, possibly | |
| 159 // more than 1 in-edge if the predecessor node was contracted). | |
| 160 // If this changes in the future, rethink the strategy. | |
| 161 assert(Node->getInEdges().size() >= 1); | |
| 162 assert(Node->getOutEdges().size() == 1); | |
| 163 | |
| 164 // If it's a (non-critical) edge where the successor has a single | |
| 165 // in-edge, then place it before the successor. | |
| 166 CfgNode *Succ = Node->getOutEdges()[0]; | |
| 167 if (Succ->getInEdges().size() == 1 && | |
| 168 PlaceIndex[Succ->getIndex()] != NoPlace) { | |
| 169 Placed.insert(PlaceIndex[Succ->getIndex()], Node); | |
| 170 PlaceIndex[Node->getIndex()] = PlaceIndex[Succ->getIndex()]; | |
| 171 continue; | |
| 172 } | |
| 173 | |
| 174 // Otherwise, place it after the (first) predecessor. | |
| 175 CfgNode *Pred = Node->getInEdges()[0]; | |
| 176 auto PredPosition = PlaceIndex[Pred->getIndex()]; | |
| 177 if (PredPosition == NoPlace) { | |
| 178 Unplaced.push_back(Node); | |
| 179 PlaceIndex[Node->getIndex()] = Unplaced.end(); | |
| 180 continue; | |
| 181 } | |
| 182 ++PredPosition; | |
| 183 Placed.insert(PredPosition, Node); | |
| 184 PlaceIndex[Node->getIndex()] = PredPosition; | |
| 185 } while (0); | |
| 186 | |
| 187 --PlaceIndex[Node->getIndex()]; | |
| 188 assert(*PlaceIndex[Node->getIndex()] == Node); | |
| 189 } | |
| 190 | |
| 191 // Reorder Nodes according to the built-up lists. | |
| 192 SizeT Cur = 0; | |
| 193 for (CfgNode *Node : Placed) | |
| 194 Nodes[Cur++] = Node; | |
|
jvoung (off chromium)
2014/10/27 22:12:20
Would it be good to renumber the nodes too (the "N
Jim Stichnoth
2014/10/28 01:20:14
There is also the issue that Liveness and Variable
| |
| 195 for (CfgNode *Node : Unplaced) | |
| 196 Nodes[Cur++] = Node; | |
| 197 for (CfgNode *Node : Extra) | |
| 198 Nodes[Cur++] = Node; | |
| 199 assert(Cur == Nodes.size()); | |
| 200 } | |
| 201 | |
| 119 void Cfg::doArgLowering() { | 202 void Cfg::doArgLowering() { |
| 120 TimerMarker T(TimerStack::TT_doArgLowering, this); | 203 TimerMarker T(TimerStack::TT_doArgLowering, this); |
| 121 getTarget()->lowerArguments(); | 204 getTarget()->lowerArguments(); |
| 122 } | 205 } |
| 123 | 206 |
| 124 void Cfg::doAddressOpt() { | 207 void Cfg::doAddressOpt() { |
| 125 TimerMarker T(TimerStack::TT_doAddressOpt, this); | 208 TimerMarker T(TimerStack::TT_doAddressOpt, this); |
| 126 for (CfgNode *Node : Nodes) | 209 for (CfgNode *Node : Nodes) |
| 127 Node->doAddressOpt(); | 210 Node->doAddressOpt(); |
| 128 } | 211 } |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 290 // liveness inconsistencies. | 373 // liveness inconsistencies. |
| 291 void Cfg::deleteRedundantAssignments() { | 374 void Cfg::deleteRedundantAssignments() { |
| 292 for (CfgNode *Node : Nodes) { | 375 for (CfgNode *Node : Nodes) { |
| 293 // Ignore Phi instructions. | 376 // Ignore Phi instructions. |
| 294 for (Inst *I : Node->getInsts()) | 377 for (Inst *I : Node->getInsts()) |
| 295 if (I->isRedundantAssign()) | 378 if (I->isRedundantAssign()) |
| 296 I->setDeleted(); | 379 I->setDeleted(); |
| 297 } | 380 } |
| 298 } | 381 } |
| 299 | 382 |
| 383 void Cfg::contractEmptyNodes() { | |
| 384 for (CfgNode *Node : Nodes) { | |
| 385 Node->contractIfEmpty(); | |
| 386 } | |
| 387 } | |
| 388 | |
| 300 void Cfg::doBranchOpt() { | 389 void Cfg::doBranchOpt() { |
| 301 TimerMarker T(TimerStack::TT_doBranchOpt, this); | 390 TimerMarker T(TimerStack::TT_doBranchOpt, this); |
| 302 for (auto I = Nodes.begin(), E = Nodes.end(); I != E; ++I) { | 391 for (auto I = Nodes.begin(), E = Nodes.end(); I != E; ++I) { |
| 303 auto NextNode = I; | 392 auto NextNode = I; |
| 304 ++NextNode; | 393 ++NextNode; |
| 305 (*I)->doBranchOpt(NextNode == E ? NULL : *NextNode); | 394 (*I)->doBranchOpt(NextNode == E ? NULL : *NextNode); |
| 306 } | 395 } |
| 307 } | 396 } |
| 308 | 397 |
| 309 // ======================== Dump routines ======================== // | 398 // ======================== Dump routines ======================== // |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 376 } | 465 } |
| 377 } | 466 } |
| 378 // Print each basic block | 467 // Print each basic block |
| 379 for (CfgNode *Node : Nodes) | 468 for (CfgNode *Node : Nodes) |
| 380 Node->dump(this); | 469 Node->dump(this); |
| 381 if (getContext()->isVerbose(IceV_Instructions)) | 470 if (getContext()->isVerbose(IceV_Instructions)) |
| 382 Str << "}\n"; | 471 Str << "}\n"; |
| 383 } | 472 } |
| 384 | 473 |
| 385 } // end of namespace Ice | 474 } // end of namespace Ice |
| OLD | NEW |