Member value propagation for instance-get instructions
Change-Id: I6191e2e4fa63ceb589f83c954b047d1c0efa2fb2
diff --git a/src/main/java/com/android/tools/r8/graph/DexEncodedField.java b/src/main/java/com/android/tools/r8/graph/DexEncodedField.java
index 670e510..27ba1a1 100644
--- a/src/main/java/com/android/tools/r8/graph/DexEncodedField.java
+++ b/src/main/java/com/android/tools/r8/graph/DexEncodedField.java
@@ -168,7 +168,8 @@
boolean isWritten = appView.appInfo().isFieldWrittenByFieldPutInstruction(this);
if (!isWritten) {
// Since the field is not written, we can simply return the default value for the type.
- return getStaticValue().asConstInstruction(code, dest, appView.options());
+ DexValue value = isStatic() ? getStaticValue() : DexValue.defaultForType(field.type);
+ return value.asConstInstruction(code, dest, appView.options());
}
// The only way to figure out whether the DexValue contains the final value is ensure the value
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 ccd346b..401fd36 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
@@ -26,6 +26,7 @@
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.InstanceGet;
import com.android.tools.r8.ir.code.Instruction;
import com.android.tools.r8.ir.code.InstructionListIterator;
import com.android.tools.r8.ir.code.InvokeMethod;
@@ -386,6 +387,35 @@
}
}
+ private void rewriteInstanceGetWithConstantValues(
+ IRCode code,
+ Set<Value> affectedValues,
+ InstructionListIterator iterator,
+ InstanceGet current) {
+ if (current.object().getTypeLattice().isNullable()) {
+ return;
+ }
+
+ DexField field = current.getField();
+
+ // TODO(b/123857022): Should be able to use definitionFor().
+ DexEncodedField target = appView.appInfo().lookupInstanceTarget(field.holder, field);
+ if (target == null || !mayPropagateValueFor(target)) {
+ return;
+ }
+
+ // Check if a this value is known const.
+ ConstInstruction replacement = target.valueAsConstInstruction(code, current.dest(), appView);
+ if (replacement != null) {
+ affectedValues.add(replacement.outValue());
+ iterator.replaceCurrentInstruction(replacement);
+ if (replacement.isDexItemBasedConstString()) {
+ code.method.getMutableOptimizationInfo().markUseIdentifierNameString();
+ }
+ target.getMutableOptimizationInfo().markAsPropagated();
+ }
+ }
+
private void insertAssumeNotNull(
IRCode code,
Set<Value> affectedValues,
@@ -437,6 +467,9 @@
blocks,
iterator,
current.asStaticGet());
+ } else if (current.isInstanceGet()) {
+ rewriteInstanceGetWithConstantValues(
+ code, affectedValues, iterator, current.asInstanceGet());
}
}
}