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

Unified Diff: pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart

Issue 1153603006: dart2js cps: Type casts and related changes to type propagation. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Another typo in SExpression unstrngifier Created 5 years, 6 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/cps_ir/cps_ir_nodes.dart
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart
index 0bb7ecc8ba9f92ff5dc96b30e8dd30a13980c28d..164663372e22cb8250b1c25be82a45353fa5b459 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart
@@ -28,6 +28,8 @@ abstract class Node {
/// that can be obtained without side-effects, divergence, or throwing
/// exceptions can be built using a [LetPrim].
abstract class Expression extends Node {
+ InteriorNode get parent; // Only InteriorNodes may contain expressions.
+
Expression plug(Expression expr) => throw 'impossible';
}
@@ -357,10 +359,47 @@ class InvokeConstructor extends Expression implements Invoke {
accept(Visitor visitor) => visitor.visitInvokeConstructor(this);
}
-// TODO(asgerf): Make a Primitive for "is" and an Expression for "as".
+/// An "is" type test.
+///
+/// Returns `true` if [value] not `null` and is an instance of [type].
+///
+/// [type] must not be the [Object], `dynamic` or [Null] types (though it might
+/// be a type variable containing one of these types). This design is chosen
+/// to simplify code generation for type tests.
+class TypeTest extends Primitive {
+ Reference<Primitive> value;
+ final DartType type;
-/// An "as" cast or an "is" check.
-class TypeOperator extends Expression {
+ /// If [type] is an [InterfaceType], this holds the internal representation of
+ /// the type arguments to [type]. Since these may reference type variables
+ /// from the enclosing class, they are not constant.
+ ///
+ /// If [type] is a [TypeVariableType], this is a singleton list with
+ /// the internal representation of the type held in that type variable.
+ ///
+ /// Otherwise the list is empty.
+ final List<Reference<Primitive>> typeArguments;
+
+ TypeTest(Primitive value,
+ this.type,
+ List<Primitive> typeArguments)
+ : this.value = new Reference<Primitive>(value),
+ this.typeArguments = _referenceList(typeArguments);
+
+ accept(Visitor visitor) => visitor.visitTypeTest(this);
+}
+
+/// An "as" type cast.
+///
+/// If [value] is `null` or is an instance of [type], [continuation] is invoked
+/// with [value] as argument. Otherwise, a [CastError] is thrown.
+///
+/// Discussion:
+/// The parameter to [continuation] is redundant since it will always equal
+/// [value], which is typically in scope in the continuation. However, it might
+/// simplify type propagation, since a better type can be computed for the
+/// continuation parameter without needing flow-sensitive analysis.
+class TypeCast extends Expression {
Reference<Primitive> value;
final DartType type;
@@ -374,22 +413,16 @@ class TypeOperator extends Expression {
/// Otherwise the list is empty.
final List<Reference<Primitive>> typeArguments;
final Reference<Continuation> continuation;
- final bool isTypeTest;
- TypeOperator(Primitive value,
- this.type,
- List<Primitive> typeArguments,
- Continuation cont,
- {bool this.isTypeTest})
+ TypeCast(Primitive value,
+ this.type,
+ List<Primitive> typeArguments,
+ Continuation cont)
: this.value = new Reference<Primitive>(value),
this.typeArguments = _referenceList(typeArguments),
- this.continuation = new Reference<Continuation>(cont) {
- assert(isTypeTest != null);
- }
-
- bool get isTypeCast => !isTypeTest;
+ this.continuation = new Reference<Continuation>(cont);
- accept(Visitor visitor) => visitor.visitTypeOperator(this);
+ accept(Visitor visitor) => visitor.visitTypeCast(this);
}
/// Invoke [toString] on each argument and concatenate the results.
@@ -439,6 +472,14 @@ class NonTailThrow extends Primitive {
accept(Visitor visitor) => visitor.visitNonTailThrow(this);
}
+/// An expression that is known to be unreachable.
+///
+/// This can be placed as the body of a call continuation, when the caller is
+/// known never to invoke it, e.g. because the calling expression always throws.
+class Unreachable extends Expression {
+ accept(Visitor visitor) => visitor.visitUnreachable(this);
+}
+
/// Gets the value from a [MutableVariable].
///
/// [MutableVariable]s can be seen as ref cells that are not first-class
@@ -495,6 +536,14 @@ class InvokeContinuation extends Expression {
if (isRecursive) cont.isRecursive = true;
}
+ /// Build a one-argument InvokeContinuation using existing reference objects.
+ ///
+ /// This is useful for converting call continuations to local continuations.
+ InvokeContinuation.fromCall(this.continuation,
+ Reference<Primitive> argument)
+ : arguments = <Reference<Primitive>>[argument],
+ isRecursive = false;
+
/// A continuation invocation whose target and arguments will be filled
/// in later.
///
@@ -875,11 +924,12 @@ abstract class Visitor<T> {
T visitThrow(Throw node);
T visitRethrow(Rethrow node);
T visitBranch(Branch node);
- T visitTypeOperator(TypeOperator node);
+ T visitTypeCast(TypeCast node);
T visitSetMutableVariable(SetMutableVariable node);
T visitSetStatic(SetStatic node);
T visitGetLazyStatic(GetLazyStatic node);
T visitSetField(SetField node);
+ T visitUnreachable(Unreachable node);
// Definitions.
T visitLiteralList(LiteralList node);
@@ -901,6 +951,7 @@ abstract class Visitor<T> {
T visitReadTypeVariable(ReadTypeVariable node);
T visitTypeExpression(TypeExpression node);
T visitCreateInvocationMirror(CreateInvocationMirror node);
+ T visitTypeTest(TypeTest node);
// Conditions.
T visitIsTrue(IsTrue node);
@@ -1018,14 +1069,21 @@ class RecursiveVisitor implements Visitor {
visit(node.condition);
}
- processTypeOperator(TypeOperator node) {}
- visitTypeOperator(TypeOperator node) {
- processTypeOperator(node);
+ processTypeCast(TypeCast node) {}
+ visitTypeCast(TypeCast node) {
+ processTypeCast(node);
processReference(node.continuation);
processReference(node.value);
node.typeArguments.forEach(processReference);
}
+ processTypeTest(TypeTest node) {}
+ visitTypeTest(TypeTest node) {
+ processTypeTest(node);
+ processReference(node.value);
+ node.typeArguments.forEach(processReference);
+ }
+
processSetMutableVariable(SetMutableVariable node) {}
visitSetMutableVariable(SetMutableVariable node) {
processSetMutableVariable(node);
@@ -1175,4 +1233,22 @@ class RecursiveVisitor implements Visitor {
processCreateInvocationMirror(node);
node.arguments.forEach(processReference);
}
+
+ processUnreachable(Unreachable node) {}
+ visitUnreachable(Unreachable node) {
+ processUnreachable(node);
+ }
+}
+
+/// Visit a just-deleted subterm and unlink all [Reference]s in it.
+class RemovalVisitor extends RecursiveVisitor {
+ const RemovalVisitor();
+
+ processReference(Reference reference) {
+ reference.unlink();
+ }
+
+ static void remove(Node node) {
+ (const RemovalVisitor()).visit(node);
+ }
}
« no previous file with comments | « pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart ('k') | pkg/compiler/lib/src/cps_ir/cps_ir_nodes_sexpr.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698