diff options
author | 2016-11-01 14:23:58 -0700 | |
---|---|---|
committer | 2016-11-03 15:02:11 -0700 | |
commit | 1e67748598b6beb3e3a7ac6fb96db66c415f6c2b (patch) | |
tree | 0a491c131a61c5718c95a382f3d943eb4a3d38dd | |
parent | c4005c3e71e98edd4a5a91c75dbee3d97b7dcda1 (diff) |
Avoid visiting just eliminated bounds check.
Test: test-art-host
Bug: 32547652
Change-Id: Ifaed3d4eee08c6d044a41ade6c1ee73989489110
-rw-r--r-- | compiler/optimizing/bounds_check_elimination.cc | 26 | ||||
-rw-r--r-- | test/622-checker-bce-regressions/expected.txt | 1 | ||||
-rw-r--r-- | test/622-checker-bce-regressions/info.txt | 1 | ||||
-rw-r--r-- | test/622-checker-bce-regressions/src/Main.java | 55 |
4 files changed, 81 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); }; diff --git a/test/622-checker-bce-regressions/expected.txt b/test/622-checker-bce-regressions/expected.txt new file mode 100644 index 0000000000..b0aad4deb5 --- /dev/null +++ b/test/622-checker-bce-regressions/expected.txt @@ -0,0 +1 @@ +passed diff --git a/test/622-checker-bce-regressions/info.txt b/test/622-checker-bce-regressions/info.txt new file mode 100644 index 0000000000..a753dfa2ff --- /dev/null +++ b/test/622-checker-bce-regressions/info.txt @@ -0,0 +1 @@ +Regression tests on BCE. diff --git a/test/622-checker-bce-regressions/src/Main.java b/test/622-checker-bce-regressions/src/Main.java new file mode 100644 index 0000000000..6ba2644b97 --- /dev/null +++ b/test/622-checker-bce-regressions/src/Main.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Regression tests for BCE. + */ +public class Main { + + static int[] array = new int[10]; + + /// CHECK-START: int Main.doNotVisitAfterForwardBCE(int[]) BCE (before) + /// CHECK-DAG: BoundsCheck loop:<<Loop:B\d+>> outer_loop:none + /// CHECK-DAG: BoundsCheck loop:<<Loop>> outer_loop:none + // + /// CHECK-START: int Main.doNotVisitAfterForwardBCE(int[]) BCE (after) + /// CHECK-NOT: BoundsCheck + static int doNotVisitAfterForwardBCE(int[] a) { + if (a == null) { + throw new Error("Null"); + } + int k = 0; + int j = 0; + for (int i = 1; i < 10; i++) { + j = i - 1; + // b/32547652: after DCE, bounds checks become consecutive, + // and second should not be revisited after forward BCE. + k = a[i] + a[i - 1]; + } + return j; + } + + public static void main(String[] args) { + expectEquals(8, doNotVisitAfterForwardBCE(array)); + System.out.println("passed"); + } + + private static void expectEquals(int expected, int result) { + if (expected != result) { + throw new Error("Expected: " + expected + ", found: " + result); + } + } +} |