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

Side by Side Diff: pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart

Issue 979693003: Streamline the CPS IR Visitor interface. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Signal an error in visit methods that should not be called. Created 5 years, 9 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 | Annotate | Revision Log
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 4
5 // IrNodes are kept in a separate library to have precise control over their 5 // IrNodes are kept in a separate library to have precise control over their
6 // dependencies on other parts of the system. 6 // dependencies on other parts of the system.
7 library dart2js.ir_nodes; 7 library dart2js.ir_nodes;
8 8
9 import '../constants/expressions.dart'; 9 import '../constants/expressions.dart';
10 import '../constants/values.dart' as values show ConstantValue; 10 import '../constants/values.dart' as values show ConstantValue;
11 import '../cps_ir/optimizers.dart'; 11 import '../cps_ir/optimizers.dart';
12 import '../dart_types.dart' show DartType, GenericType; 12 import '../dart_types.dart' show DartType, GenericType;
13 import '../dart2jslib.dart' as dart2js show invariant; 13 import '../dart2jslib.dart' as dart2js show
14 CURRENT_ELEMENT_SPANNABLE,
15 InternalErrorFunction,
16 invariant;
14 import '../elements/elements.dart'; 17 import '../elements/elements.dart';
15 import '../io/source_information.dart' show SourceInformation; 18 import '../io/source_information.dart' show SourceInformation;
16 import '../universe/universe.dart' show Selector, SelectorKind; 19 import '../universe/universe.dart' show Selector, SelectorKind;
17 20
18 abstract class Node { 21 abstract class Node {
19 /// A pointer to the parent node. Is null until set by optimization passes. 22 /// A pointer to the parent node. Is null until set by optimization passes.
20 Node parent; 23 Node parent;
21 24
22 accept(Visitor visitor); 25 accept(Visitor visitor);
23 } 26 }
(...skipping 841 matching lines...) Expand 10 before | Expand all | Expand 10 after
865 applyPass(Pass pass) => pass.rewriteConstructorDefinition(this); 868 applyPass(Pass pass) => pass.rewriteConstructorDefinition(this);
866 } 869 }
867 870
868 List<Reference<Primitive>> _referenceList(Iterable<Primitive> definitions) { 871 List<Reference<Primitive>> _referenceList(Iterable<Primitive> definitions) {
869 return definitions.map((e) => new Reference<Primitive>(e)).toList(); 872 return definitions.map((e) => new Reference<Primitive>(e)).toList();
870 } 873 }
871 874
872 abstract class Visitor<T> { 875 abstract class Visitor<T> {
873 const Visitor(); 876 const Visitor();
874 877
875 T visit(Node node) => node.accept(this); 878 T visit(Node node);
876 // Abstract classes.
877 T visitNode(Node node) => null;
878 T visitExpression(Expression node) => visitNode(node);
879 T visitDefinition(Definition node) => visitNode(node);
880 T visitPrimitive(Primitive node) => visitDefinition(node);
881 T visitCondition(Condition node) => visitNode(node);
882 T visitRunnableBody(RunnableBody node) => visitNode(node);
883 879
884 // Concrete classes. 880 // Concrete classes.
885 T visitFieldDefinition(FieldDefinition node) => visitNode(node); 881 T visitFieldDefinition(FieldDefinition node);
886 T visitFunctionDefinition(FunctionDefinition node) => visitNode(node); 882 T visitFunctionDefinition(FunctionDefinition node);
887 T visitConstructorDefinition(ConstructorDefinition node) { 883 T visitConstructorDefinition(ConstructorDefinition node);
888 return visitFunctionDefinition(node); 884 T visitRunnableBody(RunnableBody node);
889 }
890 885
891 // Initializers 886 // Initializers
892 T visitInitializer(Initializer node) => visitNode(node); 887 T visitFieldInitializer(FieldInitializer node);
893 T visitFieldInitializer(FieldInitializer node) => visitInitializer(node); 888 T visitSuperInitializer(SuperInitializer node);
894 T visitSuperInitializer(SuperInitializer node) => visitInitializer(node);
895 889
896 // Expressions. 890 // Expressions.
897 T visitLetPrim(LetPrim node) => visitExpression(node); 891 T visitLetPrim(LetPrim node);
898 T visitLetCont(LetCont node) => visitExpression(node); 892 T visitLetCont(LetCont node);
899 T visitLetHandler(LetHandler node) => visitExpression(node); 893 T visitLetHandler(LetHandler node);
900 T visitLetMutable(LetMutable node) => visitExpression(node); 894 T visitLetMutable(LetMutable node);
901 T visitInvokeStatic(InvokeStatic node) => visitExpression(node); 895 T visitInvokeContinuation(InvokeContinuation node);
902 T visitInvokeContinuation(InvokeContinuation node) => visitExpression(node); 896 T visitInvokeStatic(InvokeStatic node);
903 T visitInvokeMethod(InvokeMethod node) => visitExpression(node); 897 T visitInvokeMethod(InvokeMethod node);
904 T visitInvokeMethodDirectly(InvokeMethodDirectly node) => visitExpression(node ); 898 T visitInvokeMethodDirectly(InvokeMethodDirectly node);
905 T visitInvokeConstructor(InvokeConstructor node) => visitExpression(node); 899 T visitInvokeConstructor(InvokeConstructor node);
906 T visitConcatenateStrings(ConcatenateStrings node) => visitExpression(node); 900 T visitConcatenateStrings(ConcatenateStrings node);
907 T visitBranch(Branch node) => visitExpression(node); 901 T visitBranch(Branch node);
908 T visitTypeOperator(TypeOperator node) => visitExpression(node); 902 T visitTypeOperator(TypeOperator node);
909 T visitSetMutableVariable(SetMutableVariable node) => visitExpression(node); 903 T visitSetMutableVariable(SetMutableVariable node);
910 T visitDeclareFunction(DeclareFunction node) => visitExpression(node); 904 T visitDeclareFunction(DeclareFunction node);
911 T visitSetField(SetField node) => visitExpression(node);
912 905
913 // Definitions. 906 // Definitions.
914 T visitLiteralList(LiteralList node) => visitPrimitive(node); 907 T visitLiteralList(LiteralList node);
915 T visitLiteralMap(LiteralMap node) => visitPrimitive(node); 908 T visitLiteralMap(LiteralMap node);
916 T visitConstant(Constant node) => visitPrimitive(node); 909 T visitConstant(Constant node);
917 T visitThis(This node) => visitPrimitive(node); 910 T visitThis(This node);
918 T visitReifyTypeVar(ReifyTypeVar node) => visitPrimitive(node); 911 T visitReifyTypeVar(ReifyTypeVar node);
919 T visitCreateFunction(CreateFunction node) => visitPrimitive(node); 912 T visitCreateFunction(CreateFunction node);
920 T visitGetMutableVariable(GetMutableVariable node) => visitPrimitive(node); 913 T visitGetMutableVariable(GetMutableVariable node);
921 T visitParameter(Parameter node) => visitPrimitive(node); 914 T visitParameter(Parameter node);
922 T visitContinuation(Continuation node) => visitDefinition(node); 915 T visitContinuation(Continuation node);
923 T visitMutableVariable(MutableVariable node) => visitDefinition(node); 916 T visitMutableVariable(MutableVariable node);
924 T visitGetField(GetField node) => visitDefinition(node);
925 T visitCreateBox(CreateBox node) => visitDefinition(node);
926 T visitCreateInstance(CreateInstance node) => visitDefinition(node);
927 917
928 // Conditions. 918 // Conditions.
929 T visitIsTrue(IsTrue node) => visitCondition(node); 919 T visitIsTrue(IsTrue node);
930 920
931 // JavaScript specific nodes. 921 // JavaScript specific nodes.
932 T visitIdentical(Identical node) => visitPrimitive(node); 922 // Expressions.
933 T visitInterceptor(Interceptor node) => visitPrimitive(node); 923 T visitSetField(SetField node);
924 // Definitions.
925 T visitIdentical(Identical node);
926 T visitInterceptor(Interceptor node);
927 T visitCreateInstance(CreateInstance node);
928 T visitGetField(GetField node);
929 T visitCreateBox(CreateBox node);
934 } 930 }
935 931
936 /// Recursively visits the entire CPS term, and calls abstract `process*` 932 /// Recursively visits the entire CPS term, and calls abstract `process*`
937 /// (i.e. `processLetPrim`) functions in pre-order. 933 /// (i.e. `processLetPrim`) functions in pre-order.
938 abstract class RecursiveVisitor extends Visitor { 934 class RecursiveVisitor implements Visitor {
939 const RecursiveVisitor(); 935 const RecursiveVisitor();
940 936
941 // Ensures that RecursiveVisitor contains overrides for all relevant nodes. 937 visit(Node node) => node.accept(this);
942 // As a rule of thumb, nodes with structure to traverse should be overridden
943 // with the appropriate visits in this class (for example, visitLetCont),
944 // while leaving other nodes for subclasses (i.e., visitLiteralList).
945 visitNode(Node node) {
946 throw "$this is stale, add missing visit override for $node";
947 }
948 938
949 processReference(Reference ref) {} 939 processReference(Reference ref) {}
950 940
951 processRunnableBody(RunnableBody node) {} 941 processRunnableBody(RunnableBody node) {}
952 visitRunnableBody(RunnableBody node) { 942 visitRunnableBody(RunnableBody node) {
953 processRunnableBody(node); 943 processRunnableBody(node);
954 visit(node.returnContinuation); 944 visit(node.returnContinuation);
955 visit(node.body); 945 visit(node.body);
956 } 946 }
957 947
(...skipping 18 matching lines...) Expand all
976 visitConstructorDefinition(ConstructorDefinition node) { 966 visitConstructorDefinition(ConstructorDefinition node) {
977 processConstructorDefinition(node); 967 processConstructorDefinition(node);
978 node.parameters.forEach(visit); 968 node.parameters.forEach(visit);
979 node.initializers.forEach(visit); 969 node.initializers.forEach(visit);
980 visit(node.body); 970 visit(node.body);
981 } 971 }
982 972
983 processFieldInitializer(FieldInitializer node) {} 973 processFieldInitializer(FieldInitializer node) {}
984 visitFieldInitializer(FieldInitializer node) { 974 visitFieldInitializer(FieldInitializer node) {
985 processFieldInitializer(node); 975 processFieldInitializer(node);
986 visit(node.body.body); 976 visit(node.body);
987 } 977 }
988 978
989 processSuperInitializer(SuperInitializer node) {} 979 processSuperInitializer(SuperInitializer node) {}
990 visitSuperInitializer(SuperInitializer node) { 980 visitSuperInitializer(SuperInitializer node) {
991 processSuperInitializer(node); 981 processSuperInitializer(node);
992 node.arguments.forEach( 982 node.arguments.forEach(visit);
993 (RunnableBody argument) => visit(argument.body));
994 } 983 }
995 984
996 // Expressions. 985 // Expressions.
997 986
998 processLetPrim(LetPrim node) {} 987 processLetPrim(LetPrim node) {}
999 visitLetPrim(LetPrim node) { 988 visitLetPrim(LetPrim node) {
1000 processLetPrim(node); 989 processLetPrim(node);
1001 visit(node.primitive); 990 visit(node.primitive);
1002 visit(node.body); 991 visit(node.body);
1003 } 992 }
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
1132 } 1121 }
1133 1122
1134 processMutableVariable(node) {} 1123 processMutableVariable(node) {}
1135 visitMutableVariable(MutableVariable node) { 1124 visitMutableVariable(MutableVariable node) {
1136 processMutableVariable(node); 1125 processMutableVariable(node);
1137 } 1126 }
1138 1127
1139 processGetMutableVariable(GetMutableVariable node) {} 1128 processGetMutableVariable(GetMutableVariable node) {}
1140 visitGetMutableVariable(GetMutableVariable node) { 1129 visitGetMutableVariable(GetMutableVariable node) {
1141 processGetMutableVariable(node); 1130 processGetMutableVariable(node);
1131 processReference(node.variable);
1142 } 1132 }
1143 1133
1144 processParameter(Parameter node) {} 1134 processParameter(Parameter node) {}
1145 visitParameter(Parameter node) => processParameter(node); 1135 visitParameter(Parameter node) => processParameter(node);
1146 1136
1147 processContinuation(Continuation node) {} 1137 processContinuation(Continuation node) {}
1148 visitContinuation(Continuation node) { 1138 visitContinuation(Continuation node) {
1149 processContinuation(node); 1139 processContinuation(node);
1150 node.parameters.forEach(visitParameter); 1140 node.parameters.forEach(visitParameter);
1151 if (node.body != null) visit(node.body); 1141 if (node.body != null) visit(node.body);
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1217 freeStack.add(index); 1207 freeStack.add(index);
1218 } 1208 }
1219 } 1209 }
1220 1210
1221 /// Assigns indices to each primitive in the IR such that primitives that are 1211 /// Assigns indices to each primitive in the IR such that primitives that are
1222 /// live simultaneously never get assigned the same index. 1212 /// live simultaneously never get assigned the same index.
1223 /// This information is used by the dart tree builder to generate fewer 1213 /// This information is used by the dart tree builder to generate fewer
1224 /// redundant variables. 1214 /// redundant variables.
1225 /// Currently, the liveness analysis is very simple and is often inadequate 1215 /// Currently, the liveness analysis is very simple and is often inadequate
1226 /// for removing all of the redundant variables. 1216 /// for removing all of the redundant variables.
1227 class RegisterAllocator extends Visitor { 1217 class RegisterAllocator implements Visitor {
1218 final dart2js.InternalErrorFunction internalError;
1219
1228 /// Separate register spaces for each source-level variable/parameter. 1220 /// Separate register spaces for each source-level variable/parameter.
1229 /// Note that null is used as key for primitives without hints. 1221 /// Note that null is used as key for primitives without hints.
1230 final Map<Local, RegisterArray> elementRegisters = <Local, RegisterArray>{}; 1222 final Map<Local, RegisterArray> elementRegisters = <Local, RegisterArray>{};
1231 1223
1224 RegisterAllocator(this.internalError);
1225
1232 RegisterArray getRegisterArray(Local local) { 1226 RegisterArray getRegisterArray(Local local) {
1233 RegisterArray registers = elementRegisters[local]; 1227 RegisterArray registers = elementRegisters[local];
1234 if (registers == null) { 1228 if (registers == null) {
1235 registers = new RegisterArray(); 1229 registers = new RegisterArray();
1236 elementRegisters[local] = registers; 1230 elementRegisters[local] = registers;
1237 } 1231 }
1238 return registers; 1232 return registers;
1239 } 1233 }
1240 1234
1241 void allocate(Primitive primitive) { 1235 void allocate(Primitive primitive) {
1242 if (primitive.registerIndex == null) { 1236 if (primitive.registerIndex == null) {
1243 primitive.registerIndex = getRegisterArray(primitive.hint).makeIndex(); 1237 primitive.registerIndex = getRegisterArray(primitive.hint).makeIndex();
1244 } 1238 }
1245 } 1239 }
1246 1240
1247 void release(Primitive primitive) { 1241 void release(Primitive primitive) {
1248 // Do not share indices for temporaries as this may obstruct inlining. 1242 // Do not share indices for temporaries as this may obstruct inlining.
1249 if (primitive.hint == null) return; 1243 if (primitive.hint == null) return;
1250 if (primitive.registerIndex != null) { 1244 if (primitive.registerIndex != null) {
1251 getRegisterArray(primitive.hint).releaseIndex(primitive.registerIndex); 1245 getRegisterArray(primitive.hint).releaseIndex(primitive.registerIndex);
1252 } 1246 }
1253 } 1247 }
1254 1248
1249 void visit(Node node) => node.accept(this);
1250
1255 void visitReference(Reference reference) { 1251 void visitReference(Reference reference) {
1256 allocate(reference.definition); 1252 allocate(reference.definition);
1257 } 1253 }
1258 1254
1259 void visitFieldDefinition(FieldDefinition node) { 1255 void visitFieldDefinition(FieldDefinition node) {
1260 if (node.hasInitializer) { 1256 if (node.hasInitializer) {
1261 visit(node.body); 1257 visit(node.body);
1262 } 1258 }
1263 } 1259 }
1264 1260
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
1379 void visitConstant(Constant node) { 1375 void visitConstant(Constant node) {
1380 } 1376 }
1381 1377
1382 void visitThis(This node) { 1378 void visitThis(This node) {
1383 } 1379 }
1384 1380
1385 void visitReifyTypeVar(ReifyTypeVar node) { 1381 void visitReifyTypeVar(ReifyTypeVar node) {
1386 } 1382 }
1387 1383
1388 void visitCreateFunction(CreateFunction node) { 1384 void visitCreateFunction(CreateFunction node) {
1389 new RegisterAllocator().visit(node.definition); 1385 new RegisterAllocator(internalError).visit(node.definition);
1390 } 1386 }
1391 1387
1392 void visitGetMutableVariable(GetMutableVariable node) { 1388 void visitGetMutableVariable(GetMutableVariable node) {
1393 } 1389 }
1394 1390
1395 void visitSetMutableVariable(SetMutableVariable node) { 1391 void visitSetMutableVariable(SetMutableVariable node) {
1396 visit(node.body); 1392 visit(node.body);
1397 visitReference(node.value); 1393 visitReference(node.value);
1398 } 1394 }
1399 1395
1400 void visitDeclareFunction(DeclareFunction node) { 1396 void visitDeclareFunction(DeclareFunction node) {
1401 new RegisterAllocator().visit(node.definition); 1397 new RegisterAllocator(internalError).visit(node.definition);
1402 visit(node.body); 1398 visit(node.body);
1403 } 1399 }
1404 1400
1405 void visitParameter(Parameter node) { 1401 void visitParameter(Parameter node) {
1406 throw "Parameters should not be visited by RegisterAllocator"; 1402 // Parameters are handled differently depending on whether they are
1403 // function parameters, continuation parameters, exception handler
1404 // parameters, etc. Thus we do not call visitParameter directly and
1405 // handle them explicitly in their parent IR node.
1406 internalError(dart2js.CURRENT_ELEMENT_SPANNABLE,
1407 'tried to allocate a parameter');
1407 } 1408 }
1408 1409
1410 void visitMutableVariable(MutableVariable node) {}
1411
1409 void visitContinuation(Continuation node) { 1412 void visitContinuation(Continuation node) {
1410 visit(node.body); 1413 visit(node.body);
1411 1414
1412 // Arguments get allocated left-to-right, so we release parameters 1415 // Arguments get allocated left-to-right, so we release parameters
1413 // right-to-left. This increases the likelihood that arguments can be 1416 // right-to-left. This increases the likelihood that arguments can be
1414 // transferred without intermediate assignments. 1417 // transferred without intermediate assignments.
1415 for (int i = node.parameters.length - 1; i >= 0; --i) { 1418 for (int i = node.parameters.length - 1; i >= 0; --i) {
1416 release(node.parameters[i]); 1419 release(node.parameters[i]);
1417 } 1420 }
1418 } 1421 }
(...skipping 23 matching lines...) Expand all
1442 1445
1443 void visitIdentical(Identical node) { 1446 void visitIdentical(Identical node) {
1444 visitReference(node.left); 1447 visitReference(node.left);
1445 visitReference(node.right); 1448 visitReference(node.right);
1446 } 1449 }
1447 1450
1448 void visitInterceptor(Interceptor node) { 1451 void visitInterceptor(Interceptor node) {
1449 visitReference(node.input); 1452 visitReference(node.input);
1450 } 1453 }
1451 } 1454 }
OLDNEW
« no previous file with comments | « pkg/analyzer2dart/test/sexpr_data.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