# HG changeset patch # User Christian Humer # Date 1395334241 -3600 # Node ID f0bb82ebe30c6a376dbf42a94aa275b596b636d7 # Parent b2e2132c0effb27b233af51ae336e1103c864981 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. diff -r b2e2132c0eff -r f0bb82ebe30c graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/PolymorphicTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/PolymorphicTest.java Thu Mar 20 13:53:36 2014 +0100 +++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/PolymorphicTest.java Thu Mar 20 17:50:41 2014 +0100 @@ -64,7 +64,7 @@ TestRootNode node = TestHelper.createRoot(Node1Factory.getInstance()); assertEquals("(int,boolean)", executeWith(node, 42, false)); assertEquals("(int,int)", executeWith(node, 42, 42)); - assertEquals(NodeCost.NONE, node.getNode().getCost()); + assertEquals(NodeCost.POLYMORPHIC, node.getNode().getCost()); assertParent(node.getNode(), node.getNode().getLeft()); assertParent(node.getNode(), node.getNode().getRight()); } @@ -75,7 +75,7 @@ assertEquals("(int,boolean)", executeWith(node, 42, false)); assertEquals("(boolean,boolean)", executeWith(node, true, false)); assertEquals("(int,int)", executeWith(node, 42, 42)); - assertEquals(NodeCost.NONE, node.getNode().getCost()); + assertEquals(NodeCost.POLYMORPHIC, node.getNode().getCost()); assertParent(node.getNode(), node.getNode().getLeft()); assertParent(node.getNode(), node.getNode().getRight()); } diff -r b2e2132c0eff -r f0bb82ebe30c graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/PolymorphicTest2.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/PolymorphicTest2.java Thu Mar 20 13:53:36 2014 +0100 +++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/PolymorphicTest2.java Thu Mar 20 17:50:41 2014 +0100 @@ -42,7 +42,7 @@ assertEquals(21, executeWith(node, false, false)); assertEquals(42, executeWith(node, 21, 21)); assertEquals("(boolean,int)", executeWith(node, false, 42)); - assertEquals(NodeCost.NONE, node.getNode().getCost()); + assertEquals(NodeCost.POLYMORPHIC, node.getNode().getCost()); } @SuppressWarnings("unused") diff -r b2e2132c0eff -r f0bb82ebe30c graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java Thu Mar 20 13:53:36 2014 +0100 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java Thu Mar 20 17:50:41 2014 +0100 @@ -98,13 +98,17 @@ return param.getLocalName(); } - private static CodeTree createAccessChild(NodeExecutionData targetExecution) { + private static CodeTree createAccessChild(NodeExecutionData targetExecution, String thisReference) { + String reference = thisReference; + if (reference == null) { + reference = "this"; + } CodeTreeBuilder builder = CodeTreeBuilder.createBuilder(); Element accessElement = targetExecution.getChild().getAccessElement(); if (accessElement == null || accessElement.getKind() == ElementKind.METHOD) { - builder.string("this.").string(targetExecution.getChild().getName()); + builder.string(reference).string(".").string(targetExecution.getChild().getName()); } else if (accessElement.getKind() == ElementKind.FIELD) { - builder.string("this.").string(accessElement.getSimpleName().toString()); + builder.string(reference).string(".").string(accessElement.getSimpleName().toString()); } else { throw new AssertionError(); } @@ -322,7 +326,7 @@ * variant2 $condition != null * $type $name = $value; * - * + * * . */ private static CodeTree createLazyAssignment(CodeTreeBuilder parent, String name, TypeMirror type, CodeTree condition, CodeTree value) { @@ -357,7 +361,7 @@ nodes.nullLiteral(); arguments.string(valueName(parameter.getPreviousParameter())); } - nodes.tree(createAccessChild(executionData)); + nodes.tree(createAccessChild(executionData, null)); arguments.string(valueName(parameter)); empty = false; } @@ -928,12 +932,6 @@ var.getAnnotationMirrors().add(new CodeAnnotationMirror(getContext().getTruffleTypes().getChildAnnotation())); clazz.add(var); - CodeExecutableElement setter = new CodeExecutableElement(modifiers(PROTECTED), context.getType(void.class), "setNext0"); - setter.getParameters().add(new CodeVariableElement(clazz.asType(), "next0")); - CodeTreeBuilder builder = setter.createBuilder(); - builder.statement("this.next0 = insert(next0)"); - clazz.add(setter); - CodeExecutableElement genericCachedExecute = createCachedExecute(node, node.getPolymorphicSpecialization()); clazz.add(genericCachedExecute); @@ -948,41 +946,21 @@ } if (needsInvokeCopyConstructorMethod()) { - clazz.add(createInvokeCopyConstructor(clazz.asType(), null)); - clazz.add(createCopyPolymorphicConstructor(clazz.asType())); + clazz.add(createCopy(clazz.asType(), null)); } if (node.getGenericSpecialization() != null && node.getGenericSpecialization().isReachable()) { clazz.add(createGenericExecute(node, rootGroup)); } - clazz.add(createGetCost(node, null, NodeCost.MONOMORPHIC)); } protected boolean needsInvokeCopyConstructorMethod() { return getModel().getNode().isPolymorphic(); } - protected CodeExecutableElement createGetCost(NodeData node, SpecializationData specialization, NodeCost cost) { - CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), context.getTruffleTypes().getNodeCost(), "getCost"); - - TypeMirror nodeInfoKind = context.getTruffleTypes().getNodeCost(); - - CodeTreeBuilder builder = method.createBuilder(); - if (node.isPolymorphic() && specialization == null) { - // assume next0 exists - builder.startIf().string("next0 != null && next0.getCost() != ").staticReference(nodeInfoKind, "UNINITIALIZED").end(); - builder.startBlock(); - builder.startReturn().staticReference(nodeInfoKind, "POLYMORPHIC").end(); - builder.end(); - } - - builder.startReturn().staticReference(nodeInfoKind, cost.name()).end(); - return method; - } - - protected CodeExecutableElement createInvokeCopyConstructor(TypeMirror baseType, SpecializationData specialization) { - CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED), baseType, "invokeCopyConstructor"); + protected CodeExecutableElement createCopy(TypeMirror baseType, SpecializationData specialization) { + CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), baseType, "copyWithConstructor"); if (specialization == null) { method.getModifiers().add(ABSTRACT); } else { @@ -998,36 +976,6 @@ return method; } - protected CodeExecutableElement createCopyPolymorphicConstructor(TypeMirror baseType) { - CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED, FINAL), baseType, "copyPolymorphic"); - CodeTreeBuilder builder = method.createBuilder(); - CodeTreeBuilder nullBuilder = builder.create(); - CodeTreeBuilder oldBuilder = builder.create(); - CodeTreeBuilder resetBuilder = builder.create(); - - for (ActualParameter param : getModel().getSignatureParameters()) { - NodeExecutionData execution = param.getSpecification().getExecution(); - - CodeTree access = createAccessChild(execution); - - String oldName = "old" + Utils.firstLetterUpperCase(param.getLocalName()); - oldBuilder.declaration(execution.getChild().getNodeData().getNodeType(), oldName, access); - nullBuilder.startStatement().tree(access).string(" = null").end(); - resetBuilder.startStatement().tree(access).string(" = ").string(oldName).end(); - } - - builder.tree(oldBuilder.getRoot()); - builder.tree(nullBuilder.getRoot()); - - builder.startStatement().type(baseType).string(" copy = "); - builder.startCall("invokeCopyConstructor").end(); - builder.end(); - - builder.tree(resetBuilder.getRoot()); - builder.startReturn().string("copy").end(); - return method; - } - private List createImplicitChildrenAccessors() { NodeData node = getModel().getNode(); // Map> expectTypes = new HashMap<>(); @@ -1280,7 +1228,7 @@ private CodeExecutableElement createGenericExecuteAndSpecialize(final NodeData node, SpecializationGroup rootGroup) { TypeMirror genericReturnType = node.getGenericSpecialization().getReturnType().getType(); - CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED), genericReturnType, EXECUTE_SPECIALIZE_NAME); + CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED, FINAL), genericReturnType, EXECUTE_SPECIALIZE_NAME); method.addParameter(new CodeVariableElement(getContext().getType(int.class), "minimumState")); addInternalValueParameters(method, node.getGenericSpecialization(), true, false); method.addParameter(new CodeVariableElement(getContext().getType(String.class), "reason")); @@ -1341,7 +1289,7 @@ private CodeExecutableElement createGenericExecute(NodeData node, SpecializationGroup group) { TypeMirror genericReturnType = node.getGenericSpecialization().getReturnType().getType(); - CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED), genericReturnType, EXECUTE_GENERIC_NAME); + CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED, FINAL), genericReturnType, EXECUTE_GENERIC_NAME); if (!node.needsFrame(getContext())) { method.getAnnotationMirrors().add(new CodeAnnotationMirror(getContext().getTruffleTypes().getSlowPath())); @@ -1816,11 +1764,16 @@ String uninitializedName = nodeSpecializationClassName(node.getUninitializedSpecialization()); CodeTreeBuilder builder = parent.create(); - builder.declaration(getElement().asType(), "currentCopy", currentNode + ".copyPolymorphic()"); + builder.declaration(getElement().asType(), "currentCopy", currentNode + ".copyWithConstructor()"); + for (ActualParameter param : getModel().getSignatureParameters()) { + NodeExecutionData execution = param.getSpecification().getExecution(); + builder.startStatement().tree(createAccessChild(execution, "currentCopy")).string(" = ").nullLiteral().end(); + } + builder.startStatement().string("currentCopy.next0 = ").startNew(uninitializedName).string("currentCopy").end().end(); + builder.declaration(polyClassName, "polymorphic", builder.create().startNew(polyClassName).string(currentNode).end()); + builder.startStatement().string("polymorphic.next0 = ").string("currentCopy").end(); builder.startStatement().startCall(currentNode, "replace").string("polymorphic").string("message").end().end(); - builder.startStatement().startCall("polymorphic", "setNext0").string("currentCopy").end().end(); - builder.startStatement().startCall("currentCopy", "setNext0").startNew(uninitializedName).string(currentNode).end().end().end(); builder.startReturn(); builder.startCall("currentCopy.next0", EXECUTE_POLYMORPHIC_NAME); @@ -2300,7 +2253,7 @@ private CodeTree createExecuteChildExpression(CodeTreeBuilder parent, NodeExecutionData targetExecution, ExecutableTypeData targetExecutable, ActualParameter unexpectedParameter) { CodeTreeBuilder builder = new CodeTreeBuilder(parent); if (targetExecution != null) { - builder.tree(createAccessChild(targetExecution)); + builder.tree(createAccessChild(targetExecution, null)); builder.string("."); } @@ -2465,7 +2418,7 @@ } CodeTypeElement clazz = createClass(node, modifiers(PRIVATE, STATIC, FINAL), nodePolymorphicClassName(node), baseType, false); - clazz.getAnnotationMirrors().add(createNodeInfo(node, NodeCost.NONE)); + clazz.getAnnotationMirrors().add(createNodeInfo(node, NodeCost.POLYMORPHIC)); for (ActualParameter polymorphParameter : polymorph.getSignatureParameters()) { if (!polymorphParameter.getTypeSystemType().isGeneric()) { @@ -2508,11 +2461,10 @@ } if (needsInvokeCopyConstructorMethod()) { - clazz.add(createInvokeCopyConstructor(nodeGen.asType(), specialization)); + clazz.add(createCopy(nodeGen.asType(), specialization)); } createCachedExecuteMethods(specialization); - clazz.add(createGetCost(specialization.getNode(), specialization, NodeCost.NONE)); } private ExecutableElement createUpdateType(ActualParameter parameter) { @@ -2558,7 +2510,7 @@ } else if (specialization.isUninitialized()) { cost = NodeCost.UNINITIALIZED; } else if (specialization.isPolymorphic()) { - cost = NodeCost.NONE; + cost = NodeCost.POLYMORPHIC; } else if (specialization.isSpecialized()) { cost = NodeCost.MONOMORPHIC; } else { @@ -2594,13 +2546,7 @@ getElement().add(createUpdateTypes(nodeGen.asType())); } if (needsInvokeCopyConstructorMethod()) { - clazz.add(createInvokeCopyConstructor(nodeGen.asType(), specialization)); - } - - if (specialization.isGeneric()) { - clazz.add(createGetCost(specialization.getNode(), specialization, NodeCost.MEGAMORPHIC)); - } else if (specialization.isUninitialized()) { - clazz.add(createGetCost(specialization.getNode(), specialization, NodeCost.UNINITIALIZED)); + clazz.add(createCopy(nodeGen.asType(), specialization)); } } @@ -2726,9 +2672,9 @@ builder.end(); builder.startElseBlock(); - builder.startStatement().startCall("setNext0"); + builder.startStatement().string("next0 = "); builder.startNew(nodeSpecializationClassName(node.getUninitializedSpecialization())).string("this").end(); - builder.end().end(); + builder.end(); CodeTreeBuilder specializeCall = new CodeTreeBuilder(builder); specializeCall.startCall(EXECUTE_SPECIALIZE_NAME);