Make shallow abstractValueSupplier a singleton
Change-Id: I6b324cf2d928108e3fc685f2522248fda496db19
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/constant/SparseConditionalConstantPropagation.java b/src/main/java/com/android/tools/r8/ir/analysis/constant/SparseConditionalConstantPropagation.java
index 892ff11..5fb46a9 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/constant/SparseConditionalConstantPropagation.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/constant/SparseConditionalConstantPropagation.java
@@ -6,8 +6,10 @@
import com.android.tools.r8.graph.AppInfo;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexString;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.analysis.value.AbstractValue;
import com.android.tools.r8.ir.analysis.value.AbstractValueJoiner.AbstractValueConstantPropagationJoiner;
+import com.android.tools.r8.ir.code.AbstractValueSupplier;
import com.android.tools.r8.ir.code.BasicBlock;
import com.android.tools.r8.ir.code.ConstNumber;
import com.android.tools.r8.ir.code.IRCode;
@@ -67,7 +69,7 @@
return new SparseConditionalConstantPropagationOnCode(code).analyze().run();
}
- private class SparseConditionalConstantPropagationOnCode {
+ private class SparseConditionalConstantPropagationOnCode implements AbstractValueSupplier {
private final IRCode code;
private final Map<Value, AbstractValue> mapping = new IdentityHashMap<>();
@@ -170,8 +172,7 @@
InstructionListIterator iterator = block.listIterator();
iterator.nextUntil(i -> i == definition);
if (!definition.isArgument()
- && !definition.instructionMayHaveSideEffects(
- appView, code.context(), this::getCachedAbstractValue)) {
+ && !definition.instructionMayHaveSideEffects(appView, code.context(), this)) {
ConstNumber replacement =
ConstNumber.builder().setOutValue(value).setValue(constValue).build();
iterator.replaceCurrentInstruction(replacement, affectedValues);
@@ -245,8 +246,7 @@
code.context().getOptimizationInfo().getArgumentInfos();
value = argumentInfos.getAbstractArgumentValue(index);
} else {
- value =
- instruction.getAbstractValue(appView, code.context(), this::getCachedAbstractValue);
+ value = instruction.getAbstractValue(appView, code.context(), this);
}
AbstractValue previousValue = getCachedAbstractValue(instruction.outValue());
assert joiner.lessThanOrEqualTo(previousValue, value, instruction.getOutType());
@@ -359,5 +359,10 @@
}
return previousExecutable.get(from);
}
+
+ @Override
+ public AbstractValue getAbstractValue(Value value, AppView<?> appView, ProgramMethod context) {
+ return getCachedAbstractValue(value);
+ }
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/AbstractValueSupplier.java b/src/main/java/com/android/tools/r8/ir/code/AbstractValueSupplier.java
index 757d5d7..d6e40ed 100644
--- a/src/main/java/com/android/tools/r8/ir/code/AbstractValueSupplier.java
+++ b/src/main/java/com/android/tools/r8/ir/code/AbstractValueSupplier.java
@@ -10,29 +10,23 @@
public interface AbstractValueSupplier {
- UnknownAbstractValueSupplier UNKNOWN = new UnknownAbstractValueSupplier();
+ AbstractValueSupplier UNKNOWN = (value, appView, context) -> AbstractValue.unknown();
+ AbstractValueSupplier SHALLOW =
+ (value, appView, context) -> value.getAbstractValue(appView, context, unknown());
- AbstractValue getAbstractValue(Value value);
+ AbstractValue getAbstractValue(Value value, AppView<?> appView, ProgramMethod context);
/**
- * Returns an {@link AbstractValueSupplier} that supplies a {@link UnknownAbstractValueSupplier}
- * in the recursive call to {@link Value#getAbstractValue}, so that a shallow value is computed.
- * This is to prevent that computing the abstract value can end up evaluating large arithmetic
- * expressions, which should ideally only be done during constant propagation.
+ * Returns an {@link AbstractValueSupplier} that supplies UNKNOWN in the recursive call to {@link
+ * Value#getAbstractValue}, so that a shallow value is computed. This is to prevent that computing
+ * the abstract value can end up evaluating large arithmetic expressions, which should ideally
+ * only be done during constant propagation.
*/
- static AbstractValueSupplier getShallow(AppView<?> appView, ProgramMethod context) {
- return value -> value.getAbstractValue(appView, context, unknown());
+ static AbstractValueSupplier shallow() {
+ return SHALLOW;
}
- static UnknownAbstractValueSupplier unknown() {
+ static AbstractValueSupplier unknown() {
return UNKNOWN;
}
-
- class UnknownAbstractValueSupplier implements AbstractValueSupplier {
-
- @Override
- public AbstractValue getAbstractValue(Value value) {
- return AbstractValue.unknown();
- }
- }
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/ArithmeticBinop.java b/src/main/java/com/android/tools/r8/ir/code/ArithmeticBinop.java
index 654aff1..fd16968 100644
--- a/src/main/java/com/android/tools/r8/ir/code/ArithmeticBinop.java
+++ b/src/main/java/com/android/tools/r8/ir/code/ArithmeticBinop.java
@@ -136,8 +136,10 @@
if (outValue.hasLocalInfo()) {
return AbstractValue.unknown();
}
- AbstractValue leftAbstractValue = abstractValueSupplier.getAbstractValue(leftValue());
- AbstractValue rightAbstractValue = abstractValueSupplier.getAbstractValue(rightValue());
+ AbstractValue leftAbstractValue =
+ abstractValueSupplier.getAbstractValue(leftValue(), appView, context);
+ AbstractValue rightAbstractValue =
+ abstractValueSupplier.getAbstractValue(rightValue(), appView, context);
if (leftAbstractValue.isSingleNumberValue() && rightAbstractValue.isSingleNumberValue()) {
SingleNumberValue leftConst = leftAbstractValue.asSingleNumberValue();
SingleNumberValue rightConst = rightAbstractValue.asSingleNumberValue();
diff --git a/src/main/java/com/android/tools/r8/ir/code/Cmp.java b/src/main/java/com/android/tools/r8/ir/code/Cmp.java
index fae64e1..b9d83f71 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Cmp.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Cmp.java
@@ -165,8 +165,10 @@
if (outValue.hasLocalInfo()) {
return AbstractValue.unknown();
}
- AbstractValue leftAbstractValue = abstractValueSupplier.getAbstractValue(leftValue());
- AbstractValue rightAbstractValue = abstractValueSupplier.getAbstractValue(rightValue());
+ AbstractValue leftAbstractValue =
+ abstractValueSupplier.getAbstractValue(leftValue(), appView, context);
+ AbstractValue rightAbstractValue =
+ abstractValueSupplier.getAbstractValue(rightValue(), appView, context);
if (leftAbstractValue.isSingleNumberValue() && rightAbstractValue.isSingleNumberValue()) {
SingleNumberValue leftConst = leftAbstractValue.asSingleNumberValue();
SingleNumberValue rightConst = rightAbstractValue.asSingleNumberValue();
diff --git a/src/main/java/com/android/tools/r8/ir/code/Div.java b/src/main/java/com/android/tools/r8/ir/code/Div.java
index 6325179..f5c5593 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Div.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Div.java
@@ -140,7 +140,8 @@
if (!instructionTypeCanThrow()) {
return false;
}
- AbstractValue rightAbstractValue = abstractValueSupplier.getAbstractValue(rightValue());
+ AbstractValue rightAbstractValue =
+ abstractValueSupplier.getAbstractValue(rightValue(), appView, context);
if (rightAbstractValue.isSingleNumberValue() && !rightAbstractValue.isZero()) {
return false;
}
@@ -159,7 +160,8 @@
@Override
public AbstractValue getAbstractValue(
AppView<?> appView, ProgramMethod context, AbstractValueSupplier abstractValueSupplier) {
- AbstractValue rightAbstractValue = abstractValueSupplier.getAbstractValue(rightValue());
+ AbstractValue rightAbstractValue =
+ abstractValueSupplier.getAbstractValue(rightValue(), appView, context);
if (!rightAbstractValue.isZero()) {
return super.getAbstractValue(appView, context, abstractValueSupplier);
}
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 d200922..565e62f 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
@@ -641,8 +641,7 @@
}
public final boolean instructionMayHaveSideEffects(AppView<?> appView, ProgramMethod context) {
- return instructionMayHaveSideEffects(
- appView, context, AbstractValueSupplier.getShallow(appView, context));
+ return instructionMayHaveSideEffects(appView, context, AbstractValueSupplier.shallow());
}
public final boolean instructionMayHaveSideEffects(
@@ -654,7 +653,7 @@
public final boolean instructionMayHaveSideEffects(
AppView<?> appView, ProgramMethod context, SideEffectAssumption assumption) {
return instructionMayHaveSideEffects(
- appView, context, AbstractValueSupplier.getShallow(appView, context), assumption);
+ appView, context, AbstractValueSupplier.shallow(), assumption);
}
public boolean instructionMayHaveSideEffects(
@@ -673,8 +672,7 @@
AppView<?> appView, ProgramMethod context);
public final boolean instructionInstanceCanThrow(AppView<?> appView, ProgramMethod context) {
- return instructionInstanceCanThrow(
- appView, context, AbstractValueSupplier.getShallow(appView, context));
+ return instructionInstanceCanThrow(appView, context, AbstractValueSupplier.shallow());
}
public final boolean instructionInstanceCanThrow(
@@ -686,7 +684,7 @@
public final boolean instructionInstanceCanThrow(
AppView<?> appView, ProgramMethod context, SideEffectAssumption assumption) {
return instructionInstanceCanThrow(
- appView, context, AbstractValueSupplier.getShallow(appView, context), assumption);
+ appView, context, AbstractValueSupplier.shallow(), assumption);
}
public boolean instructionInstanceCanThrow(
diff --git a/src/main/java/com/android/tools/r8/ir/code/LogicalBinop.java b/src/main/java/com/android/tools/r8/ir/code/LogicalBinop.java
index a197004..47a0470 100644
--- a/src/main/java/com/android/tools/r8/ir/code/LogicalBinop.java
+++ b/src/main/java/com/android/tools/r8/ir/code/LogicalBinop.java
@@ -113,8 +113,10 @@
if (outValue.hasLocalInfo()) {
return AbstractValue.unknown();
}
- AbstractValue leftAbstractValue = abstractValueSupplier.getAbstractValue(leftValue());
- AbstractValue rightAbstractValue = abstractValueSupplier.getAbstractValue(rightValue());
+ AbstractValue leftAbstractValue =
+ abstractValueSupplier.getAbstractValue(leftValue(), appView, context);
+ AbstractValue rightAbstractValue =
+ abstractValueSupplier.getAbstractValue(rightValue(), appView, context);
if (leftAbstractValue.isSingleNumberValue() && rightAbstractValue.isSingleNumberValue()) {
SingleNumberValue leftConst = leftAbstractValue.asSingleNumberValue();
SingleNumberValue rightConst = rightAbstractValue.asSingleNumberValue();
diff --git a/src/main/java/com/android/tools/r8/ir/code/Neg.java b/src/main/java/com/android/tools/r8/ir/code/Neg.java
index 46b1c59..b578927 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Neg.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Neg.java
@@ -89,7 +89,8 @@
if (outValue.hasLocalInfo()) {
return AbstractValue.unknown();
}
- AbstractValue sourceLattice = abstractValueSupplier.getAbstractValue(source());
+ AbstractValue sourceLattice =
+ abstractValueSupplier.getAbstractValue(source(), appView, context);
if (sourceLattice.isSingleNumberValue()) {
SingleNumberValue sourceConst = sourceLattice.asSingleNumberValue();
long newConst;
diff --git a/src/main/java/com/android/tools/r8/ir/code/Not.java b/src/main/java/com/android/tools/r8/ir/code/Not.java
index 2a98b81..09901ea 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Not.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Not.java
@@ -46,7 +46,8 @@
if (outValue.hasLocalInfo()) {
return AbstractValue.unknown();
}
- AbstractValue sourceLattice = abstractValueSupplier.getAbstractValue(source());
+ AbstractValue sourceLattice =
+ abstractValueSupplier.getAbstractValue(source(), appView, context);
if (sourceLattice.isSingleNumberValue()) {
SingleNumberValue sourceConst = sourceLattice.asSingleNumberValue();
long newConst;
diff --git a/src/main/java/com/android/tools/r8/ir/code/Rem.java b/src/main/java/com/android/tools/r8/ir/code/Rem.java
index fae9c59..3c53f35 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Rem.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Rem.java
@@ -139,7 +139,8 @@
if (!instructionTypeCanThrow()) {
return false;
}
- AbstractValue rightAbstractValue = abstractValueSupplier.getAbstractValue(rightValue());
+ AbstractValue rightAbstractValue =
+ abstractValueSupplier.getAbstractValue(rightValue(), appView, context);
if (rightAbstractValue.isSingleNumberValue() && !rightAbstractValue.isZero()) {
return false;
}
@@ -161,7 +162,8 @@
if (outValue.hasLocalInfo()) {
return AbstractValue.unknown();
}
- AbstractValue rightLattice = abstractValueSupplier.getAbstractValue(rightValue());
+ AbstractValue rightLattice =
+ abstractValueSupplier.getAbstractValue(rightValue(), appView, context);
if (!rightLattice.isZero()) {
return super.getAbstractValue(appView, context, abstractValueSupplier);
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfoCollector.java b/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfoCollector.java
index 91477cd..fd48de4 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfoCollector.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfoCollector.java
@@ -213,8 +213,7 @@
feedback.methodReturnsArgument(method, definition.asArgument().getIndex());
}
AbstractValue abstractReturnValue =
- definition.getAbstractValue(
- appView, context, AbstractValueSupplier.getShallow(appView, context));
+ definition.getAbstractValue(appView, context, AbstractValueSupplier.shallow());
if (abstractReturnValue.isNonTrivial()) {
feedback.methodReturnsAbstractValue(method, appView, abstractReturnValue);
if (checkCastAndInstanceOfMethodSpecialization != null) {
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagator.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagator.java
index 0b5d053..898b72d 100644
--- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagator.java
+++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagator.java
@@ -131,8 +131,6 @@
ProgramMethod method, IRCode code, MethodProcessor methodProcessor, Timing timing) {
if (codeScanner != null) {
assert methodProcessor.isPrimaryMethodProcessor();
- AbstractValueSupplier abstractValueSupplier =
- value -> value.getAbstractValue(appView, method);
PathConstraintSupplier pathConstraintSupplier =
new PathConstraintSupplier(
appView,
@@ -140,7 +138,12 @@
codeScanner.getFieldValueFactory(),
codeScanner.getMethodParameterFactory());
codeScanner.scan(
- method, code, methodProcessor, abstractValueSupplier, pathConstraintSupplier, timing);
+ method,
+ code,
+ methodProcessor,
+ AbstractValueSupplier.shallow(),
+ pathConstraintSupplier,
+ timing);
assert effectivelyUnusedArgumentsAnalysis != null;
effectivelyUnusedArgumentsAnalysis.scan(method, code, pathConstraintSupplier);
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorCodeScanner.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorCodeScanner.java
index 516f0e2..5f33057 100644
--- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorCodeScanner.java
+++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorCodeScanner.java
@@ -369,7 +369,7 @@
return ConcreteArrayTypeValueState.create(nullability);
}
- AbstractValue abstractValue = abstractValueSupplier.getAbstractValue(value);
+ AbstractValue abstractValue = abstractValueSupplier.getAbstractValue(value, appView, context);
if (abstractValue.isUnknown()) {
abstractValue =
getFallbackAbstractValueForField(
@@ -1006,7 +1006,7 @@
return ConcreteArrayTypeValueState.create(nullability);
}
- AbstractValue abstractValue = abstractValueSupplier.getAbstractValue(value);
+ AbstractValue abstractValue = abstractValueSupplier.getAbstractValue(value, appView, context);
// For class types, we track both the abstract value and the dynamic type. If both are
// unknown, then use UnknownParameterState.