[vm] Improve SelectRepresentations.

It's no longer necessary to prove that a phi will fit into 64 bits to unbox it,
because all ints in Dart 2 are 64-bit.

Also, we add a new heuristic to always unbox a phi if all inputs are unboxed.

This improves MD5 performance on ARM32 AOT by 27%, matching existing JIT performance.

Change-Id: I9ebbfc3bb8d565e746d3740528fdf7ee32c0f7a4
Cq-Include-Trybots: luci.dart.try:vm-kernel-optcounter-threshold-linux-release-x64-try, vm-kernel-precomp-linux-debug-x64-try, vm-kernel-precomp-linux-release-simarm-try, vm-kernel-precomp-linux-release-simarm64-try, vm-kernel-precomp-linux-release-x64-try, vm-kernel-precomp-mac-release-simarm64-try, vm-kernel-precomp-win-release-x64-try
Reviewed-on: https://dart-review.googlesource.com/c/88841
Commit-Queue: Samir Jindel <sjindel@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
diff --git a/runtime/vm/compiler/backend/flow_graph.cc b/runtime/vm/compiler/backend/flow_graph.cc
index 7062a35..b86fae0 100644
--- a/runtime/vm/compiler/backend/flow_graph.cc
+++ b/runtime/vm/compiler/backend/flow_graph.cc
@@ -1813,8 +1813,36 @@
       break;
   }
 
-  if ((unboxed == kTagged) && phi->Type()->IsInt() &&
-      RangeUtils::Fits(phi->range(), RangeBoundary::kRangeBoundaryInt64)) {
+  // If all the inputs are unboxed, leave the Phi unboxed.
+  if ((unboxed == kTagged) && phi->Type()->IsInt()) {
+    bool should_unbox = true;
+    Representation new_representation = kTagged;
+    for (intptr_t i = 0; i < phi->InputCount(); i++) {
+      Definition* input = phi->InputAt(i)->definition();
+      if (input->representation() != kUnboxedInt64 &&
+          input->representation() != kUnboxedInt32 &&
+          input->representation() != kUnboxedUint32 && !(input == phi)) {
+        should_unbox = false;
+        break;
+      }
+
+      if (new_representation == kTagged) {
+        new_representation = input->representation();
+      } else if (new_representation != input->representation()) {
+        new_representation = kNoRepresentation;
+      }
+    }
+    if (should_unbox) {
+      unboxed = new_representation != kNoRepresentation
+                    ? new_representation
+                    : RangeUtils::Fits(phi->range(),
+                                       RangeBoundary::kRangeBoundaryInt32)
+                          ? kUnboxedInt32
+                          : kUnboxedInt64;
+    }
+  }
+
+  if ((unboxed == kTagged) && phi->Type()->IsInt()) {
     // Conservatively unbox phis that:
     //   - are proven to be of type Int;
     //   - fit into 64bits range;
@@ -1824,9 +1852,7 @@
     bool should_unbox = false;
     for (intptr_t i = 0; i < phi->InputCount(); i++) {
       Definition* input = phi->InputAt(i)->definition();
-      if (input->IsBox() &&
-          RangeUtils::Fits(input->range(),
-                           RangeBoundary::kRangeBoundaryInt64)) {
+      if (input->IsBox()) {
         should_unbox = true;
       } else if (!input->IsConstant()) {
         should_unbox = false;