From d11dd982dd81e1d296516bdeaf1f4a37ebabd53d Mon Sep 17 00:00:00 2001 From: Mayank Patke Date: Fri, 15 Feb 2019 20:44:46 +0000 Subject: [PATCH] Add typeinfo for sets and their elements and start tracing them in the inferrer. Change-Id: Ib9a4e46b77a15ab17396d519166969a221b63da4 Reviewed-on: https://dart-review.googlesource.com/c/92168 Reviewed-by: Sigmund Cherem --- .../lib/src/inferrer/node_tracer.dart | 30 ++++++--- .../lib/src/inferrer/type_graph_dump.dart | 8 +++ .../lib/src/inferrer/type_graph_nodes.dart | 61 +++++++++++++++++++ 3 files changed, 91 insertions(+), 8 deletions(-) diff --git a/pkg/compiler/lib/src/inferrer/node_tracer.dart b/pkg/compiler/lib/src/inferrer/node_tracer.dart index e0abccfd231..81b343f2eee 100644 --- a/pkg/compiler/lib/src/inferrer/node_tracer.dart +++ b/pkg/compiler/lib/src/inferrer/node_tracer.dart @@ -81,17 +81,23 @@ abstract class TracerVisitor implements TypeInformationVisitor { TracerVisitor(this.tracedType, this.inferrer); - // Work list that gets populated with [TypeInformation] that could - // contain the container. + /// Work list that gets populated with [TypeInformation] that could + /// contain the container. final List workList = []; - // Work list of lists to analyze after analyzing the users of a - // [TypeInformation]. We know the [tracedType] has been stored in these - // lists and we must check how it escapes from these lists. + /// Work list of lists to analyze after analyzing the users of a + /// [TypeInformation]. We know the [tracedType] has been stored in these + /// lists and we must check how it escapes from these lists. final List listsToAnalyze = []; - // Work list of maps to analyze after analyzing the users of a - // [TypeInformation]. We know the [tracedType] has been stored in these - // maps and we must check how it escapes from these maps. + + /// Work list of sets to analyze after analyzing the users of a + /// [TypeInformation]. We know the [tracedType] has been stored in these sets + /// and we must check how it escapes from these sets. + final List setsToAnalyze = []; + + /// Work list of maps to analyze after analyzing the users of a + /// [TypeInformation]. We know the [tracedType] has been stored in these + /// maps and we must check how it escapes from these maps. final List mapsToAnalyze = []; final Setlet flowsInto = new Setlet(); @@ -175,6 +181,10 @@ abstract class TracerVisitor implements TypeInformationVisitor { addNewEscapeInformation(info); } + void visitElementInSetTypeInformation(ElementInSetTypeInformation info) { + addNewEscapeInformation(info); + } + void visitKeyInMapTypeInformation(KeyInMapTypeInformation info) { // We do not track the use of keys from a map, so we have to bail. bailout('Used as key in Map'); @@ -188,6 +198,10 @@ abstract class TracerVisitor implements TypeInformationVisitor { listsToAnalyze.add(info); } + void visitSetTypeInformation(SetTypeInformation info) { + setsToAnalyze.add(info); + } + void visitMapTypeInformation(MapTypeInformation info) { mapsToAnalyze.add(info); } diff --git a/pkg/compiler/lib/src/inferrer/type_graph_dump.dart b/pkg/compiler/lib/src/inferrer/type_graph_dump.dart index 9eadce50253..d9ddd4d35ca 100644 --- a/pkg/compiler/lib/src/inferrer/type_graph_dump.dart +++ b/pkg/compiler/lib/src/inferrer/type_graph_dump.dart @@ -335,6 +335,10 @@ class _GraphGenerator extends TypeInformationVisitor { addNode(info, 'ElementInContainer'); } + void visitElementInSetTypeInformation(ElementInSetTypeInformation info) { + addNode(info, 'ElementInSet'); + } + void visitKeyInMapTypeInformation(KeyInMapTypeInformation info) { addNode(info, 'KeyInMap'); } @@ -347,6 +351,10 @@ class _GraphGenerator extends TypeInformationVisitor { addNode(info, 'List'); } + void visitSetTypeInformation(SetTypeInformation info) { + addNode(info, 'Set'); + } + void visitMapTypeInformation(MapTypeInformation info) { addNode(info, 'Map'); } diff --git a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart index 794e62dcb4d..467890a17f0 100644 --- a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart +++ b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart @@ -1580,6 +1580,65 @@ class ElementInContainerTypeInformation extends InferredTypeInformation { } } +/// A [SetTypeInformation] is a [TypeInformation] created for sets. +class SetTypeInformation extends TypeInformation with TracedTypeInformation { + final ElementInSetTypeInformation elementType; + + final AbstractValue originalType; + + SetTypeInformation( + MemberTypeInformation context, this.originalType, this.elementType) + : super(originalType, context) { + elementType.addUser(this); + } + + String toString() => 'Set type $type'; + + accept(TypeInformationVisitor visitor) { + return visitor.visitSetTypeInformation(this); + } + + AbstractValue computeType(InferrerEngine inferrer) { + AbstractValueDomain abstractValueDomain = inferrer.abstractValueDomain; + AbstractValue mask = type; + if (!abstractValueDomain.isSet(type) || + abstractValueDomain.getSetElementType(type) != elementType.type) { + return abstractValueDomain.createSetValue( + abstractValueDomain.getGeneralization(originalType), + abstractValueDomain.getAllocationNode(originalType), + abstractValueDomain.getAllocationElement(originalType), + elementType.type); + } + return mask; + } + + AbstractValue safeType(InferrerEngine inferrer) => originalType; + + bool hasStableType(InferrerEngine inferrer) { + return elementType.isStable && super.hasStableType(inferrer); + } + + void cleanup() { + super.cleanup(); + elementType.cleanup(); + _flowsInto = null; + } +} + +/// An [ElementInSetTypeInformation] holds the common type of the elements in a +/// [SetTypeInformation]. +class ElementInSetTypeInformation extends InferredTypeInformation { + ElementInSetTypeInformation(AbstractValueDomain abstractValueDomain, + MemberTypeInformation context, elementType) + : super(abstractValueDomain, context, elementType); + + String toString() => 'Element in set $type'; + + accept(TypeInformationVisitor visitor) { + return visitor.visitElementInSetTypeInformation(this); + } +} + /// A [MapTypeInformation] is a [TypeInformation] created /// for maps. class MapTypeInformation extends TypeInformation with TracedTypeInformation { @@ -1920,9 +1979,11 @@ abstract class TypeInformationVisitor { T visitPhiElementTypeInformation(PhiElementTypeInformation info); T visitElementInContainerTypeInformation( ElementInContainerTypeInformation info); + T visitElementInSetTypeInformation(ElementInSetTypeInformation info); T visitKeyInMapTypeInformation(KeyInMapTypeInformation info); T visitValueInMapTypeInformation(ValueInMapTypeInformation info); T visitListTypeInformation(ListTypeInformation info); + T visitSetTypeInformation(SetTypeInformation info); T visitMapTypeInformation(MapTypeInformation info); T visitConcreteTypeInformation(ConcreteTypeInformation info); T visitStringLiteralTypeInformation(StringLiteralTypeInformation info);