summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Mingyao Yang <mingyao@google.com> 2017-11-21 14:44:54 -0800
committer Mingyao Yang <mingyao@google.com> 2017-11-22 10:46:57 -0800
commitcebb5e709af5ed5b475a56743f984967d991e7b9 (patch)
treedb2b6c243606979c905ec10a5cced999eba0f209
parent8cceb1faf894c26b89ceacd3d60599fe0b4b93b7 (diff)
type conversion elimination for constant input
type conversion on constant input can be eliminated if the constant value falls in the result type's range. Test: run-test on host, 711-checker-type-conversion Change-Id: I372139d681aa06fa6e760d7814c86ac949292813
-rw-r--r--compiler/optimizing/data_type.h13
-rw-r--r--compiler/optimizing/instruction_simplifier.cc10
-rw-r--r--test/711-checker-type-conversion/expected.txt0
-rw-r--r--test/711-checker-type-conversion/info.txt1
-rw-r--r--test/711-checker-type-conversion/src/Main.java71
5 files changed, 95 insertions, 0 deletions
diff --git a/compiler/optimizing/data_type.h b/compiler/optimizing/data_type.h
index 75a7fbe6ca..d253036479 100644
--- a/compiler/optimizing/data_type.h
+++ b/compiler/optimizing/data_type.h
@@ -186,6 +186,7 @@ class DataType {
}
static bool IsTypeConversionImplicit(Type input_type, Type result_type);
+ static bool IsTypeConversionImplicit(int64_t value, Type result_type);
static const char* PrettyDescriptor(Type type);
@@ -213,6 +214,18 @@ inline bool DataType::IsTypeConversionImplicit(Type input_type, Type result_type
MaxValueOfIntegralType(input_type) <= MaxValueOfIntegralType(result_type));
}
+inline bool DataType::IsTypeConversionImplicit(int64_t value, Type result_type) {
+ if (IsIntegralType(result_type) && result_type != Type::kInt64) {
+ // If the constant value falls in the range of the result_type, type
+ // conversion isn't needed.
+ return value >= MinValueOfIntegralType(result_type) &&
+ value <= MaxValueOfIntegralType(result_type);
+ }
+ // Conversion isn't implicit if it's into non-integer types, or 64-bit int
+ // which may have different number of registers.
+ return false;
+}
+
} // namespace art
#endif // ART_COMPILER_OPTIMIZING_DATA_TYPE_H_
diff --git a/compiler/optimizing/instruction_simplifier.cc b/compiler/optimizing/instruction_simplifier.cc
index fbfee12be9..a6dfa475eb 100644
--- a/compiler/optimizing/instruction_simplifier.cc
+++ b/compiler/optimizing/instruction_simplifier.cc
@@ -1159,6 +1159,16 @@ void InstructionSimplifierVisitor::VisitTypeConversion(HTypeConversion* instruct
RecordSimplification();
return;
}
+ } else if (input->IsIntConstant()) {
+ // Try to eliminate type conversion on int constant whose value falls into
+ // the range of the result type.
+ int32_t value = input->AsIntConstant()->GetValue();
+ if (DataType::IsTypeConversionImplicit(value, result_type)) {
+ instruction->ReplaceWith(input);
+ instruction->GetBlock()->RemoveInstruction(instruction);
+ RecordSimplification();
+ return;
+ }
}
}
diff --git a/test/711-checker-type-conversion/expected.txt b/test/711-checker-type-conversion/expected.txt
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/711-checker-type-conversion/expected.txt
diff --git a/test/711-checker-type-conversion/info.txt b/test/711-checker-type-conversion/info.txt
new file mode 100644
index 0000000000..5b63572a76
--- /dev/null
+++ b/test/711-checker-type-conversion/info.txt
@@ -0,0 +1 @@
+Tests for type conversion elimination.
diff --git a/test/711-checker-type-conversion/src/Main.java b/test/711-checker-type-conversion/src/Main.java
new file mode 100644
index 0000000000..64ffcd2f1f
--- /dev/null
+++ b/test/711-checker-type-conversion/src/Main.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2017 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 {
+
+ public static void assertByteEquals(byte expected, byte result) {
+ if (expected != result) {
+ throw new Error("Expected: " + expected + ", found: " + result);
+ }
+ }
+
+ /// CHECK-START: byte Main.getByte1() instruction_simplifier (before)
+ /// CHECK: TypeConversion
+ /// CHECK: TypeConversion
+ /// CHECK: Add
+ /// CHECK: TypeConversion
+
+ /// CHECK-START: byte Main.getByte1() instruction_simplifier (after)
+ /// CHECK-NOT: TypeConversion
+ /// CHECK: Add
+ /// CHECK: TypeConversion
+
+ /// CHECK-START: byte Main.getByte1() instruction_simplifier$before_codegen (after)
+ /// CHECK-NOT: Add
+ /// CHECK-NOT: TypeConversion
+
+ static byte getByte1() {
+ int i = -2;
+ int j = -3;
+ return (byte)((byte)i + (byte)j);
+ }
+
+ /// CHECK-START: byte Main.getByte2() instruction_simplifier (before)
+ /// CHECK: TypeConversion
+ /// CHECK: TypeConversion
+ /// CHECK: Add
+ /// CHECK: TypeConversion
+
+ /// CHECK-START: byte Main.getByte2() instruction_simplifier (after)
+ /// CHECK-NOT: TypeConversion
+ /// CHECK: Add
+ /// CHECK: TypeConversion
+
+ /// CHECK-START: byte Main.getByte2() instruction_simplifier$before_codegen (after)
+ /// CHECK-NOT: Add
+ /// CHECK: TypeConversion
+
+ static byte getByte2() {
+ int i = -100;
+ int j = -101;
+ return (byte)((byte)i + (byte)j);
+ }
+
+ public static void main(String[] args) {
+ assertByteEquals(getByte1(), (byte)-5);
+ assertByteEquals(getByte2(), (byte)(-201));
+ }
+}