Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(278)

Side by Side Diff: src/IceCfgNode.cpp

Issue 819403002: Subzero: Use range-based for loops with llvm::ilist<Inst> lists. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Created 5 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/IceCfg.cpp ('k') | src/IceOperand.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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 (auto I = Phis.begin(), E = Phis.end(); I != E; ++I) 60 for (Inst &I : Phis)
61 I->renumber(Func); 61 I.renumber(Func);
62 for (auto I = Insts.begin(), E = Insts.end(); I != E; ++I) 62 for (Inst &I : Insts)
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 (auto I = Phis.begin(), E = Phis.end(); I != E; ++I) { 89 for (Inst &I : Phis) {
90 auto Phi = llvm::dyn_cast<InstPhi>(I); 90 auto Phi = llvm::dyn_cast<InstPhi>(&I);
91 Insts.insert(Insts.begin(), Phi->lower(Func)); 91 Insts.insert(Insts.begin(), Phi->lower(Func));
92 } 92 }
93 } 93 }
94 94
95 // 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
96 // out-edge, create a corresponding assignment instruction, and add 96 // out-edge, create a corresponding assignment instruction, and add
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
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 } else { 179 } else {
180 ++InsertionPoint; 180 ++InsertionPoint;
181 } 181 }
182 } 182 }
183 } 183 }
184 } 184 }
185 185
186 // Consider every out-edge. 186 // Consider every out-edge.
187 for (CfgNode *Succ : OutEdges) { 187 for (CfgNode *Succ : OutEdges) {
188 // Consider every Phi instruction at the out-edge. 188 // Consider every Phi instruction at the out-edge.
189 for (auto I = Succ->Phis.begin(), E = Succ->Phis.end(); I != E; ++I) { 189 for (Inst &I : Succ->Phis) {
190 auto Phi = llvm::dyn_cast<InstPhi>(I); 190 auto Phi = llvm::dyn_cast<InstPhi>(&I);
191 Operand *Operand = Phi->getOperandForTarget(this); 191 Operand *Operand = Phi->getOperandForTarget(this);
192 assert(Operand); 192 assert(Operand);
193 Variable *Dest = I->getDest(); 193 Variable *Dest = I.getDest();
194 assert(Dest); 194 assert(Dest);
195 InstAssign *NewInst = InstAssign::create(Func, Dest, Operand); 195 InstAssign *NewInst = InstAssign::create(Func, Dest, Operand);
196 if (CmpInstDest == Operand) 196 if (CmpInstDest == Operand)
197 Insts.insert(SafeInsertionPoint, NewInst); 197 Insts.insert(SafeInsertionPoint, NewInst);
198 else 198 else
199 Insts.insert(InsertionPoint, NewInst); 199 Insts.insert(InsertionPoint, NewInst);
200 } 200 }
201 } 201 }
202 } 202 }
203 203
204 // Deletes the phi instructions after the loads and stores are placed. 204 // Deletes the phi instructions after the loads and stores are placed.
205 void CfgNode::deletePhis() { 205 void CfgNode::deletePhis() {
206 for (auto I = Phis.begin(), E = Phis.end(); I != E; ++I) 206 for (Inst &I : Phis)
207 I->setDeleted(); 207 I.setDeleted();
208 } 208 }
209 209
210 // 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
211 // hooking up the in and out edges appropriately. (The EdgeIndex 211 // hooking up the in and out edges appropriately. (The EdgeIndex
212 // 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
213 // 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
214 // 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
215 // terminator instruction. If there are multiple edges from Pred to 215 // terminator instruction. If there are multiple edges from Pred to
216 // 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
217 // edge is undefined. This could happen with a switch instruction, or 217 // edge is undefined. This could happen with a switch instruction, or
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
312 struct { 312 struct {
313 InstPhi *Phi; 313 InstPhi *Phi;
314 Variable *Dest; 314 Variable *Dest;
315 Operand *Src; 315 Operand *Src;
316 bool Processed; 316 bool Processed;
317 size_t NumPred; // number of entries whose Src is this Dest 317 size_t NumPred; // number of entries whose Src is this Dest
318 int32_t Weight; // preference for topological order 318 int32_t Weight; // preference for topological order
319 } Desc[getPhis().size()]; 319 } Desc[getPhis().size()];
320 320
321 size_t NumPhis = 0; 321 size_t NumPhis = 0;
322 for (auto I = Phis.begin(), E = Phis.end(); I != E; ++I) { 322 for (Inst &I : Phis) {
323 auto Inst = llvm::dyn_cast<InstPhi>(I); 323 auto Inst = llvm::dyn_cast<InstPhi>(&I);
324 if (!Inst->isDeleted()) { 324 if (!Inst->isDeleted()) {
325 Desc[NumPhis].Phi = Inst; 325 Desc[NumPhis].Phi = Inst;
326 Desc[NumPhis].Dest = Inst->getDest(); 326 Desc[NumPhis].Dest = Inst->getDest();
327 ++NumPhis; 327 ++NumPhis;
328 } 328 }
329 } 329 }
330 if (NumPhis == 0) 330 if (NumPhis == 0)
331 return; 331 return;
332 332
333 SizeT InEdgeIndex = 0; 333 SizeT InEdgeIndex = 0;
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
468 468
469 Func->getTarget()->lowerPhiAssignments(Split, Assignments); 469 Func->getTarget()->lowerPhiAssignments(Split, Assignments);
470 470
471 // Renumber the instructions to be monotonically increasing so 471 // Renumber the instructions to be monotonically increasing so
472 // that addNode() doesn't assert when multi-definitions are added 472 // that addNode() doesn't assert when multi-definitions are added
473 // out of order. 473 // out of order.
474 Split->renumberInstructions(); 474 Split->renumberInstructions();
475 Func->getVMetadata()->addNode(Split); 475 Func->getVMetadata()->addNode(Split);
476 } 476 }
477 477
478 for (auto I = Phis.begin(), E = Phis.end(); I != E; ++I) 478 for (Inst &I : Phis)
479 I->setDeleted(); 479 I.setDeleted();
480 } 480 }
481 481
482 // Does address mode optimization. Pass each instruction to the 482 // Does address mode optimization. Pass each instruction to the
483 // TargetLowering object. If it returns a new instruction 483 // TargetLowering object. If it returns a new instruction
484 // (representing the optimized address mode), then insert the new 484 // (representing the optimized address mode), then insert the new
485 // instruction and delete the old. 485 // instruction and delete the old.
486 void CfgNode::doAddressOpt() { 486 void CfgNode::doAddressOpt() {
487 TargetLowering *Target = Func->getTarget(); 487 TargetLowering *Target = Func->getTarget();
488 LoweringContext &Context = Target->getContext(); 488 LoweringContext &Context = Target->getContext();
489 Context.init(this); 489 Context.init(this);
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
532 void CfgNode::livenessLightweight() { 532 void CfgNode::livenessLightweight() {
533 SizeT NumVars = Func->getNumVariables(); 533 SizeT NumVars = Func->getNumVariables();
534 LivenessBV Live(NumVars); 534 LivenessBV Live(NumVars);
535 // Process regular instructions in reverse order. 535 // Process regular instructions in reverse order.
536 // TODO(stichnot): Use llvm::make_range with LLVM 3.5. 536 // TODO(stichnot): Use llvm::make_range with LLVM 3.5.
537 for (auto I = Insts.rbegin(), E = Insts.rend(); I != E; ++I) { 537 for (auto I = Insts.rbegin(), E = Insts.rend(); I != E; ++I) {
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 for (auto I = Phis.begin(), E = Phis.end(); I != E; ++I) { 542 for (Inst &I : Phis) {
543 if (I->isDeleted()) 543 if (I.isDeleted())
544 continue; 544 continue;
545 I->livenessLightweight(Func, Live); 545 I.livenessLightweight(Func, Live);
546 } 546 }
547 } 547 }
548 548
549 // Performs liveness analysis on the block. Returns true if the 549 // Performs liveness analysis on the block. Returns true if the
550 // incoming liveness changed from before, false if it stayed the same. 550 // incoming liveness changed from before, false if it stayed the same.
551 // (If it changes, the node's predecessors need to be processed 551 // (If it changes, the node's predecessors need to be processed
552 // again.) 552 // again.)
553 bool CfgNode::liveness(Liveness *Liveness) { 553 bool CfgNode::liveness(Liveness *Liveness) {
554 SizeT NumVars = Liveness->getNumVarsInNode(this); 554 SizeT NumVars = Liveness->getNumVarsInNode(this);
555 LivenessBV Live(NumVars); 555 LivenessBV Live(NumVars);
556 LiveBeginEndMap *LiveBegin = nullptr; 556 LiveBeginEndMap *LiveBegin = nullptr;
557 LiveBeginEndMap *LiveEnd = nullptr; 557 LiveBeginEndMap *LiveEnd = nullptr;
558 // Mark the beginning and ending of each variable's live range 558 // Mark the beginning and ending of each variable's live range
559 // with the sentinel instruction number 0. 559 // with the sentinel instruction number 0.
560 if (Liveness->getMode() == Liveness_Intervals) { 560 if (Liveness->getMode() == Liveness_Intervals) {
561 LiveBegin = Liveness->getLiveBegin(this); 561 LiveBegin = Liveness->getLiveBegin(this);
562 LiveEnd = Liveness->getLiveEnd(this); 562 LiveEnd = Liveness->getLiveEnd(this);
563 LiveBegin->clear(); 563 LiveBegin->clear();
564 LiveEnd->clear(); 564 LiveEnd->clear();
565 // Guess that the number of live ranges beginning is roughly the 565 // Guess that the number of live ranges beginning is roughly the
566 // number of instructions, and same for live ranges ending. 566 // number of instructions, and same for live ranges ending.
567 LiveBegin->reserve(getInstCountEstimate()); 567 LiveBegin->reserve(getInstCountEstimate());
568 LiveEnd->reserve(getInstCountEstimate()); 568 LiveEnd->reserve(getInstCountEstimate());
569 } 569 }
570 // Initialize Live to be the union of all successors' LiveIn. 570 // Initialize Live to be the union of all successors' LiveIn.
571 for (CfgNode *Succ : OutEdges) { 571 for (CfgNode *Succ : OutEdges) {
572 Live |= Liveness->getLiveIn(Succ); 572 Live |= Liveness->getLiveIn(Succ);
573 // Mark corresponding argument of phis in successor as live. 573 // Mark corresponding argument of phis in successor as live.
574 for (auto I = Succ->Phis.begin(), E = Succ->Phis.end(); I != E; ++I) { 574 for (Inst &I : Succ->Phis) {
575 auto Phi = llvm::dyn_cast<InstPhi>(I); 575 auto Phi = llvm::dyn_cast<InstPhi>(&I);
576 Phi->livenessPhiOperand(Live, this, Liveness); 576 Phi->livenessPhiOperand(Live, this, Liveness);
577 } 577 }
578 } 578 }
579 Liveness->getLiveOut(this) = Live; 579 Liveness->getLiveOut(this) = Live;
580 580
581 // Process regular instructions in reverse order. 581 // Process regular instructions in reverse order.
582 for (auto I = Insts.rbegin(), E = Insts.rend(); I != E; ++I) { 582 for (auto I = Insts.rbegin(), E = Insts.rend(); I != E; ++I) {
583 if (I->isDeleted()) 583 if (I->isDeleted())
584 continue; 584 continue;
585 I->liveness(I->getNumber(), Live, Liveness, LiveBegin, LiveEnd); 585 I->liveness(I->getNumber(), Live, Liveness, LiveBegin, LiveEnd);
586 } 586 }
587 // Process phis in forward order so that we can override the 587 // Process phis in forward order so that we can override the
588 // instruction number to be that of the earliest phi instruction in 588 // instruction number to be that of the earliest phi instruction in
589 // the block. 589 // the block.
590 SizeT NumNonDeadPhis = 0; 590 SizeT NumNonDeadPhis = 0;
591 InstNumberT FirstPhiNumber = Inst::NumberSentinel; 591 InstNumberT FirstPhiNumber = Inst::NumberSentinel;
592 for (auto I = Phis.begin(), E = Phis.end(); I != E; ++I) { 592 for (Inst &I : Phis) {
593 if (I->isDeleted()) 593 if (I.isDeleted())
594 continue; 594 continue;
595 if (FirstPhiNumber == Inst::NumberSentinel) 595 if (FirstPhiNumber == Inst::NumberSentinel)
596 FirstPhiNumber = I->getNumber(); 596 FirstPhiNumber = I.getNumber();
597 if (I->liveness(FirstPhiNumber, Live, Liveness, LiveBegin, LiveEnd)) 597 if (I.liveness(FirstPhiNumber, Live, Liveness, LiveBegin, LiveEnd))
598 ++NumNonDeadPhis; 598 ++NumNonDeadPhis;
599 } 599 }
600 600
601 // When using the sparse representation, after traversing the 601 // When using the sparse representation, after traversing the
602 // instructions in the block, the Live bitvector should only contain 602 // instructions in the block, the Live bitvector should only contain
603 // set bits for global variables upon block entry. We validate this 603 // set bits for global variables upon block entry. We validate this
604 // by shrinking the Live vector and then testing it against the 604 // by shrinking the Live vector and then testing it against the
605 // pre-shrunk version. (The shrinking is required, but the 605 // pre-shrunk version. (The shrinking is required, but the
606 // validation is not.) 606 // validation is not.)
607 LivenessBV LiveOrig = Live; 607 LivenessBV LiveOrig = Live;
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
717 } 717 }
718 } 718 }
719 719
720 // If this node contains only deleted instructions, and ends in an 720 // If this node contains only deleted instructions, and ends in an
721 // unconditional branch, contract the node by repointing all its 721 // unconditional branch, contract the node by repointing all its
722 // in-edges to its successor. 722 // in-edges to its successor.
723 void CfgNode::contractIfEmpty() { 723 void CfgNode::contractIfEmpty() {
724 if (InEdges.empty()) 724 if (InEdges.empty())
725 return; 725 return;
726 Inst *Branch = nullptr; 726 Inst *Branch = nullptr;
727 for (auto I = Insts.begin(), E = Insts.end(); I != E; ++I) { 727 for (Inst &I : Insts) {
728 if (I->isDeleted()) 728 if (I.isDeleted())
729 continue; 729 continue;
730 if (I->isUnconditionalBranch()) 730 if (I.isUnconditionalBranch())
731 Branch = I; 731 Branch = &I;
732 else if (!I->isRedundantAssign()) 732 else if (!I.isRedundantAssign())
733 return; 733 return;
734 } 734 }
735 Branch->setDeleted(); 735 Branch->setDeleted();
736 assert(OutEdges.size() == 1); 736 assert(OutEdges.size() == 1);
737 // Repoint all this node's in-edges to this node's successor, unless 737 // Repoint all this node's in-edges to this node's successor, unless
738 // this node's successor is actually itself (in which case the 738 // this node's successor is actually itself (in which case the
739 // statement "OutEdges.front()->InEdges.push_back(Pred)" could 739 // statement "OutEdges.front()->InEdges.push_back(Pred)" could
740 // invalidate the iterator over this->InEdges). 740 // invalidate the iterator over this->InEdges).
741 if (OutEdges.front() != this) { 741 if (OutEdges.front() != this) {
742 for (CfgNode *Pred : InEdges) { 742 for (CfgNode *Pred : InEdges) {
743 for (auto I = Pred->OutEdges.begin(), E = Pred->OutEdges.end(); I != E; 743 for (auto I = Pred->OutEdges.begin(), E = Pred->OutEdges.end(); I != E;
744 ++I) { 744 ++I) {
745 if (*I == this) { 745 if (*I == this) {
746 *I = OutEdges.front(); 746 *I = OutEdges.front();
747 OutEdges.front()->InEdges.push_back(Pred); 747 OutEdges.front()->InEdges.push_back(Pred);
748 } 748 }
749 } 749 }
750 for (auto I = Pred->getInsts().begin(), E = Pred->getInsts().end(); 750 for (Inst &I : Pred->getInsts()) {
751 I != E; ++I) { 751 if (!I.isDeleted())
752 if (!I->isDeleted()) 752 I.repointEdge(this, OutEdges.front());
753 I->repointEdge(this, OutEdges.front());
754 } 753 }
755 } 754 }
756 } 755 }
757 InEdges.clear(); 756 InEdges.clear();
758 // Don't bother removing the single out-edge, which would also 757 // Don't bother removing the single out-edge, which would also
759 // require finding the corresponding in-edge in the successor and 758 // require finding the corresponding in-edge in the successor and
760 // removing it. 759 // removing it.
761 } 760 }
762 761
763 void CfgNode::doBranchOpt(const CfgNode *NextNode) { 762 void CfgNode::doBranchOpt(const CfgNode *NextNode) {
764 TargetLowering *Target = Func->getTarget(); 763 TargetLowering *Target = Func->getTarget();
765 // Check every instruction for a branch optimization opportunity. 764 // Check every instruction for a branch optimization opportunity.
766 // It may be more efficient to iterate in reverse and stop after the 765 // It may be more efficient to iterate in reverse and stop after the
767 // first opportunity, unless there is some target lowering where we 766 // first opportunity, unless there is some target lowering where we
768 // have the possibility of multiple such optimizations per block 767 // have the possibility of multiple such optimizations per block
769 // (currently not the case for x86 lowering). 768 // (currently not the case for x86 lowering).
770 for (auto I = Insts.begin(), E = Insts.end(); I != E; ++I) { 769 for (Inst &I : Insts) {
771 if (!I->isDeleted()) { 770 if (!I.isDeleted()) {
772 Target->doBranchOpt(I, NextNode); 771 Target->doBranchOpt(&I, NextNode);
773 } 772 }
774 } 773 }
775 } 774 }
776 775
777 // ======================== Dump routines ======================== // 776 // ======================== Dump routines ======================== //
778 777
779 namespace { 778 namespace {
780 779
781 // Helper functions for emit(). 780 // Helper functions for emit().
782 781
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
865 return; 864 return;
866 Func->setCurrentNode(this); 865 Func->setCurrentNode(this);
867 Ostream &Str = Func->getContext()->getStrEmit(); 866 Ostream &Str = Func->getContext()->getStrEmit();
868 Liveness *Liveness = Func->getLiveness(); 867 Liveness *Liveness = Func->getLiveness();
869 bool DecorateAsm = Liveness && Func->getContext()->getFlags().DecorateAsm; 868 bool DecorateAsm = Liveness && Func->getContext()->getFlags().DecorateAsm;
870 Str << getAsmName() << ":\n"; 869 Str << getAsmName() << ":\n";
871 std::vector<SizeT> LiveRegCount(Func->getTarget()->getNumRegisters()); 870 std::vector<SizeT> LiveRegCount(Func->getTarget()->getNumRegisters());
872 if (DecorateAsm) 871 if (DecorateAsm)
873 emitRegisterUsage(Str, Func, this, true, LiveRegCount); 872 emitRegisterUsage(Str, Func, this, true, LiveRegCount);
874 873
875 for (auto I = Phis.begin(), E = Phis.end(); I != E; ++I) { 874 for (const Inst &I : Phis) {
876 if (I->isDeleted()) 875 if (I.isDeleted())
877 continue; 876 continue;
878 // Emitting a Phi instruction should cause an error. 877 // Emitting a Phi instruction should cause an error.
879 I->emit(Func); 878 I.emit(Func);
880 } 879 }
881 for (auto I = Insts.begin(), E = Insts.end(); I != E; ++I) { 880 for (const Inst &I : Insts) {
882 if (I->isDeleted()) 881 if (I.isDeleted())
883 continue; 882 continue;
884 if (I->isRedundantAssign()) { 883 if (I.isRedundantAssign()) {
885 Variable *Dest = I->getDest(); 884 Variable *Dest = I.getDest();
886 if (DecorateAsm && Dest->hasReg() && !I->isLastUse(I->getSrc(0))) 885 if (DecorateAsm && Dest->hasReg() && !I.isLastUse(I.getSrc(0)))
887 ++LiveRegCount[Dest->getRegNum()]; 886 ++LiveRegCount[Dest->getRegNum()];
888 continue; 887 continue;
889 } 888 }
890 I->emit(Func); 889 I.emit(Func);
891 if (DecorateAsm) 890 if (DecorateAsm)
892 emitLiveRangesEnded(Str, Func, I, LiveRegCount); 891 emitLiveRangesEnded(Str, Func, &I, LiveRegCount);
893 Str << "\n"; 892 Str << "\n";
894 updateStats(Func, I); 893 updateStats(Func, &I);
895 } 894 }
896 if (DecorateAsm) 895 if (DecorateAsm)
897 emitRegisterUsage(Str, Func, this, false, LiveRegCount); 896 emitRegisterUsage(Str, Func, this, false, LiveRegCount);
898 } 897 }
899 898
900 void CfgNode::emitIAS(Cfg *Func) const { 899 void CfgNode::emitIAS(Cfg *Func) const {
901 Func->setCurrentNode(this); 900 Func->setCurrentNode(this);
902 Assembler *Asm = Func->getAssembler<Assembler>(); 901 Assembler *Asm = Func->getAssembler<Assembler>();
903 Asm->BindCfgNodeLabel(getIndex()); 902 Asm->BindCfgNodeLabel(getIndex());
904 for (auto I = Phis.begin(), E = Phis.end(); I != E; ++I) { 903 for (const Inst &I : Phis) {
905 if (I->isDeleted()) 904 if (I.isDeleted())
906 continue; 905 continue;
907 // Emitting a Phi instruction should cause an error. 906 // Emitting a Phi instruction should cause an error.
908 I->emitIAS(Func); 907 I.emitIAS(Func);
909 } 908 }
910 for (auto I = Insts.begin(), E = Insts.end(); I != E; ++I) { 909 for (const Inst &I : Insts) {
911 if (I->isDeleted()) 910 if (I.isDeleted())
912 continue; 911 continue;
913 if (I->isRedundantAssign()) 912 if (I.isRedundantAssign())
914 continue; 913 continue;
915 I->emitIAS(Func); 914 I.emitIAS(Func);
916 updateStats(Func, I); 915 updateStats(Func, &I);
917 } 916 }
918 } 917 }
919 918
920 void CfgNode::dump(Cfg *Func) const { 919 void CfgNode::dump(Cfg *Func) const {
921 if (!ALLOW_DUMP) 920 if (!ALLOW_DUMP)
922 return; 921 return;
923 Func->setCurrentNode(this); 922 Func->setCurrentNode(this);
924 Ostream &Str = Func->getContext()->getStrDump(); 923 Ostream &Str = Func->getContext()->getStrDump();
925 Liveness *Liveness = Func->getLiveness(); 924 Liveness *Liveness = Func->getLiveness();
926 if (Func->getContext()->isVerbose(IceV_Instructions)) { 925 if (Func->getContext()->isVerbose(IceV_Instructions)) {
(...skipping 24 matching lines...) Expand all
951 if (Func->getContext()->isVerbose(IceV_RegOrigins) && Var->hasReg()) { 950 if (Func->getContext()->isVerbose(IceV_RegOrigins) && Var->hasReg()) {
952 Str << ":" << Func->getTarget()->getRegName(Var->getRegNum(), 951 Str << ":" << Func->getTarget()->getRegName(Var->getRegNum(),
953 Var->getType()); 952 Var->getType());
954 } 953 }
955 } 954 }
956 } 955 }
957 Str << "\n"; 956 Str << "\n";
958 } 957 }
959 // Dump each instruction. 958 // Dump each instruction.
960 if (Func->getContext()->isVerbose(IceV_Instructions)) { 959 if (Func->getContext()->isVerbose(IceV_Instructions)) {
961 for (auto I = Phis.begin(), E = Phis.end(); I != E; ++I) 960 for (const Inst &I : Phis)
962 I->dumpDecorated(Func); 961 I.dumpDecorated(Func);
963 for (auto I = Insts.begin(), E = Insts.end(); I != E; ++I) 962 for (const Inst &I : Insts)
964 I->dumpDecorated(Func); 963 I.dumpDecorated(Func);
965 } 964 }
966 // Dump the live-out variables. 965 // Dump the live-out variables.
967 LivenessBV LiveOut; 966 LivenessBV LiveOut;
968 if (Liveness) 967 if (Liveness)
969 LiveOut = Liveness->getLiveOut(this); 968 LiveOut = Liveness->getLiveOut(this);
970 if (Func->getContext()->isVerbose(IceV_Liveness) && !LiveOut.empty()) { 969 if (Func->getContext()->isVerbose(IceV_Liveness) && !LiveOut.empty()) {
971 Str << " // LiveOut:"; 970 Str << " // LiveOut:";
972 for (SizeT i = 0; i < LiveOut.size(); ++i) { 971 for (SizeT i = 0; i < LiveOut.size(); ++i) {
973 if (LiveOut[i]) { 972 if (LiveOut[i]) {
974 Variable *Var = Liveness->getVariable(i, this); 973 Variable *Var = Liveness->getVariable(i, this);
(...skipping 14 matching lines...) Expand all
989 if (!First) 988 if (!First)
990 Str << ", "; 989 Str << ", ";
991 First = false; 990 First = false;
992 Str << "%" << I->getName(); 991 Str << "%" << I->getName();
993 } 992 }
994 Str << "\n"; 993 Str << "\n";
995 } 994 }
996 } 995 }
997 996
998 } // end of namespace Ice 997 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceCfg.cpp ('k') | src/IceOperand.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698