Small optimization to ValueUtils.computeSingleUseArrayValues()

Visit array-put instructions in reverse order when checking for
dominance so as to fully utilize the caching done by DominatorChecker.

Bug: b/244238384
Change-Id: I1ee73cc6af50c90c43ee0fded5d76f15575fbd8e
diff --git a/src/main/java/com/android/tools/r8/utils/DominatorChecker.java b/src/main/java/com/android/tools/r8/utils/DominatorChecker.java
index 46c6716..c2fd047 100644
--- a/src/main/java/com/android/tools/r8/utils/DominatorChecker.java
+++ b/src/main/java/com/android/tools/r8/utils/DominatorChecker.java
@@ -16,7 +16,6 @@
 public interface DominatorChecker {
   boolean check(BasicBlock targetBlock);
 
-  DominatorChecker TRUE_CHECKER = targetBlock -> true;
   DominatorChecker FALSE_CHECKER = targetBlock -> false;
 
   class PrecomputedDominatorChecker implements DominatorChecker {
diff --git a/src/main/java/com/android/tools/r8/utils/ValueUtils.java b/src/main/java/com/android/tools/r8/utils/ValueUtils.java
index 509816c..68d3364 100644
--- a/src/main/java/com/android/tools/r8/utils/ValueUtils.java
+++ b/src/main/java/com/android/tools/r8/utils/ValueUtils.java
@@ -170,8 +170,11 @@
 
     // Ensure that all paths from new-array-empty to |usage| contain all array-put instructions.
     DominatorChecker dominatorChecker = DominatorChecker.create(definition.getBlock(), usageBlock);
-    for (Instruction user : arrayValue.uniqueUsers()) {
-      if (!dominatorChecker.check(user.getBlock())) {
+    // Visit in reverse order because array-puts generally appear in order, and DominatorChecker's
+    // cache is more effective when visiting in reverse order.
+    for (int i = arraySize - 1; i >= 0; --i) {
+      ArrayPut arrayPut = arrayPutsByIndex[i];
+      if (arrayPut != null && !dominatorChecker.check(arrayPut.getBlock())) {
         return null;
       }
     }