OLD | NEW |
---|---|
1 //===- subzero/src/IceCfgNode.cpp - Basic block (node) implementation -----===// | 1 //===- subzero/src/IceCfgNode.cpp - Basic block (node) implementation -----===// |
2 // | 2 // |
3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 // | 9 // |
10 // This file implements the CfgNode class, including the complexities | 10 // This file implements the CfgNode class, including the complexities |
(...skipping 86 matching lines...) Loading... | |
97 // all the assignments near the end of this block. They need to be | 97 // all the assignments near the end of this block. They need to be |
98 // added before any branch instruction, and also if the block ends | 98 // added before any branch instruction, and also if the block ends |
99 // with a compare instruction followed by a branch instruction that we | 99 // with a compare instruction followed by a branch instruction that we |
100 // may want to fuse, it's better to insert the new assignments before | 100 // may want to fuse, it's better to insert the new assignments before |
101 // the compare instruction. The tryOptimizedCmpxchgCmpBr() method | 101 // the compare instruction. The tryOptimizedCmpxchgCmpBr() method |
102 // assumes this ordering of instructions. | 102 // assumes this ordering of instructions. |
103 // | 103 // |
104 // Note that this transformation takes the Phi dest variables out of | 104 // Note that this transformation takes the Phi dest variables out of |
105 // SSA form, as there may be assignments to the dest variable in | 105 // SSA form, as there may be assignments to the dest variable in |
106 // multiple blocks. | 106 // multiple blocks. |
107 // | |
108 // TODO: Defer this pass until after register allocation, then split | |
109 // critical edges, add the assignments, and lower them. This should | |
110 // reduce the amount of shuffling at the end of each block. | |
111 void CfgNode::placePhiStores() { | 107 void CfgNode::placePhiStores() { |
112 // Find the insertion point. | 108 // Find the insertion point. |
113 InstList::iterator InsertionPoint = Insts.end(); | 109 InstList::iterator InsertionPoint = Insts.end(); |
114 // Every block must end in a terminator instruction, and therefore | 110 // Every block must end in a terminator instruction, and therefore |
115 // must have at least one instruction, so it's valid to decrement | 111 // must have at least one instruction, so it's valid to decrement |
116 // InsertionPoint (but assert just in case). | 112 // InsertionPoint (but assert just in case). |
117 assert(InsertionPoint != Insts.begin()); | 113 assert(InsertionPoint != Insts.begin()); |
118 --InsertionPoint; | 114 --InsertionPoint; |
119 // Confirm that InsertionPoint is a terminator instruction. Calling | 115 // Confirm that InsertionPoint is a terminator instruction. Calling |
120 // getTerminatorEdges() on a non-terminator instruction will cause | 116 // getTerminatorEdges() on a non-terminator instruction will cause |
(...skipping 124 matching lines...) Loading... | |
245 for (auto I = InEdges.begin(), E = InEdges.end(); !Found && I != E; ++I) { | 241 for (auto I = InEdges.begin(), E = InEdges.end(); !Found && I != E; ++I) { |
246 if (*I == Pred) { | 242 if (*I == Pred) { |
247 *I = NewNode; | 243 *I = NewNode; |
248 NewNode->OutEdges.push_back(this); | 244 NewNode->OutEdges.push_back(this); |
249 Found = true; | 245 Found = true; |
250 } | 246 } |
251 } | 247 } |
252 assert(Found); | 248 assert(Found); |
253 // Repoint a suitable branch instruction's target. | 249 // Repoint a suitable branch instruction's target. |
254 Found = false; | 250 Found = false; |
255 for (auto I = Pred->getInsts().rbegin(), E = Pred->getInsts().rend(); | 251 for (auto I = Pred->getInsts().rbegin(), E = Pred->getInsts().rend(); |
jvoung (off chromium)
2015/01/09 19:10:43
can this be converted to reverse_range() too?
Jim Stichnoth
2015/01/09 19:41:23
Done. (I didn't do it initially because of style
| |
256 !Found && I != E; ++I) { | 252 !Found && I != E; ++I) { |
257 if (!I->isDeleted()) { | 253 if (!I->isDeleted()) { |
258 Found = I->repointEdge(this, NewNode); | 254 Found = I->repointEdge(this, NewNode); |
259 } | 255 } |
260 } | 256 } |
261 assert(Found); | 257 assert(Found); |
262 return NewNode; | 258 return NewNode; |
263 } | 259 } |
264 | 260 |
265 namespace { | 261 namespace { |
(...skipping 260 matching lines...) Loading... | |
526 assert(Context.getCur() != Orig); | 522 assert(Context.getCur() != Orig); |
527 } | 523 } |
528 // Do preliminary lowering of the Phi instructions. | 524 // Do preliminary lowering of the Phi instructions. |
529 Target->prelowerPhis(); | 525 Target->prelowerPhis(); |
530 } | 526 } |
531 | 527 |
532 void CfgNode::livenessLightweight() { | 528 void CfgNode::livenessLightweight() { |
533 SizeT NumVars = Func->getNumVariables(); | 529 SizeT NumVars = Func->getNumVariables(); |
534 LivenessBV Live(NumVars); | 530 LivenessBV Live(NumVars); |
535 // Process regular instructions in reverse order. | 531 // Process regular instructions in reverse order. |
536 // TODO(stichnot): Use llvm::make_range with LLVM 3.5. | 532 for (Inst &I : reverse_range(Insts)) { |
537 for (auto I = Insts.rbegin(), E = Insts.rend(); I != E; ++I) { | 533 if (I.isDeleted()) |
538 if (I->isDeleted()) | |
539 continue; | 534 continue; |
540 I->livenessLightweight(Func, Live); | 535 I.livenessLightweight(Func, Live); |
541 } | 536 } |
542 for (Inst &I : Phis) { | 537 for (Inst &I : Phis) { |
543 if (I.isDeleted()) | 538 if (I.isDeleted()) |
544 continue; | 539 continue; |
545 I.livenessLightweight(Func, Live); | 540 I.livenessLightweight(Func, Live); |
546 } | 541 } |
547 } | 542 } |
548 | 543 |
549 // Performs liveness analysis on the block. Returns true if the | 544 // Performs liveness analysis on the block. Returns true if the |
550 // incoming liveness changed from before, false if it stayed the same. | 545 // incoming liveness changed from before, false if it stayed the same. |
(...skipping 21 matching lines...) Loading... | |
572 Live |= Liveness->getLiveIn(Succ); | 567 Live |= Liveness->getLiveIn(Succ); |
573 // Mark corresponding argument of phis in successor as live. | 568 // Mark corresponding argument of phis in successor as live. |
574 for (Inst &I : Succ->Phis) { | 569 for (Inst &I : Succ->Phis) { |
575 auto Phi = llvm::dyn_cast<InstPhi>(&I); | 570 auto Phi = llvm::dyn_cast<InstPhi>(&I); |
576 Phi->livenessPhiOperand(Live, this, Liveness); | 571 Phi->livenessPhiOperand(Live, this, Liveness); |
577 } | 572 } |
578 } | 573 } |
579 Liveness->getLiveOut(this) = Live; | 574 Liveness->getLiveOut(this) = Live; |
580 | 575 |
581 // Process regular instructions in reverse order. | 576 // Process regular instructions in reverse order. |
582 for (auto I = Insts.rbegin(), E = Insts.rend(); I != E; ++I) { | 577 for (Inst &I : reverse_range(Insts)) { |
583 if (I->isDeleted()) | 578 if (I.isDeleted()) |
584 continue; | 579 continue; |
585 I->liveness(I->getNumber(), Live, Liveness, LiveBegin, LiveEnd); | 580 I.liveness(I.getNumber(), Live, Liveness, LiveBegin, LiveEnd); |
586 } | 581 } |
587 // Process phis in forward order so that we can override the | 582 // Process phis in forward order so that we can override the |
588 // instruction number to be that of the earliest phi instruction in | 583 // instruction number to be that of the earliest phi instruction in |
589 // the block. | 584 // the block. |
590 SizeT NumNonDeadPhis = 0; | 585 SizeT NumNonDeadPhis = 0; |
591 InstNumberT FirstPhiNumber = Inst::NumberSentinel; | 586 InstNumberT FirstPhiNumber = Inst::NumberSentinel; |
592 for (Inst &I : Phis) { | 587 for (Inst &I : Phis) { |
593 if (I.isDeleted()) | 588 if (I.isDeleted()) |
594 continue; | 589 continue; |
595 if (FirstPhiNumber == Inst::NumberSentinel) | 590 if (FirstPhiNumber == Inst::NumberSentinel) |
(...skipping 392 matching lines...) Loading... | |
988 if (!First) | 983 if (!First) |
989 Str << ", "; | 984 Str << ", "; |
990 First = false; | 985 First = false; |
991 Str << "%" << I->getName(); | 986 Str << "%" << I->getName(); |
992 } | 987 } |
993 Str << "\n"; | 988 Str << "\n"; |
994 } | 989 } |
995 } | 990 } |
996 | 991 |
997 } // end of namespace Ice | 992 } // end of namespace Ice |
OLD | NEW |