OLD | NEW |
1 //===- subzero/src/IceCfgNode.cpp - Basic block (node) implementation -----===// | 1 //===- subzero/src/IceCfgNode.cpp - Basic block (node) 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 /// \file | 10 /// \file |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
73 // creating the InEdges list. | 73 // creating the InEdges list. |
74 void CfgNode::computePredecessors() { | 74 void CfgNode::computePredecessors() { |
75 for (CfgNode *Succ : OutEdges) | 75 for (CfgNode *Succ : OutEdges) |
76 Succ->InEdges.push_back(this); | 76 Succ->InEdges.push_back(this); |
77 } | 77 } |
78 | 78 |
79 void CfgNode::computeSuccessors() { | 79 void CfgNode::computeSuccessors() { |
80 OutEdges = Insts.rbegin()->getTerminatorEdges(); | 80 OutEdges = Insts.rbegin()->getTerminatorEdges(); |
81 } | 81 } |
82 | 82 |
| 83 // Validate each Phi instruction in the node with respect to control flow. For |
| 84 // every phi argument, its label must appear in the predecessor list. For each |
| 85 // predecessor, there must be a phi argument with that label. We don't check |
| 86 // that phi arguments with the same label have the same value. |
| 87 void CfgNode::validatePhis() { |
| 88 for (Inst &Instr : Phis) { |
| 89 auto *Phi = llvm::cast<InstPhi>(&Instr); |
| 90 // We do a simple O(N^2) algorithm to check for consistency. Even so, it |
| 91 // shows up as only about 0.2% of the total translation time. But if |
| 92 // necessary, we could improve the complexity by using a hash table to count |
| 93 // how many times each node is referenced in the Phi instruction, and how |
| 94 // many times each node is referenced in the incoming edge list, and compare |
| 95 // the two for equality. |
| 96 for (SizeT i = 0; i < Phi->getSrcSize(); ++i) { |
| 97 CfgNode *Label = Phi->getLabel(i); |
| 98 bool Found = false; |
| 99 for (CfgNode *InNode : getInEdges()) { |
| 100 if (InNode == Label) { |
| 101 Found = true; |
| 102 break; |
| 103 } |
| 104 } |
| 105 if (!Found) |
| 106 llvm::report_fatal_error("Phi error: label for bad incoming edge"); |
| 107 } |
| 108 for (CfgNode *InNode : getInEdges()) { |
| 109 bool Found = false; |
| 110 for (SizeT i = 0; i < Phi->getSrcSize(); ++i) { |
| 111 CfgNode *Label = Phi->getLabel(i); |
| 112 if (InNode == Label) { |
| 113 Found = true; |
| 114 break; |
| 115 } |
| 116 } |
| 117 if (!Found) |
| 118 llvm::report_fatal_error("Phi error: missing label for incoming edge"); |
| 119 } |
| 120 } |
| 121 } |
| 122 |
83 // This does part 1 of Phi lowering, by creating a new dest variable | 123 // This does part 1 of Phi lowering, by creating a new dest variable |
84 // for each Phi instruction, replacing the Phi instruction's dest with | 124 // for each Phi instruction, replacing the Phi instruction's dest with |
85 // that variable, and adding an explicit assignment of the old dest to | 125 // that variable, and adding an explicit assignment of the old dest to |
86 // the new dest. For example, | 126 // the new dest. For example, |
87 // a=phi(...) | 127 // a=phi(...) |
88 // changes to | 128 // changes to |
89 // "a_phi=phi(...); a=a_phi". | 129 // "a_phi=phi(...); a=a_phi". |
90 // | 130 // |
91 // This is in preparation for part 2 which deletes the Phi | 131 // This is in preparation for part 2 which deletes the Phi |
92 // instructions and appends assignment instructions to predecessor | 132 // instructions and appends assignment instructions to predecessor |
(...skipping 1194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1287 InstIntrinsicCall *Inst = InstIntrinsicCall::create( | 1327 InstIntrinsicCall *Inst = InstIntrinsicCall::create( |
1288 Func, 5, Func->makeVariable(IceType_i64), RMWI64Name, Info->Info); | 1328 Func, 5, Func->makeVariable(IceType_i64), RMWI64Name, Info->Info); |
1289 Inst->addArg(AtomicRMWOp); | 1329 Inst->addArg(AtomicRMWOp); |
1290 Inst->addArg(Counter); | 1330 Inst->addArg(Counter); |
1291 Inst->addArg(One); | 1331 Inst->addArg(One); |
1292 Inst->addArg(OrderAcquireRelease); | 1332 Inst->addArg(OrderAcquireRelease); |
1293 Insts.push_front(Inst); | 1333 Insts.push_front(Inst); |
1294 } | 1334 } |
1295 | 1335 |
1296 } // end of namespace Ice | 1336 } // end of namespace Ice |
OLD | NEW |