# HG changeset patch # User Christian Humer # Date 1367016589 -7200 # Node ID 86d981cd8e22e2bd15eebd7fd0e2c6de06126cb5 # Parent 927e0792094bab2126ad2fd781494b7c4b8da8dc Fixed a bug in new code generation layout. diff -r 927e0792094b -r 86d981cd8e22 graal/com.oracle.truffle.api.codegen.test/src/com/oracle/truffle/api/codegen/test/GuardsTest.java --- a/graal/com.oracle.truffle.api.codegen.test/src/com/oracle/truffle/api/codegen/test/GuardsTest.java Fri Apr 26 23:03:09 2013 +0200 +++ b/graal/com.oracle.truffle.api.codegen.test/src/com/oracle/truffle/api/codegen/test/GuardsTest.java Sat Apr 27 00:49:49 2013 +0200 @@ -45,23 +45,19 @@ assertEquals(Integer.MAX_VALUE, executeWith(root, Integer.MAX_VALUE - 1, 1)); assertEquals(1, InvocationGuard.specializedInvocations); assertEquals(0, InvocationGuard.genericInvocations); - assertEquals(1, InvocationGuard.guardInvocations); assertEquals(42, executeWith(root, Integer.MAX_VALUE, 1)); assertEquals(1, InvocationGuard.specializedInvocations); assertEquals(1, InvocationGuard.genericInvocations); - assertEquals(2, InvocationGuard.guardInvocations); } @NodeChildren({@NodeChild("value0"), @NodeChild("value1")}) public abstract static class InvocationGuard extends ValueNode { - static int guardInvocations = 0; static int specializedInvocations = 0; static int genericInvocations = 0; boolean guard(int value0, int value1) { - guardInvocations++; return value0 != Integer.MAX_VALUE; } diff -r 927e0792094b -r 86d981cd8e22 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeTreeBuilder.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeTreeBuilder.java Fri Apr 26 23:03:09 2013 +0200 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeTreeBuilder.java Sat Apr 27 00:49:49 2013 +0200 @@ -475,6 +475,19 @@ currentElement.registerAtEnd(callback); } + public CodeTreeBuilder defaultDeclaration(TypeMirror type, String name) { + if (!Utils.isVoid(type)) { + startStatement(); + type(type); + string(" "); + string(name); + string(" = "); + defaultValue(type); + end(); // statement + } + return this; + } + public CodeTreeBuilder declaration(TypeMirror type, String name, CodeTree init) { if (Utils.isVoid(type)) { startStatement(); diff -r 927e0792094b -r 86d981cd8e22 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java Fri Apr 26 23:03:09 2013 +0200 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java Sat Apr 27 00:49:49 2013 +0200 @@ -760,8 +760,12 @@ builder.end(); emitSpecializationListeners(builder, node); + builder.defaultDeclaration(node.getGenericSpecialization().getReturnSignature().getPrimitiveType(), "result"); + if (node.getGenericSpecialization().isUseSpecializationsForGeneric()) { + builder.defaultDeclaration(getContext().getType(boolean.class), "resultIsSet"); + } builder.startStatement().string("boolean allowed = (minimumState == ").string(nodeSpecializationClassName(node.getSpecializations().get(0))).string(".class)").end(); - prefix = "allowed"; + prefix = null; } addInternalValueParameters(method, node.getGenericSpecialization(), true); @@ -801,9 +805,10 @@ execute.tree(createGenericInvoke(builder, current, specialize)); - if (specialize) { + if (specialize && !current.isGeneric()) { builder.startStatement().string("allowed = allowed || (minimumState == ").string(nodeSpecializationClassName(current)).string(".class)").end(); } + builder.tree(createGuardAndCast(builder, prefix, current.getNode().getGenericSpecialization(), current, true, execute.getRoot(), null, true)); } @@ -811,10 +816,6 @@ builder.string("// unreachable ").string(specializationData.getId()).newLine(); } - if (specialize) { - builder.startThrow().startNew(getContext().getType(AssertionError.class)).end().end(); - } - return method; } @@ -825,21 +826,57 @@ builder.startTryBlock(); } - if (current.getMethod() == null) { + CodeTree executeCall = null; + if (current.getMethod() != null) { + executeCall = createTemplateMethodCall(builder, null, current.getNode().getGenericSpecialization(), current, null); + } + + if (specialize && executeCall == null && !current.getNode().getGenericSpecialization().isUseSpecializationsForGeneric()) { emitEncounteredSynthetic(builder); - } else { - CodeTree executeCall = createTemplateMethodCall(builder, null, current.getNode().getGenericSpecialization(), current, null); + } else if (specialize) { + + if (current.getNode().getGenericSpecialization().isUseSpecializationsForGeneric()) { + builder.startIf().string("!resultIsSet").end().startBlock(); + if (executeCall != null) { + if (current.getReturnSignature().isVoid()) { + builder.statement(executeCall); + } else { + builder.startStatement().string("result = ").tree(executeCall).end(); + } + builder.statement("resultIsSet = true"); + } else { + emitEncounteredSynthetic(builder); + } + builder.end(); + } - if (specialize) { - builder.declaration(current.getReturnSignature().getPrimitiveType(), "result", executeCall); - builder.startStatement().startCall("super", "replace"); - builder.startGroup().startNew(nodeSpecializationClassName(current)).string("this").end().end(); - builder.end().end(); + if (!current.isGeneric()) { + builder.startIf().string("allowed").end().startBlock(); + } + + if (!current.getNode().getGenericSpecialization().isUseSpecializationsForGeneric()) { if (current.getReturnSignature().isVoid()) { - builder.returnStatement(); + builder.statement(executeCall); } else { - builder.startReturn().string("result").end(); + builder.startStatement().string("result = ").tree(executeCall).end(); } + } + + builder.startStatement().startCall("super", "replace"); + builder.startGroup().startNew(nodeSpecializationClassName(current)).string("this").end().end(); + builder.end().end(); + + if (current.getReturnSignature().isVoid()) { + builder.returnStatement(); + } else { + builder.startReturn().string("result").end(); + } + if (!current.isGeneric()) { + builder.end(); + } + } else { + if (executeCall == null) { + emitEncounteredSynthetic(builder); } else { builder.startReturn().tree(executeCall).end(); }