diff options
author | Yohann Roussel <yroussel@google.com> | 2016-12-21 20:41:05 +0100 |
---|---|---|
committer | Yohann Roussel <yroussel@google.com> | 2017-03-15 16:39:36 +0100 |
commit | 65fde2592b460fa184ca61adb939add9a9aa320c (patch) | |
tree | b27852e514d4d5501ee482991ad45571a3a97232 | |
parent | 40a4bf725abf4edc27af28a610a682a9f9863214 (diff) | |
download | jack-65fde2592b460fa184ca61adb939add9a9aa320c.tar.gz |
Fix conditional simplificatationub-jack-douarn-rc4
- Take into account value and conditional conversions.
- Support unboxing of Object.
- Since we convert value and conditional, take care to not convert twice
the same conditional when it is the value of another conditional.
Test: PreSubmitTests
Bug: 32343452
Change-Id: Idbc77bbd8fceae81c5fd6f505dba7a0537df44f5
5 files changed, 59 insertions, 16 deletions
diff --git a/jack-tests/tests/com/android/jack/box/BoxTests.java b/jack-tests/tests/com/android/jack/box/BoxTests.java index 8729f385d..24a94e7c7 100644 --- a/jack-tests/tests/com/android/jack/box/BoxTests.java +++ b/jack-tests/tests/com/android/jack/box/BoxTests.java @@ -89,7 +89,6 @@ public class BoxTests extends RuntimeTest { @Test @Runtime - @KnownIssue public void test004() throws Exception { new RuntimeTestHelper(TEST004).setSourceLevel(SourceLevel.JAVA_7).compileAndRunTest(); } diff --git a/jack-tests/tests/com/android/jack/conditional/ConditionalTests.java b/jack-tests/tests/com/android/jack/conditional/ConditionalTests.java index 068128076..f97572d29 100644 --- a/jack-tests/tests/com/android/jack/conditional/ConditionalTests.java +++ b/jack-tests/tests/com/android/jack/conditional/ConditionalTests.java @@ -124,7 +124,6 @@ public class ConditionalTests extends RuntimeTest { @Test @Runtime @Category(RuntimeRegressionTest.class) - @KnownIssue public void test009() throws Exception { new RuntimeTestHelper(TEST009).compileAndRunTest(); } @@ -139,6 +138,6 @@ public class ConditionalTests extends RuntimeTest { rtTestInfos.add(TEST006); rtTestInfos.add(TEST007); rtTestInfos.add(TEST008); -// rtTestInfos.add(TEST009); + rtTestInfos.add(TEST009); } } diff --git a/jack-tests/tests/com/android/jack/conditional/test009/jack/ConditionalTest009.java b/jack-tests/tests/com/android/jack/conditional/test009/jack/ConditionalTest009.java index 5a98f8aa9..284d65440 100644 --- a/jack-tests/tests/com/android/jack/conditional/test009/jack/ConditionalTest009.java +++ b/jack-tests/tests/com/android/jack/conditional/test009/jack/ConditionalTest009.java @@ -29,6 +29,14 @@ public class ConditionalTest009 { public void test002() { Assert.assertEquals(35312635, get2()); } + @Test + public void test003() { + Assert.assertEquals(35312635, get3()); + } + @Test + public void test004() { + Assert.assertEquals(35312635, get4()); + } @SuppressWarnings("unused") public int get() { @@ -44,4 +52,19 @@ public class ConditionalTest009 { i >>>= (int) (float) 702730947; return i; } + + public int get3() { + int i = 35312635; + int s = 702730947; + Integer shift = (int) (true ? s : -1284717918.0f); + i >>>= shift; + return i; + } + + public int get4() { + int i = 35312635; + Integer s = 702730947; + i >>>= (int) (true ? s : -1284717918.0f); + return i; + } } diff --git a/jack/src/com/android/jack/ir/impl/JackIrBuilder.java b/jack/src/com/android/jack/ir/impl/JackIrBuilder.java index 705d780ca..ec4deeb52 100644 --- a/jack/src/com/android/jack/ir/impl/JackIrBuilder.java +++ b/jack/src/com/android/jack/ir/impl/JackIrBuilder.java @@ -704,21 +704,31 @@ public class JackIrBuilder { // One branch of (condition ? valueIfTrue : valueIfFalse) is dead code, // drop the dead code by keeping only (condition, value). // The condition must be kept even if its value is unused because it may have side effect - JExpression value; - JExpression condition; + Expression ecjValue; if (optimizedTrue) { assert !optimizedFalse; - value = pop(x.valueIfTrue); - condition = pop(x.condition); + ecjValue = x.valueIfTrue; } else { - value = pop(x.valueIfFalse); - condition = pop(x.condition); + ecjValue = x.valueIfFalse; } + JExpression value = pop(ecjValue); + JExpression condition = pop(x.condition); + + boolean isValueOptimizeConditional = ecjValue instanceof ConditionalExpression + && (isOptimizedTrue(((ConditionalExpression) ecjValue).condition) + || isOptimizedFalse(((ConditionalExpression) ecjValue).condition)); + // If value is a optimized conditional, it was already converted by the second call to + // generateImplicitConversion below. In this case, don't generate again the implicit + // conversion. + if (!isValueOptimizeConditional) { + value = generateImplicitConversion(ecjValue.implicitConversion, value); + } + + value = generateImplicitConversion(x.implicitConversion, value); if (condition instanceof JBooleanLiteral) { - push(generateImplicitConversion(x.implicitConversion, value)); + push(value); } else { - push(new JMultiExpression(info, condition, - generateImplicitConversion(x.implicitConversion, value))); + push(new JMultiExpression(info, condition, value)); } } else { JExpression valueIfFalse = pop(x.valueIfFalse); @@ -742,16 +752,25 @@ public class JackIrBuilder { JExpression convertedExpression = expr; + int typeIdTo = (implicitConversionCode & TypeIds.IMPLICIT_CONVERSION_MASK) >> 4; if ((implicitConversionCode & TypeIds.UNBOXING) != 0) { - final int typeId = implicitConversionCode & TypeIds.COMPILE_TYPE_MASK; - JPrimitiveType typeToUnbox = getJType(typeId); + int typeIdFrom = implicitConversionCode & TypeIds.COMPILE_TYPE_MASK; + JPrimitiveType typeToUnbox; + if (typeIdFrom == TypeIds.T_JavaLangObject) { + // Declared type is object, let's infer unboxed type from result type and cast to it + // before unboxing + typeToUnbox = getJType(typeIdTo); + convertedExpression = new JDynamicCastOperation(convertedExpression.getSourceInfo(), + convertedExpression, typeToUnbox.getWrapperType()); + } else { + typeToUnbox = getJType(typeIdFrom); + } assert typeToUnbox != null; convertedExpression = TypeLegalizer.unbox(convertedExpression, typeToUnbox.getWrapperType()); } - final int typeId = (implicitConversionCode & TypeIds.IMPLICIT_CONVERSION_MASK) >> 4; - JPrimitiveType primitiveType = getJType(typeId); + JPrimitiveType primitiveType = getJType(typeIdTo); if (primitiveType != null) { if (!primitiveType.isSameType(convertedExpression.getType())) { convertedExpression = new JDynamicCastOperation(convertedExpression.getSourceInfo(), diff --git a/jack/src/com/android/jack/transformations/ast/TypeLegalizer.java b/jack/src/com/android/jack/transformations/ast/TypeLegalizer.java index 0ad888dd4..e11815d22 100644 --- a/jack/src/com/android/jack/transformations/ast/TypeLegalizer.java +++ b/jack/src/com/android/jack/transformations/ast/TypeLegalizer.java @@ -35,6 +35,7 @@ import com.android.jack.ir.ast.JMethod; import com.android.jack.ir.ast.JMethodCall; import com.android.jack.ir.ast.JMethodId; import com.android.jack.ir.ast.JNewArray; +import com.android.jack.ir.ast.JNullType; import com.android.jack.ir.ast.JPolymorphicMethodCall; import com.android.jack.ir.ast.JPrimitiveType; import com.android.jack.ir.ast.JPrimitiveType.JPrimitiveTypeEnum; @@ -438,6 +439,8 @@ public class TypeLegalizer implements RunnableSchedulable<JMethod> { JMethodId unboxMethod = typeToUnbox.getOrCreateMethodId(methodName, Lists.<JType>create(), MethodKind.INSTANCE_VIRTUAL, returnType); + assert exprToUnbox.getType() == JNullType.INSTANCE + || exprToUnbox.getType().isSameType(typeToUnbox); JMethodCall unboxMethodCall = new JMethodCall(exprToUnbox.getSourceInfo(), exprToUnbox, typeToUnbox, unboxMethod, unboxMethod.getMethodIdWide().canBeVirtual()); |