| 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 // This file implements the CfgNode class, including the complexities | 10 // This file implements the CfgNode class, including the complexities |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 97 // all the assignments near the end of this block. They need to be | 97 // all the assignments near the end of this block. They need to be |
| 98 // added before any branch instruction, and also if the block ends | 98 // added before any branch instruction, and also if the block ends |
| 99 // with a compare instruction followed by a branch instruction that we | 99 // with a compare instruction followed by a branch instruction that we |
| 100 // may want to fuse, it's better to insert the new assignments before | 100 // may want to fuse, it's better to insert the new assignments before |
| 101 // the compare instruction. The tryOptimizedCmpxchgCmpBr() method | 101 // the compare instruction. The tryOptimizedCmpxchgCmpBr() method |
| 102 // assumes this ordering of instructions. | 102 // assumes this ordering of instructions. |
| 103 // | 103 // |
| 104 // Note that this transformation takes the Phi dest variables out of | 104 // Note that this transformation takes the Phi dest variables out of |
| 105 // SSA form, as there may be assignments to the dest variable in | 105 // SSA form, as there may be assignments to the dest variable in |
| 106 // multiple blocks. | 106 // multiple blocks. |
| 107 // | |
| 108 // TODO: Defer this pass until after register allocation, then split | |
| 109 // critical edges, add the assignments, and lower them. This should | |
| 110 // reduce the amount of shuffling at the end of each block. | |
| 111 void CfgNode::placePhiStores() { | 107 void CfgNode::placePhiStores() { |
| 112 // Find the insertion point. | 108 // Find the insertion point. |
| 113 InstList::iterator InsertionPoint = Insts.end(); | 109 InstList::iterator InsertionPoint = Insts.end(); |
| 114 // Every block must end in a terminator instruction, and therefore | 110 // Every block must end in a terminator instruction, and therefore |
| 115 // must have at least one instruction, so it's valid to decrement | 111 // must have at least one instruction, so it's valid to decrement |
| 116 // InsertionPoint (but assert just in case). | 112 // InsertionPoint (but assert just in case). |
| 117 assert(InsertionPoint != Insts.begin()); | 113 assert(InsertionPoint != Insts.begin()); |
| 118 --InsertionPoint; | 114 --InsertionPoint; |
| 119 // Confirm that InsertionPoint is a terminator instruction. Calling | 115 // Confirm that InsertionPoint is a terminator instruction. Calling |
| 120 // getTerminatorEdges() on a non-terminator instruction will cause | 116 // getTerminatorEdges() on a non-terminator instruction will cause |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 243 // Repoint this node's in-edge. | 239 // Repoint this node's in-edge. |
| 244 Found = false; | 240 Found = false; |
| 245 for (auto I = InEdges.begin(), E = InEdges.end(); !Found && I != E; ++I) { | 241 for (auto I = InEdges.begin(), E = InEdges.end(); !Found && I != E; ++I) { |
| 246 if (*I == Pred) { | 242 if (*I == Pred) { |
| 247 *I = NewNode; | 243 *I = NewNode; |
| 248 NewNode->OutEdges.push_back(this); | 244 NewNode->OutEdges.push_back(this); |
| 249 Found = true; | 245 Found = true; |
| 250 } | 246 } |
| 251 } | 247 } |
| 252 assert(Found); | 248 assert(Found); |
| 253 // Repoint a suitable branch instruction's target. | 249 // Repoint a suitable branch instruction's target and return. |
| 254 Found = false; | 250 Found = false; |
| 255 for (auto I = Pred->getInsts().rbegin(), E = Pred->getInsts().rend(); | 251 for (Inst &I : reverse_range(Pred->getInsts())) { |
| 256 !Found && I != E; ++I) { | 252 if (!I.isDeleted() && I.repointEdge(this, NewNode)) |
| 257 if (!I->isDeleted()) { | 253 return NewNode; |
| 258 Found = I->repointEdge(this, NewNode); | |
| 259 } | |
| 260 } | 254 } |
| 255 // This should be unreachable, so the assert will fail. |
| 261 assert(Found); | 256 assert(Found); |
| 262 return NewNode; | 257 return NewNode; |
| 263 } | 258 } |
| 264 | 259 |
| 265 namespace { | 260 namespace { |
| 266 | 261 |
| 267 // Helper function used by advancedPhiLowering(). | 262 // Helper function used by advancedPhiLowering(). |
| 268 bool sameVarOrReg(const Variable *Var, const Operand *Opnd) { | 263 bool sameVarOrReg(const Variable *Var, const Operand *Opnd) { |
| 269 if (Var == Opnd) | 264 if (Var == Opnd) |
| 270 return true; | 265 return true; |
| (...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 526 assert(Context.getCur() != Orig); | 521 assert(Context.getCur() != Orig); |
| 527 } | 522 } |
| 528 // Do preliminary lowering of the Phi instructions. | 523 // Do preliminary lowering of the Phi instructions. |
| 529 Target->prelowerPhis(); | 524 Target->prelowerPhis(); |
| 530 } | 525 } |
| 531 | 526 |
| 532 void CfgNode::livenessLightweight() { | 527 void CfgNode::livenessLightweight() { |
| 533 SizeT NumVars = Func->getNumVariables(); | 528 SizeT NumVars = Func->getNumVariables(); |
| 534 LivenessBV Live(NumVars); | 529 LivenessBV Live(NumVars); |
| 535 // Process regular instructions in reverse order. | 530 // Process regular instructions in reverse order. |
| 536 // TODO(stichnot): Use llvm::make_range with LLVM 3.5. | 531 for (Inst &I : reverse_range(Insts)) { |
| 537 for (auto I = Insts.rbegin(), E = Insts.rend(); I != E; ++I) { | 532 if (I.isDeleted()) |
| 538 if (I->isDeleted()) | |
| 539 continue; | 533 continue; |
| 540 I->livenessLightweight(Func, Live); | 534 I.livenessLightweight(Func, Live); |
| 541 } | 535 } |
| 542 for (Inst &I : Phis) { | 536 for (Inst &I : Phis) { |
| 543 if (I.isDeleted()) | 537 if (I.isDeleted()) |
| 544 continue; | 538 continue; |
| 545 I.livenessLightweight(Func, Live); | 539 I.livenessLightweight(Func, Live); |
| 546 } | 540 } |
| 547 } | 541 } |
| 548 | 542 |
| 549 // Performs liveness analysis on the block. Returns true if the | 543 // Performs liveness analysis on the block. Returns true if the |
| 550 // incoming liveness changed from before, false if it stayed the same. | 544 // incoming liveness changed from before, false if it stayed the same. |
| (...skipping 21 matching lines...) Expand all Loading... |
| 572 Live |= Liveness->getLiveIn(Succ); | 566 Live |= Liveness->getLiveIn(Succ); |
| 573 // Mark corresponding argument of phis in successor as live. | 567 // Mark corresponding argument of phis in successor as live. |
| 574 for (Inst &I : Succ->Phis) { | 568 for (Inst &I : Succ->Phis) { |
| 575 auto Phi = llvm::dyn_cast<InstPhi>(&I); | 569 auto Phi = llvm::dyn_cast<InstPhi>(&I); |
| 576 Phi->livenessPhiOperand(Live, this, Liveness); | 570 Phi->livenessPhiOperand(Live, this, Liveness); |
| 577 } | 571 } |
| 578 } | 572 } |
| 579 Liveness->getLiveOut(this) = Live; | 573 Liveness->getLiveOut(this) = Live; |
| 580 | 574 |
| 581 // Process regular instructions in reverse order. | 575 // Process regular instructions in reverse order. |
| 582 for (auto I = Insts.rbegin(), E = Insts.rend(); I != E; ++I) { | 576 for (Inst &I : reverse_range(Insts)) { |
| 583 if (I->isDeleted()) | 577 if (I.isDeleted()) |
| 584 continue; | 578 continue; |
| 585 I->liveness(I->getNumber(), Live, Liveness, LiveBegin, LiveEnd); | 579 I.liveness(I.getNumber(), Live, Liveness, LiveBegin, LiveEnd); |
| 586 } | 580 } |
| 587 // Process phis in forward order so that we can override the | 581 // Process phis in forward order so that we can override the |
| 588 // instruction number to be that of the earliest phi instruction in | 582 // instruction number to be that of the earliest phi instruction in |
| 589 // the block. | 583 // the block. |
| 590 SizeT NumNonDeadPhis = 0; | 584 SizeT NumNonDeadPhis = 0; |
| 591 InstNumberT FirstPhiNumber = Inst::NumberSentinel; | 585 InstNumberT FirstPhiNumber = Inst::NumberSentinel; |
| 592 for (Inst &I : Phis) { | 586 for (Inst &I : Phis) { |
| 593 if (I.isDeleted()) | 587 if (I.isDeleted()) |
| 594 continue; | 588 continue; |
| 595 if (FirstPhiNumber == Inst::NumberSentinel) | 589 if (FirstPhiNumber == Inst::NumberSentinel) |
| (...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 988 if (!First) | 982 if (!First) |
| 989 Str << ", "; | 983 Str << ", "; |
| 990 First = false; | 984 First = false; |
| 991 Str << "%" << I->getName(); | 985 Str << "%" << I->getName(); |
| 992 } | 986 } |
| 993 Str << "\n"; | 987 Str << "\n"; |
| 994 } | 988 } |
| 995 } | 989 } |
| 996 | 990 |
| 997 } // end of namespace Ice | 991 } // end of namespace Ice |
| OLD | NEW |