Add support for iget/iput in virtual method hoister

Bug: b/241190995
Change-Id: I58f4fe00f8a768ab9d139dd78487aa54c7a0a992
diff --git a/src/main/java/com/android/tools/r8/ir/code/InstanceFieldInstruction.java b/src/main/java/com/android/tools/r8/ir/code/InstanceFieldInstruction.java
index faebe44..a9b3668 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InstanceFieldInstruction.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InstanceFieldInstruction.java
@@ -4,12 +4,17 @@
 
 package com.android.tools.r8.ir.code;
 
+import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
 import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.DexField;
+import com.android.tools.r8.graph.FieldResolutionResult;
 import com.android.tools.r8.graph.ProgramMethod;
 import com.android.tools.r8.ir.code.Instruction.SideEffectAssumption;
 
 public interface InstanceFieldInstruction {
 
+  DexField getField();
+
   boolean hasOutValue();
 
   Value outValue();
@@ -33,4 +38,7 @@
   boolean isInstancePut();
 
   InstancePut asInstancePut();
+
+  FieldResolutionResult resolveField(
+      AppView<? extends AppInfoWithClassHierarchy> appView, ProgramMethod context);
 }
diff --git a/src/main/java/com/android/tools/r8/optimize/virtualmethodhoisting/VirtualMethodHoister.java b/src/main/java/com/android/tools/r8/optimize/virtualmethodhoisting/VirtualMethodHoister.java
index 93b2570..0f7160e 100644
--- a/src/main/java/com/android/tools/r8/optimize/virtualmethodhoisting/VirtualMethodHoister.java
+++ b/src/main/java/com/android/tools/r8/optimize/virtualmethodhoisting/VirtualMethodHoister.java
@@ -18,7 +18,9 @@
 import static com.android.tools.r8.ir.code.Opcodes.IF;
 import static com.android.tools.r8.ir.code.Opcodes.INC;
 import static com.android.tools.r8.ir.code.Opcodes.INIT_CLASS;
+import static com.android.tools.r8.ir.code.Opcodes.INSTANCE_GET;
 import static com.android.tools.r8.ir.code.Opcodes.INSTANCE_OF;
+import static com.android.tools.r8.ir.code.Opcodes.INSTANCE_PUT;
 import static com.android.tools.r8.ir.code.Opcodes.INT_SWITCH;
 import static com.android.tools.r8.ir.code.Opcodes.MONITOR;
 import static com.android.tools.r8.ir.code.Opcodes.MUL;
@@ -47,6 +49,7 @@
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexClass;
 import com.android.tools.r8.graph.DexEncodedMethod;
+import com.android.tools.r8.graph.DexField;
 import com.android.tools.r8.graph.DexItemFactory;
 import com.android.tools.r8.graph.DexMethod;
 import com.android.tools.r8.graph.DexProgramClass;
@@ -349,6 +352,8 @@
               break;
             }
 
+          case INSTANCE_GET:
+          case INSTANCE_PUT:
           case STATIC_GET:
           case STATIC_PUT:
             {
@@ -360,10 +365,17 @@
                 return false;
               }
 
-              if (fieldInstruction.isStaticPut()) {
-                Value value = fieldInstruction.asStaticPut().value();
-                DexType fieldType = fieldInstruction.getField().getType();
-                if (isInvalidUseOfThis(value, fieldType, targetMethod)) {
+              DexField field = fieldInstruction.getField();
+              if (fieldInstruction.isInstanceFieldInstruction()) {
+                Value object = fieldInstruction.asInstanceFieldInstruction().object();
+                if (isInvalidUseOfThis(object, field.getHolderType(), targetMethod)) {
+                  return false;
+                }
+              }
+
+              if (fieldInstruction.isFieldPut()) {
+                Value value = fieldInstruction.asFieldPut().value();
+                if (isInvalidUseOfThis(value, field.getType(), targetMethod)) {
                   return false;
                 }
               }