| 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 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 (InstPhi *I : Phis) |
| 61 I->renumber(Func); | 61 I->renumber(Func); |
| 62 for (Inst *I : Insts) | 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 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 110 // Find the insertion point. | 110 // Find the insertion point. |
| 111 InstList::iterator InsertionPoint = Insts.end(); | 111 InstList::iterator InsertionPoint = Insts.end(); |
| 112 // Every block must end in a terminator instruction, and therefore | 112 // Every block must end in a terminator instruction, and therefore |
| 113 // must have at least one instruction, so it's valid to decrement | 113 // must have at least one instruction, so it's valid to decrement |
| 114 // InsertionPoint (but assert just in case). | 114 // InsertionPoint (but assert just in case). |
| 115 assert(InsertionPoint != Insts.begin()); | 115 assert(InsertionPoint != Insts.begin()); |
| 116 --InsertionPoint; | 116 --InsertionPoint; |
| 117 // Confirm that InsertionPoint is a terminator instruction. Calling | 117 // Confirm that InsertionPoint is a terminator instruction. Calling |
| 118 // getTerminatorEdges() on a non-terminator instruction will cause | 118 // getTerminatorEdges() on a non-terminator instruction will cause |
| 119 // an llvm_unreachable(). | 119 // an llvm_unreachable(). |
| 120 (void)(*InsertionPoint)->getTerminatorEdges(); | 120 (void)InsertionPoint->getTerminatorEdges(); |
| 121 // SafeInsertionPoint is always immediately before the terminator | 121 // SafeInsertionPoint is always immediately before the terminator |
| 122 // instruction. If the block ends in a compare and conditional | 122 // instruction. If the block ends in a compare and conditional |
| 123 // branch, it's better to place the Phi store before the compare so | 123 // branch, it's better to place the Phi store before the compare so |
| 124 // as not to interfere with compare/branch fusing. However, if the | 124 // as not to interfere with compare/branch fusing. However, if the |
| 125 // compare instruction's dest operand is the same as the new | 125 // compare instruction's dest operand is the same as the new |
| 126 // assignment statement's source operand, this can't be done due to | 126 // assignment statement's source operand, this can't be done due to |
| 127 // data dependences, so we need to fall back to the | 127 // data dependences, so we need to fall back to the |
| 128 // SafeInsertionPoint. To illustrate: | 128 // SafeInsertionPoint. To illustrate: |
| 129 // ; <label>:95 | 129 // ; <label>:95 |
| 130 // %97 = load i8* %96, align 1 | 130 // %97 = load i8* %96, align 1 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 160 // but we could also do it here. | 160 // but we could also do it here. |
| 161 InstList::iterator SafeInsertionPoint = InsertionPoint; | 161 InstList::iterator SafeInsertionPoint = InsertionPoint; |
| 162 // Keep track of the dest variable of a compare instruction, so that | 162 // Keep track of the dest variable of a compare instruction, so that |
| 163 // we insert the new instruction at the SafeInsertionPoint if the | 163 // we insert the new instruction at the SafeInsertionPoint if the |
| 164 // compare's dest matches the Phi-lowered assignment's source. | 164 // compare's dest matches the Phi-lowered assignment's source. |
| 165 Variable *CmpInstDest = NULL; | 165 Variable *CmpInstDest = NULL; |
| 166 // If the current insertion point is at a conditional branch | 166 // If the current insertion point is at a conditional branch |
| 167 // instruction, and the previous instruction is a compare | 167 // instruction, and the previous instruction is a compare |
| 168 // instruction, then we move the insertion point before the compare | 168 // instruction, then we move the insertion point before the compare |
| 169 // instruction so as not to interfere with compare/branch fusing. | 169 // instruction so as not to interfere with compare/branch fusing. |
| 170 if (InstBr *Branch = llvm::dyn_cast<InstBr>(*InsertionPoint)) { | 170 if (InstBr *Branch = llvm::dyn_cast<InstBr>(InsertionPoint)) { |
| 171 if (!Branch->isUnconditional()) { | 171 if (!Branch->isUnconditional()) { |
| 172 if (InsertionPoint != Insts.begin()) { | 172 if (InsertionPoint != Insts.begin()) { |
| 173 --InsertionPoint; | 173 --InsertionPoint; |
| 174 if (llvm::isa<InstIcmp>(*InsertionPoint) || | 174 if (llvm::isa<InstIcmp>(InsertionPoint) || |
| 175 llvm::isa<InstFcmp>(*InsertionPoint)) { | 175 llvm::isa<InstFcmp>(InsertionPoint)) { |
| 176 CmpInstDest = (*InsertionPoint)->getDest(); | 176 CmpInstDest = InsertionPoint->getDest(); |
| 177 } else { | 177 } else { |
| 178 ++InsertionPoint; | 178 ++InsertionPoint; |
| 179 } | 179 } |
| 180 } | 180 } |
| 181 } | 181 } |
| 182 } | 182 } |
| 183 | 183 |
| 184 // Consider every out-edge. | 184 // Consider every out-edge. |
| 185 for (CfgNode *Succ : OutEdges) { | 185 for (CfgNode *Succ : OutEdges) { |
| 186 // Consider every Phi instruction at the out-edge. | 186 // Consider every Phi instruction at the out-edge. |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 243 *I = NewNode; | 243 *I = NewNode; |
| 244 NewNode->OutEdges.push_back(this); | 244 NewNode->OutEdges.push_back(this); |
| 245 Found = true; | 245 Found = true; |
| 246 } | 246 } |
| 247 } | 247 } |
| 248 assert(Found); | 248 assert(Found); |
| 249 // Repoint a suitable branch instruction's target. | 249 // Repoint a suitable branch instruction's target. |
| 250 Found = false; | 250 Found = false; |
| 251 for (auto I = Pred->getInsts().rbegin(), E = Pred->getInsts().rend(); | 251 for (auto I = Pred->getInsts().rbegin(), E = Pred->getInsts().rend(); |
| 252 !Found && I != E; ++I) { | 252 !Found && I != E; ++I) { |
| 253 if (!(*I)->isDeleted()) { | 253 if (!I->isDeleted()) { |
| 254 Found = (*I)->repointEdge(this, NewNode); | 254 Found = I->repointEdge(this, NewNode); |
| 255 } | 255 } |
| 256 } | 256 } |
| 257 assert(Found); | 257 assert(Found); |
| 258 return NewNode; | 258 return NewNode; |
| 259 } | 259 } |
| 260 | 260 |
| 261 namespace { | 261 namespace { |
| 262 | 262 |
| 263 // Helper function used by advancedPhiLowering(). | 263 // Helper function used by advancedPhiLowering(). |
| 264 bool sameVarOrReg(const Variable *Var, const Operand *Opnd) { | 264 bool sameVarOrReg(const Variable *Var, const Operand *Opnd) { |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 523 // Do preliminary lowering of the Phi instructions. | 523 // Do preliminary lowering of the Phi instructions. |
| 524 Target->prelowerPhis(); | 524 Target->prelowerPhis(); |
| 525 } | 525 } |
| 526 | 526 |
| 527 void CfgNode::livenessLightweight() { | 527 void CfgNode::livenessLightweight() { |
| 528 SizeT NumVars = Func->getNumVariables(); | 528 SizeT NumVars = Func->getNumVariables(); |
| 529 LivenessBV Live(NumVars); | 529 LivenessBV Live(NumVars); |
| 530 // Process regular instructions in reverse order. | 530 // Process regular instructions in reverse order. |
| 531 // TODO(stichnot): Use llvm::make_range with LLVM 3.5. | 531 // TODO(stichnot): Use llvm::make_range with LLVM 3.5. |
| 532 for (auto I = Insts.rbegin(), E = Insts.rend(); I != E; ++I) { | 532 for (auto I = Insts.rbegin(), E = Insts.rend(); I != E; ++I) { |
| 533 if ((*I)->isDeleted()) | 533 if (I->isDeleted()) |
| 534 continue; | 534 continue; |
| 535 (*I)->livenessLightweight(Func, Live); | 535 I->livenessLightweight(Func, Live); |
| 536 } | 536 } |
| 537 for (InstPhi *I : Phis) { | 537 for (InstPhi *I : Phis) { |
| 538 if (I->isDeleted()) | 538 if (I->isDeleted()) |
| 539 continue; | 539 continue; |
| 540 I->livenessLightweight(Func, Live); | 540 I->livenessLightweight(Func, Live); |
| 541 } | 541 } |
| 542 } | 542 } |
| 543 | 543 |
| 544 // Performs liveness analysis on the block. Returns true if the | 544 // Performs liveness analysis on the block. Returns true if the |
| 545 // incoming liveness changed from before, false if it stayed the same. | 545 // incoming liveness changed from before, false if it stayed the same. |
| (...skipping 20 matching lines...) Expand all Loading... |
| 566 for (CfgNode *Succ : OutEdges) { | 566 for (CfgNode *Succ : OutEdges) { |
| 567 Live |= Liveness->getLiveIn(Succ); | 567 Live |= Liveness->getLiveIn(Succ); |
| 568 // Mark corresponding argument of phis in successor as live. | 568 // Mark corresponding argument of phis in successor as live. |
| 569 for (InstPhi *I : Succ->Phis) | 569 for (InstPhi *I : Succ->Phis) |
| 570 I->livenessPhiOperand(Live, this, Liveness); | 570 I->livenessPhiOperand(Live, this, Liveness); |
| 571 } | 571 } |
| 572 Liveness->getLiveOut(this) = Live; | 572 Liveness->getLiveOut(this) = Live; |
| 573 | 573 |
| 574 // Process regular instructions in reverse order. | 574 // Process regular instructions in reverse order. |
| 575 for (auto I = Insts.rbegin(), E = Insts.rend(); I != E; ++I) { | 575 for (auto I = Insts.rbegin(), E = Insts.rend(); I != E; ++I) { |
| 576 if ((*I)->isDeleted()) | 576 if (I->isDeleted()) |
| 577 continue; | 577 continue; |
| 578 (*I)->liveness((*I)->getNumber(), Live, Liveness, LiveBegin, LiveEnd); | 578 I->liveness(I->getNumber(), Live, Liveness, LiveBegin, LiveEnd); |
| 579 } | 579 } |
| 580 // Process phis in forward order so that we can override the | 580 // Process phis in forward order so that we can override the |
| 581 // instruction number to be that of the earliest phi instruction in | 581 // instruction number to be that of the earliest phi instruction in |
| 582 // the block. | 582 // the block. |
| 583 SizeT NumNonDeadPhis = 0; | 583 SizeT NumNonDeadPhis = 0; |
| 584 InstNumberT FirstPhiNumber = Inst::NumberSentinel; | 584 InstNumberT FirstPhiNumber = Inst::NumberSentinel; |
| 585 for (InstPhi *I : Phis) { | 585 for (InstPhi *I : Phis) { |
| 586 if (I->isDeleted()) | 586 if (I->isDeleted()) |
| 587 continue; | 587 continue; |
| 588 if (FirstPhiNumber == Inst::NumberSentinel) | 588 if (FirstPhiNumber == Inst::NumberSentinel) |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 647 for (InstPhi *I : Phis) { | 647 for (InstPhi *I : Phis) { |
| 648 I->deleteIfDead(); | 648 I->deleteIfDead(); |
| 649 if (I->isDeleted()) | 649 if (I->isDeleted()) |
| 650 continue; | 650 continue; |
| 651 if (FirstInstNum == Inst::NumberSentinel) | 651 if (FirstInstNum == Inst::NumberSentinel) |
| 652 FirstInstNum = I->getNumber(); | 652 FirstInstNum = I->getNumber(); |
| 653 assert(I->getNumber() > LastInstNum); | 653 assert(I->getNumber() > LastInstNum); |
| 654 LastInstNum = I->getNumber(); | 654 LastInstNum = I->getNumber(); |
| 655 } | 655 } |
| 656 // Process instructions | 656 // Process instructions |
| 657 for (Inst *I : Insts) { | 657 for (auto I = Insts.begin(), E = Insts.end(); I != E; ++I) { |
| 658 I->deleteIfDead(); | 658 I->deleteIfDead(); |
| 659 if (I->isDeleted()) | 659 if (I->isDeleted()) |
| 660 continue; | 660 continue; |
| 661 if (FirstInstNum == Inst::NumberSentinel) | 661 if (FirstInstNum == Inst::NumberSentinel) |
| 662 FirstInstNum = I->getNumber(); | 662 FirstInstNum = I->getNumber(); |
| 663 assert(I->getNumber() > LastInstNum); | 663 assert(I->getNumber() > LastInstNum); |
| 664 LastInstNum = I->getNumber(); | 664 LastInstNum = I->getNumber(); |
| 665 // Create fake live ranges for a Kill instruction, but only if the | 665 // Create fake live ranges for a Kill instruction, but only if the |
| 666 // linked instruction is still alive. | 666 // linked instruction is still alive. |
| 667 if (Mode == Liveness_Intervals) { | 667 if (Mode == Liveness_Intervals) { |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 746 } | 746 } |
| 747 } | 747 } |
| 748 | 748 |
| 749 // If this node contains only deleted instructions, and ends in an | 749 // If this node contains only deleted instructions, and ends in an |
| 750 // unconditional branch, contract the node by repointing all its | 750 // unconditional branch, contract the node by repointing all its |
| 751 // in-edges to its successor. | 751 // in-edges to its successor. |
| 752 void CfgNode::contractIfEmpty() { | 752 void CfgNode::contractIfEmpty() { |
| 753 if (InEdges.empty()) | 753 if (InEdges.empty()) |
| 754 return; | 754 return; |
| 755 Inst *Branch = NULL; | 755 Inst *Branch = NULL; |
| 756 for (Inst *I : Insts) { | 756 for (auto I = Insts.begin(), E = Insts.end(); I != E; ++I) { |
| 757 if (I->isDeleted()) | 757 if (I->isDeleted()) |
| 758 continue; | 758 continue; |
| 759 if (I->isUnconditionalBranch()) | 759 if (I->isUnconditionalBranch()) |
| 760 Branch = I; | 760 Branch = I; |
| 761 else if (!I->isRedundantAssign()) | 761 else if (!I->isRedundantAssign()) |
| 762 return; | 762 return; |
| 763 } | 763 } |
| 764 Branch->setDeleted(); | 764 Branch->setDeleted(); |
| 765 assert(OutEdges.size() == 1); | 765 assert(OutEdges.size() == 1); |
| 766 // Repoint all this node's in-edges to this node's successor, unless | 766 // Repoint all this node's in-edges to this node's successor, unless |
| 767 // this node's successor is actually itself (in which case the | 767 // this node's successor is actually itself (in which case the |
| 768 // statement "OutEdges.front()->InEdges.push_back(Pred)" could | 768 // statement "OutEdges.front()->InEdges.push_back(Pred)" could |
| 769 // invalidate the iterator over this->InEdges). | 769 // invalidate the iterator over this->InEdges). |
| 770 if (OutEdges.front() != this) { | 770 if (OutEdges.front() != this) { |
| 771 for (CfgNode *Pred : InEdges) { | 771 for (CfgNode *Pred : InEdges) { |
| 772 for (auto I = Pred->OutEdges.begin(), E = Pred->OutEdges.end(); I != E; | 772 for (auto I = Pred->OutEdges.begin(), E = Pred->OutEdges.end(); I != E; |
| 773 ++I) { | 773 ++I) { |
| 774 if (*I == this) { | 774 if (*I == this) { |
| 775 *I = OutEdges.front(); | 775 *I = OutEdges.front(); |
| 776 OutEdges.front()->InEdges.push_back(Pred); | 776 OutEdges.front()->InEdges.push_back(Pred); |
| 777 } | 777 } |
| 778 } | 778 } |
| 779 for (Inst *I : Pred->getInsts()) { | 779 for (auto I = Pred->getInsts().begin(), E = Pred->getInsts().end(); |
| 780 I != E; ++I) { |
| 780 if (!I->isDeleted()) | 781 if (!I->isDeleted()) |
| 781 I->repointEdge(this, OutEdges.front()); | 782 I->repointEdge(this, OutEdges.front()); |
| 782 } | 783 } |
| 783 } | 784 } |
| 784 } | 785 } |
| 785 InEdges.clear(); | 786 InEdges.clear(); |
| 786 // Don't bother removing the single out-edge, which would also | 787 // Don't bother removing the single out-edge, which would also |
| 787 // require finding the corresponding in-edge in the successor and | 788 // require finding the corresponding in-edge in the successor and |
| 788 // removing it. | 789 // removing it. |
| 789 } | 790 } |
| 790 | 791 |
| 791 void CfgNode::doBranchOpt(const CfgNode *NextNode) { | 792 void CfgNode::doBranchOpt(const CfgNode *NextNode) { |
| 792 TargetLowering *Target = Func->getTarget(); | 793 TargetLowering *Target = Func->getTarget(); |
| 793 // Check every instruction for a branch optimization opportunity. | 794 // Check every instruction for a branch optimization opportunity. |
| 794 // It may be more efficient to iterate in reverse and stop after the | 795 // It may be more efficient to iterate in reverse and stop after the |
| 795 // first opportunity, unless there is some target lowering where we | 796 // first opportunity, unless there is some target lowering where we |
| 796 // have the possibility of multiple such optimizations per block | 797 // have the possibility of multiple such optimizations per block |
| 797 // (currently not the case for x86 lowering). | 798 // (currently not the case for x86 lowering). |
| 798 for (Inst *I : Insts) { | 799 for (auto I = Insts.begin(), E = Insts.end(); I != E; ++I) { |
| 799 if (!I->isDeleted()) { | 800 if (!I->isDeleted()) { |
| 800 Target->doBranchOpt(I, NextNode); | 801 Target->doBranchOpt(I, NextNode); |
| 801 } | 802 } |
| 802 } | 803 } |
| 803 } | 804 } |
| 804 | 805 |
| 805 // ======================== Dump routines ======================== // | 806 // ======================== Dump routines ======================== // |
| 806 | 807 |
| 807 namespace { | 808 namespace { |
| 808 | 809 |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 894 if (DecorateAsm) | 895 if (DecorateAsm) |
| 895 emitRegisterUsage(Str, Func, this, true, LiveRegCount); | 896 emitRegisterUsage(Str, Func, this, true, LiveRegCount); |
| 896 | 897 |
| 897 for (InstPhi *Phi : Phis) { | 898 for (InstPhi *Phi : Phis) { |
| 898 if (Phi->isDeleted()) | 899 if (Phi->isDeleted()) |
| 899 continue; | 900 continue; |
| 900 // Emitting a Phi instruction should cause an error. | 901 // Emitting a Phi instruction should cause an error. |
| 901 Inst *Instr = Phi; | 902 Inst *Instr = Phi; |
| 902 Instr->emit(Func); | 903 Instr->emit(Func); |
| 903 } | 904 } |
| 904 for (Inst *I : Insts) { | 905 for (auto I = Insts.begin(), E = Insts.end(); I != E; ++I) { |
| 905 if (I->isDeleted()) | 906 if (I->isDeleted()) |
| 906 continue; | 907 continue; |
| 907 if (I->isRedundantAssign()) { | 908 if (I->isRedundantAssign()) { |
| 908 Variable *Dest = I->getDest(); | 909 Variable *Dest = I->getDest(); |
| 909 if (DecorateAsm && Dest->hasReg() && !I->isLastUse(I->getSrc(0))) | 910 if (DecorateAsm && Dest->hasReg() && !I->isLastUse(I->getSrc(0))) |
| 910 ++LiveRegCount[Dest->getRegNum()]; | 911 ++LiveRegCount[Dest->getRegNum()]; |
| 911 continue; | 912 continue; |
| 912 } | 913 } |
| 913 I->emit(Func); | 914 I->emit(Func); |
| 914 if (DecorateAsm) | 915 if (DecorateAsm) |
| 915 emitLiveRangesEnded(Str, Func, I, LiveRegCount); | 916 emitLiveRangesEnded(Str, Func, I, LiveRegCount); |
| 916 Str << "\n"; | 917 Str << "\n"; |
| 917 updateStats(Func, I); | 918 updateStats(Func, I); |
| 918 } | 919 } |
| 919 if (DecorateAsm) | 920 if (DecorateAsm) |
| 920 emitRegisterUsage(Str, Func, this, false, LiveRegCount); | 921 emitRegisterUsage(Str, Func, this, false, LiveRegCount); |
| 921 } | 922 } |
| 922 | 923 |
| 923 void CfgNode::emitIAS(Cfg *Func) const { | 924 void CfgNode::emitIAS(Cfg *Func) const { |
| 924 Func->setCurrentNode(this); | 925 Func->setCurrentNode(this); |
| 925 Assembler *Asm = Func->getAssembler<Assembler>(); | 926 Assembler *Asm = Func->getAssembler<Assembler>(); |
| 926 Asm->BindCfgNodeLabel(getIndex()); | 927 Asm->BindCfgNodeLabel(getIndex()); |
| 927 for (InstPhi *Phi : Phis) { | 928 for (InstPhi *Phi : Phis) { |
| 928 if (Phi->isDeleted()) | 929 if (Phi->isDeleted()) |
| 929 continue; | 930 continue; |
| 930 // Emitting a Phi instruction should cause an error. | 931 // Emitting a Phi instruction should cause an error. |
| 931 Inst *Instr = Phi; | 932 Inst *Instr = Phi; |
| 932 Instr->emitIAS(Func); | 933 Instr->emitIAS(Func); |
| 933 } | 934 } |
| 934 for (Inst *I : Insts) { | 935 for (auto I = Insts.begin(), E = Insts.end(); I != E; ++I) { |
| 935 if (I->isDeleted()) | 936 if (I->isDeleted()) |
| 936 continue; | 937 continue; |
| 937 if (I->isRedundantAssign()) | 938 if (I->isRedundantAssign()) |
| 938 continue; | 939 continue; |
| 939 I->emitIAS(Func); | 940 I->emitIAS(Func); |
| 940 updateStats(Func, I); | 941 updateStats(Func, I); |
| 941 } | 942 } |
| 942 } | 943 } |
| 943 | 944 |
| 944 void CfgNode::dump(Cfg *Func) const { | 945 void CfgNode::dump(Cfg *Func) const { |
| (...skipping 30 matching lines...) Expand all Loading... |
| 975 Var->getType()); | 976 Var->getType()); |
| 976 } | 977 } |
| 977 } | 978 } |
| 978 } | 979 } |
| 979 Str << "\n"; | 980 Str << "\n"; |
| 980 } | 981 } |
| 981 // Dump each instruction. | 982 // Dump each instruction. |
| 982 if (Func->getContext()->isVerbose(IceV_Instructions)) { | 983 if (Func->getContext()->isVerbose(IceV_Instructions)) { |
| 983 for (InstPhi *I : Phis) | 984 for (InstPhi *I : Phis) |
| 984 I->dumpDecorated(Func); | 985 I->dumpDecorated(Func); |
| 985 for (Inst *I : Insts) | 986 for (auto I = Insts.begin(), E = Insts.end(); I != E; ++I) |
| 986 I->dumpDecorated(Func); | 987 I->dumpDecorated(Func); |
| 987 } | 988 } |
| 988 // Dump the live-out variables. | 989 // Dump the live-out variables. |
| 989 LivenessBV LiveOut; | 990 LivenessBV LiveOut; |
| 990 if (Liveness) | 991 if (Liveness) |
| 991 LiveOut = Liveness->getLiveOut(this); | 992 LiveOut = Liveness->getLiveOut(this); |
| 992 if (Func->getContext()->isVerbose(IceV_Liveness) && !LiveOut.empty()) { | 993 if (Func->getContext()->isVerbose(IceV_Liveness) && !LiveOut.empty()) { |
| 993 Str << " // LiveOut:"; | 994 Str << " // LiveOut:"; |
| 994 for (SizeT i = 0; i < LiveOut.size(); ++i) { | 995 for (SizeT i = 0; i < LiveOut.size(); ++i) { |
| 995 if (LiveOut[i]) { | 996 if (LiveOut[i]) { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1011 if (!First) | 1012 if (!First) |
| 1012 Str << ", "; | 1013 Str << ", "; |
| 1013 First = false; | 1014 First = false; |
| 1014 Str << "%" << I->getName(); | 1015 Str << "%" << I->getName(); |
| 1015 } | 1016 } |
| 1016 Str << "\n"; | 1017 Str << "\n"; |
| 1017 } | 1018 } |
| 1018 } | 1019 } |
| 1019 | 1020 |
| 1020 } // end of namespace Ice | 1021 } // end of namespace Ice |
| OLD | NEW |