Merge "Initiate a constant propagation pass in the optimizing compiler."
diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc
index 8282795..376d1af 100644
--- a/compiler/optimizing/nodes.cc
+++ b/compiler/optimizing/nodes.cc
@@ -194,6 +194,11 @@
}
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 10d471c..d98d2ad 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -338,6 +338,13 @@
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 65675dc..d541a62 100644
--- a/compiler/optimizing/ssa_phi_elimination.cc
+++ b/compiler/optimizing/ssa_phi_elimination.cc
@@ -83,6 +83,10 @@
}
}
+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 @@
// 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 99fd9eb..ad3b205 100644
--- a/compiler/optimizing/ssa_test.cc
+++ b/compiler/optimizing/ssa_test.cc
@@ -207,8 +207,8 @@
"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 @@
" 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 @@
" 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"