summaryrefslogtreecommitdiffstats
path: root/compiler/optimizing
diff options
context:
space:
mode:
authorNicolas Geoffray <ngeoffray@google.com>2014-09-18 15:02:40 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2014-09-18 15:02:41 +0000
commitaaadf03fd8d9f6a50a3b8b4b916e7cc161e4edba (patch)
tree2447d33b3338e2448f061aaeff471bd9342325d3 /compiler/optimizing
parent6aa606c9284ac31961f4c5b20c3645ac78acfaad (diff)
parent604c6e4764edb2fd244e9f47626868cda5644a7a (diff)
downloadart-aaadf03fd8d9f6a50a3b8b4b916e7cc161e4edba.zip
art-aaadf03fd8d9f6a50a3b8b4b916e7cc161e4edba.tar.gz
art-aaadf03fd8d9f6a50a3b8b4b916e7cc161e4edba.tar.bz2
Merge "Ensure the first predecessor of a loop is the pre header."
Diffstat (limited to 'compiler/optimizing')
-rw-r--r--compiler/optimizing/nodes.cc5
-rw-r--r--compiler/optimizing/nodes.h7
-rw-r--r--compiler/optimizing/ssa_phi_elimination.cc9
3 files changed, 20 insertions, 1 deletions
diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc
index 7b5a78e..06a55e8 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 b012cef..a4c8ce5 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(predecessors_.Size() == 2);
+ 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 @@ 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) {