diff options
| -rw-r--r-- | compiler/optimizing/nodes.cc | 5 | ||||
| -rw-r--r-- | compiler/optimizing/nodes.h | 7 | ||||
| -rw-r--r-- | compiler/optimizing/ssa_phi_elimination.cc | 9 | ||||
| -rw-r--r-- | compiler/optimizing/ssa_test.cc | 12 |
4 files changed, 26 insertions, 7 deletions
diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc index 82827952ba..376d1af3ef 100644 --- a/compiler/optimizing/nodes.cc +++ b/compiler/optimizing/nodes.cc @@ -194,6 +194,11 @@ void HGraph::SimplifyLoop(HBasicBlock* header) { } pre_header->AddSuccessor(header); } + + // Make sure the second predecessor of a loop header is the back edge. + if (header->GetPredecessors().Get(1) != info->GetBackEdges().Get(0)) { + header->SwapPredecessors(); + } } void HGraph::SimplifyCFG() { diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index 10d471c049..d98d2ad75f 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -338,6 +338,13 @@ class HBasicBlock : public ArenaObject { block->successors_.Add(this); } + void SwapPredecessors() { + DCHECK_EQ(predecessors_.Size(), 2u); + HBasicBlock* temp = predecessors_.Get(0); + predecessors_.Put(0, predecessors_.Get(1)); + predecessors_.Put(1, temp); + } + size_t GetPredecessorIndexOf(HBasicBlock* predecessor) { for (size_t i = 0, e = predecessors_.Size(); i < e; ++i) { if (predecessors_.Get(i) == predecessor) { diff --git a/compiler/optimizing/ssa_phi_elimination.cc b/compiler/optimizing/ssa_phi_elimination.cc index 65675dc273..d541a62b5c 100644 --- a/compiler/optimizing/ssa_phi_elimination.cc +++ b/compiler/optimizing/ssa_phi_elimination.cc @@ -83,6 +83,10 @@ void SsaDeadPhiElimination::Run() { } } +static bool LoopPreHeaderIsFirstPredecessor(HBasicBlock* block) { + return block->GetPredecessors().Get(0) == block->GetLoopInformation()->GetPreHeader(); +} + void SsaRedundantPhiElimination::Run() { // Add all phis in the worklist. for (HReversePostOrderIterator it(*graph_); !it.Done(); it.Advance()) { @@ -102,7 +106,10 @@ void SsaRedundantPhiElimination::Run() { // Find if the inputs of the phi are the same instruction. HInstruction* candidate = phi->InputAt(0); - // A loop phi cannot have itself as the first phi. + // A loop phi cannot have itself as the first phi. Note that this + // check relies on our simplification pass ensuring the pre-header + // block is first in the list of predecessors of the loop header. + DCHECK(!phi->IsLoopHeaderPhi() || LoopPreHeaderIsFirstPredecessor(phi->GetBlock())); DCHECK_NE(phi, candidate); for (size_t i = 1; i < phi->InputCount(); ++i) { diff --git a/compiler/optimizing/ssa_test.cc b/compiler/optimizing/ssa_test.cc index 99fd9ebacb..ad3b205830 100644 --- a/compiler/optimizing/ssa_test.cc +++ b/compiler/optimizing/ssa_test.cc @@ -207,8 +207,8 @@ TEST(SsaTest, Loop1) { "BasicBlock 2, pred: 3, 6, succ: 3\n" " 4: Phi(6, 0) [6]\n" " 5: Goto\n" - "BasicBlock 3, pred: 2, 5, succ: 2\n" - " 6: Phi(4, 0) [4]\n" + "BasicBlock 3, pred: 5, 2, succ: 2\n" + " 6: Phi(0, 4) [4]\n" " 7: Goto\n" "BasicBlock 4\n" // Synthesized blocks to avoid critical edge. @@ -298,8 +298,8 @@ TEST(SsaTest, Loop4) { " 2: Goto\n" "BasicBlock 1, pred: 0, succ: 4\n" " 3: Goto\n" - "BasicBlock 2, pred: 3, 4, succ: 5, 3\n" - " 4: Phi(1, 0) [9, 5, 5]\n" + "BasicBlock 2, pred: 4, 3, succ: 5, 3\n" + " 4: Phi(0, 1) [9, 5, 5]\n" " 5: Equal(4, 4) [6]\n" " 6: If(5)\n" "BasicBlock 3, pred: 2, succ: 2\n" @@ -339,8 +339,8 @@ TEST(SsaTest, Loop5) { " 6: Goto\n" "BasicBlock 3, pred: 1, succ: 8\n" " 7: Goto\n" - "BasicBlock 4, pred: 5, 8, succ: 6, 5\n" - " 8: Phi(8, 14) [8, 12, 9, 9]\n" + "BasicBlock 4, pred: 8, 5, succ: 6, 5\n" + " 8: Phi(14, 8) [8, 12, 9, 9]\n" " 9: Equal(8, 8) [10]\n" " 10: If(9)\n" "BasicBlock 5, pred: 4, succ: 4\n" |