| 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 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 50 } | 50 } |
| 51 } | 51 } |
| 52 | 52 |
| 53 // Renumbers the non-deleted instructions in the node. This needs to | 53 // Renumbers the non-deleted instructions in the node. This needs to |
| 54 // be done in preparation for live range analysis. The instruction | 54 // be done in preparation for live range analysis. The instruction |
| 55 // numbers in a block must be monotonically increasing. The range of | 55 // numbers in a block must be monotonically increasing. The range of |
| 56 // instruction numbers in a block, from lowest to highest, must not | 56 // instruction numbers in a block, from lowest to highest, must not |
| 57 // overlap with the range of any other block. | 57 // overlap with the range of any other block. |
| 58 void CfgNode::renumberInstructions() { | 58 void CfgNode::renumberInstructions() { |
| 59 InstNumberT FirstNumber = Func->getNextInstNumber(); | 59 InstNumberT FirstNumber = Func->getNextInstNumber(); |
| 60 for (InstPhi *I : Phis) | 60 for (auto I = Phis.begin(), E = Phis.end(); I != E; ++I) |
| 61 I->renumber(Func); | 61 I->renumber(Func); |
| 62 for (auto I = Insts.begin(), E = Insts.end(); I != E; ++I) | 62 for (auto I = Insts.begin(), E = Insts.end(); I != E; ++I) |
| 63 I->renumber(Func); | 63 I->renumber(Func); |
| 64 InstCountEstimate = Func->getNextInstNumber() - FirstNumber; | 64 InstCountEstimate = Func->getNextInstNumber() - FirstNumber; |
| 65 } | 65 } |
| 66 | 66 |
| 67 // When a node is created, the OutEdges are immediately known, but the | 67 // When a node is created, the OutEdges are immediately known, but the |
| 68 // InEdges have to be built up incrementally. After the CFG has been | 68 // InEdges have to be built up incrementally. After the CFG has been |
| 69 // constructed, the computePredecessors() pass finalizes it by | 69 // constructed, the computePredecessors() pass finalizes it by |
| 70 // creating the InEdges list. | 70 // creating the InEdges list. |
| 71 void CfgNode::computePredecessors() { | 71 void CfgNode::computePredecessors() { |
| 72 OutEdges = Insts.rbegin()->getTerminatorEdges(); | 72 OutEdges = Insts.rbegin()->getTerminatorEdges(); |
| 73 for (CfgNode *Succ : OutEdges) | 73 for (CfgNode *Succ : OutEdges) |
| 74 Succ->InEdges.push_back(this); | 74 Succ->InEdges.push_back(this); |
| 75 } | 75 } |
| 76 | 76 |
| 77 // This does part 1 of Phi lowering, by creating a new dest variable | 77 // This does part 1 of Phi lowering, by creating a new dest variable |
| 78 // for each Phi instruction, replacing the Phi instruction's dest with | 78 // for each Phi instruction, replacing the Phi instruction's dest with |
| 79 // that variable, and adding an explicit assignment of the old dest to | 79 // that variable, and adding an explicit assignment of the old dest to |
| 80 // the new dest. For example, | 80 // the new dest. For example, |
| 81 // a=phi(...) | 81 // a=phi(...) |
| 82 // changes to | 82 // changes to |
| 83 // "a_phi=phi(...); a=a_phi". | 83 // "a_phi=phi(...); a=a_phi". |
| 84 // | 84 // |
| 85 // This is in preparation for part 2 which deletes the Phi | 85 // This is in preparation for part 2 which deletes the Phi |
| 86 // instructions and appends assignment instructions to predecessor | 86 // instructions and appends assignment instructions to predecessor |
| 87 // blocks. Note that this transformation preserves SSA form. | 87 // blocks. Note that this transformation preserves SSA form. |
| 88 void CfgNode::placePhiLoads() { | 88 void CfgNode::placePhiLoads() { |
| 89 for (InstPhi *I : Phis) | 89 for (auto I = Phis.begin(), E = Phis.end(); I != E; ++I) { |
| 90 Insts.insert(Insts.begin(), I->lower(Func)); | 90 auto Phi = llvm::dyn_cast<InstPhi>(I); |
| 91 Insts.insert(Insts.begin(), Phi->lower(Func)); |
| 92 } |
| 91 } | 93 } |
| 92 | 94 |
| 93 // This does part 2 of Phi lowering. For each Phi instruction at each | 95 // This does part 2 of Phi lowering. For each Phi instruction at each |
| 94 // out-edge, create a corresponding assignment instruction, and add | 96 // out-edge, create a corresponding assignment instruction, and add |
| 95 // 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 |
| 96 // added before any branch instruction, and also if the block ends | 98 // added before any branch instruction, and also if the block ends |
| 97 // with a compare instruction followed by a branch instruction that we | 99 // with a compare instruction followed by a branch instruction that we |
| 98 // 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 |
| 99 // the compare instruction. The tryOptimizedCmpxchgCmpBr() method | 101 // the compare instruction. The tryOptimizedCmpxchgCmpBr() method |
| 100 // assumes this ordering of instructions. | 102 // assumes this ordering of instructions. |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 177 } else { | 179 } else { |
| 178 ++InsertionPoint; | 180 ++InsertionPoint; |
| 179 } | 181 } |
| 180 } | 182 } |
| 181 } | 183 } |
| 182 } | 184 } |
| 183 | 185 |
| 184 // Consider every out-edge. | 186 // Consider every out-edge. |
| 185 for (CfgNode *Succ : OutEdges) { | 187 for (CfgNode *Succ : OutEdges) { |
| 186 // Consider every Phi instruction at the out-edge. | 188 // Consider every Phi instruction at the out-edge. |
| 187 for (InstPhi *I : Succ->Phis) { | 189 for (auto I = Succ->Phis.begin(), E = Succ->Phis.end(); I != E; ++I) { |
| 188 Operand *Operand = I->getOperandForTarget(this); | 190 auto Phi = llvm::dyn_cast<InstPhi>(I); |
| 191 Operand *Operand = Phi->getOperandForTarget(this); |
| 189 assert(Operand); | 192 assert(Operand); |
| 190 Variable *Dest = I->getDest(); | 193 Variable *Dest = I->getDest(); |
| 191 assert(Dest); | 194 assert(Dest); |
| 192 InstAssign *NewInst = InstAssign::create(Func, Dest, Operand); | 195 InstAssign *NewInst = InstAssign::create(Func, Dest, Operand); |
| 193 if (CmpInstDest == Operand) | 196 if (CmpInstDest == Operand) |
| 194 Insts.insert(SafeInsertionPoint, NewInst); | 197 Insts.insert(SafeInsertionPoint, NewInst); |
| 195 else | 198 else |
| 196 Insts.insert(InsertionPoint, NewInst); | 199 Insts.insert(InsertionPoint, NewInst); |
| 197 } | 200 } |
| 198 } | 201 } |
| 199 } | 202 } |
| 200 | 203 |
| 201 // Deletes the phi instructions after the loads and stores are placed. | 204 // Deletes the phi instructions after the loads and stores are placed. |
| 202 void CfgNode::deletePhis() { | 205 void CfgNode::deletePhis() { |
| 203 for (InstPhi *I : Phis) | 206 for (auto I = Phis.begin(), E = Phis.end(); I != E; ++I) |
| 204 I->setDeleted(); | 207 I->setDeleted(); |
| 205 } | 208 } |
| 206 | 209 |
| 207 // Splits the edge from Pred to this node by creating a new node and | 210 // Splits the edge from Pred to this node by creating a new node and |
| 208 // hooking up the in and out edges appropriately. (The EdgeIndex | 211 // hooking up the in and out edges appropriately. (The EdgeIndex |
| 209 // parameter is only used to make the new node's name unique when | 212 // parameter is only used to make the new node's name unique when |
| 210 // there are multiple edges between the same pair of nodes.) The new | 213 // there are multiple edges between the same pair of nodes.) The new |
| 211 // node's instruction list is initialized to the empty list, with no | 214 // node's instruction list is initialized to the empty list, with no |
| 212 // terminator instruction. If there are multiple edges from Pred to | 215 // terminator instruction. If there are multiple edges from Pred to |
| 213 // this node, only one edge is split, and the particular choice of | 216 // this node, only one edge is split, and the particular choice of |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 309 struct { | 312 struct { |
| 310 InstPhi *Phi; | 313 InstPhi *Phi; |
| 311 Variable *Dest; | 314 Variable *Dest; |
| 312 Operand *Src; | 315 Operand *Src; |
| 313 bool Processed; | 316 bool Processed; |
| 314 size_t NumPred; // number of entries whose Src is this Dest | 317 size_t NumPred; // number of entries whose Src is this Dest |
| 315 int32_t Weight; // preference for topological order | 318 int32_t Weight; // preference for topological order |
| 316 } Desc[getPhis().size()]; | 319 } Desc[getPhis().size()]; |
| 317 | 320 |
| 318 size_t NumPhis = 0; | 321 size_t NumPhis = 0; |
| 319 for (InstPhi *Inst : getPhis()) { | 322 for (auto I = Phis.begin(), E = Phis.end(); I != E; ++I) { |
| 323 auto Inst = llvm::dyn_cast<InstPhi>(I); |
| 320 if (!Inst->isDeleted()) { | 324 if (!Inst->isDeleted()) { |
| 321 Desc[NumPhis].Phi = Inst; | 325 Desc[NumPhis].Phi = Inst; |
| 322 Desc[NumPhis].Dest = Inst->getDest(); | 326 Desc[NumPhis].Dest = Inst->getDest(); |
| 323 ++NumPhis; | 327 ++NumPhis; |
| 324 } | 328 } |
| 325 } | 329 } |
| 326 if (NumPhis == 0) | 330 if (NumPhis == 0) |
| 327 return; | 331 return; |
| 328 | 332 |
| 329 SizeT InEdgeIndex = 0; | 333 SizeT InEdgeIndex = 0; |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 463 | 467 |
| 464 Func->getTarget()->lowerPhiAssignments(Split, Assignments); | 468 Func->getTarget()->lowerPhiAssignments(Split, Assignments); |
| 465 | 469 |
| 466 // Renumber the instructions to be monotonically increasing so | 470 // Renumber the instructions to be monotonically increasing so |
| 467 // that addNode() doesn't assert when multi-definitions are added | 471 // that addNode() doesn't assert when multi-definitions are added |
| 468 // out of order. | 472 // out of order. |
| 469 Split->renumberInstructions(); | 473 Split->renumberInstructions(); |
| 470 Func->getVMetadata()->addNode(Split); | 474 Func->getVMetadata()->addNode(Split); |
| 471 } | 475 } |
| 472 | 476 |
| 473 for (InstPhi *Inst : getPhis()) | 477 for (auto I = Phis.begin(), E = Phis.end(); I != E; ++I) |
| 474 Inst->setDeleted(); | 478 I->setDeleted(); |
| 475 } | 479 } |
| 476 | 480 |
| 477 // Does address mode optimization. Pass each instruction to the | 481 // Does address mode optimization. Pass each instruction to the |
| 478 // TargetLowering object. If it returns a new instruction | 482 // TargetLowering object. If it returns a new instruction |
| 479 // (representing the optimized address mode), then insert the new | 483 // (representing the optimized address mode), then insert the new |
| 480 // instruction and delete the old. | 484 // instruction and delete the old. |
| 481 void CfgNode::doAddressOpt() { | 485 void CfgNode::doAddressOpt() { |
| 482 TargetLowering *Target = Func->getTarget(); | 486 TargetLowering *Target = Func->getTarget(); |
| 483 LoweringContext &Context = Target->getContext(); | 487 LoweringContext &Context = Target->getContext(); |
| 484 Context.init(this); | 488 Context.init(this); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 527 void CfgNode::livenessLightweight() { | 531 void CfgNode::livenessLightweight() { |
| 528 SizeT NumVars = Func->getNumVariables(); | 532 SizeT NumVars = Func->getNumVariables(); |
| 529 LivenessBV Live(NumVars); | 533 LivenessBV Live(NumVars); |
| 530 // Process regular instructions in reverse order. | 534 // Process regular instructions in reverse order. |
| 531 // TODO(stichnot): Use llvm::make_range with LLVM 3.5. | 535 // TODO(stichnot): Use llvm::make_range with LLVM 3.5. |
| 532 for (auto I = Insts.rbegin(), E = Insts.rend(); I != E; ++I) { | 536 for (auto I = Insts.rbegin(), E = Insts.rend(); I != E; ++I) { |
| 533 if (I->isDeleted()) | 537 if (I->isDeleted()) |
| 534 continue; | 538 continue; |
| 535 I->livenessLightweight(Func, Live); | 539 I->livenessLightweight(Func, Live); |
| 536 } | 540 } |
| 537 for (InstPhi *I : Phis) { | 541 for (auto I = Phis.begin(), E = Phis.end(); I != E; ++I) { |
| 538 if (I->isDeleted()) | 542 if (I->isDeleted()) |
| 539 continue; | 543 continue; |
| 540 I->livenessLightweight(Func, Live); | 544 I->livenessLightweight(Func, Live); |
| 541 } | 545 } |
| 542 } | 546 } |
| 543 | 547 |
| 544 // Performs liveness analysis on the block. Returns true if the | 548 // Performs liveness analysis on the block. Returns true if the |
| 545 // incoming liveness changed from before, false if it stayed the same. | 549 // incoming liveness changed from before, false if it stayed the same. |
| 546 // (If it changes, the node's predecessors need to be processed | 550 // (If it changes, the node's predecessors need to be processed |
| 547 // again.) | 551 // again.) |
| (...skipping 11 matching lines...) Expand all Loading... |
| 559 LiveEnd->clear(); | 563 LiveEnd->clear(); |
| 560 // Guess that the number of live ranges beginning is roughly the | 564 // Guess that the number of live ranges beginning is roughly the |
| 561 // number of instructions, and same for live ranges ending. | 565 // number of instructions, and same for live ranges ending. |
| 562 LiveBegin->reserve(getInstCountEstimate()); | 566 LiveBegin->reserve(getInstCountEstimate()); |
| 563 LiveEnd->reserve(getInstCountEstimate()); | 567 LiveEnd->reserve(getInstCountEstimate()); |
| 564 } | 568 } |
| 565 // Initialize Live to be the union of all successors' LiveIn. | 569 // Initialize Live to be the union of all successors' LiveIn. |
| 566 for (CfgNode *Succ : OutEdges) { | 570 for (CfgNode *Succ : OutEdges) { |
| 567 Live |= Liveness->getLiveIn(Succ); | 571 Live |= Liveness->getLiveIn(Succ); |
| 568 // Mark corresponding argument of phis in successor as live. | 572 // Mark corresponding argument of phis in successor as live. |
| 569 for (InstPhi *I : Succ->Phis) | 573 for (auto I = Succ->Phis.begin(), E = Succ->Phis.end(); I != E; ++I) { |
| 570 I->livenessPhiOperand(Live, this, Liveness); | 574 auto Phi = llvm::dyn_cast<InstPhi>(I); |
| 575 Phi->livenessPhiOperand(Live, this, Liveness); |
| 576 } |
| 571 } | 577 } |
| 572 Liveness->getLiveOut(this) = Live; | 578 Liveness->getLiveOut(this) = Live; |
| 573 | 579 |
| 574 // Process regular instructions in reverse order. | 580 // Process regular instructions in reverse order. |
| 575 for (auto I = Insts.rbegin(), E = Insts.rend(); I != E; ++I) { | 581 for (auto I = Insts.rbegin(), E = Insts.rend(); I != E; ++I) { |
| 576 if (I->isDeleted()) | 582 if (I->isDeleted()) |
| 577 continue; | 583 continue; |
| 578 I->liveness(I->getNumber(), Live, Liveness, LiveBegin, LiveEnd); | 584 I->liveness(I->getNumber(), Live, Liveness, LiveBegin, LiveEnd); |
| 579 } | 585 } |
| 580 // Process phis in forward order so that we can override the | 586 // Process phis in forward order so that we can override the |
| 581 // instruction number to be that of the earliest phi instruction in | 587 // instruction number to be that of the earliest phi instruction in |
| 582 // the block. | 588 // the block. |
| 583 SizeT NumNonDeadPhis = 0; | 589 SizeT NumNonDeadPhis = 0; |
| 584 InstNumberT FirstPhiNumber = Inst::NumberSentinel; | 590 InstNumberT FirstPhiNumber = Inst::NumberSentinel; |
| 585 for (InstPhi *I : Phis) { | 591 for (auto I = Phis.begin(), E = Phis.end(); I != E; ++I) { |
| 586 if (I->isDeleted()) | 592 if (I->isDeleted()) |
| 587 continue; | 593 continue; |
| 588 if (FirstPhiNumber == Inst::NumberSentinel) | 594 if (FirstPhiNumber == Inst::NumberSentinel) |
| 589 FirstPhiNumber = I->getNumber(); | 595 FirstPhiNumber = I->getNumber(); |
| 590 if (I->liveness(FirstPhiNumber, Live, Liveness, LiveBegin, LiveEnd)) | 596 if (I->liveness(FirstPhiNumber, Live, Liveness, LiveBegin, LiveEnd)) |
| 591 ++NumNonDeadPhis; | 597 ++NumNonDeadPhis; |
| 592 } | 598 } |
| 593 | 599 |
| 594 // When using the sparse representation, after traversing the | 600 // When using the sparse representation, after traversing the |
| 595 // instructions in the block, the Live bitvector should only contain | 601 // instructions in the block, the Live bitvector should only contain |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 637 // It is assumed that within a single basic block, a live range begins | 643 // It is assumed that within a single basic block, a live range begins |
| 638 // at most once and ends at most once. This is certainly true for | 644 // at most once and ends at most once. This is certainly true for |
| 639 // pure SSA form. It is also true once phis are lowered, since each | 645 // pure SSA form. It is also true once phis are lowered, since each |
| 640 // assignment to the phi-based temporary is in a different basic | 646 // assignment to the phi-based temporary is in a different basic |
| 641 // block, and there is a single read that ends the live in the basic | 647 // block, and there is a single read that ends the live in the basic |
| 642 // block that contained the actual phi instruction. | 648 // block that contained the actual phi instruction. |
| 643 void CfgNode::livenessPostprocess(LivenessMode Mode, Liveness *Liveness) { | 649 void CfgNode::livenessPostprocess(LivenessMode Mode, Liveness *Liveness) { |
| 644 InstNumberT FirstInstNum = Inst::NumberSentinel; | 650 InstNumberT FirstInstNum = Inst::NumberSentinel; |
| 645 InstNumberT LastInstNum = Inst::NumberSentinel; | 651 InstNumberT LastInstNum = Inst::NumberSentinel; |
| 646 // Process phis in any order. Process only Dest operands. | 652 // Process phis in any order. Process only Dest operands. |
| 647 for (InstPhi *I : Phis) { | 653 for (auto I = Phis.begin(), E = Phis.end(); I != E; ++I) { |
| 648 I->deleteIfDead(); | 654 I->deleteIfDead(); |
| 649 if (I->isDeleted()) | 655 if (I->isDeleted()) |
| 650 continue; | 656 continue; |
| 651 if (FirstInstNum == Inst::NumberSentinel) | 657 if (FirstInstNum == Inst::NumberSentinel) |
| 652 FirstInstNum = I->getNumber(); | 658 FirstInstNum = I->getNumber(); |
| 653 assert(I->getNumber() > LastInstNum); | 659 assert(I->getNumber() > LastInstNum); |
| 654 LastInstNum = I->getNumber(); | 660 LastInstNum = I->getNumber(); |
| 655 } | 661 } |
| 656 // Process instructions | 662 // Process instructions |
| 657 for (auto I = Insts.begin(), E = Insts.end(); I != E; ++I) { | 663 for (auto I = Insts.begin(), E = Insts.end(); I != E; ++I) { |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 882 return; | 888 return; |
| 883 Func->setCurrentNode(this); | 889 Func->setCurrentNode(this); |
| 884 Ostream &Str = Func->getContext()->getStrEmit(); | 890 Ostream &Str = Func->getContext()->getStrEmit(); |
| 885 Liveness *Liveness = Func->getLiveness(); | 891 Liveness *Liveness = Func->getLiveness(); |
| 886 bool DecorateAsm = Liveness && Func->getContext()->getFlags().DecorateAsm; | 892 bool DecorateAsm = Liveness && Func->getContext()->getFlags().DecorateAsm; |
| 887 Str << getAsmName() << ":\n"; | 893 Str << getAsmName() << ":\n"; |
| 888 std::vector<SizeT> LiveRegCount(Func->getTarget()->getNumRegisters()); | 894 std::vector<SizeT> LiveRegCount(Func->getTarget()->getNumRegisters()); |
| 889 if (DecorateAsm) | 895 if (DecorateAsm) |
| 890 emitRegisterUsage(Str, Func, this, true, LiveRegCount); | 896 emitRegisterUsage(Str, Func, this, true, LiveRegCount); |
| 891 | 897 |
| 892 for (InstPhi *Phi : Phis) { | 898 for (auto I = Phis.begin(), E = Phis.end(); I != E; ++I) { |
| 893 if (Phi->isDeleted()) | 899 if (I->isDeleted()) |
| 894 continue; | 900 continue; |
| 895 // Emitting a Phi instruction should cause an error. | 901 // Emitting a Phi instruction should cause an error. |
| 896 Inst *Instr = Phi; | 902 I->emit(Func); |
| 897 Instr->emit(Func); | |
| 898 } | 903 } |
| 899 for (auto I = Insts.begin(), E = Insts.end(); I != E; ++I) { | 904 for (auto I = Insts.begin(), E = Insts.end(); I != E; ++I) { |
| 900 if (I->isDeleted()) | 905 if (I->isDeleted()) |
| 901 continue; | 906 continue; |
| 902 if (I->isRedundantAssign()) { | 907 if (I->isRedundantAssign()) { |
| 903 Variable *Dest = I->getDest(); | 908 Variable *Dest = I->getDest(); |
| 904 if (DecorateAsm && Dest->hasReg() && !I->isLastUse(I->getSrc(0))) | 909 if (DecorateAsm && Dest->hasReg() && !I->isLastUse(I->getSrc(0))) |
| 905 ++LiveRegCount[Dest->getRegNum()]; | 910 ++LiveRegCount[Dest->getRegNum()]; |
| 906 continue; | 911 continue; |
| 907 } | 912 } |
| 908 I->emit(Func); | 913 I->emit(Func); |
| 909 if (DecorateAsm) | 914 if (DecorateAsm) |
| 910 emitLiveRangesEnded(Str, Func, I, LiveRegCount); | 915 emitLiveRangesEnded(Str, Func, I, LiveRegCount); |
| 911 Str << "\n"; | 916 Str << "\n"; |
| 912 updateStats(Func, I); | 917 updateStats(Func, I); |
| 913 } | 918 } |
| 914 if (DecorateAsm) | 919 if (DecorateAsm) |
| 915 emitRegisterUsage(Str, Func, this, false, LiveRegCount); | 920 emitRegisterUsage(Str, Func, this, false, LiveRegCount); |
| 916 } | 921 } |
| 917 | 922 |
| 918 void CfgNode::emitIAS(Cfg *Func) const { | 923 void CfgNode::emitIAS(Cfg *Func) const { |
| 919 Func->setCurrentNode(this); | 924 Func->setCurrentNode(this); |
| 920 Assembler *Asm = Func->getAssembler<Assembler>(); | 925 Assembler *Asm = Func->getAssembler<Assembler>(); |
| 921 Asm->BindCfgNodeLabel(getIndex()); | 926 Asm->BindCfgNodeLabel(getIndex()); |
| 922 for (InstPhi *Phi : Phis) { | 927 for (auto I = Phis.begin(), E = Phis.end(); I != E; ++I) { |
| 923 if (Phi->isDeleted()) | 928 if (I->isDeleted()) |
| 924 continue; | 929 continue; |
| 925 // Emitting a Phi instruction should cause an error. | 930 // Emitting a Phi instruction should cause an error. |
| 926 Inst *Instr = Phi; | 931 I->emitIAS(Func); |
| 927 Instr->emitIAS(Func); | |
| 928 } | 932 } |
| 929 for (auto I = Insts.begin(), E = Insts.end(); I != E; ++I) { | 933 for (auto I = Insts.begin(), E = Insts.end(); I != E; ++I) { |
| 930 if (I->isDeleted()) | 934 if (I->isDeleted()) |
| 931 continue; | 935 continue; |
| 932 if (I->isRedundantAssign()) | 936 if (I->isRedundantAssign()) |
| 933 continue; | 937 continue; |
| 934 I->emitIAS(Func); | 938 I->emitIAS(Func); |
| 935 updateStats(Func, I); | 939 updateStats(Func, I); |
| 936 } | 940 } |
| 937 } | 941 } |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 970 if (Func->getContext()->isVerbose(IceV_RegOrigins) && Var->hasReg()) { | 974 if (Func->getContext()->isVerbose(IceV_RegOrigins) && Var->hasReg()) { |
| 971 Str << ":" << Func->getTarget()->getRegName(Var->getRegNum(), | 975 Str << ":" << Func->getTarget()->getRegName(Var->getRegNum(), |
| 972 Var->getType()); | 976 Var->getType()); |
| 973 } | 977 } |
| 974 } | 978 } |
| 975 } | 979 } |
| 976 Str << "\n"; | 980 Str << "\n"; |
| 977 } | 981 } |
| 978 // Dump each instruction. | 982 // Dump each instruction. |
| 979 if (Func->getContext()->isVerbose(IceV_Instructions)) { | 983 if (Func->getContext()->isVerbose(IceV_Instructions)) { |
| 980 for (InstPhi *I : Phis) | 984 for (auto I = Phis.begin(), E = Phis.end(); I != E; ++I) |
| 981 I->dumpDecorated(Func); | 985 I->dumpDecorated(Func); |
| 982 for (auto I = Insts.begin(), E = Insts.end(); I != E; ++I) | 986 for (auto I = Insts.begin(), E = Insts.end(); I != E; ++I) |
| 983 I->dumpDecorated(Func); | 987 I->dumpDecorated(Func); |
| 984 } | 988 } |
| 985 // Dump the live-out variables. | 989 // Dump the live-out variables. |
| 986 LivenessBV LiveOut; | 990 LivenessBV LiveOut; |
| 987 if (Liveness) | 991 if (Liveness) |
| 988 LiveOut = Liveness->getLiveOut(this); | 992 LiveOut = Liveness->getLiveOut(this); |
| 989 if (Func->getContext()->isVerbose(IceV_Liveness) && !LiveOut.empty()) { | 993 if (Func->getContext()->isVerbose(IceV_Liveness) && !LiveOut.empty()) { |
| 990 Str << " // LiveOut:"; | 994 Str << " // LiveOut:"; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1008 if (!First) | 1012 if (!First) |
| 1009 Str << ", "; | 1013 Str << ", "; |
| 1010 First = false; | 1014 First = false; |
| 1011 Str << "%" << I->getName(); | 1015 Str << "%" << I->getName(); |
| 1012 } | 1016 } |
| 1013 Str << "\n"; | 1017 Str << "\n"; |
| 1014 } | 1018 } |
| 1015 } | 1019 } |
| 1016 | 1020 |
| 1017 } // end of namespace Ice | 1021 } // end of namespace Ice |
| OLD | NEW |