Reland "Add argumentIndex field to Argument instruction"

This reverts commit ea3ee6628936f0b8da17349f0c88567a049ea131.

Change-Id: I5cc8a2027c8b5327c3633114fca319a7bcf7055a
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/InstanceFieldValueAnalysis.java b/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/InstanceFieldValueAnalysis.java
index 6c1fe58..ecc93b7 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/InstanceFieldValueAnalysis.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/InstanceFieldValueAnalysis.java
@@ -78,7 +78,7 @@
     if (root.isDefinedByInstructionSatisfying(Instruction::isArgument)) {
       Argument argument = root.definition.asArgument();
       builder.recordInitializationInfo(
-          field, factory.createArgumentInitializationInfo(argument.getArgumentIndex()));
+          field, factory.createArgumentInitializationInfo(argument.getIndex()));
     }
   }
 }
diff --git a/src/main/java/com/android/tools/r8/ir/code/Argument.java b/src/main/java/com/android/tools/r8/ir/code/Argument.java
index 046af1b..1db2ba6 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Argument.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Argument.java
@@ -21,26 +21,33 @@
  */
 public class Argument extends Instruction {
 
+  private final int index;
   private final boolean knownToBeBoolean;
 
-  public Argument(Value outValue, boolean knownToBeBoolean) {
+  public Argument(Value outValue, int index, boolean knownToBeBoolean) {
     super(outValue);
+    this.index = index;
     this.knownToBeBoolean = knownToBeBoolean;
-    outValue.markAsArgument();
   }
 
-  public int getArgumentIndex() {
+  public int getIndex() {
+    assert verifyIndex();
+    return index;
+  }
+
+  private boolean verifyIndex() {
     int index = 0;
     InstructionIterator instructionIterator = getBlock().iterator();
     while (instructionIterator.hasNext()) {
       Instruction instruction = instructionIterator.next();
       assert instruction.isArgument();
       if (instruction == this) {
-        break;
+        assert index == this.index;
+        return true;
       }
       index++;
     }
-    return index;
+    return false;
   }
 
   @Override
diff --git a/src/main/java/com/android/tools/r8/ir/code/BasicBlock.java b/src/main/java/com/android/tools/r8/ir/code/BasicBlock.java
index f4bb790..584ea2c 100644
--- a/src/main/java/com/android/tools/r8/ir/code/BasicBlock.java
+++ b/src/main/java/com/android/tools/r8/ir/code/BasicBlock.java
@@ -621,6 +621,10 @@
     return instructions.isEmpty();
   }
 
+  public int size() {
+    return instructions.size();
+  }
+
   public boolean isReturnBlock() {
     return exit().isReturn();
   }
diff --git a/src/main/java/com/android/tools/r8/ir/code/FixedRegisterValue.java b/src/main/java/com/android/tools/r8/ir/code/FixedRegisterValue.java
index f7411d9..b074e44 100644
--- a/src/main/java/com/android/tools/r8/ir/code/FixedRegisterValue.java
+++ b/src/main/java/com/android/tools/r8/ir/code/FixedRegisterValue.java
@@ -5,6 +5,7 @@
 
 import com.android.tools.r8.errors.Unreachable;
 import com.android.tools.r8.ir.analysis.type.TypeLatticeElement;
+import java.util.function.Predicate;
 
 // Value that has a fixed register allocated. These are used for inserting spill, restore, and phi
 // moves in the spilling register allocator.
@@ -50,6 +51,11 @@
   }
 
   @Override
+  public boolean isDefinedByInstructionSatisfying(Predicate<Instruction> predicate) {
+    return false;
+  }
+
+  @Override
   public boolean isFixedRegisterValue() {
     return true;
   }
diff --git a/src/main/java/com/android/tools/r8/ir/code/Value.java b/src/main/java/com/android/tools/r8/ir/code/Value.java
index e46aca6..5566552 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Value.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Value.java
@@ -226,7 +226,6 @@
   private LiveIntervals liveIntervals;
   private int needsRegister = -1;
   private boolean isThis = false;
-  private boolean isArgument = false;
   private LongInterval valueRange;
   private DebugData debugData;
   protected TypeLatticeElement typeLattice;
@@ -914,14 +913,8 @@
         || typeLattice.nullability().isDefinitelyNotNull();
   }
 
-  public void markAsArgument() {
-    assert !isArgument;
-    assert !isThis;
-    isArgument = true;
-  }
-
   public boolean isArgument() {
-    return isArgument;
+    return isDefinedByInstructionSatisfying(Instruction::isArgument);
   }
 
   public boolean onlyDependsOnArgument() {
@@ -945,21 +938,6 @@
     }
   }
 
-  public int computeArgumentPosition(IRCode code) {
-    assert isArgument;
-    int position = 0;
-    InstructionIterator instructionIterator = code.entryBlock().iterator();
-    while (instructionIterator.hasNext()) {
-      Instruction instruction = instructionIterator.next();
-      assert instruction.isArgument();
-      if (instruction.outValue() == this) {
-        return position;
-      }
-      position++;
-    }
-    throw new Unreachable();
-  }
-
   public boolean knownToBeBoolean() {
     return knownToBeBoolean(null);
   }
@@ -991,7 +969,7 @@
   }
 
   public void markAsThis() {
-    assert isArgument;
+    assert isArgument();
     assert !isThis;
     isThis = true;
   }
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java b/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java
index 7995fdb..78b1405 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java
@@ -914,7 +914,7 @@
   public void addThisArgument(int register, TypeLatticeElement receiverType) {
     DebugLocalInfo local = getOutgoingLocal(register);
     Value value = writeRegister(register, receiverType, ThrowingInfo.NO_THROW, local);
-    addInstruction(new Argument(value, false));
+    addInstruction(new Argument(value, currentBlock.size(), false));
     receiverValue = value;
     value.markAsThis();
   }
@@ -922,13 +922,13 @@
   public void addNonThisArgument(int register, TypeLatticeElement typeLattice) {
       DebugLocalInfo local = getOutgoingLocal(register);
       Value value = writeRegister(register, typeLattice, ThrowingInfo.NO_THROW, local);
-      addNonThisArgument(new Argument(value, false));
+    addNonThisArgument(new Argument(value, currentBlock.size(), false));
   }
 
   public void addBooleanNonThisArgument(int register) {
       DebugLocalInfo local = getOutgoingLocal(register);
       Value value = writeRegister(register, getInt(), ThrowingInfo.NO_THROW, local);
-      addNonThisArgument(new Argument(value, true));
+    addNonThisArgument(new Argument(value, currentBlock.size(), true));
   }
 
   private void addNonThisArgument(Argument argument) {
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/DefaultInliningOracle.java b/src/main/java/com/android/tools/r8/ir/optimize/DefaultInliningOracle.java
index 8370b69..f1c5dc9 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/DefaultInliningOracle.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/DefaultInliningOracle.java
@@ -607,11 +607,11 @@
 
     for (Monitor monitor : inlinee.code.<Monitor>instructions(Instruction::isMonitorEnter)) {
       Value monitorEnterValue = monitor.object().getAliasedValue();
-      if (monitorEnterValue.isArgument()) {
+      if (monitorEnterValue.isDefinedByInstructionSatisfying(Instruction::isArgument)) {
         monitorEnterValue =
             invoke
                 .arguments()
-                .get(monitorEnterValue.computeArgumentPosition(inlinee.code))
+                .get(monitorEnterValue.definition.asArgument().getIndex())
                 .getAliasedValue();
       }
       addMonitorEnterValue(
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 b9345e9..b5215f6 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
@@ -338,10 +338,7 @@
       if (!aliasedValue.isPhi()) {
         Instruction definition = aliasedValue.definition;
         if (definition.isArgument()) {
-          // Find the argument number.
-          int index = aliasedValue.computeArgumentPosition(code);
-          assert index >= 0;
-          feedback.methodReturnsArgument(method, index);
+          feedback.methodReturnsArgument(method, definition.asArgument().getIndex());
         }
         DexType context = method.method.holder;
         AbstractValue abstractReturnValue = definition.getAbstractValue(appView, context);
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/TrivialGotoEliminationTest.java b/src/test/java/com/android/tools/r8/ir/optimize/TrivialGotoEliminationTest.java
index 5d48fa6..6104883 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/TrivialGotoEliminationTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/TrivialGotoEliminationTest.java
@@ -137,7 +137,7 @@
             TypeLatticeElement.fromDexType(
                 app.dexItemFactory.throwableType, Nullability.definitelyNotNull(), appView),
             null);
-    instruction = new Argument(value, false);
+    instruction = new Argument(value, 0, false);
     instruction.setPosition(position);
     block0.add(instruction, metadata);
     instruction = new If(Type.EQ, value);