comparison graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java @ 14641:f0bb82ebe30c

Truffle-DSL: some fixes and optimizations to the generated code. Fixed polymorphic specialization nodes could still reference children in some cases. Removed generation of getCost methods since they were very expensive to call. Removed generation of copyPolymorphic, setNext0. Made generated executeGeneric0 and executeAndSpecialize0 final.
author Christian Humer <christian.humer@gmail.com>
date Thu, 20 Mar 2014 17:50:41 +0100
parents a08b8694f556
children 2a4b6003ef03
comparison
equal deleted inserted replaced
14638:b2e2132c0eff 14641:f0bb82ebe30c
96 96
97 private static String valueName(ActualParameter param) { 97 private static String valueName(ActualParameter param) {
98 return param.getLocalName(); 98 return param.getLocalName();
99 } 99 }
100 100
101 private static CodeTree createAccessChild(NodeExecutionData targetExecution) { 101 private static CodeTree createAccessChild(NodeExecutionData targetExecution, String thisReference) {
102 String reference = thisReference;
103 if (reference == null) {
104 reference = "this";
105 }
102 CodeTreeBuilder builder = CodeTreeBuilder.createBuilder(); 106 CodeTreeBuilder builder = CodeTreeBuilder.createBuilder();
103 Element accessElement = targetExecution.getChild().getAccessElement(); 107 Element accessElement = targetExecution.getChild().getAccessElement();
104 if (accessElement == null || accessElement.getKind() == ElementKind.METHOD) { 108 if (accessElement == null || accessElement.getKind() == ElementKind.METHOD) {
105 builder.string("this.").string(targetExecution.getChild().getName()); 109 builder.string(reference).string(".").string(targetExecution.getChild().getName());
106 } else if (accessElement.getKind() == ElementKind.FIELD) { 110 } else if (accessElement.getKind() == ElementKind.FIELD) {
107 builder.string("this.").string(accessElement.getSimpleName().toString()); 111 builder.string(reference).string(".").string(accessElement.getSimpleName().toString());
108 } else { 112 } else {
109 throw new AssertionError(); 113 throw new AssertionError();
110 } 114 }
111 if (targetExecution.isIndexed()) { 115 if (targetExecution.isIndexed()) {
112 builder.string("[" + targetExecution.getIndex() + "]"); 116 builder.string("[" + targetExecution.getIndex() + "]");
320 * } 324 * }
321 * 325 *
322 * variant2 $condition != null 326 * variant2 $condition != null
323 * $type $name = $value; 327 * $type $name = $value;
324 * </pre> 328 * </pre>
325 * 329 *
326 * . 330 * .
327 */ 331 */
328 private static CodeTree createLazyAssignment(CodeTreeBuilder parent, String name, TypeMirror type, CodeTree condition, CodeTree value) { 332 private static CodeTree createLazyAssignment(CodeTreeBuilder parent, String name, TypeMirror type, CodeTree condition, CodeTree value) {
329 CodeTreeBuilder builder = new CodeTreeBuilder(parent); 333 CodeTreeBuilder builder = new CodeTreeBuilder(parent);
330 if (condition == null) { 334 if (condition == null) {
355 if (executionData != null) { 359 if (executionData != null) {
356 if (executionData.isShortCircuit()) { 360 if (executionData.isShortCircuit()) {
357 nodes.nullLiteral(); 361 nodes.nullLiteral();
358 arguments.string(valueName(parameter.getPreviousParameter())); 362 arguments.string(valueName(parameter.getPreviousParameter()));
359 } 363 }
360 nodes.tree(createAccessChild(executionData)); 364 nodes.tree(createAccessChild(executionData, null));
361 arguments.string(valueName(parameter)); 365 arguments.string(valueName(parameter));
362 empty = false; 366 empty = false;
363 } 367 }
364 } 368 }
365 nodes.end(); 369 nodes.end();
926 930
927 CodeVariableElement var = new CodeVariableElement(modifiers(PROTECTED), clazz.asType(), "next0"); 931 CodeVariableElement var = new CodeVariableElement(modifiers(PROTECTED), clazz.asType(), "next0");
928 var.getAnnotationMirrors().add(new CodeAnnotationMirror(getContext().getTruffleTypes().getChildAnnotation())); 932 var.getAnnotationMirrors().add(new CodeAnnotationMirror(getContext().getTruffleTypes().getChildAnnotation()));
929 clazz.add(var); 933 clazz.add(var);
930 934
931 CodeExecutableElement setter = new CodeExecutableElement(modifiers(PROTECTED), context.getType(void.class), "setNext0");
932 setter.getParameters().add(new CodeVariableElement(clazz.asType(), "next0"));
933 CodeTreeBuilder builder = setter.createBuilder();
934 builder.statement("this.next0 = insert(next0)");
935 clazz.add(setter);
936
937 CodeExecutableElement genericCachedExecute = createCachedExecute(node, node.getPolymorphicSpecialization()); 935 CodeExecutableElement genericCachedExecute = createCachedExecute(node, node.getPolymorphicSpecialization());
938 clazz.add(genericCachedExecute); 936 clazz.add(genericCachedExecute);
939 937
940 getElement().add(createUpdateTypes(clazz.asType())); 938 getElement().add(createUpdateTypes(clazz.asType()));
941 } 939 }
946 clazz.add(createGenericExecuteAndSpecialize(node, rootGroup)); 944 clazz.add(createGenericExecuteAndSpecialize(node, rootGroup));
947 clazz.add(createInfoMessage(node)); 945 clazz.add(createInfoMessage(node));
948 } 946 }
949 947
950 if (needsInvokeCopyConstructorMethod()) { 948 if (needsInvokeCopyConstructorMethod()) {
951 clazz.add(createInvokeCopyConstructor(clazz.asType(), null)); 949 clazz.add(createCopy(clazz.asType(), null));
952 clazz.add(createCopyPolymorphicConstructor(clazz.asType()));
953 } 950 }
954 951
955 if (node.getGenericSpecialization() != null && node.getGenericSpecialization().isReachable()) { 952 if (node.getGenericSpecialization() != null && node.getGenericSpecialization().isReachable()) {
956 clazz.add(createGenericExecute(node, rootGroup)); 953 clazz.add(createGenericExecute(node, rootGroup));
957 } 954 }
958 955
959 clazz.add(createGetCost(node, null, NodeCost.MONOMORPHIC));
960 } 956 }
961 957
962 protected boolean needsInvokeCopyConstructorMethod() { 958 protected boolean needsInvokeCopyConstructorMethod() {
963 return getModel().getNode().isPolymorphic(); 959 return getModel().getNode().isPolymorphic();
964 } 960 }
965 961
966 protected CodeExecutableElement createGetCost(NodeData node, SpecializationData specialization, NodeCost cost) { 962 protected CodeExecutableElement createCopy(TypeMirror baseType, SpecializationData specialization) {
967 CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), context.getTruffleTypes().getNodeCost(), "getCost"); 963 CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), baseType, "copyWithConstructor");
968
969 TypeMirror nodeInfoKind = context.getTruffleTypes().getNodeCost();
970
971 CodeTreeBuilder builder = method.createBuilder();
972 if (node.isPolymorphic() && specialization == null) {
973 // assume next0 exists
974 builder.startIf().string("next0 != null && next0.getCost() != ").staticReference(nodeInfoKind, "UNINITIALIZED").end();
975 builder.startBlock();
976 builder.startReturn().staticReference(nodeInfoKind, "POLYMORPHIC").end();
977 builder.end();
978 }
979
980 builder.startReturn().staticReference(nodeInfoKind, cost.name()).end();
981 return method;
982 }
983
984 protected CodeExecutableElement createInvokeCopyConstructor(TypeMirror baseType, SpecializationData specialization) {
985 CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED), baseType, "invokeCopyConstructor");
986 if (specialization == null) { 964 if (specialization == null) {
987 method.getModifiers().add(ABSTRACT); 965 method.getModifiers().add(ABSTRACT);
988 } else { 966 } else {
989 CodeTreeBuilder builder = method.createBuilder(); 967 CodeTreeBuilder builder = method.createBuilder();
990 builder.startReturn(); 968 builder.startReturn();
993 for (ActualParameter param : getImplicitTypeParamters(specialization)) { 971 for (ActualParameter param : getImplicitTypeParamters(specialization)) {
994 builder.string(implicitTypeName(param)); 972 builder.string(implicitTypeName(param));
995 } 973 }
996 builder.end().end(); 974 builder.end().end();
997 } 975 }
998 return method;
999 }
1000
1001 protected CodeExecutableElement createCopyPolymorphicConstructor(TypeMirror baseType) {
1002 CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED, FINAL), baseType, "copyPolymorphic");
1003 CodeTreeBuilder builder = method.createBuilder();
1004 CodeTreeBuilder nullBuilder = builder.create();
1005 CodeTreeBuilder oldBuilder = builder.create();
1006 CodeTreeBuilder resetBuilder = builder.create();
1007
1008 for (ActualParameter param : getModel().getSignatureParameters()) {
1009 NodeExecutionData execution = param.getSpecification().getExecution();
1010
1011 CodeTree access = createAccessChild(execution);
1012
1013 String oldName = "old" + Utils.firstLetterUpperCase(param.getLocalName());
1014 oldBuilder.declaration(execution.getChild().getNodeData().getNodeType(), oldName, access);
1015 nullBuilder.startStatement().tree(access).string(" = null").end();
1016 resetBuilder.startStatement().tree(access).string(" = ").string(oldName).end();
1017 }
1018
1019 builder.tree(oldBuilder.getRoot());
1020 builder.tree(nullBuilder.getRoot());
1021
1022 builder.startStatement().type(baseType).string(" copy = ");
1023 builder.startCall("invokeCopyConstructor").end();
1024 builder.end();
1025
1026 builder.tree(resetBuilder.getRoot());
1027 builder.startReturn().string("copy").end();
1028 return method; 976 return method;
1029 } 977 }
1030 978
1031 private List<CodeExecutableElement> createImplicitChildrenAccessors() { 979 private List<CodeExecutableElement> createImplicitChildrenAccessors() {
1032 NodeData node = getModel().getNode(); 980 NodeData node = getModel().getNode();
1278 return var; 1226 return var;
1279 } 1227 }
1280 1228
1281 private CodeExecutableElement createGenericExecuteAndSpecialize(final NodeData node, SpecializationGroup rootGroup) { 1229 private CodeExecutableElement createGenericExecuteAndSpecialize(final NodeData node, SpecializationGroup rootGroup) {
1282 TypeMirror genericReturnType = node.getGenericSpecialization().getReturnType().getType(); 1230 TypeMirror genericReturnType = node.getGenericSpecialization().getReturnType().getType();
1283 CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED), genericReturnType, EXECUTE_SPECIALIZE_NAME); 1231 CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED, FINAL), genericReturnType, EXECUTE_SPECIALIZE_NAME);
1284 method.addParameter(new CodeVariableElement(getContext().getType(int.class), "minimumState")); 1232 method.addParameter(new CodeVariableElement(getContext().getType(int.class), "minimumState"));
1285 addInternalValueParameters(method, node.getGenericSpecialization(), true, false); 1233 addInternalValueParameters(method, node.getGenericSpecialization(), true, false);
1286 method.addParameter(new CodeVariableElement(getContext().getType(String.class), "reason")); 1234 method.addParameter(new CodeVariableElement(getContext().getType(String.class), "reason"));
1287 1235
1288 CodeTreeBuilder builder = method.createBuilder(); 1236 CodeTreeBuilder builder = method.createBuilder();
1339 return SpecializationGroup.create(filteredSpecializations); 1287 return SpecializationGroup.create(filteredSpecializations);
1340 } 1288 }
1341 1289
1342 private CodeExecutableElement createGenericExecute(NodeData node, SpecializationGroup group) { 1290 private CodeExecutableElement createGenericExecute(NodeData node, SpecializationGroup group) {
1343 TypeMirror genericReturnType = node.getGenericSpecialization().getReturnType().getType(); 1291 TypeMirror genericReturnType = node.getGenericSpecialization().getReturnType().getType();
1344 CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED), genericReturnType, EXECUTE_GENERIC_NAME); 1292 CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED, FINAL), genericReturnType, EXECUTE_GENERIC_NAME);
1345 1293
1346 if (!node.needsFrame(getContext())) { 1294 if (!node.needsFrame(getContext())) {
1347 method.getAnnotationMirrors().add(new CodeAnnotationMirror(getContext().getTruffleTypes().getSlowPath())); 1295 method.getAnnotationMirrors().add(new CodeAnnotationMirror(getContext().getTruffleTypes().getSlowPath()));
1348 } 1296 }
1349 addInternalValueParameters(method, node.getGenericSpecialization(), node.needsFrame(getContext()), false); 1297 addInternalValueParameters(method, node.getGenericSpecialization(), node.needsFrame(getContext()), false);
1814 private CodeTree createRewritePolymorphic(CodeTreeBuilder parent, NodeData node, String currentNode) { 1762 private CodeTree createRewritePolymorphic(CodeTreeBuilder parent, NodeData node, String currentNode) {
1815 String polyClassName = nodePolymorphicClassName(node); 1763 String polyClassName = nodePolymorphicClassName(node);
1816 String uninitializedName = nodeSpecializationClassName(node.getUninitializedSpecialization()); 1764 String uninitializedName = nodeSpecializationClassName(node.getUninitializedSpecialization());
1817 CodeTreeBuilder builder = parent.create(); 1765 CodeTreeBuilder builder = parent.create();
1818 1766
1819 builder.declaration(getElement().asType(), "currentCopy", currentNode + ".copyPolymorphic()"); 1767 builder.declaration(getElement().asType(), "currentCopy", currentNode + ".copyWithConstructor()");
1768 for (ActualParameter param : getModel().getSignatureParameters()) {
1769 NodeExecutionData execution = param.getSpecification().getExecution();
1770 builder.startStatement().tree(createAccessChild(execution, "currentCopy")).string(" = ").nullLiteral().end();
1771 }
1772 builder.startStatement().string("currentCopy.next0 = ").startNew(uninitializedName).string("currentCopy").end().end();
1773
1820 builder.declaration(polyClassName, "polymorphic", builder.create().startNew(polyClassName).string(currentNode).end()); 1774 builder.declaration(polyClassName, "polymorphic", builder.create().startNew(polyClassName).string(currentNode).end());
1775 builder.startStatement().string("polymorphic.next0 = ").string("currentCopy").end();
1821 builder.startStatement().startCall(currentNode, "replace").string("polymorphic").string("message").end().end(); 1776 builder.startStatement().startCall(currentNode, "replace").string("polymorphic").string("message").end().end();
1822 builder.startStatement().startCall("polymorphic", "setNext0").string("currentCopy").end().end();
1823 builder.startStatement().startCall("currentCopy", "setNext0").startNew(uninitializedName).string(currentNode).end().end().end();
1824 1777
1825 builder.startReturn(); 1778 builder.startReturn();
1826 builder.startCall("currentCopy.next0", EXECUTE_POLYMORPHIC_NAME); 1779 builder.startCall("currentCopy.next0", EXECUTE_POLYMORPHIC_NAME);
1827 addInternalValueParameterNames(builder, node.getGenericSpecialization(), node.getGenericSpecialization(), null, true, null); 1780 addInternalValueParameterNames(builder, node.getGenericSpecialization(), node.getGenericSpecialization(), null, true, null);
1828 builder.end(); 1781 builder.end();
2298 } 2251 }
2299 2252
2300 private CodeTree createExecuteChildExpression(CodeTreeBuilder parent, NodeExecutionData targetExecution, ExecutableTypeData targetExecutable, ActualParameter unexpectedParameter) { 2253 private CodeTree createExecuteChildExpression(CodeTreeBuilder parent, NodeExecutionData targetExecution, ExecutableTypeData targetExecutable, ActualParameter unexpectedParameter) {
2301 CodeTreeBuilder builder = new CodeTreeBuilder(parent); 2254 CodeTreeBuilder builder = new CodeTreeBuilder(parent);
2302 if (targetExecution != null) { 2255 if (targetExecution != null) {
2303 builder.tree(createAccessChild(targetExecution)); 2256 builder.tree(createAccessChild(targetExecution, null));
2304 builder.string("."); 2257 builder.string(".");
2305 } 2258 }
2306 2259
2307 builder.startCall(targetExecutable.getMethodName()); 2260 builder.startCall(targetExecutable.getMethodName());
2308 2261
2463 if (nodeGen != null) { 2416 if (nodeGen != null) {
2464 baseType = nodeGen.asType(); 2417 baseType = nodeGen.asType();
2465 } 2418 }
2466 CodeTypeElement clazz = createClass(node, modifiers(PRIVATE, STATIC, FINAL), nodePolymorphicClassName(node), baseType, false); 2419 CodeTypeElement clazz = createClass(node, modifiers(PRIVATE, STATIC, FINAL), nodePolymorphicClassName(node), baseType, false);
2467 2420
2468 clazz.getAnnotationMirrors().add(createNodeInfo(node, NodeCost.NONE)); 2421 clazz.getAnnotationMirrors().add(createNodeInfo(node, NodeCost.POLYMORPHIC));
2469 2422
2470 for (ActualParameter polymorphParameter : polymorph.getSignatureParameters()) { 2423 for (ActualParameter polymorphParameter : polymorph.getSignatureParameters()) {
2471 if (!polymorphParameter.getTypeSystemType().isGeneric()) { 2424 if (!polymorphParameter.getTypeSystemType().isGeneric()) {
2472 continue; 2425 continue;
2473 } 2426 }
2506 } 2459 }
2507 getElement().add(createUpdateType(parameter)); 2460 getElement().add(createUpdateType(parameter));
2508 } 2461 }
2509 2462
2510 if (needsInvokeCopyConstructorMethod()) { 2463 if (needsInvokeCopyConstructorMethod()) {
2511 clazz.add(createInvokeCopyConstructor(nodeGen.asType(), specialization)); 2464 clazz.add(createCopy(nodeGen.asType(), specialization));
2512 } 2465 }
2513 2466
2514 createCachedExecuteMethods(specialization); 2467 createCachedExecuteMethods(specialization);
2515 clazz.add(createGetCost(specialization.getNode(), specialization, NodeCost.NONE));
2516 } 2468 }
2517 2469
2518 private ExecutableElement createUpdateType(ActualParameter parameter) { 2470 private ExecutableElement createUpdateType(ActualParameter parameter) {
2519 CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED), getContext().getType(void.class), createUpdateTypeName(parameter)); 2471 CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED), getContext().getType(void.class), createUpdateTypeName(parameter));
2520 method.getParameters().add(new CodeVariableElement(getContext().getType(Class.class), "type")); 2472 method.getParameters().add(new CodeVariableElement(getContext().getType(Class.class), "type"));
2556 if (specialization.isGeneric()) { 2508 if (specialization.isGeneric()) {
2557 cost = NodeCost.MEGAMORPHIC; 2509 cost = NodeCost.MEGAMORPHIC;
2558 } else if (specialization.isUninitialized()) { 2510 } else if (specialization.isUninitialized()) {
2559 cost = NodeCost.UNINITIALIZED; 2511 cost = NodeCost.UNINITIALIZED;
2560 } else if (specialization.isPolymorphic()) { 2512 } else if (specialization.isPolymorphic()) {
2561 cost = NodeCost.NONE; 2513 cost = NodeCost.POLYMORPHIC;
2562 } else if (specialization.isSpecialized()) { 2514 } else if (specialization.isSpecialized()) {
2563 cost = NodeCost.MONOMORPHIC; 2515 cost = NodeCost.MONOMORPHIC;
2564 } else { 2516 } else {
2565 throw new AssertionError(); 2517 throw new AssertionError();
2566 } 2518 }
2592 createCachedExecuteMethods(specialization); 2544 createCachedExecuteMethods(specialization);
2593 if (specialization.getNode().isPolymorphic()) { 2545 if (specialization.getNode().isPolymorphic()) {
2594 getElement().add(createUpdateTypes(nodeGen.asType())); 2546 getElement().add(createUpdateTypes(nodeGen.asType()));
2595 } 2547 }
2596 if (needsInvokeCopyConstructorMethod()) { 2548 if (needsInvokeCopyConstructorMethod()) {
2597 clazz.add(createInvokeCopyConstructor(nodeGen.asType(), specialization)); 2549 clazz.add(createCopy(nodeGen.asType(), specialization));
2598 }
2599
2600 if (specialization.isGeneric()) {
2601 clazz.add(createGetCost(specialization.getNode(), specialization, NodeCost.MEGAMORPHIC));
2602 } else if (specialization.isUninitialized()) {
2603 clazz.add(createGetCost(specialization.getNode(), specialization, NodeCost.UNINITIALIZED));
2604 } 2550 }
2605 } 2551 }
2606 2552
2607 protected void createConstructors(CodeTypeElement clazz) { 2553 protected void createConstructors(CodeTypeElement clazz) {
2608 TypeElement superTypeElement = Utils.fromTypeMirror(clazz.getSuperclass()); 2554 TypeElement superTypeElement = Utils.fromTypeMirror(clazz.getSuperclass());
2724 builder.tree(createGenericInvoke(builder, node.getPolymorphicSpecialization(), node.getGenericSpecialization(), 2670 builder.tree(createGenericInvoke(builder, node.getPolymorphicSpecialization(), node.getGenericSpecialization(),
2725 createReplaceCall(builder, node.getGenericSpecialization(), "root", castRoot, message), null)); 2671 createReplaceCall(builder, node.getGenericSpecialization(), "root", castRoot, message), null));
2726 builder.end(); 2672 builder.end();
2727 2673
2728 builder.startElseBlock(); 2674 builder.startElseBlock();
2729 builder.startStatement().startCall("setNext0"); 2675 builder.startStatement().string("next0 = ");
2730 builder.startNew(nodeSpecializationClassName(node.getUninitializedSpecialization())).string("this").end(); 2676 builder.startNew(nodeSpecializationClassName(node.getUninitializedSpecialization())).string("this").end();
2731 builder.end().end(); 2677 builder.end();
2732 2678
2733 CodeTreeBuilder specializeCall = new CodeTreeBuilder(builder); 2679 CodeTreeBuilder specializeCall = new CodeTreeBuilder(builder);
2734 specializeCall.startCall(EXECUTE_SPECIALIZE_NAME); 2680 specializeCall.startCall(EXECUTE_SPECIALIZE_NAME);
2735 specializeCall.string("0"); 2681 specializeCall.string("0");
2736 addInternalValueParameterNames(specializeCall, specialization, node.getGenericSpecialization(), null, true, null); 2682 addInternalValueParameterNames(specializeCall, specialization, node.getGenericSpecialization(), null, true, null);