diff options
author | Nicolas Geoffray <ngeoffray@google.com> | 2015-06-19 16:17:05 +0100 |
---|---|---|
committer | Nicolas Geoffray <ngeoffray@google.com> | 2015-06-22 12:38:56 +0100 |
commit | 1e256bf257e8d97df9b2178ae8658b731ca2d662 (patch) | |
tree | aa13e2795a2b9e1469a941af4856ae1751cf48db /compiler | |
parent | bbcec62c0484fbfb82ee2c317e8afa478a63027b (diff) | |
download | art-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')
-rw-r--r-- | compiler/optimizing/constant_folding_test.cc | 4 | ||||
-rw-r--r-- | compiler/optimizing/dead_code_elimination_test.cc | 6 | ||||
-rw-r--r-- | compiler/optimizing/nodes.cc | 5 | ||||
-rw-r--r-- | compiler/optimizing/nodes.h | 14 | ||||
-rw-r--r-- | compiler/optimizing/ssa_test.cc | 14 |
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" |