diff options
| -rw-r--r-- | compiler/optimizing/loop_analysis.h | 4 | ||||
| -rw-r--r-- | compiler/optimizing/nodes.h | 8 | ||||
| -rw-r--r-- | test/530-checker-peel-unroll/src/Main.java | 108 |
3 files changed, 113 insertions, 7 deletions
diff --git a/compiler/optimizing/loop_analysis.h b/compiler/optimizing/loop_analysis.h index c09d3ff00f..7f321b73c8 100644 --- a/compiler/optimizing/loop_analysis.h +++ b/compiler/optimizing/loop_analysis.h @@ -113,9 +113,7 @@ class LoopAnalysis : public ValueObject { instruction->IsUnresolvedStaticFieldGet() || instruction->IsUnresolvedStaticFieldSet() || // TODO: Support loops with intrinsified invokes. - instruction->IsInvoke() || - // TODO: Support loops with ClinitChecks. - instruction->IsClinitCheck()); + instruction->IsInvoke()); } }; diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index 975ad1c324..825779989c 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -5155,6 +5155,7 @@ class HDivZeroCheck FINAL : public HExpression<1> { SetRawInputAt(0, value); } + bool IsClonable() const OVERRIDE { return true; } bool CanBeMoved() const OVERRIDE { return true; } bool InstructionDataEquals(const HInstruction* other ATTRIBUTE_UNUSED) const OVERRIDE { @@ -5606,6 +5607,7 @@ class HTypeConversion FINAL : public HExpression<1> { DataType::Type GetInputType() const { return GetInput()->GetType(); } DataType::Type GetResultType() const { return GetType(); } + bool IsClonable() const OVERRIDE { return true; } bool CanBeMoved() const OVERRIDE { return true; } bool InstructionDataEquals(const HInstruction* other ATTRIBUTE_UNUSED) const OVERRIDE { return true; @@ -6641,8 +6643,7 @@ class HClinitCheck FINAL : public HExpression<1> { dex_pc) { SetRawInputAt(0, constant); } - - bool IsClonable() const OVERRIDE { return true; } + // TODO: Make ClinitCheck clonable. bool CanBeMoved() const OVERRIDE { return true; } bool InstructionDataEquals(const HInstruction* other ATTRIBUTE_UNUSED) const OVERRIDE { return true; @@ -7112,6 +7113,8 @@ class HInstanceOf FINAL : public HTypeCheckInstruction { bitstring_mask, SideEffectsForArchRuntimeCalls(check_kind)) {} + bool IsClonable() const OVERRIDE { return true; } + bool NeedsEnvironment() const OVERRIDE { return CanCallRuntime(GetTypeCheckKind()); } @@ -7201,6 +7204,7 @@ class HCheckCast FINAL : public HTypeCheckInstruction { bitstring_mask, SideEffects::CanTriggerGC()) {} + bool IsClonable() const OVERRIDE { return true; } bool NeedsEnvironment() const OVERRIDE { // Instruction may throw a CheckCastError. return true; diff --git a/test/530-checker-peel-unroll/src/Main.java b/test/530-checker-peel-unroll/src/Main.java index 804c9fe916..11c29649ff 100644 --- a/test/530-checker-peel-unroll/src/Main.java +++ b/test/530-checker-peel-unroll/src/Main.java @@ -53,11 +53,17 @@ public class Main { } private static final void initIntArray(int[] a) { - for (int i = 0; i < LENGTH; i++) { + for (int i = 0; i < a.length; i++) { a[i] = i % 4; } } + private static final void initDoubleArray(double[] a) { + for (int i = 0; i < a.length; i++) { + a[i] = (double)(i % 4); + } + } + /// CHECK-START: void Main.unrollingLoadStoreElimination(int[]) loop_optimization (before) /// CHECK-DAG: <<Array:l\d+>> ParameterValue loop:none /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none @@ -684,6 +690,96 @@ public class Main { return s + t; } + /// CHECK-START: void Main.unrollingInstanceOf(int[], java.lang.Object[]) loop_optimization (before) + /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none + /// CHECK-DAG: Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none + /// CHECK-DAG: InstanceOf loop:<<Loop>> outer_loop:none + // + /// CHECK-NOT: InstanceOf + + /// CHECK-START: void Main.unrollingInstanceOf(int[], java.lang.Object[]) loop_optimization (after) + /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none + /// CHECK-DAG: Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none + /// CHECK-DAG: InstanceOf loop:<<Loop>> outer_loop:none + /// CHECK-DAG: InstanceOf loop:<<Loop>> outer_loop:none + // + /// CHECK-NOT: InstanceOf + public void unrollingInstanceOf(int[] a, Object[] obj_array) { + for (int i = 0; i < LENGTH_B; i++) { + if (obj_array[i] instanceof Integer) { + a[i] += 1; + } + } + } + + /// CHECK-START: void Main.unrollingDivZeroCheck(int[], int) loop_optimization (before) + /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none + /// CHECK-DAG: Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none + /// CHECK-DAG: DivZeroCheck loop:<<Loop>> outer_loop:none + // + /// CHECK-NOT: DivZeroCheck + + /// CHECK-START: void Main.unrollingDivZeroCheck(int[], int) loop_optimization (after) + /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none + /// CHECK-DAG: Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none + /// CHECK-DAG: DivZeroCheck loop:<<Loop>> outer_loop:none + /// CHECK-DAG: DivZeroCheck loop:<<Loop>> outer_loop:none + // + /// CHECK-NOT: DivZeroCheck + public void unrollingDivZeroCheck(int[] a, int r) { + for (int i = 0; i < LENGTH_B; i++) { + a[i] += a[i] / r; + } + } + + /// CHECK-START: void Main.unrollingTypeConversion(int[], double[]) loop_optimization (before) + /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none + /// CHECK-DAG: Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none + /// CHECK-DAG: TypeConversion loop:<<Loop>> outer_loop:none + // + /// CHECK-NOT: TypeConversion + + /// CHECK-START: void Main.unrollingTypeConversion(int[], double[]) loop_optimization (after) + /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none + /// CHECK-DAG: Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none + /// CHECK-DAG: TypeConversion loop:<<Loop>> outer_loop:none + /// CHECK-DAG: TypeConversion loop:<<Loop>> outer_loop:none + // + /// CHECK-NOT: TypeConversion + public void unrollingTypeConversion(int[] a, double[] b) { + for (int i = 0; i < LENGTH_B; i++) { + a[i] = (int) b[i]; + } + } + + interface Itf { + } + + class SubMain extends Main implements Itf { + } + + /// CHECK-START: void Main.unrollingCheckCast(int[], java.lang.Object) loop_optimization (before) + /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none + /// CHECK-DAG: Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none + /// CHECK-DAG: CheckCast loop:<<Loop>> outer_loop:none + // + /// CHECK-NOT: CheckCast + + /// CHECK-START: void Main.unrollingCheckCast(int[], java.lang.Object) loop_optimization (after) + /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none + /// CHECK-DAG: Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none + /// CHECK-DAG: CheckCast loop:<<Loop>> outer_loop:none + /// CHECK-DAG: CheckCast loop:<<Loop>> outer_loop:none + // + /// CHECK-NOT: CheckCast + public void unrollingCheckCast(int[] a, Object o) { + for (int i = 0; i < LENGTH_B; i++) { + if (((SubMain)o) == o) { + a[i] = i; + } + } + } + /// CHECK-START: void Main.noUnrollingOddTripCount(int[]) loop_optimization (before) /// CHECK-DAG: <<Array:l\d+>> ParameterValue loop:none /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none @@ -985,9 +1081,17 @@ public class Main { initMatrix(mB); initMatrix(mC); - int expected = 174291419; + int expected = 174291515; int found = 0; + double[] doubleArray = new double[LENGTH_B]; + initDoubleArray(doubleArray); + + unrollingInstanceOf(a, new Integer[LENGTH_B]); + unrollingDivZeroCheck(a, 15); + unrollingTypeConversion(a, doubleArray); + unrollingCheckCast(a, new SubMain()); + unrollingWhile(a); unrollingLoadStoreElimination(a); unrollingSwitch(a); |