summaryrefslogtreecommitdiffstats
path: root/compiler/optimizing
diff options
context:
space:
mode:
authorNicolas Geoffray <ngeoffray@google.com>2015-06-19 16:17:05 +0100
committerNicolas Geoffray <ngeoffray@google.com>2015-06-22 12:38:56 +0100
commit1e256bf257e8d97df9b2178ae8658b731ca2d662 (patch)
treeaa13e2795a2b9e1469a941af4856ae1751cf48db /compiler/optimizing
parentbbcec62c0484fbfb82ee2c317e8afa478a63027b (diff)
downloadart-1e256bf257e8d97df9b2178ae8658b731ca2d662.zip
art-1e256bf257e8d97df9b2178ae8658b731ca2d662.tar.gz
art-1e256bf257e8d97df9b2178ae8658b731ca2d662.tar.bz2
Be careful with predecessor/successor index.
When we simplify the CFG, we must preserve things that were already simplified. For example, the index in the predecessor list or successor list of a block must be preserved for ensuring the first block is a loop pre header. bug:21867463 (cherry picked from commit 8b20f88b0a8d1b374dd5eaae289d19734c77b8f8) Change-Id: I2581b5a50942290da96cd9ec876f6f2573e0a6c4
Diffstat (limited to 'compiler/optimizing')
-rw-r--r--compiler/optimizing/constant_folding_test.cc4
-rw-r--r--compiler/optimizing/dead_code_elimination_test.cc6
-rw-r--r--compiler/optimizing/nodes.cc5
-rw-r--r--compiler/optimizing/nodes.h14
-rw-r--r--compiler/optimizing/ssa_test.cc14
5 files changed, 29 insertions, 14 deletions
diff --git a/compiler/optimizing/constant_folding_test.cc b/compiler/optimizing/constant_folding_test.cc
index 422223f..11f6362 100644
--- a/compiler/optimizing/constant_folding_test.cc
+++ b/compiler/optimizing/constant_folding_test.cc
@@ -627,8 +627,8 @@ TEST(ConstantFolding, ConstantCondition) {
" 9: If(8)\n"
"BasicBlock 2, pred: 1, succ: 3\n"
" 12: Goto 3\n"
- "BasicBlock 3, pred: 2, 5, succ: 4\n"
- " 22: Phi(3, 5) [15]\n"
+ "BasicBlock 3, pred: 5, 2, succ: 4\n"
+ " 22: Phi(5, 3) [15]\n"
" 15: Add(22, 3)\n"
" 17: ReturnVoid\n"
"BasicBlock 4, pred: 3\n"
diff --git a/compiler/optimizing/dead_code_elimination_test.cc b/compiler/optimizing/dead_code_elimination_test.cc
index 3209d3e..ee3a61a 100644
--- a/compiler/optimizing/dead_code_elimination_test.cc
+++ b/compiler/optimizing/dead_code_elimination_test.cc
@@ -89,8 +89,8 @@ TEST(DeadCodeElimination, AdditionAndConditionalJump) {
" 9: If(8)\n"
"BasicBlock 2, pred: 1, succ: 3\n"
" 12: Goto 3\n"
- "BasicBlock 3, pred: 2, 5, succ: 4\n"
- " 22: Phi(3, 5) [15]\n"
+ "BasicBlock 3, pred: 5, 2, succ: 4\n"
+ " 22: Phi(5, 3) [15]\n"
" 15: Add(22, 3)\n"
" 17: ReturnVoid\n"
"BasicBlock 4, pred: 3\n"
@@ -101,7 +101,7 @@ TEST(DeadCodeElimination, AdditionAndConditionalJump) {
// Expected difference after dead code elimination.
diff_t expected_diff = {
{ " 3: IntConstant [15, 22, 8]\n", " 3: IntConstant [22, 8]\n" },
- { " 22: Phi(3, 5) [15]\n", " 22: Phi(3, 5)\n" },
+ { " 22: Phi(5, 3) [15]\n", " 22: Phi(5, 3)\n" },
{ " 15: Add(22, 3)\n", removed }
};
std::string expected_after = Patch(expected_before, expected_diff);
diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc
index fb150c3..c01364a 100644
--- a/compiler/optimizing/nodes.cc
+++ b/compiler/optimizing/nodes.cc
@@ -179,8 +179,9 @@ void HGraph::SplitCriticalEdge(HBasicBlock* block, HBasicBlock* successor) {
HBasicBlock* new_block = new (arena_) HBasicBlock(this, successor->GetDexPc());
AddBlock(new_block);
new_block->AddInstruction(new (arena_) HGoto());
- block->ReplaceSuccessor(successor, new_block);
- new_block->AddSuccessor(successor);
+ // Use `InsertBetween` to ensure the predecessor index and successor index of
+ // `block` and `successor` are preserved.
+ new_block->InsertBetween(block, successor);
if (successor->IsLoopHeader()) {
// If we split at a back edge boundary, make the new block the back edge.
HLoopInformation* info = successor->GetLoopInformation();
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index c1f1c9d..394e3fc 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -582,6 +582,20 @@ class HBasicBlock : public ArenaObject<kArenaAllocMisc> {
predecessors_.Put(predecessor_index, new_block);
}
+ // Insert `this` between `predecessor` and `successor. This method
+ // preserves the indicies, and will update the first edge found between
+ // `predecessor` and `successor`.
+ void InsertBetween(HBasicBlock* predecessor, HBasicBlock* successor) {
+ size_t predecessor_index = successor->GetPredecessorIndexOf(predecessor);
+ DCHECK_NE(predecessor_index, static_cast<size_t>(-1));
+ size_t successor_index = predecessor->GetSuccessorIndexOf(successor);
+ DCHECK_NE(successor_index, static_cast<size_t>(-1));
+ successor->predecessors_.Put(predecessor_index, this);
+ predecessor->successors_.Put(successor_index, this);
+ successors_.Add(successor);
+ predecessors_.Add(predecessor);
+ }
+
void RemovePredecessor(HBasicBlock* block) {
predecessors_.Delete(block);
}
diff --git a/compiler/optimizing/ssa_test.cc b/compiler/optimizing/ssa_test.cc
index fb3e7d7..0e8c058 100644
--- a/compiler/optimizing/ssa_test.cc
+++ b/compiler/optimizing/ssa_test.cc
@@ -115,7 +115,7 @@ TEST(SsaTest, CFG1) {
" 3: If(2)\n"
"BasicBlock 2, pred: 1, succ: 3\n"
" 4: Goto\n"
- "BasicBlock 3, pred: 2, 5, succ: 4\n"
+ "BasicBlock 3, pred: 5, 2, succ: 4\n"
" 5: ReturnVoid\n"
"BasicBlock 4, pred: 3\n"
" 6: Exit\n"
@@ -145,8 +145,8 @@ TEST(SsaTest, CFG2) {
" 4: If(3)\n"
"BasicBlock 2, pred: 1, succ: 3\n"
" 5: Goto\n"
- "BasicBlock 3, pred: 2, 5, succ: 4\n"
- " 6: Phi(1, 0) [7]\n"
+ "BasicBlock 3, pred: 5, 2, succ: 4\n"
+ " 6: Phi(0, 1) [7]\n"
" 7: Return(6)\n"
"BasicBlock 4, pred: 3\n"
" 8: Exit\n"
@@ -428,8 +428,8 @@ TEST(SsaTest, Loop7) {
" 10: Goto\n"
"BasicBlock 5, pred: 3, succ: 2\n"
" 11: Goto\n"
- "BasicBlock 6, pred: 4, 8, succ: 7\n"
- " 12: Phi(2, 5) [13]\n"
+ "BasicBlock 6, pred: 8, 4, succ: 7\n"
+ " 12: Phi(5, 2) [13]\n"
" 13: Return(12)\n"
"BasicBlock 7, pred: 6\n"
" 14: Exit\n"
@@ -480,7 +480,7 @@ TEST(SsaTest, LocalInIf) {
" 4: If(3)\n"
"BasicBlock 2, pred: 1, succ: 3\n"
" 5: Goto\n"
- "BasicBlock 3, pred: 2, 5, succ: 4\n"
+ "BasicBlock 3, pred: 5, 2, succ: 4\n"
" 6: ReturnVoid\n"
"BasicBlock 4, pred: 3\n"
" 7: Exit\n"
@@ -517,7 +517,7 @@ TEST(SsaTest, MultiplePredecessors) {
" 8: Add(0, 0)\n"
" 9: Goto\n"
// This block should not get a phi for local 1.
- "BasicBlock 5, pred: 2, 4, 7, succ: 6\n"
+ "BasicBlock 5, pred: 2, 7, 4, succ: 6\n"
" 10: ReturnVoid\n"
"BasicBlock 6, pred: 5\n"
" 11: Exit\n"