[LIR] Add instance field instructions.

Bug: b/225838009
Change-Id: I59305dfabf9d4a2242e893c544b846624d52a693
diff --git a/src/main/java/com/android/tools/r8/ir/code/InstanceGet.java b/src/main/java/com/android/tools/r8/ir/code/InstanceGet.java
index d01444f..e14f898 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InstanceGet.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InstanceGet.java
@@ -32,6 +32,7 @@
 import com.android.tools.r8.ir.conversion.DexBuilder;
 import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
 import com.android.tools.r8.ir.optimize.InliningConstraints;
+import com.android.tools.r8.lightir.LirBuilder;
 import com.android.tools.r8.shaking.AppInfoWithLiveness;
 import java.util.Set;
 
@@ -266,6 +267,11 @@
     registry.registerInstanceFieldRead(getField());
   }
 
+  @Override
+  public void buildLir(LirBuilder<Value, ?> builder) {
+    builder.addInstanceGet(getField(), object());
+  }
+
   public static class Builder extends BuilderBase<Builder, InstanceGet> {
 
     private DexField field;
diff --git a/src/main/java/com/android/tools/r8/ir/code/InstancePut.java b/src/main/java/com/android/tools/r8/ir/code/InstancePut.java
index bc4d8df..acc4428 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InstancePut.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InstancePut.java
@@ -33,6 +33,7 @@
 import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
 import com.android.tools.r8.ir.optimize.InliningConstraints;
 import com.android.tools.r8.ir.regalloc.RegisterAllocator;
+import com.android.tools.r8.lightir.LirBuilder;
 import com.android.tools.r8.shaking.AppInfoWithLiveness;
 import java.util.Arrays;
 
@@ -283,4 +284,9 @@
   void internalRegisterUse(UseRegistry<?> registry, DexClassAndMethod context) {
     registry.registerInstanceFieldWrite(getField());
   }
+
+  @Override
+  public void buildLir(LirBuilder<Value, ?> builder) {
+    builder.addInstancePut(getField(), object(), value());
+  }
 }
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
index 0050541..c2917b8 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
@@ -1056,13 +1056,15 @@
       OptimizationFeedback feedback,
       BytecodeMetadataProvider bytecodeMetadataProvider,
       Timing timing) {
-    IRCode round1 = doRoundtripWithStrategy(code, new ExternalPhisStrategy(), "indirect phis");
-    IRCode round2 = doRoundtripWithStrategy(round1, new PhiInInstructionsStrategy(), "inline phis");
+    IRCode round1 =
+        doRoundtripWithStrategy(code, new ExternalPhisStrategy(), "indirect phis", timing);
+    IRCode round2 =
+        doRoundtripWithStrategy(round1, new PhiInInstructionsStrategy(), "inline phis", timing);
     return round2;
   }
 
   private <EV, S extends LirStrategy<Value, EV>> IRCode doRoundtripWithStrategy(
-      IRCode code, S strategy, String name) {
+      IRCode code, S strategy, String name, Timing timing) {
     timing.begin("IR->LIR (" + name + ")");
     LirCode<EV> lirCode =
         IR2LirConverter.translate(code, strategy.getEncodingStrategy(), appView.dexItemFactory());
diff --git a/src/main/java/com/android/tools/r8/lightir/Lir2IRConverter.java b/src/main/java/com/android/tools/r8/lightir/Lir2IRConverter.java
index 95591f5..689d5ff 100644
--- a/src/main/java/com/android/tools/r8/lightir/Lir2IRConverter.java
+++ b/src/main/java/com/android/tools/r8/lightir/Lir2IRConverter.java
@@ -27,6 +27,8 @@
 import com.android.tools.r8.ir.code.IRCode;
 import com.android.tools.r8.ir.code.If;
 import com.android.tools.r8.ir.code.IfType;
+import com.android.tools.r8.ir.code.InstanceGet;
+import com.android.tools.r8.ir.code.InstancePut;
 import com.android.tools.r8.ir.code.Instruction;
 import com.android.tools.r8.ir.code.InvokeDirect;
 import com.android.tools.r8.ir.code.InvokeInterface;
@@ -412,6 +414,17 @@
     }
 
     @Override
+    public void onInstanceGet(DexField field, EV object) {
+      Value dest = getOutValueForNextInstruction(field.getTypeElement(appView));
+      addInstruction(new InstanceGet(dest, getValue(object), field));
+    }
+
+    @Override
+    public void onInstancePut(DexField field, EV object, EV value) {
+      addInstruction(new InstancePut(field, getValue(object), getValue(value)));
+    }
+
+    @Override
     public void onReturnVoid() {
       addInstruction(new Return());
       closeCurrentBlock();
diff --git a/src/main/java/com/android/tools/r8/lightir/LirBuilder.java b/src/main/java/com/android/tools/r8/lightir/LirBuilder.java
index 7730e8f..8209c80 100644
--- a/src/main/java/com/android/tools/r8/lightir/LirBuilder.java
+++ b/src/main/java/com/android/tools/r8/lightir/LirBuilder.java
@@ -298,6 +298,16 @@
     return addOneItemInstruction(LirOpcodes.GETSTATIC, field);
   }
 
+  public LirBuilder<V, EV> addInstanceGet(DexField field, V object) {
+    return addInstructionTemplate(
+        LirOpcodes.GETFIELD, Collections.singletonList(field), Collections.singletonList(object));
+  }
+
+  public LirBuilder<V, EV> addInstancePut(DexField field, V object, V value) {
+    return addInstructionTemplate(
+        LirOpcodes.PUTFIELD, Collections.singletonList(field), ImmutableList.of(object, value));
+  }
+
   public LirBuilder<V, EV> addInvokeInstruction(int opcode, DexMethod method, List<V> arguments) {
     return addInstructionTemplate(opcode, Collections.singletonList(method), arguments);
   }
diff --git a/src/main/java/com/android/tools/r8/lightir/LirParsedInstructionCallback.java b/src/main/java/com/android/tools/r8/lightir/LirParsedInstructionCallback.java
index 77b9422..a83524c 100644
--- a/src/main/java/com/android/tools/r8/lightir/LirParsedInstructionCallback.java
+++ b/src/main/java/com/android/tools/r8/lightir/LirParsedInstructionCallback.java
@@ -126,6 +126,10 @@
     onFieldInstruction(field);
   }
 
+  public abstract void onInstanceGet(DexField field, EV object);
+
+  public abstract void onInstancePut(DexField field, EV object, EV value);
+
   public void onReturnVoid() {
     onInstruction();
   }
@@ -250,6 +254,21 @@
           onStaticGet(field);
           return;
         }
+      case LirOpcodes.GETFIELD:
+        {
+          DexField field = (DexField) getConstantItem(view.getNextConstantOperand());
+          EV object = getNextValueOperand(view);
+          onInstanceGet(field, object);
+          return;
+        }
+      case LirOpcodes.PUTFIELD:
+        {
+          DexField field = (DexField) getConstantItem(view.getNextConstantOperand());
+          EV object = getNextValueOperand(view);
+          EV value = getNextValueOperand(view);
+          onInstancePut(field, object, value);
+          return;
+        }
       case LirOpcodes.RETURN:
         {
           onReturnVoid();
diff --git a/src/main/java/com/android/tools/r8/lightir/LirPrinter.java b/src/main/java/com/android/tools/r8/lightir/LirPrinter.java
index a705fd2..33dedd6 100644
--- a/src/main/java/com/android/tools/r8/lightir/LirPrinter.java
+++ b/src/main/java/com/android/tools/r8/lightir/LirPrinter.java
@@ -189,6 +189,19 @@
   }
 
   @Override
+  public void onInstanceGet(DexField field, EV object) {
+    appendOutValue();
+    builder.append(field).append(' ');
+    appendValueArguments(object);
+  }
+
+  @Override
+  public void onInstancePut(DexField field, EV object, EV value) {
+    builder.append(field).append(' ');
+    appendValueArguments(object, value);
+  }
+
+  @Override
   public void onReturnVoid() {
     // Nothing to append.
   }