| 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 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 206 void CfgNode::deletePhis() { | 206 void CfgNode::deletePhis() { |
| 207 for (Inst &I : Phis) | 207 for (Inst &I : Phis) |
| 208 I.setDeleted(); | 208 I.setDeleted(); |
| 209 } | 209 } |
| 210 | 210 |
| 211 // Splits the edge from Pred to this node by creating a new node and | 211 // Splits the edge from Pred to this node by creating a new node and |
| 212 // hooking up the in and out edges appropriately. (The EdgeIndex | 212 // hooking up the in and out edges appropriately. (The EdgeIndex |
| 213 // parameter is only used to make the new node's name unique when | 213 // parameter is only used to make the new node's name unique when |
| 214 // there are multiple edges between the same pair of nodes.) The new | 214 // there are multiple edges between the same pair of nodes.) The new |
| 215 // node's instruction list is initialized to the empty list, with no | 215 // node's instruction list is initialized to the empty list, with no |
| 216 // terminator instruction. If there are multiple edges from Pred to | 216 // terminator instruction. There must not be multiple edges from Pred |
| 217 // this node, only one edge is split, and the particular choice of | 217 // to this node so all Inst::getTerminatorEdges implementations must |
| 218 // edge is undefined. This could happen with a switch instruction, or | 218 // not contain duplicates. |
| 219 // a conditional branch that weirdly has both branches to the same | |
| 220 // place. TODO(stichnot,kschimpf): Figure out whether this is legal | |
| 221 // in the LLVM IR or the PNaCl bitcode, and if so, we need to | |
| 222 // establish a strong relationship among the ordering of Pred's | |
| 223 // out-edge list, this node's in-edge list, and the Phi instruction's | |
| 224 // operand list. | |
| 225 CfgNode *CfgNode::splitIncomingEdge(CfgNode *Pred, SizeT EdgeIndex) { | 219 CfgNode *CfgNode::splitIncomingEdge(CfgNode *Pred, SizeT EdgeIndex) { |
| 226 CfgNode *NewNode = Func->makeNode(); | 220 CfgNode *NewNode = Func->makeNode(); |
| 227 if (BuildDefs::dump()) | 221 if (BuildDefs::dump()) |
| 228 NewNode->setName("split_" + Pred->getName() + "_" + getName() + "_" + | 222 NewNode->setName("split_" + Pred->getName() + "_" + getName() + "_" + |
| 229 std::to_string(EdgeIndex)); | 223 std::to_string(EdgeIndex)); |
| 230 // The new node is added to the end of the node list, and will later | 224 // The new node is added to the end of the node list, and will later |
| 231 // need to be sorted into a reasonable topological order. | 225 // need to be sorted into a reasonable topological order. |
| 232 NewNode->setNeedsPlacement(true); | 226 NewNode->setNeedsPlacement(true); |
| 233 // Repoint Pred's out-edge. | 227 // Repoint Pred's out-edge. |
| 234 bool Found = false; | 228 bool Found = false; |
| 235 for (auto I = Pred->OutEdges.begin(), E = Pred->OutEdges.end(); | 229 for (CfgNode *&I : Pred->OutEdges) { |
| 236 !Found && I != E; ++I) { | 230 if (I == this) { |
| 237 if (*I == this) { | 231 I = NewNode; |
| 238 *I = NewNode; | |
| 239 NewNode->InEdges.push_back(Pred); | 232 NewNode->InEdges.push_back(Pred); |
| 240 Found = true; | 233 Found = true; |
| 234 break; |
| 241 } | 235 } |
| 242 } | 236 } |
| 243 assert(Found); | 237 assert(Found); |
| 244 // Repoint this node's in-edge. | 238 // Repoint this node's in-edge. |
| 245 Found = false; | 239 Found = false; |
| 246 for (auto I = InEdges.begin(), E = InEdges.end(); !Found && I != E; ++I) { | 240 for (CfgNode *&I : InEdges) { |
| 247 if (*I == Pred) { | 241 if (I == Pred) { |
| 248 *I = NewNode; | 242 I = NewNode; |
| 249 NewNode->OutEdges.push_back(this); | 243 NewNode->OutEdges.push_back(this); |
| 250 Found = true; | 244 Found = true; |
| 245 break; |
| 251 } | 246 } |
| 252 } | 247 } |
| 253 assert(Found); | 248 assert(Found); |
| 254 // Repoint a suitable branch instruction's target and return. | 249 // Repoint all suitable branch instructions' target and return. |
| 255 Found = false; | 250 Found = false; |
| 256 for (Inst &I : reverse_range(Pred->getInsts())) { | 251 for (Inst &I : Pred->getInsts()) |
| 257 if (!I.isDeleted() && I.repointEdge(this, NewNode)) | 252 if (!I.isDeleted() && I.repointEdges(this, NewNode)) |
| 258 return NewNode; | 253 Found = true; |
| 259 } | |
| 260 // This should be unreachable, so the assert will fail. | |
| 261 assert(Found); | 254 assert(Found); |
| 262 return NewNode; | 255 return NewNode; |
| 263 } | 256 } |
| 264 | 257 |
| 265 namespace { | 258 namespace { |
| 266 | 259 |
| 267 // Helper function used by advancedPhiLowering(). | 260 // Helper function used by advancedPhiLowering(). |
| 268 bool sameVarOrReg(const Variable *Var, const Operand *Opnd) { | 261 bool sameVarOrReg(const Variable *Var, const Operand *Opnd) { |
| 269 if (Var == Opnd) | 262 if (Var == Opnd) |
| 270 return true; | 263 return true; |
| (...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 745 for (CfgNode *Pred : InEdges) { | 738 for (CfgNode *Pred : InEdges) { |
| 746 for (auto I = Pred->OutEdges.begin(), E = Pred->OutEdges.end(); I != E; | 739 for (auto I = Pred->OutEdges.begin(), E = Pred->OutEdges.end(); I != E; |
| 747 ++I) { | 740 ++I) { |
| 748 if (*I == this) { | 741 if (*I == this) { |
| 749 *I = OutEdges.front(); | 742 *I = OutEdges.front(); |
| 750 OutEdges.front()->InEdges.push_back(Pred); | 743 OutEdges.front()->InEdges.push_back(Pred); |
| 751 } | 744 } |
| 752 } | 745 } |
| 753 for (Inst &I : Pred->getInsts()) { | 746 for (Inst &I : Pred->getInsts()) { |
| 754 if (!I.isDeleted()) | 747 if (!I.isDeleted()) |
| 755 I.repointEdge(this, OutEdges.front()); | 748 I.repointEdges(this, OutEdges.front()); |
| 756 } | 749 } |
| 757 } | 750 } |
| 758 } | 751 } |
| 759 InEdges.clear(); | 752 InEdges.clear(); |
| 760 // Don't bother removing the single out-edge, which would also | 753 // Don't bother removing the single out-edge, which would also |
| 761 // require finding the corresponding in-edge in the successor and | 754 // require finding the corresponding in-edge in the successor and |
| 762 // removing it. | 755 // removing it. |
| 763 } | 756 } |
| 764 | 757 |
| 765 void CfgNode::doBranchOpt(const CfgNode *NextNode) { | 758 void CfgNode::doBranchOpt(const CfgNode *NextNode) { |
| (...skipping 502 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1268 InstIntrinsicCall *Inst = InstIntrinsicCall::create( | 1261 InstIntrinsicCall *Inst = InstIntrinsicCall::create( |
| 1269 Func, 5, Func->makeVariable(IceType_i64), RMWI64Name, Info->Info); | 1262 Func, 5, Func->makeVariable(IceType_i64), RMWI64Name, Info->Info); |
| 1270 Inst->addArg(AtomicRMWOp); | 1263 Inst->addArg(AtomicRMWOp); |
| 1271 Inst->addArg(Counter); | 1264 Inst->addArg(Counter); |
| 1272 Inst->addArg(One); | 1265 Inst->addArg(One); |
| 1273 Inst->addArg(OrderAcquireRelease); | 1266 Inst->addArg(OrderAcquireRelease); |
| 1274 Insts.push_front(Inst); | 1267 Insts.push_front(Inst); |
| 1275 } | 1268 } |
| 1276 | 1269 |
| 1277 } // end of namespace Ice | 1270 } // end of namespace Ice |
| OLD | NEW |