diff options
| author | 2015-11-10 18:31:55 +0000 | |
|---|---|---|
| committer | 2015-11-10 18:31:55 +0000 | |
| commit | feaf26db63a62bce5a80550f500efa67ff64424f (patch) | |
| tree | 4df965d3e647ae9a6d62b28e747e6da03c30c052 | |
| parent | 969670298516b9316b36270fcc4c21bfcd499595 (diff) | |
| parent | 9e23df5c21bed53ead79e3131b67105abc8871e4 (diff) | |
Merge "Optimizing: Improve constant folding + DCE for inlining."
| -rw-r--r-- | compiler/optimizing/inliner.cc | 2 | ||||
| -rw-r--r-- | compiler/optimizing/nodes.cc | 2 | ||||
| -rw-r--r-- | compiler/optimizing/nodes.h | 13 | ||||
| -rw-r--r-- | test/442-checker-constant-folding/src/Main.java | 28 | ||||
| -rw-r--r-- | test/548-checker-inlining-and-dce/expected.txt | 0 | ||||
| -rw-r--r-- | test/548-checker-inlining-and-dce/info.txt | 1 | ||||
| -rw-r--r-- | test/548-checker-inlining-and-dce/src/Main.java | 85 |
7 files changed, 130 insertions, 1 deletions
diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc index 353881e47a..c9319f5d07 100644 --- a/compiler/optimizing/inliner.cc +++ b/compiler/optimizing/inliner.cc @@ -406,8 +406,8 @@ bool HInliner::TryBuildAndInline(ArtMethod* resolved_method, &type_propagation, &sharpening, &simplify, - &dce, &fold, + &dce, }; for (size_t i = 0; i < arraysize(optimizations); ++i) { diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc index 8100b58ae6..716888a269 100644 --- a/compiler/optimizing/nodes.cc +++ b/compiler/optimizing/nodes.cc @@ -1095,6 +1095,8 @@ HConstant* HBinaryOperation::TryStaticEvaluation() const { } else if (GetRight()->IsLongConstant()) { return Evaluate(GetLeft()->AsLongConstant(), GetRight()->AsLongConstant()); } + } else if (GetLeft()->IsNullConstant() && GetRight()->IsNullConstant()) { + return Evaluate(GetLeft()->AsNullConstant(), GetRight()->AsNullConstant()); } return nullptr; } diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index a3f3d17b9d..7ea6176e96 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -2595,6 +2595,11 @@ class HBinaryOperation : public HExpression<2> { VLOG(compiler) << DebugName() << " is not defined for the (long, int) case."; return nullptr; } + virtual HConstant* Evaluate(HNullConstant* x ATTRIBUTE_UNUSED, + HNullConstant* y ATTRIBUTE_UNUSED) const { + VLOG(compiler) << DebugName() << " is not defined for the (null, null) case."; + return nullptr; + } // Returns an input that can legally be used as the right input and is // constant, or null. @@ -2685,6 +2690,10 @@ class HEqual : public HCondition { return GetBlock()->GetGraph()->GetIntConstant( Compute(x->GetValue(), y->GetValue()), GetDexPc()); } + HConstant* Evaluate(HNullConstant* x ATTRIBUTE_UNUSED, + HNullConstant* y ATTRIBUTE_UNUSED) const OVERRIDE { + return GetBlock()->GetGraph()->GetConstant(GetType(), 1); + } DECLARE_INSTRUCTION(Equal); @@ -2717,6 +2726,10 @@ class HNotEqual : public HCondition { return GetBlock()->GetGraph()->GetIntConstant( Compute(x->GetValue(), y->GetValue()), GetDexPc()); } + HConstant* Evaluate(HNullConstant* x ATTRIBUTE_UNUSED, + HNullConstant* y ATTRIBUTE_UNUSED) const OVERRIDE { + return GetBlock()->GetGraph()->GetConstant(GetType(), 0); + } DECLARE_INSTRUCTION(NotEqual); diff --git a/test/442-checker-constant-folding/src/Main.java b/test/442-checker-constant-folding/src/Main.java index 59e7282ac7..43bc9d06a2 100644 --- a/test/442-checker-constant-folding/src/Main.java +++ b/test/442-checker-constant-folding/src/Main.java @@ -659,6 +659,33 @@ public class Main { /** + * Exercise constant folding on constant (static) condition for null references. + */ + + /// CHECK-START: int Main.StaticConditionNulls() constant_folding_after_inlining (before) + /// CHECK-DAG: <<Null:l\d+>> NullConstant + /// CHECK-DAG: <<Cond:z\d+>> NotEqual [<<Null>>,<<Null>>] + /// CHECK-DAG: If [<<Cond>>] + + /// CHECK-START: int Main.StaticConditionNulls() constant_folding_after_inlining (after) + /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 + /// CHECK-DAG: If [<<Const0>>] + + /// CHECK-START: int Main.StaticConditionNulls() constant_folding_after_inlining (after) + /// CHECK-NOT: NotEqual + + private static Object getNull() { + return null; + } + + public static int StaticConditionNulls() { + Object a = getNull(); + Object b = getNull(); + return (a == b) ? 5 : 2; + } + + + /** * Exercise constant folding on a program with condition * (i.e. jumps) leading to the creation of many blocks. * @@ -1208,6 +1235,7 @@ public class Main { assertLongEquals(9, XorLongInt()); assertIntEquals(5, StaticCondition()); + assertIntEquals(5, StaticConditionNulls()); assertIntEquals(7, JumpsAndConditionals(true)); assertIntEquals(3, JumpsAndConditionals(false)); diff --git a/test/548-checker-inlining-and-dce/expected.txt b/test/548-checker-inlining-and-dce/expected.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/548-checker-inlining-and-dce/expected.txt diff --git a/test/548-checker-inlining-and-dce/info.txt b/test/548-checker-inlining-and-dce/info.txt new file mode 100644 index 0000000000..3255d6bbc4 --- /dev/null +++ b/test/548-checker-inlining-and-dce/info.txt @@ -0,0 +1 @@ +Test that inlining works when code preventing inlining is eliminated by DCE. diff --git a/test/548-checker-inlining-and-dce/src/Main.java b/test/548-checker-inlining-and-dce/src/Main.java new file mode 100644 index 0000000000..38fdcc0b94 --- /dev/null +++ b/test/548-checker-inlining-and-dce/src/Main.java @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2015 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. + */ + +public class Main { + + private void inlinedForNull(Iterable it) { + if (it != null) { + // We're not inlining invoke-interface at the moment. + it.iterator(); + } + } + + private void inlinedForFalse(boolean value, Iterable it) { + if (value) { + // We're not inlining invoke-interface at the moment. + it.iterator(); + } + } + + /// CHECK-START: void Main.testInlinedForFalseInlined(java.lang.Iterable) inliner (before) + /// CHECK: InvokeStaticOrDirect + + /// CHECK-START: void Main.testInlinedForFalseInlined(java.lang.Iterable) inliner (after) + /// CHECK-NOT: InvokeStaticOrDirect + /// CHECK-NOT: InvokeInterface + + public void testInlinedForFalseInlined(Iterable it) { + inlinedForFalse(false, it); + } + + /// CHECK-START: void Main.testInlinedForFalseNotInlined(java.lang.Iterable) inliner (before) + /// CHECK: InvokeStaticOrDirect + + /// CHECK-START: void Main.testInlinedForFalseNotInlined(java.lang.Iterable) inliner (after) + /// CHECK: InvokeStaticOrDirect + + public void testInlinedForFalseNotInlined(Iterable it) { + inlinedForFalse(true, it); + } + + /// CHECK-START: void Main.testInlinedForNullInlined(java.lang.Iterable) inliner (before) + /// CHECK: InvokeStaticOrDirect + + /// CHECK-START: void Main.testInlinedForNullInlined(java.lang.Iterable) inliner (after) + /// CHECK-NOT: InvokeStaticOrDirect + /// CHECK-NOT: InvokeInterface + + public void testInlinedForNullInlined(Iterable it) { + inlinedForNull(null); + } + + /// CHECK-START: void Main.testInlinedForNullNotInlined(java.lang.Iterable) inliner (before) + /// CHECK: InvokeStaticOrDirect + + /// CHECK-START: void Main.testInlinedForNullNotInlined(java.lang.Iterable) inliner (after) + /// CHECK: InvokeStaticOrDirect + + public void testInlinedForNullNotInlined(Iterable it) { + inlinedForNull(it); + } + + public static void main(String[] args) { + Main m = new Main(); + Iterable it = new Iterable() { + public java.util.Iterator iterator() { return null; } + }; + m.testInlinedForFalseInlined(it); + m.testInlinedForFalseNotInlined(it); + m.testInlinedForNullInlined(it); + m.testInlinedForNullNotInlined(it); + } +} |