mirror of
https://github.com/dart-lang/sdk
synced 2024-11-05 18:22:09 +00:00
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:
parent
61ab8e7816
commit
d11dd982dd
3 changed files with 91 additions and 8 deletions
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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');
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue