Use SSA nodes to infer map key/value types.

This consolidates our logic for inferring element types for lists, sets,
and maps.

Change-Id: Ic57a3d857e2462f11482e8b89d884a5537f5eb90
Reviewed-on: https://dart-review.googlesource.com/c/93367
Reviewed-by: Sigmund Cherem <sigmund@google.com>
Commit-Queue: Mayank Patke <fishythefish@google.com>
diff --git a/pkg/compiler/lib/src/inferrer/type_system.dart b/pkg/compiler/lib/src/inferrer/type_system.dart
index 7d47272..22d41df 100644
--- a/pkg/compiler/lib/src/inferrer/type_system.dart
+++ b/pkg/compiler/lib/src/inferrer/type_system.dart
@@ -536,22 +536,38 @@
     assert(keyTypes.length == valueTypes.length);
     bool isFixed = (type.type == _abstractValueDomain.constMapType);
 
-    AbstractValue keyType, valueType;
+    TypeInformation keyType, valueType;
+    for (int i = 0; i < keyTypes.length; ++i) {
+      TypeInformation type = keyTypes[i];
+      keyType = keyType == null
+          ? allocatePhi(null, null, type, isTry: false)
+          : addPhiInput(null, keyType, type);
+
+      type = valueTypes[i];
+      valueType = valueType == null
+          ? allocatePhi(null, null, type, isTry: false)
+          : addPhiInput(null, valueType, type);
+    }
+
+    keyType =
+        keyType == null ? nonNullEmpty() : simplifyPhi(null, null, keyType);
+    valueType =
+        valueType == null ? nonNullEmpty() : simplifyPhi(null, null, valueType);
+
+    AbstractValue keyTypeMask, valueTypeMask;
     if (isFixed) {
-      keyType = keyTypes.fold(nonNullEmptyType.type,
-          (type, info) => _abstractValueDomain.union(type, info.type));
-      valueType = valueTypes.fold(nonNullEmptyType.type,
-          (type, info) => _abstractValueDomain.union(type, info.type));
+      keyTypeMask = keyType.type;
+      valueTypeMask = valueType.type;
     } else {
-      keyType = valueType = dynamicType.type;
+      keyTypeMask = valueTypeMask = dynamicType.type;
     }
     AbstractValue mask = _abstractValueDomain.createMapValue(
-        type.type, node, element, keyType, valueType);
+        type.type, node, element, keyTypeMask, valueTypeMask);
 
-    TypeInformation keyTypeInfo =
-        new KeyInMapTypeInformation(_abstractValueDomain, currentMember, null);
+    TypeInformation keyTypeInfo = new KeyInMapTypeInformation(
+        _abstractValueDomain, currentMember, keyType);
     TypeInformation valueTypeInfo = new ValueInMapTypeInformation(
-        _abstractValueDomain, currentMember, null);
+        _abstractValueDomain, currentMember, valueType);
     allocatedTypes.add(keyTypeInfo);
     allocatedTypes.add(valueTypeInfo);