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());
         }
       }
     }