[dart2wasm] Avoid extra global definitions for int constants that are wasmI32.

In a few places we create IntConstants to represent constant fields that are typed as WasmI32. If these are nested within other constants we end up hitting ConstantCreator.visitIntConstant for them. This always generates a global for a BoxedInt constant, whether it's used or not.

The global we create goes unused because in constant intiailizer for the outer constant we use the wasmI32 value directly.

At -O0 this reduced the wasm binary size by ~24k for a simple Flutter app. Binaryen mostly treeshakes these unused globals but I still see a slight improvement even with binaryen running.

Change-Id: I89b8392138269d7322196fa415e56e3062a46088
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/408121
Commit-Queue: Nate Biggs <natebiggs@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
diff --git a/pkg/dart2wasm/lib/constants.dart b/pkg/dart2wasm/lib/constants.dart
index 776cba9..66764e1 100644
--- a/pkg/dart2wasm/lib/constants.dart
+++ b/pkg/dart2wasm/lib/constants.dart
@@ -109,6 +109,11 @@
   Types get types => translator.types;
   CoreTypes get coreTypes => translator.coreTypes;
 
+  Constant makeWasmI32(int value) {
+    return InstanceConstant(translator.wasmI32Class.reference, const [],
+        {translator.wasmI32Value.fieldReference: IntConstant(value)});
+  }
+
   /// Makes a `WasmArray<_Type>` [InstanceConstant].
   InstanceConstant makeTypeArray(Iterable<DartType> types) {
     return makeArrayOf(
@@ -225,7 +230,7 @@
   InstanceConstant _makeInterfaceTypeConstant(InterfaceType type) {
     return _makeTypeConstant(translator.interfaceTypeClass, type.nullability, {
       translator.interfaceTypeClassIdField.fieldReference:
-          IntConstant(translator.classIdNumbering.classIds[type.classNode]!),
+          makeWasmI32(translator.classIdNumbering.classIds[type.classNode]!),
       translator.interfaceTypeTypeArguments.fieldReference:
           makeTypeArray(type.typeArguments),
     });
@@ -593,6 +598,9 @@
     if (cls == translator.immutableWasmArrayClass) {
       return _makeWasmArrayLiteral(constant, mutable: false);
     }
+    if (cls == translator.wasmI32Class) {
+      return null;
+    }
 
     ClassInfo info = translator.classInfo[cls]!;
     translator.functions.recordClassAllocation(info.classId);
diff --git a/pkg/dart2wasm/lib/kernel_nodes.dart b/pkg/dart2wasm/lib/kernel_nodes.dart
index be4af93..366b73a 100644
--- a/pkg/dart2wasm/lib/kernel_nodes.dart
+++ b/pkg/dart2wasm/lib/kernel_nodes.dart
@@ -158,6 +158,7 @@
   late final wasmI8Class = index.getClass("dart:_wasm", "WasmI8");
   late final wasmI16Class = index.getClass("dart:_wasm", "WasmI16");
   late final wasmI32Class = index.getClass("dart:_wasm", "WasmI32");
+  late final wasmI32Value = index.getField("dart:_wasm", "WasmI32", "_value");
   late final wasmI64Class = index.getClass("dart:_wasm", "WasmI64");
   late final wasmF32Class = index.getClass("dart:_wasm", "WasmF32");
   late final wasmF64Class = index.getClass("dart:_wasm", "WasmF64");
diff --git a/pkg/dart2wasm/lib/types.dart b/pkg/dart2wasm/lib/types.dart
index 837a5e6..4a0d82e 100644
--- a/pkg/dart2wasm/lib/types.dart
+++ b/pkg/dart2wasm/lib/types.dart
@@ -1219,7 +1219,7 @@
     final table = buildRowDisplacementTable(rows, firstAvailable: 1);
     typeRowDisplacementTable = translator.constants.makeArrayOf(wasmI32, [
       for (final entry in table)
-        IntConstant(entry == null
+        translator.constants.makeWasmI32(entry == null
             ? 0
             : (entry.$2 == noSubstitutionIndex ? -entry.$1 : entry.$1)),
     ]);
@@ -1233,7 +1233,8 @@
 
     typeRowDisplacementOffsets = translator.constants.makeArrayOf(wasmI32, [
       for (int classId = 0; classId < translator.classes.length; ++classId)
-        IntConstant(rowForSuperclass[classId]?.offset ?? -1),
+        translator.constants
+            .makeWasmI32(rowForSuperclass[classId]?.offset ?? -1),
     ]);
   }