summaryrefslogtreecommitdiff
path: root/compiler/optimizing/bounds_check_elimination.cc
diff options
context:
space:
mode:
author Aart Bik <ajcbik@google.com> 2016-11-01 14:23:58 -0700
committer Aart Bik <ajcbik@google.com> 2016-11-03 15:02:11 -0700
commit1e67748598b6beb3e3a7ac6fb96db66c415f6c2b (patch)
tree0a491c131a61c5718c95a382f3d943eb4a3d38dd /compiler/optimizing/bounds_check_elimination.cc
parentc4005c3e71e98edd4a5a91c75dbee3d97b7dcda1 (diff)
Avoid visiting just eliminated bounds check.
Test: test-art-host Bug: 32547652 Change-Id: Ifaed3d4eee08c6d044a41ade6c1ee73989489110
Diffstat (limited to 'compiler/optimizing/bounds_check_elimination.cc')
-rw-r--r--compiler/optimizing/bounds_check_elimination.cc26
1 files changed, 24 insertions, 2 deletions
diff --git a/compiler/optimizing/bounds_check_elimination.cc b/compiler/optimizing/bounds_check_elimination.cc
index d2357a5d05..7dc094b25f 100644
--- a/compiler/optimizing/bounds_check_elimination.cc
+++ b/compiler/optimizing/bounds_check_elimination.cc
@@ -548,7 +548,21 @@ class BCEVisitor : public HGraphVisitor {
void VisitBasicBlock(HBasicBlock* block) OVERRIDE {
DCHECK(!IsAddedBlock(block));
first_index_bounds_check_map_.clear();
- HGraphVisitor::VisitBasicBlock(block);
+ // Visit phis and instructions using a safe iterator. The iteration protects
+ // against deleting the current instruction during iteration. However, it
+ // must advance next_ if that instruction is deleted during iteration.
+ for (HInstruction* instruction = block->GetFirstPhi(); instruction != nullptr;) {
+ DCHECK(instruction->IsInBlock());
+ next_ = instruction->GetNext();
+ instruction->Accept(this);
+ instruction = next_;
+ }
+ for (HInstruction* instruction = block->GetFirstInstruction(); instruction != nullptr;) {
+ DCHECK(instruction->IsInBlock());
+ next_ = instruction->GetNext();
+ instruction->Accept(this);
+ instruction = next_;
+ }
// We should never deoptimize from an osr method, otherwise we might wrongly optimize
// code dominated by the deoptimization.
if (!GetGraph()->IsCompilingOsr()) {
@@ -1798,7 +1812,12 @@ class BCEVisitor : public HGraphVisitor {
}
/** Helper method to replace an instruction with another instruction. */
- static void ReplaceInstruction(HInstruction* instruction, HInstruction* replacement) {
+ void ReplaceInstruction(HInstruction* instruction, HInstruction* replacement) {
+ // Safe iteration.
+ if (instruction == next_) {
+ next_ = next_->GetNext();
+ }
+ // Replace and remove.
instruction->ReplaceWith(replacement);
instruction->GetBlock()->RemoveInstruction(instruction);
}
@@ -1831,6 +1850,9 @@ class BCEVisitor : public HGraphVisitor {
// Range analysis based on induction variables.
InductionVarRange induction_range_;
+ // Safe iteration.
+ HInstruction* next_;
+
DISALLOW_COPY_AND_ASSIGN(BCEVisitor);
};