Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(58)

Unified Diff: pkg/compiler/lib/src/inferrer/locals_handler.dart

Issue 3002313002: Use KernelTypeGraphBuilder in KernelInferrerEngine (Closed)
Patch Set: Updated cf. comments. Created 3 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: pkg/compiler/lib/src/inferrer/locals_handler.dart
diff --git a/pkg/compiler/lib/src/inferrer/locals_handler.dart b/pkg/compiler/lib/src/inferrer/locals_handler.dart
index b5935f2e446658c6ef620bb6a7e842a020d3a53d..3e71335cc70e443cc02ffcab34addd1fd1d1d967 100644
--- a/pkg/compiler/lib/src/inferrer/locals_handler.dart
+++ b/pkg/compiler/lib/src/inferrer/locals_handler.dart
@@ -9,6 +9,7 @@ import 'dart:collection' show IterableMixin;
import '../options.dart' show CompilerOptions;
import '../elements/elements.dart';
import '../elements/entities.dart';
+import '../elements/types.dart';
import '../tree/tree.dart';
import '../util/util.dart';
import 'inferrer_engine.dart';
@@ -22,20 +23,20 @@ import 'type_system.dart';
* The inferrer makes sure updates get merged into the parent scope,
* once the control flow block has been visited.
*/
-class VariableScope {
+class VariableScope<T> {
Map<Local, TypeInformation> variables;
/// The parent of this scope. Null for the root scope.
final VariableScope parent;
/// The [Node] that created this scope.
- final Node block;
+ final T block;
VariableScope(this.block, [parent])
: this.variables = null,
this.parent = parent;
- VariableScope.deepCopyOf(VariableScope other)
+ VariableScope.deepCopyOf(VariableScope<T> other)
: variables = other.variables == null
? null
: new Map<Local, TypeInformation>.from(other.variables),
@@ -44,7 +45,7 @@ class VariableScope {
? null
: new VariableScope.deepCopyOf(other.parent);
- VariableScope.topLevelCopyOf(VariableScope other)
+ VariableScope.topLevelCopyOf(VariableScope<T> other)
: variables = other.variables == null
? null
: new Map<Local, TypeInformation>.from(other.variables),
@@ -73,7 +74,7 @@ class VariableScope {
}
void forEachLocalUntilNode(
- Node node, void f(Local variable, TypeInformation type),
+ T node, void f(Local variable, TypeInformation type),
[Setlet<Local> seenLocals]) {
if (seenLocals == null) seenLocals = new Setlet<Local>();
if (variables != null) {
@@ -103,9 +104,9 @@ class VariableScope {
}
/// Tracks initializers via initializations and assignments.
-class FieldInitializationScope {
- final TypeSystem<Node> types;
- Map<Element, TypeInformation> fields;
+class FieldInitializationScope<T> {
+ final TypeSystem<T> types;
+ Map<FieldEntity, TypeInformation> fields;
bool isThisExposed;
/// `true` when control flow prevents accumulating definite assignments,
@@ -116,42 +117,42 @@ class FieldInitializationScope {
: isThisExposed = false,
isIndefinite = false;
- FieldInitializationScope.internalFrom(FieldInitializationScope other)
+ FieldInitializationScope.internalFrom(FieldInitializationScope<T> other)
: types = other.types,
isThisExposed = other.isThisExposed,
isIndefinite = other.isIndefinite;
- factory FieldInitializationScope.from(FieldInitializationScope other) {
+ factory FieldInitializationScope.from(FieldInitializationScope<T> other) {
if (other == null) return null;
- return new FieldInitializationScope.internalFrom(other);
+ return new FieldInitializationScope<T>.internalFrom(other);
}
- void updateField(Element field, TypeInformation type) {
+ void updateField(FieldEntity field, TypeInformation type) {
if (isThisExposed) return;
if (isIndefinite) return;
- fields ??= new Map<Element, TypeInformation>();
+ fields ??= new Map<FieldEntity, TypeInformation>();
fields[field] = type;
}
- TypeInformation readField(Element field) {
+ TypeInformation readField(FieldEntity field) {
return fields == null ? null : fields[field];
}
- void forEach(void f(Element element, TypeInformation type)) {
+ void forEach(void f(FieldEntity element, TypeInformation type)) {
fields?.forEach(f);
}
- void mergeDiamondFlow(
- FieldInitializationScope thenScope, FieldInitializationScope elseScope) {
+ void mergeDiamondFlow(FieldInitializationScope<T> thenScope,
+ FieldInitializationScope<T> elseScope) {
// Quick bailout check. If [isThisExposed] or [isIndefinite] is true, we
// know the code following won'TypeInformation do anything.
if (isThisExposed) return;
if (isIndefinite) return;
- FieldInitializationScope otherScope =
+ FieldInitializationScope<T> otherScope =
(elseScope == null || elseScope.fields == null) ? this : elseScope;
- thenScope.forEach((Element field, TypeInformation type) {
+ thenScope.forEach((FieldEntity field, TypeInformation type) {
TypeInformation otherType = otherScope.readField(field);
if (otherType == null) return;
updateField(field, types.allocateDiamondPhi(type, otherType));
@@ -241,15 +242,15 @@ class ArgumentsTypesIterator implements Iterator<TypeInformation> {
/**
* Placeholder for inferred types of local variables.
*/
-class LocalsHandler {
+class LocalsHandler<T> {
final CompilerOptions options;
- final TypeSystem<Node> types;
- final InferrerEngine inferrer;
- final VariableScope locals;
+ final TypeSystem<T> types;
+ final InferrerEngine<T> inferrer;
+ final VariableScope<T> locals;
final Map<Local, FieldEntity> captured;
final Map<Local, FieldEntity> capturedAndBoxed;
- final FieldInitializationScope fieldScope;
- LocalsHandler tryBlock;
+ final FieldInitializationScope<T> fieldScope;
+ LocalsHandler<T> tryBlock;
bool seenReturnOrThrow = false;
bool seenBreakOrContinue = false;
@@ -259,17 +260,17 @@ class LocalsHandler {
bool get inTryBlock => tryBlock != null;
- LocalsHandler(this.inferrer, this.types, this.options, Node block,
+ LocalsHandler(this.inferrer, this.types, this.options, T block,
[this.fieldScope])
- : locals = new VariableScope(block),
+ : locals = new VariableScope<T>(block),
captured = new Map<Local, FieldEntity>(),
capturedAndBoxed = new Map<Local, FieldEntity>(),
tryBlock = null;
- LocalsHandler.from(LocalsHandler other, Node block,
+ LocalsHandler.from(LocalsHandler<T> other, T block,
{bool useOtherTryBlock: true})
- : locals = new VariableScope(block, other.locals),
- fieldScope = new FieldInitializationScope.from(other.fieldScope),
+ : locals = new VariableScope<T>(block, other.locals),
+ fieldScope = new FieldInitializationScope<T>.from(other.fieldScope),
captured = other.captured,
capturedAndBoxed = other.capturedAndBoxed,
types = other.types,
@@ -278,9 +279,9 @@ class LocalsHandler {
tryBlock = useOtherTryBlock ? other.tryBlock : this;
}
- LocalsHandler.deepCopyOf(LocalsHandler other)
- : locals = new VariableScope.deepCopyOf(other.locals),
- fieldScope = new FieldInitializationScope.from(other.fieldScope),
+ LocalsHandler.deepCopyOf(LocalsHandler<T> other)
+ : locals = new VariableScope<T>.deepCopyOf(other.locals),
+ fieldScope = new FieldInitializationScope<T>.from(other.fieldScope),
captured = other.captured,
capturedAndBoxed = other.capturedAndBoxed,
tryBlock = other.tryBlock,
@@ -288,9 +289,9 @@ class LocalsHandler {
inferrer = other.inferrer,
options = other.options;
- LocalsHandler.topLevelCopyOf(LocalsHandler other)
- : locals = new VariableScope.topLevelCopyOf(other.locals),
- fieldScope = new FieldInitializationScope.from(other.fieldScope),
+ LocalsHandler.topLevelCopyOf(LocalsHandler<T> other)
+ : locals = new VariableScope<T>.topLevelCopyOf(other.locals),
+ fieldScope = new FieldInitializationScope<T>.from(other.fieldScope),
captured = other.captured,
capturedAndBoxed = other.capturedAndBoxed,
tryBlock = other.tryBlock,
@@ -308,16 +309,16 @@ class LocalsHandler {
}
}
- void update(LocalElement local, TypeInformation type, Node node) {
+ void update(Local local, TypeInformation type, T node, DartType staticType,
+ {bool isSetIfNull: false}) {
assert(type != null);
if (options.trustTypeAnnotations || options.enableTypeAssertions) {
- type = types.narrowType(type, local.type);
+ type = types.narrowType(type, staticType);
}
updateLocal() {
TypeInformation currentType = locals[local];
- SendSet send = node != null ? node.asSendSet() : null;
- if (send != null && send.isIfNullAssignment && currentType != null) {
+ if (isSetIfNull && currentType != null) {
// If-null assignments may return either the new or the original value
// narrowed to non-null.
type = types.addPhiInput(
@@ -354,6 +355,13 @@ class LocalsHandler {
}
}
+ void narrow(Local local, DartType type, T node, {bool isSetIfNull: false}) {
+ TypeInformation existing = use(local);
+ TypeInformation newType =
+ types.narrowType(existing, type, isNullable: false);
+ update(local, newType, node, type, isSetIfNull: isSetIfNull);
+ }
+
void setCaptured(Local local, FieldEntity field) {
captured[local] = field;
}
@@ -362,7 +370,8 @@ class LocalsHandler {
capturedAndBoxed[local] = field;
}
- void mergeDiamondFlow(LocalsHandler thenBranch, LocalsHandler elseBranch) {
+ void mergeDiamondFlow(
+ LocalsHandler<T> thenBranch, LocalsHandler<T> elseBranch) {
if (fieldScope != null && elseBranch != null) {
fieldScope.mergeDiamondFlow(thenBranch.fieldScope, elseBranch.fieldScope);
}
@@ -374,7 +383,7 @@ class LocalsHandler {
elseBranch.seenBreakOrContinue;
if (aborts) return;
- void mergeOneBranch(LocalsHandler other) {
+ void mergeOneBranch(LocalsHandler<T> other) {
other.locals.forEachOwnLocal((Local local, TypeInformation type) {
TypeInformation myType = locals[local];
if (myType == null) return; // Variable is only defined in [other].
@@ -383,7 +392,7 @@ class LocalsHandler {
});
}
- void inPlaceUpdateOneBranch(LocalsHandler other) {
+ void inPlaceUpdateOneBranch(LocalsHandler<T> other) {
other.locals.forEachOwnLocal((Local local, TypeInformation type) {
TypeInformation myType = locals[local];
if (myType == null) return; // Variable is only defined in [other].
@@ -453,17 +462,17 @@ class LocalsHandler {
* where [:this:] is the [LocalsHandler] for the paths through the
* labeled statement that do not break out.
*/
- void mergeAfterBreaks(List<LocalsHandler> handlers,
+ void mergeAfterBreaks(List<LocalsHandler<T>> handlers,
{bool keepOwnLocals: true}) {
- Node level = locals.block;
+ T level = locals.block;
// Use a separate locals handler to perform the merge in, so that Phi
// creation does not invalidate previous type knowledge while we might
// still look it up.
- LocalsHandler merged = new LocalsHandler.from(this, level);
+ LocalsHandler<T> merged = new LocalsHandler<T>.from(this, level);
Set<Local> seenLocals = new Setlet<Local>();
bool allBranchesAbort = true;
// Merge all other handlers.
- for (LocalsHandler handler in handlers) {
+ for (LocalsHandler<T> handler in handlers) {
allBranchesAbort = allBranchesAbort && handler.seenReturnOrThrow;
merged.mergeHandler(handler, seenLocals);
}
@@ -493,7 +502,7 @@ class LocalsHandler {
* unless the local is already present in the set [seen]. This effectively
* overwrites the current type knowledge in this handler.
*/
- bool mergeHandler(LocalsHandler other, [Set<Local> seen]) {
+ bool mergeHandler(LocalsHandler<T> other, [Set<Local> seen]) {
if (other.seenReturnOrThrow) return false;
bool changed = false;
other.locals.forEachLocalUntilNode(locals.block, (local, otherType) {
@@ -528,7 +537,7 @@ class LocalsHandler {
return changed;
}
- void startLoop(Node loop) {
+ void startLoop(T loop) {
locals.forEachLocal((Local variable, TypeInformation type) {
TypeInformation newType = types.allocateLoopPhi(loop, variable, type,
isTry: loop is TryStatement);
@@ -538,7 +547,7 @@ class LocalsHandler {
});
}
- void endLoop(Node loop) {
+ void endLoop(T loop) {
locals.forEachLocal((Local variable, TypeInformation type) {
TypeInformation newType = types.simplifyPhi(loop, variable, type);
if (newType != type) {
@@ -547,7 +556,7 @@ class LocalsHandler {
});
}
- void updateField(Element element, TypeInformation type) {
+ void updateField(FieldEntity element, TypeInformation type) {
fieldScope.updateField(element, type);
}
}
« no previous file with comments | « pkg/compiler/lib/src/inferrer/kernel_inferrer_engine.dart ('k') | pkg/compiler/lib/src/js_model/js_strategy.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698