Migrate utils to create constant replacement to AbstractValue.
Bug: 69963623
Change-Id: Id94d5a8e071077c59a99936e18b65e606d100ab5
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/value/AbstractValue.java b/src/main/java/com/android/tools/r8/ir/analysis/value/AbstractValue.java
index 32e2621..eae4fc8 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/value/AbstractValue.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/value/AbstractValue.java
@@ -11,7 +11,11 @@
* concretization of this abstract value has size 1).
*/
public boolean isSingleValue() {
- return isSingleEnumValue() || isSingleNumberValue() || isSingleStringValue();
+ return false;
+ }
+
+ public SingleValue asSingleValue() {
+ return null;
}
public boolean isSingleEnumValue() {
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/value/SingleEnumValue.java b/src/main/java/com/android/tools/r8/ir/analysis/value/SingleEnumValue.java
index a9050ef..8573c36 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/value/SingleEnumValue.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/value/SingleEnumValue.java
@@ -4,9 +4,15 @@
package com.android.tools.r8.ir.analysis.value;
+import com.android.tools.r8.errors.Unreachable;
+import com.android.tools.r8.graph.AppInfoWithSubtyping;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexField;
+import com.android.tools.r8.ir.code.IRCode;
+import com.android.tools.r8.ir.code.Instruction;
+import com.android.tools.r8.ir.code.TypeAndLocalInfoSupplier;
-public class SingleEnumValue extends AbstractValue {
+public class SingleEnumValue extends SingleValue {
private final DexField field;
@@ -34,4 +40,12 @@
public int hashCode() {
return System.identityHashCode(this);
}
+
+ @Override
+ public Instruction createMaterializingInstruction(
+ AppView<? extends AppInfoWithSubtyping> appView,
+ IRCode code,
+ TypeAndLocalInfoSupplier info) {
+ throw new Unreachable("unless we store single enum as a method's returned value.");
+ }
}
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/value/SingleNumberValue.java b/src/main/java/com/android/tools/r8/ir/analysis/value/SingleNumberValue.java
index 914516a..949dbb5 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/value/SingleNumberValue.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/value/SingleNumberValue.java
@@ -4,7 +4,17 @@
package com.android.tools.r8.ir.analysis.value;
-public class SingleNumberValue extends AbstractValue {
+import com.android.tools.r8.graph.AppInfoWithSubtyping;
+import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.DebugLocalInfo;
+import com.android.tools.r8.ir.analysis.type.TypeLatticeElement;
+import com.android.tools.r8.ir.code.ConstNumber;
+import com.android.tools.r8.ir.code.IRCode;
+import com.android.tools.r8.ir.code.Instruction;
+import com.android.tools.r8.ir.code.TypeAndLocalInfoSupplier;
+import com.android.tools.r8.ir.code.Value;
+
+public class SingleNumberValue extends SingleValue {
private final long value;
@@ -36,4 +46,16 @@
public int hashCode() {
return System.identityHashCode(this);
}
+
+ @Override
+ public Instruction createMaterializingInstruction(
+ AppView<? extends AppInfoWithSubtyping> appView, IRCode code, TypeAndLocalInfoSupplier info) {
+ TypeLatticeElement typeLattice = info.getTypeLattice();
+ DebugLocalInfo debugLocalInfo = info.getLocalInfo();
+ assert !typeLattice.isReference() || value == 0;
+ Value returnedValue =
+ code.createValue(
+ typeLattice.isReference() ? TypeLatticeElement.NULL : typeLattice, debugLocalInfo);
+ return new ConstNumber(returnedValue, value);
+ }
}
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/value/SingleStringValue.java b/src/main/java/com/android/tools/r8/ir/analysis/value/SingleStringValue.java
index acb2f69..d2a8726 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/value/SingleStringValue.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/value/SingleStringValue.java
@@ -4,9 +4,22 @@
package com.android.tools.r8.ir.analysis.value;
-import com.android.tools.r8.graph.DexString;
+import static com.android.tools.r8.ir.analysis.type.Nullability.definitelyNotNull;
+import static com.android.tools.r8.ir.analysis.type.TypeLatticeElement.stringClassType;
-public class SingleStringValue extends AbstractValue {
+import com.android.tools.r8.graph.AppInfoWithSubtyping;
+import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.DebugLocalInfo;
+import com.android.tools.r8.graph.DexString;
+import com.android.tools.r8.ir.analysis.type.TypeLatticeElement;
+import com.android.tools.r8.ir.code.BasicBlock.ThrowingInfo;
+import com.android.tools.r8.ir.code.ConstString;
+import com.android.tools.r8.ir.code.IRCode;
+import com.android.tools.r8.ir.code.Instruction;
+import com.android.tools.r8.ir.code.TypeAndLocalInfoSupplier;
+import com.android.tools.r8.ir.code.Value;
+
+public class SingleStringValue extends SingleValue {
private final DexString string;
@@ -38,4 +51,26 @@
public int hashCode() {
return string.hashCode();
}
+
+ @Override
+ public Instruction createMaterializingInstruction(
+ AppView<? extends AppInfoWithSubtyping> appView,
+ IRCode code,
+ TypeAndLocalInfoSupplier info) {
+ TypeLatticeElement typeLattice = info.getTypeLattice();
+ DebugLocalInfo debugLocalInfo = info.getLocalInfo();
+ assert typeLattice.isClassType();
+ assert appView
+ .isSubtype(
+ appView.dexItemFactory().stringType,
+ typeLattice.asClassTypeLatticeElement().getClassType())
+ .isTrue();
+ Value returnedValue =
+ code.createValue(stringClassType(appView, definitelyNotNull()), debugLocalInfo);
+ ConstString instruction =
+ new ConstString(
+ returnedValue, string, ThrowingInfo.defaultForConstString(appView.options()));
+ assert !instruction.instructionInstanceCanThrow();
+ return instruction;
+ }
}
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/value/SingleValue.java b/src/main/java/com/android/tools/r8/ir/analysis/value/SingleValue.java
new file mode 100644
index 0000000..9972328
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/ir/analysis/value/SingleValue.java
@@ -0,0 +1,29 @@
+// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.ir.analysis.value;
+
+import com.android.tools.r8.graph.AppInfoWithSubtyping;
+import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.ir.code.IRCode;
+import com.android.tools.r8.ir.code.Instruction;
+import com.android.tools.r8.ir.code.TypeAndLocalInfoSupplier;
+
+public abstract class SingleValue extends AbstractValue {
+
+ @Override
+ public boolean isSingleValue() {
+ return true;
+ }
+
+ @Override
+ public SingleValue asSingleValue() {
+ return this;
+ }
+
+ public abstract Instruction createMaterializingInstruction(
+ AppView<? extends AppInfoWithSubtyping> appView,
+ IRCode code,
+ TypeAndLocalInfoSupplier info);
+}
diff --git a/src/main/java/com/android/tools/r8/ir/code/Instruction.java b/src/main/java/com/android/tools/r8/ir/code/Instruction.java
index 309b424..7452a66 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Instruction.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Instruction.java
@@ -40,7 +40,7 @@
import java.util.Set;
import java.util.function.Function;
-public abstract class Instruction implements InstructionOrPhi {
+public abstract class Instruction implements InstructionOrPhi, TypeAndLocalInfoSupplier {
protected Value outValue = null;
protected final List<Value> inValues = new ArrayList<>();
@@ -138,6 +138,14 @@
return oldOutValue;
}
+ @Override
+ public TypeLatticeElement getTypeLattice() {
+ if (hasOutValue()) {
+ return outValue().getTypeLattice();
+ }
+ return null;
+ }
+
public void addDebugValue(Value value) {
assert value.hasLocalInfo();
if (debugValues == null) {
@@ -595,6 +603,7 @@
public abstract int maxOutValueRegister();
+ @Override
public DebugLocalInfo getLocalInfo() {
return outValue == null ? null : outValue.getLocalInfo();
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/TypeAndLocalInfoSupplier.java b/src/main/java/com/android/tools/r8/ir/code/TypeAndLocalInfoSupplier.java
new file mode 100644
index 0000000..f5ca688
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/ir/code/TypeAndLocalInfoSupplier.java
@@ -0,0 +1,13 @@
+// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.ir.code;
+
+import com.android.tools.r8.graph.DebugLocalInfo;
+import com.android.tools.r8.ir.analysis.type.TypeLatticeElement;
+
+public interface TypeAndLocalInfoSupplier {
+ DebugLocalInfo getLocalInfo();
+ TypeLatticeElement getTypeLattice();
+}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/MemberValuePropagation.java b/src/main/java/com/android/tools/r8/ir/optimize/MemberValuePropagation.java
index adc1112..a2c60a3 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/MemberValuePropagation.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/MemberValuePropagation.java
@@ -3,27 +3,20 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.ir.optimize;
-import static com.android.tools.r8.ir.analysis.type.Nullability.definitelyNotNull;
-import static com.android.tools.r8.ir.analysis.type.TypeLatticeElement.stringClassType;
-
import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DebugLocalInfo;
import com.android.tools.r8.graph.DexDefinition;
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexReference;
-import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.ir.analysis.type.Nullability;
import com.android.tools.r8.ir.analysis.type.TypeAnalysis;
import com.android.tools.r8.ir.analysis.type.TypeLatticeElement;
+import com.android.tools.r8.ir.analysis.value.AbstractValue;
import com.android.tools.r8.ir.code.BasicBlock;
-import com.android.tools.r8.ir.code.BasicBlock.ThrowingInfo;
import com.android.tools.r8.ir.code.ConstInstruction;
-import com.android.tools.r8.ir.code.ConstNumber;
-import com.android.tools.r8.ir.code.ConstString;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.IRMetadata;
import com.android.tools.r8.ir.code.InstanceGet;
@@ -128,14 +121,15 @@
}
ProguardMemberRuleReturnValue returnValueRule = rule.getReturnValue();
- TypeLatticeElement typeLattice = instruction.outValue().getTypeLattice();
// Check if this value can be assumed constant.
if (returnValueRule.isSingleValue()) {
- return createConstNumberReplacement(
- code, returnValueRule.getSingleValue(), typeLattice, instruction.getLocalInfo());
+ return appView.abstractValueFactory()
+ .createSingleNumberValue(returnValueRule.getSingleValue())
+ .createMaterializingInstruction(appView, code, instruction);
}
+ TypeLatticeElement typeLattice = instruction.outValue().getTypeLattice();
if (returnValueRule.isField()) {
DexField field = returnValueRule.getField();
assert typeLattice
@@ -176,35 +170,6 @@
return null;
}
- private static ConstNumber createConstNumberReplacement(
- IRCode code, long constant, TypeLatticeElement typeLattice, DebugLocalInfo debugLocalInfo) {
- assert !typeLattice.isReference() || constant == 0;
- Value returnedValue =
- code.createValue(
- typeLattice.isReference() ? TypeLatticeElement.NULL : typeLattice, debugLocalInfo);
- return new ConstNumber(returnedValue, constant);
- }
-
- private ConstString createConstStringReplacement(
- IRCode code,
- DexString constant,
- TypeLatticeElement typeLattice,
- DebugLocalInfo debugLocalInfo) {
- assert typeLattice.isClassType();
- assert appView
- .isSubtype(
- appView.dexItemFactory().stringType,
- typeLattice.asClassTypeLatticeElement().getClassType())
- .isTrue();
- Value returnedValue =
- code.createValue(stringClassType(appView, definitelyNotNull()), debugLocalInfo);
- ConstString instruction =
- new ConstString(
- returnedValue, constant, ThrowingInfo.defaultForConstString(appView.options()));
- assert !instruction.instructionInstanceCanThrow();
- return instruction;
- }
-
private void setValueRangeFromProguardRule(ProguardMemberRule rule, Value value) {
if (rule.hasReturnValue() && rule.getReturnValue().isValueRange()) {
assert !rule.getReturnValue().isSingleValue();
@@ -307,20 +272,12 @@
if (target == null || !mayPropagateValueFor(target)) {
return;
}
- if (target.getOptimizationInfo().returnsConstant()) {
- ConstInstruction replacement;
- if (target.getOptimizationInfo().returnsConstantNumber()) {
- long constant = target.getOptimizationInfo().getReturnedConstantNumber();
- replacement =
- createConstNumberReplacement(
- code, constant, current.outValue().getTypeLattice(), current.getLocalInfo());
- } else {
- assert target.getOptimizationInfo().returnsConstantString();
- DexString constant = target.getOptimizationInfo().getReturnedConstantString();
- replacement =
- createConstStringReplacement(
- code, constant, current.outValue().getTypeLattice(), current.getLocalInfo());
- }
+
+ AbstractValue abstractReturnValue = target.getOptimizationInfo().getAbstractReturnValue();
+ if (abstractReturnValue.isSingleValue()) {
+ Instruction replacement =
+ abstractReturnValue.asSingleValue()
+ .createMaterializingInstruction(appView, code, current);
affectedValues.addAll(current.outValue().affectedValues());
current.outValue().replaceUsers(replacement.outValue());
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/DefaultMethodOptimizationInfo.java b/src/main/java/com/android/tools/r8/ir/optimize/info/DefaultMethodOptimizationInfo.java
index 3b64d1c..e6d0589 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/DefaultMethodOptimizationInfo.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/DefaultMethodOptimizationInfo.java
@@ -5,7 +5,6 @@
package com.android.tools.r8.ir.optimize.info;
import com.android.tools.r8.graph.DexEncodedMethod.ClassInlinerEligibility;
-import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.ir.analysis.type.ClassTypeLatticeElement;
import com.android.tools.r8.ir.analysis.type.TypeLatticeElement;
@@ -27,7 +26,7 @@
static int UNKNOWN_RETURNED_ARGUMENT = -1;
static boolean UNKNOWN_NEVER_RETURNS_NULL = false;
static boolean UNKNOWN_NEVER_RETURNS_NORMALLY = false;
- static AbstractValue UNKNOWN_CONSTANT_VALUE = UnknownValue.getInstance();
+ static AbstractValue UNKNOWN_ABSTRACT_RETURN_VALUE = UnknownValue.getInstance();
static TypeLatticeElement UNKNOWN_TYPE = null;
static ClassTypeLatticeElement UNKNOWN_CLASS_TYPE = null;
static boolean DOES_NOT_USE_IDENTIFIER_NAME_STRING = false;
@@ -141,30 +140,13 @@
}
@Override
- public boolean returnsConstantNumber() {
- return UNKNOWN_CONSTANT_VALUE.isSingleNumberValue();
- }
-
- @Override
- public boolean returnsConstantString() {
- return UNKNOWN_CONSTANT_VALUE.isSingleStringValue();
- }
-
- @Override
public ClassInlinerEligibility getClassInlinerEligibility() {
return UNKNOWN_CLASS_INLINER_ELIGIBILITY;
}
@Override
- public long getReturnedConstantNumber() {
- assert returnsConstantNumber();
- return UNKNOWN_CONSTANT_VALUE.asSingleNumberValue().getValue();
- }
-
- @Override
- public DexString getReturnedConstantString() {
- assert returnsConstantString();
- return UNKNOWN_CONSTANT_VALUE.asSingleStringValue().getDexString();
+ public AbstractValue getAbstractReturnValue() {
+ return UNKNOWN_ABSTRACT_RETURN_VALUE;
}
@Override
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfo.java b/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfo.java
index 93cdc1b..26aab1b 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfo.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfo.java
@@ -5,10 +5,10 @@
package com.android.tools.r8.ir.optimize.info;
import com.android.tools.r8.graph.DexEncodedMethod.ClassInlinerEligibility;
-import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.ir.analysis.type.ClassTypeLatticeElement;
import com.android.tools.r8.ir.analysis.type.TypeLatticeElement;
+import com.android.tools.r8.ir.analysis.value.AbstractValue;
import com.android.tools.r8.ir.optimize.info.ParameterUsagesInfo.ParameterUsage;
import com.android.tools.r8.ir.optimize.info.initializer.ClassInitializerInfo;
import com.android.tools.r8.ir.optimize.info.initializer.InstanceInitializerInfo;
@@ -55,14 +55,6 @@
boolean neverReturnsNormally();
- default boolean returnsConstant() {
- return returnsConstantNumber() || returnsConstantString();
- }
-
- boolean returnsConstantNumber();
-
- boolean returnsConstantString();
-
ClassInlinerEligibility getClassInlinerEligibility();
Set<DexType> getInitializedClassesOnNormalExit();
@@ -73,9 +65,7 @@
boolean isInitializerEnablingJavaAssertions();
- long getReturnedConstantNumber();
-
- DexString getReturnedConstantString();
+ AbstractValue getAbstractReturnValue();
boolean forceInline();
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/UpdatableMethodOptimizationInfo.java b/src/main/java/com/android/tools/r8/ir/optimize/info/UpdatableMethodOptimizationInfo.java
index d553a4c..8bb6fc3 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/UpdatableMethodOptimizationInfo.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/UpdatableMethodOptimizationInfo.java
@@ -35,7 +35,8 @@
private boolean neverReturnsNull = DefaultMethodOptimizationInfo.UNKNOWN_NEVER_RETURNS_NULL;
private boolean neverReturnsNormally =
DefaultMethodOptimizationInfo.UNKNOWN_NEVER_RETURNS_NORMALLY;
- private AbstractValue constantValue = DefaultMethodOptimizationInfo.UNKNOWN_CONSTANT_VALUE;
+ private AbstractValue abstractReturnValue =
+ DefaultMethodOptimizationInfo.UNKNOWN_ABSTRACT_RETURN_VALUE;
private TypeLatticeElement returnsObjectWithUpperBoundType =
DefaultMethodOptimizationInfo.UNKNOWN_TYPE;
private ClassTypeLatticeElement returnsObjectWithLowerBoundType =
@@ -93,7 +94,7 @@
returnValueOnlyDependsOnArguments = template.returnValueOnlyDependsOnArguments;
neverReturnsNull = template.neverReturnsNull;
neverReturnsNormally = template.neverReturnsNormally;
- constantValue = template.constantValue;
+ abstractReturnValue = template.abstractReturnValue;
returnsObjectWithUpperBoundType = template.returnsObjectWithUpperBoundType;
returnsObjectWithLowerBoundType = template.returnsObjectWithLowerBoundType;
inlining = template.inlining;
@@ -235,30 +236,13 @@
}
@Override
- public boolean returnsConstantNumber() {
- return constantValue.isSingleNumberValue();
- }
-
- @Override
- public boolean returnsConstantString() {
- return constantValue.isSingleStringValue();
- }
-
- @Override
public ClassInlinerEligibility getClassInlinerEligibility() {
return classInlinerEligibility;
}
@Override
- public long getReturnedConstantNumber() {
- assert returnsConstantNumber();
- return constantValue.asSingleNumberValue().getValue();
- }
-
- @Override
- public DexString getReturnedConstantString() {
- assert returnsConstantString();
- return constantValue.asSingleStringValue().getDexString();
+ public AbstractValue getAbstractReturnValue() {
+ return abstractReturnValue;
}
@Override
@@ -356,21 +340,21 @@
}
void markReturnsConstantNumber(AppView<?> appView, long value) {
- assert !constantValue.isSingleStringValue();
- assert !constantValue.isSingleNumberValue()
- || constantValue.asSingleNumberValue().getValue() == value
+ assert !abstractReturnValue.isSingleStringValue();
+ assert !abstractReturnValue.isSingleNumberValue()
+ || abstractReturnValue.asSingleNumberValue().getValue() == value
: "return constant number changed from "
- + constantValue.asSingleNumberValue().getValue() + " to " + value;
- constantValue = appView.abstractValueFactory().createSingleNumberValue(value);
+ + abstractReturnValue.asSingleNumberValue().getValue() + " to " + value;
+ abstractReturnValue = appView.abstractValueFactory().createSingleNumberValue(value);
}
void markReturnsConstantString(AppView<?> appView, DexString value) {
- assert !constantValue.isSingleNumberValue();
- assert !constantValue.isSingleStringValue()
- || constantValue.asSingleStringValue().getDexString() == value
+ assert !abstractReturnValue.isSingleNumberValue();
+ assert !abstractReturnValue.isSingleStringValue()
+ || abstractReturnValue.asSingleStringValue().getDexString() == value
: "return constant string changed from "
- + constantValue.asSingleStringValue().getDexString() + " to " + value;
- constantValue = appView.abstractValueFactory().createSingleStringValue(value);
+ + abstractReturnValue.asSingleStringValue().getDexString() + " to " + value;
+ abstractReturnValue = appView.abstractValueFactory().createSingleStringValue(value);
}
void markReturnsObjectWithUpperBoundType(AppView<?> appView, TypeLatticeElement type) {