Minor cleanup of register allocator

This removes a couple of errorprone suppressions.

Change-Id: Id8be0092d6e87158d1cf7f4eefd91472a2ab8bfe
diff --git a/src/main/java/com/android/tools/r8/graph/DebugLocalInfo.java b/src/main/java/com/android/tools/r8/graph/DebugLocalInfo.java
index 095f467..e72e63a 100644
--- a/src/main/java/com/android/tools/r8/graph/DebugLocalInfo.java
+++ b/src/main/java/com/android/tools/r8/graph/DebugLocalInfo.java
@@ -5,6 +5,7 @@
 
 import com.android.tools.r8.errors.Unreachable;
 import com.android.tools.r8.utils.DescriptorUtils;
+import com.android.tools.r8.utils.ObjectUtils;
 import com.android.tools.r8.utils.structural.StructuralItem;
 import com.android.tools.r8.utils.structural.StructuralMapping;
 import com.android.tools.r8.utils.structural.StructuralSpecification;
@@ -39,6 +40,14 @@
     this.signature = signature;
   }
 
+  public boolean isIdenticalTo(DebugLocalInfo other) {
+    return ObjectUtils.identical(this, other);
+  }
+
+  public boolean isNotIdenticalTo(DebugLocalInfo other) {
+    return !isIdenticalTo(other);
+  }
+
   @Override
   public DebugLocalInfo self() {
     return this;
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 d08946f..2b027ab 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
@@ -284,6 +284,10 @@
     return getLocalInfo() != null;
   }
 
+  public boolean hasSameLocalInfo(Value other) {
+    return ObjectUtils.identical(getLocalInfo(), other.getLocalInfo());
+  }
+
   public void setLocalInfo(DebugLocalInfo local) {
     assert local != null;
     assert debugData == null;
diff --git a/src/main/java/com/android/tools/r8/ir/regalloc/LinearScanRegisterAllocator.java b/src/main/java/com/android/tools/r8/ir/regalloc/LinearScanRegisterAllocator.java
index 3023f7a..50b95a7 100644
--- a/src/main/java/com/android/tools/r8/ir/regalloc/LinearScanRegisterAllocator.java
+++ b/src/main/java/com/android/tools/r8/ir/regalloc/LinearScanRegisterAllocator.java
@@ -38,7 +38,7 @@
 import com.android.tools.r8.ir.code.Sub;
 import com.android.tools.r8.ir.code.Value;
 import com.android.tools.r8.ir.code.Xor;
-import com.android.tools.r8.ir.regalloc.RegisterPositions.Type;
+import com.android.tools.r8.ir.regalloc.RegisterPositions.RegisterType;
 import com.android.tools.r8.utils.ArrayUtils;
 import com.android.tools.r8.utils.BooleanUtils;
 import com.android.tools.r8.utils.InternalOptions;
@@ -356,7 +356,7 @@
   }
 
   // TODO(b/270398965): Replace LinkedList.
-  @SuppressWarnings({"JdkObsolete", "ReferenceEquality"})
+  @SuppressWarnings("JdkObsolete")
   public static void computeDebugInfo(
       IRCode code,
       ImmutableList<BasicBlock> blocks,
@@ -476,7 +476,7 @@
               LocalRange openRange = it.next();
               if (openRange.value == endAnnotation) {
                 // Don't remove the local from open-ranges as it is still technically open.
-                assert currentLocals.get(openRange.register) == openRange.local;
+                assert openRange.local.isIdenticalTo(currentLocals.get(openRange.register));
                 currentLocals.remove(openRange.register);
                 ending.put(openRange.register, openRange.local);
                 break;
@@ -570,7 +570,6 @@
     return false;
   }
 
-  @SuppressWarnings("ReferenceEquality")
   private static void setLocalsAtEntry(
       BasicBlock block,
       InstructionListIterator instructionIterator,
@@ -606,12 +605,12 @@
     Int2ReferenceMap<DebugLocalInfo> ending = new Int2ReferenceOpenHashMap<>();
     Int2ReferenceMap<DebugLocalInfo> starting = new Int2ReferenceOpenHashMap<>();
     for (Entry<DebugLocalInfo> initialLocal : initialLocals.int2ReferenceEntrySet()) {
-      if (finalLocals.get(initialLocal.getIntKey()) != initialLocal.getValue()) {
+      if (initialLocal.getValue().isNotIdenticalTo(finalLocals.get(initialLocal.getIntKey()))) {
         ending.put(initialLocal.getIntKey(), initialLocal.getValue());
       }
     }
     for (Entry<DebugLocalInfo> finalLocal : finalLocals.int2ReferenceEntrySet()) {
-      if (initialLocals.get(finalLocal.getIntKey()) != finalLocal.getValue()) {
+      if (finalLocal.getValue().isNotIdenticalTo(initialLocals.get(finalLocal.getIntKey()))) {
         starting.put(finalLocal.getIntKey(), finalLocal.getValue());
       }
     }
@@ -621,7 +620,6 @@
     }
   }
 
-  @SuppressWarnings("ReferenceEquality")
   private static DebugLocalsChange createLocalsChange(
       Int2ReferenceMap<DebugLocalInfo> ending,
       Int2ReferenceMap<DebugLocalInfo> starting,
@@ -636,7 +634,7 @@
     } else {
       IntSet unneeded = new IntArraySet(Math.min(ending.size(), starting.size()));
       for (Entry<DebugLocalInfo> entry : ending.int2ReferenceEntrySet()) {
-        if (starting.get(entry.getIntKey()) == entry.getValue()) {
+        if (entry.getValue().isIdenticalTo(starting.get(entry.getIntKey()))) {
           unneeded.add(entry.getIntKey());
         }
       }
@@ -954,6 +952,7 @@
     freeRegisters.clear();
     maxRegisterNumber = -1;
     active.clear();
+    expiredHere.clear();
     inactive.clear();
     unhandled.clear();
     moveExceptionIntervals.clear();
@@ -1020,10 +1019,8 @@
     // Go through each unhandled live interval and find a register for it.
     while (!unhandled.isEmpty()) {
       assert invariantsHold(mode);
-      expiredHere.clear();
 
       LiveIntervals unhandledInterval = unhandled.poll();
-
       setHintForDestRegOfCheckCast(unhandledInterval);
       setHintToPromote2AddrInstruction(unhandledInterval);
 
@@ -1041,11 +1038,11 @@
       // Perform the actual allocation.
       if (unhandledInterval.isLinked() && !unhandledInterval.isArgumentInterval()) {
         allocateLinkedIntervals(unhandledInterval, false);
-      } else {
-        if (!allocateSingleInterval(unhandledInterval, mode)) {
-          return false;
-        }
+      } else if (!allocateSingleInterval(unhandledInterval, mode)) {
+        return false;
       }
+
+      expiredHere.clear();
     }
     return true;
   }
@@ -1215,6 +1212,7 @@
       freeRegisters.remove(getMoveExceptionRegister());
       computedFreeRegisters.remove(getMoveExceptionRegister());
     }
+    assert expiredHere.isEmpty();
     assert freeRegisters.equals(computedFreeRegisters);
     return true;
   }
@@ -1248,17 +1246,17 @@
     return true;
   }
 
-  @SuppressWarnings("ReferenceEquality")
   private void setHintForDestRegOfCheckCast(LiveIntervals unhandledInterval) {
-    if (unhandledInterval.getHint() == null &&
-        unhandledInterval.getValue().definition instanceof CheckCast) {
-      CheckCast checkcast = unhandledInterval.getValue().definition.asCheckCast();
-      Value checkcastInput = checkcast.inValues().get(0);
-      assert checkcastInput != null;
-      if (checkcastInput.getLiveIntervals() != null &&
-          !checkcastInput.getLiveIntervals().overlaps(unhandledInterval) &&
-          checkcastInput.getLocalInfo() == unhandledInterval.getValue().definition.getLocalInfo()) {
-        unhandledInterval.setHint(checkcastInput.getLiveIntervals(), unhandled);
+    if (unhandledInterval.getHint() != null) {
+      return;
+    }
+    Value value = unhandledInterval.getValue();
+    if (value.isDefinedByInstructionSatisfying(Instruction::isCheckCast)) {
+      CheckCast checkcast = value.getDefinition().asCheckCast();
+      Value object = checkcast.object();
+      if (!object.getLiveIntervals().overlaps(unhandledInterval)
+          && object.hasSameLocalInfo(value)) {
+        unhandledInterval.setHint(object.getLiveIntervals(), unhandled);
       }
     }
   }
@@ -1269,19 +1267,20 @@
    * that is the left interval or the right interval if possible when intervals do not overlap.
    */
   private void setHintToPromote2AddrInstruction(LiveIntervals unhandledInterval) {
-    if (unhandledInterval.getHint() == null &&
-        unhandledInterval.getValue().definition instanceof ArithmeticBinop) {
-      ArithmeticBinop binOp = unhandledInterval.getValue().definition.asArithmeticBinop();
-      Value left = binOp.leftValue();
-      assert left != null;
-      if (left.getLiveIntervals() != null &&
-          !left.getLiveIntervals().overlaps(unhandledInterval)) {
+    if (unhandledInterval.getHint() != null) {
+      return;
+    }
+    Value value = unhandledInterval.getValue();
+    if (value.isDefinedByInstructionSatisfying(Instruction::isArithmeticBinop)) {
+      ArithmeticBinop binop = value.getDefinition().asArithmeticBinop();
+      Value left = binop.leftValue();
+      if (left.getLiveIntervals() != null && !left.getLiveIntervals().overlaps(unhandledInterval)) {
         unhandledInterval.setHint(left.getLiveIntervals(), unhandled);
       } else {
-        Value right = binOp.rightValue();
-        assert right != null;
-        if (binOp.isCommutative() && right.getLiveIntervals() != null &&
-            !right.getLiveIntervals().overlaps(unhandledInterval)) {
+        Value right = binop.rightValue();
+        if (binop.isCommutative()
+            && right.getLiveIntervals() != null
+            && !right.getLiveIntervals().overlaps(unhandledInterval)) {
           unhandledInterval.setHint(right.getLiveIntervals(), unhandled);
         }
       }
@@ -1810,7 +1809,6 @@
     return false;
   }
 
-  @SuppressWarnings("BadImport")
   private boolean allocateSingleInterval(LiveIntervals unhandledInterval, ArgumentReuseMode mode) {
     int registerConstraint = unhandledInterval.getRegisterLimit();
     assert registerConstraint <= Constants.U16BIT_MAX;
@@ -1850,7 +1848,11 @@
     // free position.
     int candidate =
         getLargestValidCandidate(
-            unhandledInterval, registerConstraint, needsRegisterPair, freePositions, Type.ANY);
+            unhandledInterval,
+            registerConstraint,
+            needsRegisterPair,
+            freePositions,
+            RegisterType.ANY);
 
     // It is not always possible to find a largest valid candidate. If none of the usable register
     // are free we typically get the last candidate. However, if that candidate has to be
@@ -2159,7 +2161,7 @@
       int registerConstraint,
       RegisterPositions freePositions,
       boolean needsRegisterPair,
-      RegisterPositions.Type type) {
+      RegisterType type) {
     int candidate = REGISTER_CANDIDATE_NOT_FOUND;
     int largest = -1;
 
@@ -2209,7 +2211,7 @@
       int registerConstraint,
       boolean needsRegisterPair,
       RegisterPositionsWithExtraBlockedRegisters freePositions,
-      RegisterPositions.Type type) {
+      RegisterType type) {
     if (workaroundNeeded.test(unhandledInterval)) {
       int lastCandidate = candidate;
       while (workaroundNeededForCandidate.test(unhandledInterval, candidate)) {
@@ -2244,7 +2246,7 @@
       int registerConstraint,
       boolean needsRegisterPair,
       RegisterPositions usePositions,
-      RegisterPositions.Type type) {
+      RegisterType type) {
     int candidate =
         getLargestCandidate(
             unhandledInterval, registerConstraint, usePositions, needsRegisterPair, type);
@@ -2288,7 +2290,6 @@
     return candidate;
   }
 
-  @SuppressWarnings("BadImport")
   private void allocateBlockedRegister(LiveIntervals unhandledInterval) {
     int registerConstraint = unhandledInterval.getRegisterLimit();
     if (registerConstraint < Constants.U16BIT_MAX) {
@@ -2362,11 +2363,15 @@
             registerConstraint,
             needsRegisterPair,
             usePositions,
-            Type.CONST_NUMBER);
+            RegisterType.CONST_NUMBER);
     // Look for a non-const, non-monitor candidate.
     int otherCandidate =
         getLargestValidCandidate(
-            unhandledInterval, registerConstraint, needsRegisterPair, usePositions, Type.OTHER);
+            unhandledInterval,
+            registerConstraint,
+            needsRegisterPair,
+            usePositions,
+            RegisterType.OTHER);
     if (otherCandidate != REGISTER_CANDIDATE_NOT_FOUND) {
       // There is a potential other candidate, check if that should be used instead.
       if (candidate == REGISTER_CANDIDATE_NOT_FOUND) {
@@ -2391,8 +2396,13 @@
     // runtimes (b/80118070). To remove this restriction, we would need to know when the call to
     // <init> has definitely happened, and would be safe to split the value after that point.
     if (candidate == REGISTER_CANDIDATE_NOT_FOUND) {
-      candidate = getLargestValidCandidate(
-          unhandledInterval, registerConstraint, needsRegisterPair, usePositions, Type.MONITOR);
+      candidate =
+          getLargestValidCandidate(
+              unhandledInterval,
+              registerConstraint,
+              needsRegisterPair,
+              usePositions,
+              RegisterType.MONITOR);
     }
 
     int largestUsePosition = getLargestPosition(usePositions, candidate, needsRegisterPair);
diff --git a/src/main/java/com/android/tools/r8/ir/regalloc/RegisterPositions.java b/src/main/java/com/android/tools/r8/ir/regalloc/RegisterPositions.java
index caafb2e..445b46f 100644
--- a/src/main/java/com/android/tools/r8/ir/regalloc/RegisterPositions.java
+++ b/src/main/java/com/android/tools/r8/ir/regalloc/RegisterPositions.java
@@ -11,14 +11,14 @@
  */
 public abstract class RegisterPositions {
 
-  enum Type {
+  enum RegisterType {
     MONITOR,
     CONST_NUMBER,
     OTHER,
     ANY
   }
 
-  public abstract boolean hasType(int index, Type type);
+  public abstract boolean hasType(int index, RegisterType type);
 
   public abstract void set(int index, int value, LiveIntervals intervals);
 
diff --git a/src/main/java/com/android/tools/r8/ir/regalloc/RegisterPositionsImpl.java b/src/main/java/com/android/tools/r8/ir/regalloc/RegisterPositionsImpl.java
index 0f11ebf..ca6f13c 100644
--- a/src/main/java/com/android/tools/r8/ir/regalloc/RegisterPositionsImpl.java
+++ b/src/main/java/com/android/tools/r8/ir/regalloc/RegisterPositionsImpl.java
@@ -31,7 +31,7 @@
   }
 
   @Override
-  public boolean hasType(int index, Type type) {
+  public boolean hasType(int index, RegisterType type) {
     assert !isBlocked(index);
     switch (type) {
       case MONITOR:
diff --git a/src/main/java/com/android/tools/r8/ir/regalloc/RegisterPositionsWithExtraBlockedRegisters.java b/src/main/java/com/android/tools/r8/ir/regalloc/RegisterPositionsWithExtraBlockedRegisters.java
index 16c7bb4..bb2a46b 100644
--- a/src/main/java/com/android/tools/r8/ir/regalloc/RegisterPositionsWithExtraBlockedRegisters.java
+++ b/src/main/java/com/android/tools/r8/ir/regalloc/RegisterPositionsWithExtraBlockedRegisters.java
@@ -17,7 +17,7 @@
   }
 
   @Override
-  public boolean hasType(int index, Type type) {
+  public boolean hasType(int index, RegisterType type) {
     assert !isBlockedTemporarily(index);
     return positions.hasType(index, type);
   }