Chromium Code Reviews| 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 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 77 // computePredecessors() pass finalizes it by creating the InEdges list. | 77 // computePredecessors() pass finalizes it by creating the InEdges list. |
| 78 void CfgNode::computePredecessors() { | 78 void CfgNode::computePredecessors() { |
| 79 for (CfgNode *Succ : OutEdges) | 79 for (CfgNode *Succ : OutEdges) |
| 80 Succ->InEdges.push_back(this); | 80 Succ->InEdges.push_back(this); |
| 81 } | 81 } |
| 82 | 82 |
| 83 void CfgNode::computeSuccessors() { | 83 void CfgNode::computeSuccessors() { |
| 84 OutEdges = Insts.rbegin()->getTerminatorEdges(); | 84 OutEdges = Insts.rbegin()->getTerminatorEdges(); |
| 85 } | 85 } |
| 86 | 86 |
| 87 // Validate each Phi instruction in the node with respect to control flow. For | 87 // Ensure each Phi instruction in the node is consistent with respect to control |
| 88 // every phi argument, its label must appear in the predecessor list. For each | 88 // flow. For each predecessor, there must be a phi argument with that label. |
| 89 // predecessor, there must be a phi argument with that label. We don't check | 89 // For every phi argument, its label must appear in the predecessor list or the |
| 90 // that phi arguments with the same label have the same value. | 90 // value must be zero. The latter allows us to remove some dead control flow |
|
Jim Stichnoth
2016/04/04 15:50:31
I suggest this change of the "For every phi argume
sehr
2016/04/04 17:06:41
Done.
| |
| 91 void CfgNode::validatePhis() { | 91 // without a major rework of the phi nodes. We don't check that phi arguments |
|
Jim Stichnoth
2016/04/04 15:50:31
I prefer "phi instruction" over "phi node", but yo
sehr
2016/04/04 17:06:41
Done.
| |
| 92 // with the same label have the same value. | |
| 93 void CfgNode::enforcePhiConsistency() { | |
| 92 for (Inst &Instr : Phis) { | 94 for (Inst &Instr : Phis) { |
| 93 auto *Phi = llvm::cast<InstPhi>(&Instr); | 95 auto *Phi = llvm::cast<InstPhi>(&Instr); |
| 94 // We do a simple O(N^2) algorithm to check for consistency. Even so, it | 96 // We do a simple O(N^2) algorithm to check for consistency. Even so, it |
| 95 // shows up as only about 0.2% of the total translation time. But if | 97 // shows up as only about 0.2% of the total translation time. But if |
| 96 // necessary, we could improve the complexity by using a hash table to | 98 // necessary, we could improve the complexity by using a hash table to |
| 97 // count how many times each node is referenced in the Phi instruction, and | 99 // count how many times each node is referenced in the Phi instruction, and |
| 98 // how many times each node is referenced in the incoming edge list, and | 100 // how many times each node is referenced in the incoming edge list, and |
| 99 // compare the two for equality. | 101 // compare the two for equality. |
| 100 for (SizeT i = 0; i < Phi->getSrcSize(); ++i) { | 102 for (SizeT i = 0; i < Phi->getSrcSize(); ++i) { |
| 101 CfgNode *Label = Phi->getLabel(i); | 103 CfgNode *Label = Phi->getLabel(i); |
| 102 bool Found = false; | 104 bool Found = false; |
| 103 for (CfgNode *InNode : getInEdges()) { | 105 for (CfgNode *InNode : getInEdges()) { |
| 104 if (InNode == Label) { | 106 if (InNode == Label) { |
| 105 Found = true; | 107 Found = true; |
| 106 break; | 108 break; |
| 107 } | 109 } |
| 108 } | 110 } |
| 109 if (!Found) | 111 if (!Found) { |
| 110 llvm::report_fatal_error("Phi error: label for bad incoming edge"); | 112 // Predecessor was unreachable, so if (impossibly) the control flow |
| 113 // enters from that predecessor, the value should be zero. | |
| 114 Phi->clearOperandForTarget(Label); | |
| 115 } | |
| 111 } | 116 } |
| 112 for (CfgNode *InNode : getInEdges()) { | 117 for (CfgNode *InNode : getInEdges()) { |
| 113 bool Found = false; | 118 bool Found = false; |
| 114 for (SizeT i = 0; i < Phi->getSrcSize(); ++i) { | 119 for (SizeT i = 0; i < Phi->getSrcSize(); ++i) { |
| 115 CfgNode *Label = Phi->getLabel(i); | 120 CfgNode *Label = Phi->getLabel(i); |
| 116 if (InNode == Label) { | 121 if (InNode == Label) { |
| 117 Found = true; | 122 Found = true; |
| 118 break; | 123 break; |
| 119 } | 124 } |
| 120 } | 125 } |
| (...skipping 1334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1455 auto *Instr = InstIntrinsicCall::create( | 1460 auto *Instr = InstIntrinsicCall::create( |
| 1456 Func, 5, Func->makeVariable(IceType_i64), RMWI64Name, Info->Info); | 1461 Func, 5, Func->makeVariable(IceType_i64), RMWI64Name, Info->Info); |
| 1457 Instr->addArg(AtomicRMWOp); | 1462 Instr->addArg(AtomicRMWOp); |
| 1458 Instr->addArg(Counter); | 1463 Instr->addArg(Counter); |
| 1459 Instr->addArg(One); | 1464 Instr->addArg(One); |
| 1460 Instr->addArg(OrderAcquireRelease); | 1465 Instr->addArg(OrderAcquireRelease); |
| 1461 Insts.push_front(Instr); | 1466 Insts.push_front(Instr); |
| 1462 } | 1467 } |
| 1463 | 1468 |
| 1464 } // end of namespace Ice | 1469 } // end of namespace Ice |
| OLD | NEW |