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

Side by Side 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 library dart2js.ir_nodes; 4 library dart2js.ir_nodes;
5 5
6 import '../constants/expressions.dart'; 6 import '../constants/expressions.dart';
7 import '../constants/values.dart' as values show ConstantValue; 7 import '../constants/values.dart' as values show ConstantValue;
8 import '../dart_types.dart' show DartType, InterfaceType, TypeVariableType; 8 import '../dart_types.dart' show DartType, InterfaceType, TypeVariableType;
9 import '../elements/elements.dart'; 9 import '../elements/elements.dart';
10 import '../io/source_information.dart' show SourceInformation; 10 import '../io/source_information.dart' show SourceInformation;
(...skipping 10 matching lines...) Expand all
21 /// side-effects. 21 /// side-effects.
22 /// 22 ///
23 /// Evaluation continues by stepping into a sub-expression, invoking a 23 /// Evaluation continues by stepping into a sub-expression, invoking a
24 /// continuation, or throwing an exception. 24 /// continuation, or throwing an exception.
25 /// 25 ///
26 /// Expressions do not a return value. Expressions that produce values should 26 /// Expressions do not a return value. Expressions that produce values should
27 /// invoke a [Continuation] with the result as argument. Alternatively, values 27 /// invoke a [Continuation] with the result as argument. Alternatively, values
28 /// that can be obtained without side-effects, divergence, or throwing 28 /// that can be obtained without side-effects, divergence, or throwing
29 /// exceptions can be built using a [LetPrim]. 29 /// exceptions can be built using a [LetPrim].
30 abstract class Expression extends Node { 30 abstract class Expression extends Node {
31 InteriorNode get parent; // Only InteriorNodes may contain expressions.
32
31 Expression plug(Expression expr) => throw 'impossible'; 33 Expression plug(Expression expr) => throw 'impossible';
32 } 34 }
33 35
34 /// The base class of things that variables can refer to: primitives, 36 /// The base class of things that variables can refer to: primitives,
35 /// continuations, function and continuation parameters, etc. 37 /// continuations, function and continuation parameters, etc.
36 abstract class Definition<T extends Definition<T>> extends Node { 38 abstract class Definition<T extends Definition<T>> extends Node {
37 // The head of a linked-list of occurrences, in no particular order. 39 // The head of a linked-list of occurrences, in no particular order.
38 Reference<T> firstRef; 40 Reference<T> firstRef;
39 41
40 bool get hasAtMostOneUse => firstRef == null || firstRef.next == null; 42 bool get hasAtMostOneUse => firstRef == null || firstRef.next == null;
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after
350 this.target, 352 this.target,
351 this.selector, 353 this.selector,
352 List<Primitive> args, 354 List<Primitive> args,
353 Continuation cont) 355 Continuation cont)
354 : arguments = _referenceList(args), 356 : arguments = _referenceList(args),
355 continuation = new Reference<Continuation>(cont); 357 continuation = new Reference<Continuation>(cont);
356 358
357 accept(Visitor visitor) => visitor.visitInvokeConstructor(this); 359 accept(Visitor visitor) => visitor.visitInvokeConstructor(this);
358 } 360 }
359 361
360 // TODO(asgerf): Make a Primitive for "is" and an Expression for "as". 362 /// An "is" type test.
361 363 ///
362 /// An "as" cast or an "is" check. 364 /// Returns `true` if [value] not `null` and is an instance of [type].
363 class TypeOperator extends Expression { 365 ///
366 /// [type] must not be the [Object], `dynamic` or [Null] types (though it might
367 /// be a type variable containing one of these types). This design is chosen
368 /// to simplify code generation for type tests.
369 class TypeTest extends Primitive {
364 Reference<Primitive> value; 370 Reference<Primitive> value;
365 final DartType type; 371 final DartType type;
366 372
373 /// If [type] is an [InterfaceType], this holds the internal representation of
374 /// the type arguments to [type]. Since these may reference type variables
375 /// from the enclosing class, they are not constant.
376 ///
377 /// If [type] is a [TypeVariableType], this is a singleton list with
378 /// the internal representation of the type held in that type variable.
379 ///
380 /// Otherwise the list is empty.
381 final List<Reference<Primitive>> typeArguments;
382
383 TypeTest(Primitive value,
384 this.type,
385 List<Primitive> typeArguments)
386 : this.value = new Reference<Primitive>(value),
387 this.typeArguments = _referenceList(typeArguments);
388
389 accept(Visitor visitor) => visitor.visitTypeTest(this);
390 }
391
392 /// An "as" type cast.
393 ///
394 /// If [value] is `null` or is an instance of [type], [continuation] is invoked
395 /// with [value] as argument. Otherwise, a [CastError] is thrown.
396 ///
397 /// Discussion:
398 /// The parameter to [continuation] is redundant since it will always equal
399 /// [value], which is typically in scope in the continuation. However, it might
400 /// simplify type propagation, since a better type can be computed for the
401 /// continuation parameter without needing flow-sensitive analysis.
402 class TypeCast extends Expression {
403 Reference<Primitive> value;
404 final DartType type;
405
367 /// If [type] is an [InterfaceType], this holds the internal representation of 406 /// If [type] is an [InterfaceType], this holds the internal representation of
368 /// the type arguments to [type]. Since these may reference type variables 407 /// the type arguments to [type]. Since these may reference type variables
369 /// from the enclosing class, they are not constant. 408 /// from the enclosing class, they are not constant.
370 /// 409 ///
371 /// If [type] is a [TypeVariableType], this is a singleton list with 410 /// If [type] is a [TypeVariableType], this is a singleton list with
372 /// the internal representation of the type held in that type variable. 411 /// the internal representation of the type held in that type variable.
373 /// 412 ///
374 /// Otherwise the list is empty. 413 /// Otherwise the list is empty.
375 final List<Reference<Primitive>> typeArguments; 414 final List<Reference<Primitive>> typeArguments;
376 final Reference<Continuation> continuation; 415 final Reference<Continuation> continuation;
377 final bool isTypeTest;
378 416
379 TypeOperator(Primitive value, 417 TypeCast(Primitive value,
380 this.type, 418 this.type,
381 List<Primitive> typeArguments, 419 List<Primitive> typeArguments,
382 Continuation cont, 420 Continuation cont)
383 {bool this.isTypeTest})
384 : this.value = new Reference<Primitive>(value), 421 : this.value = new Reference<Primitive>(value),
385 this.typeArguments = _referenceList(typeArguments), 422 this.typeArguments = _referenceList(typeArguments),
386 this.continuation = new Reference<Continuation>(cont) { 423 this.continuation = new Reference<Continuation>(cont);
387 assert(isTypeTest != null);
388 }
389 424
390 bool get isTypeCast => !isTypeTest; 425 accept(Visitor visitor) => visitor.visitTypeCast(this);
391
392 accept(Visitor visitor) => visitor.visitTypeOperator(this);
393 } 426 }
394 427
395 /// Invoke [toString] on each argument and concatenate the results. 428 /// Invoke [toString] on each argument and concatenate the results.
396 class ConcatenateStrings extends Expression { 429 class ConcatenateStrings extends Expression {
397 final List<Reference<Primitive>> arguments; 430 final List<Reference<Primitive>> arguments;
398 final Reference<Continuation> continuation; 431 final Reference<Continuation> continuation;
399 432
400 ConcatenateStrings(List<Primitive> args, Continuation cont) 433 ConcatenateStrings(List<Primitive> args, Continuation cont)
401 : arguments = _referenceList(args), 434 : arguments = _referenceList(args),
402 continuation = new Reference<Continuation>(cont); 435 continuation = new Reference<Continuation>(cont);
(...skipping 29 matching lines...) Expand all
432 /// translation, a [NonTailThrow] is used as that value. A cleanup pass 465 /// translation, a [NonTailThrow] is used as that value. A cleanup pass
433 /// removes these and replaces them with [Throw] expressions. 466 /// removes these and replaces them with [Throw] expressions.
434 class NonTailThrow extends Primitive { 467 class NonTailThrow extends Primitive {
435 final Reference<Primitive> value; 468 final Reference<Primitive> value;
436 469
437 NonTailThrow(Primitive value) : value = new Reference<Primitive>(value); 470 NonTailThrow(Primitive value) : value = new Reference<Primitive>(value);
438 471
439 accept(Visitor visitor) => visitor.visitNonTailThrow(this); 472 accept(Visitor visitor) => visitor.visitNonTailThrow(this);
440 } 473 }
441 474
475 /// An expression that is known to be unreachable.
476 ///
477 /// This can be placed as the body of a call continuation, when the caller is
478 /// known never to invoke it, e.g. because the calling expression always throws.
479 class Unreachable extends Expression {
480 accept(Visitor visitor) => visitor.visitUnreachable(this);
481 }
482
442 /// Gets the value from a [MutableVariable]. 483 /// Gets the value from a [MutableVariable].
443 /// 484 ///
444 /// [MutableVariable]s can be seen as ref cells that are not first-class 485 /// [MutableVariable]s can be seen as ref cells that are not first-class
445 /// values. A [LetPrim] with a [GetMutableVariable] can then be seen as: 486 /// values. A [LetPrim] with a [GetMutableVariable] can then be seen as:
446 /// 487 ///
447 /// let prim p = ![variable] in [body] 488 /// let prim p = ![variable] in [body]
448 /// 489 ///
449 class GetMutableVariable extends Primitive { 490 class GetMutableVariable extends Primitive {
450 final Reference<MutableVariable> variable; 491 final Reference<MutableVariable> variable;
451 492
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
488 bool isRecursive; 529 bool isRecursive;
489 530
490 InvokeContinuation(Continuation cont, List<Primitive> args, 531 InvokeContinuation(Continuation cont, List<Primitive> args,
491 {this.isRecursive: false}) 532 {this.isRecursive: false})
492 : continuation = new Reference<Continuation>(cont), 533 : continuation = new Reference<Continuation>(cont),
493 arguments = _referenceList(args) { 534 arguments = _referenceList(args) {
494 assert(cont.parameters == null || cont.parameters.length == args.length); 535 assert(cont.parameters == null || cont.parameters.length == args.length);
495 if (isRecursive) cont.isRecursive = true; 536 if (isRecursive) cont.isRecursive = true;
496 } 537 }
497 538
539 /// Build a one-argument InvokeContinuation using existing reference objects.
540 ///
541 /// This is useful for converting call continuations to local continuations.
542 InvokeContinuation.fromCall(this.continuation,
543 Reference<Primitive> argument)
544 : arguments = <Reference<Primitive>>[argument],
545 isRecursive = false;
546
498 /// A continuation invocation whose target and arguments will be filled 547 /// A continuation invocation whose target and arguments will be filled
499 /// in later. 548 /// in later.
500 /// 549 ///
501 /// Used as a placeholder for a jump whose target is not yet created 550 /// Used as a placeholder for a jump whose target is not yet created
502 /// (e.g., in the translation of break and continue). 551 /// (e.g., in the translation of break and continue).
503 InvokeContinuation.uninitialized({this.isRecursive: false}) 552 InvokeContinuation.uninitialized({this.isRecursive: false})
504 : continuation = null, 553 : continuation = null,
505 arguments = null; 554 arguments = null;
506 555
507 accept(Visitor visitor) => visitor.visitInvokeContinuation(this); 556 accept(Visitor visitor) => visitor.visitInvokeContinuation(this);
(...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after
868 T visitLetMutable(LetMutable node); 917 T visitLetMutable(LetMutable node);
869 T visitInvokeContinuation(InvokeContinuation node); 918 T visitInvokeContinuation(InvokeContinuation node);
870 T visitInvokeStatic(InvokeStatic node); 919 T visitInvokeStatic(InvokeStatic node);
871 T visitInvokeMethod(InvokeMethod node); 920 T visitInvokeMethod(InvokeMethod node);
872 T visitInvokeMethodDirectly(InvokeMethodDirectly node); 921 T visitInvokeMethodDirectly(InvokeMethodDirectly node);
873 T visitInvokeConstructor(InvokeConstructor node); 922 T visitInvokeConstructor(InvokeConstructor node);
874 T visitConcatenateStrings(ConcatenateStrings node); 923 T visitConcatenateStrings(ConcatenateStrings node);
875 T visitThrow(Throw node); 924 T visitThrow(Throw node);
876 T visitRethrow(Rethrow node); 925 T visitRethrow(Rethrow node);
877 T visitBranch(Branch node); 926 T visitBranch(Branch node);
878 T visitTypeOperator(TypeOperator node); 927 T visitTypeCast(TypeCast node);
879 T visitSetMutableVariable(SetMutableVariable node); 928 T visitSetMutableVariable(SetMutableVariable node);
880 T visitSetStatic(SetStatic node); 929 T visitSetStatic(SetStatic node);
881 T visitGetLazyStatic(GetLazyStatic node); 930 T visitGetLazyStatic(GetLazyStatic node);
882 T visitSetField(SetField node); 931 T visitSetField(SetField node);
932 T visitUnreachable(Unreachable node);
883 933
884 // Definitions. 934 // Definitions.
885 T visitLiteralList(LiteralList node); 935 T visitLiteralList(LiteralList node);
886 T visitLiteralMap(LiteralMap node); 936 T visitLiteralMap(LiteralMap node);
887 T visitConstant(Constant node); 937 T visitConstant(Constant node);
888 T visitCreateFunction(CreateFunction node); 938 T visitCreateFunction(CreateFunction node);
889 T visitGetMutableVariable(GetMutableVariable node); 939 T visitGetMutableVariable(GetMutableVariable node);
890 T visitParameter(Parameter node); 940 T visitParameter(Parameter node);
891 T visitContinuation(Continuation node); 941 T visitContinuation(Continuation node);
892 T visitMutableVariable(MutableVariable node); 942 T visitMutableVariable(MutableVariable node);
893 T visitNonTailThrow(NonTailThrow node); 943 T visitNonTailThrow(NonTailThrow node);
894 T visitGetStatic(GetStatic node); 944 T visitGetStatic(GetStatic node);
895 T visitIdentical(Identical node); 945 T visitIdentical(Identical node);
896 T visitInterceptor(Interceptor node); 946 T visitInterceptor(Interceptor node);
897 T visitCreateInstance(CreateInstance node); 947 T visitCreateInstance(CreateInstance node);
898 T visitGetField(GetField node); 948 T visitGetField(GetField node);
899 T visitCreateBox(CreateBox node); 949 T visitCreateBox(CreateBox node);
900 T visitReifyRuntimeType(ReifyRuntimeType node); 950 T visitReifyRuntimeType(ReifyRuntimeType node);
901 T visitReadTypeVariable(ReadTypeVariable node); 951 T visitReadTypeVariable(ReadTypeVariable node);
902 T visitTypeExpression(TypeExpression node); 952 T visitTypeExpression(TypeExpression node);
903 T visitCreateInvocationMirror(CreateInvocationMirror node); 953 T visitCreateInvocationMirror(CreateInvocationMirror node);
954 T visitTypeTest(TypeTest node);
904 955
905 // Conditions. 956 // Conditions.
906 T visitIsTrue(IsTrue node); 957 T visitIsTrue(IsTrue node);
907 } 958 }
908 959
909 /// Recursively visits the entire CPS term, and calls abstract `process*` 960 /// Recursively visits the entire CPS term, and calls abstract `process*`
910 /// (i.e. `processLetPrim`) functions in pre-order. 961 /// (i.e. `processLetPrim`) functions in pre-order.
911 class RecursiveVisitor implements Visitor { 962 class RecursiveVisitor implements Visitor {
912 const RecursiveVisitor(); 963 const RecursiveVisitor();
913 964
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
1011 } 1062 }
1012 1063
1013 processBranch(Branch node) {} 1064 processBranch(Branch node) {}
1014 visitBranch(Branch node) { 1065 visitBranch(Branch node) {
1015 processBranch(node); 1066 processBranch(node);
1016 processReference(node.trueContinuation); 1067 processReference(node.trueContinuation);
1017 processReference(node.falseContinuation); 1068 processReference(node.falseContinuation);
1018 visit(node.condition); 1069 visit(node.condition);
1019 } 1070 }
1020 1071
1021 processTypeOperator(TypeOperator node) {} 1072 processTypeCast(TypeCast node) {}
1022 visitTypeOperator(TypeOperator node) { 1073 visitTypeCast(TypeCast node) {
1023 processTypeOperator(node); 1074 processTypeCast(node);
1024 processReference(node.continuation); 1075 processReference(node.continuation);
1025 processReference(node.value); 1076 processReference(node.value);
1026 node.typeArguments.forEach(processReference); 1077 node.typeArguments.forEach(processReference);
1027 } 1078 }
1028 1079
1080 processTypeTest(TypeTest node) {}
1081 visitTypeTest(TypeTest node) {
1082 processTypeTest(node);
1083 processReference(node.value);
1084 node.typeArguments.forEach(processReference);
1085 }
1086
1029 processSetMutableVariable(SetMutableVariable node) {} 1087 processSetMutableVariable(SetMutableVariable node) {}
1030 visitSetMutableVariable(SetMutableVariable node) { 1088 visitSetMutableVariable(SetMutableVariable node) {
1031 processSetMutableVariable(node); 1089 processSetMutableVariable(node);
1032 processReference(node.variable); 1090 processReference(node.variable);
1033 processReference(node.value); 1091 processReference(node.value);
1034 visit(node.body); 1092 visit(node.body);
1035 } 1093 }
1036 1094
1037 processGetLazyStatic(GetLazyStatic node) {} 1095 processGetLazyStatic(GetLazyStatic node) {}
1038 visitGetLazyStatic(GetLazyStatic node) { 1096 visitGetLazyStatic(GetLazyStatic node) {
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
1168 visitNonTailThrow(NonTailThrow node) { 1226 visitNonTailThrow(NonTailThrow node) {
1169 processNonTailThrow(node); 1227 processNonTailThrow(node);
1170 processReference(node.value); 1228 processReference(node.value);
1171 } 1229 }
1172 1230
1173 processCreateInvocationMirror(CreateInvocationMirror node) {} 1231 processCreateInvocationMirror(CreateInvocationMirror node) {}
1174 visitCreateInvocationMirror(CreateInvocationMirror node) { 1232 visitCreateInvocationMirror(CreateInvocationMirror node) {
1175 processCreateInvocationMirror(node); 1233 processCreateInvocationMirror(node);
1176 node.arguments.forEach(processReference); 1234 node.arguments.forEach(processReference);
1177 } 1235 }
1236
1237 processUnreachable(Unreachable node) {}
1238 visitUnreachable(Unreachable node) {
1239 processUnreachable(node);
1240 }
1178 } 1241 }
1242
1243 /// Visit a just-deleted subterm and unlink all [Reference]s in it.
1244 class RemovalVisitor extends RecursiveVisitor {
1245 const RemovalVisitor();
1246
1247 processReference(Reference reference) {
1248 reference.unlink();
1249 }
1250
1251 static void remove(Node node) {
1252 (const RemovalVisitor()).visit(node);
1253 }
1254 }
OLDNEW
« 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