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 |