| 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 | 
|---|