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 <sigmund@google.com>
This commit is contained in:
Mayank Patke 2019-02-15 20:44:46 +00:00 committed by commit-bot@chromium.org
parent 61ab8e7816
commit d11dd982dd
3 changed files with 91 additions and 8 deletions

View file

@ -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<TypeInformation> workList = <TypeInformation>[];
// 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<ListTypeInformation> listsToAnalyze = <ListTypeInformation>[];
// 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<SetTypeInformation> setsToAnalyze = <SetTypeInformation>[];
/// 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<MapTypeInformation> mapsToAnalyze = <MapTypeInformation>[];
final Setlet<TypeInformation> flowsInto = new Setlet<TypeInformation>();
@ -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);
}

View file

@ -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');
}

View file

@ -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> {
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);