# HG changeset patch # User Christian Humer # Date 1360953178 -3600 # Node ID b891ec348f8a593a64c212134ea21d1513ac24e4 # Parent 8b48c8ebdff448bcdfc5ecf1b41c617e161126b0 Made the usage of generic types more flexible for short circuits and generic specializations. diff -r 8b48c8ebdff4 -r b891ec348f8a graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/GenericParser.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/GenericParser.java Fri Feb 15 16:48:22 2013 +0100 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/GenericParser.java Fri Feb 15 19:32:58 2013 +0100 @@ -23,12 +23,15 @@ package com.oracle.truffle.codegen.processor.node; import java.lang.annotation.*; +import java.util.*; import javax.lang.model.element.*; +import javax.lang.model.type.*; import com.oracle.truffle.api.codegen.*; import com.oracle.truffle.codegen.processor.*; import com.oracle.truffle.codegen.processor.template.*; +import com.oracle.truffle.codegen.processor.template.ParameterSpec.*; public class GenericParser extends MethodParser { @@ -43,7 +46,13 @@ @Override protected ParameterSpec createValueParameterSpec(String valueName, NodeData nodeData) { - return new ParameterSpec(valueName, nodeData.findGenericExecutableType(getContext()).getType().getPrimitiveType(), false); + List execTypes = nodeData.findGenericExecutableTypes(getContext()); + List types = new ArrayList<>(); + for (ExecutableTypeData type : execTypes) { + types.add(type.getType().getPrimitiveType()); + } + TypeMirror[] array = types.toArray(new TypeMirror[types.size()]); + return new ParameterSpec(valueName, array, nodeData.getTypeSystem().getGenericType(), false, Cardinality.ONE); } @Override diff -r 8b48c8ebdff4 -r b891ec348f8a 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 Feb 15 16:48:22 2013 +0100 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java Fri Feb 15 19:32:58 2013 +0100 @@ -747,7 +747,7 @@ private void buildGenericValueExecute(CodeTreeBuilder builder, SpecializationData specialization, NodeFieldData field, NodeFieldData exceptionSpec) { ActualParameter specParameter = specialization.findParameter(field.getName()); - + NodeData node = specialization.getNode(); boolean shortCircuit = startShortCircuit(builder, specialization, field, exceptionSpec); builder.startStatement(); @@ -758,7 +758,7 @@ builder.string(valueName(specialization, specParameter)); builder.string(" = "); - ExecutableTypeData genericExecutableType = field.getNodeData().findGenericExecutableType(getContext()); + ExecutableTypeData genericExecutableType = field.getNodeData().findGenericExecutableType(getContext(), specParameter.getActualTypeData(node.getTypeSystem())); if (genericExecutableType == null) { throw new AssertionError("Must have generic executable type. Parser validation most likely failed. " + Arrays.toString(field.getNodeData().getExecutableTypes())); } diff -r 8b48c8ebdff4 -r b891ec348f8a graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeData.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeData.java Fri Feb 15 16:48:22 2013 +0100 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeData.java Fri Feb 15 19:32:58 2013 +0100 @@ -126,34 +126,17 @@ return executableTypes; } - public ExecutableTypeData findGenericExecutableType(ProcessorContext context) { + public ExecutableTypeData findGenericExecutableType(ProcessorContext context, TypeData type) { List types = findGenericExecutableTypes(context); - if (types.isEmpty()) { - return null; - } else if (types.size() == 1) { - return types.get(0); - } else if (types.size() == 2) { - if (types.get(0).getType().isVoid()) { - return types.get(1); - } else if (types.get(1).getType().isVoid()) { - return types.get(0); + for (ExecutableTypeData availableType : types) { + if (Utils.typeEquals(availableType.getType().getBoxedType(), type.getBoxedType())) { + return availableType; } } - - ExecutableTypeData execType = null; - for (ExecutableTypeData type : types) { - TypeData returnType = type.getReturnType().getActualTypeData(getTypeSystem()); - if (returnType.isGeneric()) { - if (execType != null) { - return null; - } - execType = type; - } - } - return execType; + return null; } - private List findGenericExecutableTypes(ProcessorContext context) { + public List findGenericExecutableTypes(ProcessorContext context) { List types = new ArrayList<>(); for (ExecutableTypeData type : executableTypes) { if (!type.hasUnexpectedValue(context)) { diff -r 8b48c8ebdff4 -r b891ec348f8a graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeParser.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeParser.java Fri Feb 15 16:48:22 2013 +0100 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeParser.java Fri Feb 15 19:32:58 2013 +0100 @@ -435,9 +435,9 @@ // TODO redirect errors from resolve. context.getLog().error(errorElement, "Node type '%s' is invalid.", Utils.getQualifiedName(nodeType)); return null; - } else if (fieldNodeData.findGenericExecutableType(context) == null) { + } else if (fieldNodeData.findGenericExecutableTypes(context).isEmpty()) { // TODO better error handling for (no or multiple?) - context.getLog().error(errorElement, "No or multiple executable generic types found for node '%s'.", Utils.getQualifiedName(nodeType)); + context.getLog().error(errorElement, "No executable generic types found for node '%s'.", Utils.getQualifiedName(nodeType)); return null; } } @@ -612,13 +612,21 @@ return valid; } - private static boolean isGenericShortCutMethod(NodeData node, TemplateMethod method) { + private boolean isGenericShortCutMethod(NodeData node, TemplateMethod method) { for (NodeFieldData field : node.getFields()) { ActualParameter parameter = method.findParameter(field.getName()); if (parameter == null) { continue; } - if (!Utils.typeEquals(node.getTypeSystem().getGenericType(), parameter.getActualType())) { + ExecutableTypeData found = null; + List executableElements = field.getNodeData().findGenericExecutableTypes(context); + for (ExecutableTypeData executable : executableElements) { + if (executable.getType().equalsType(parameter.getActualTypeData(node.getTypeSystem()))) { + found = executable; + break; + } + } + if (found == null) { return false; } } diff -r 8b48c8ebdff4 -r b891ec348f8a graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/ParameterSpec.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/ParameterSpec.java Fri Feb 15 16:48:22 2013 +0100 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/ParameterSpec.java Fri Feb 15 19:32:58 2013 +0100 @@ -38,12 +38,10 @@ private final String name; private final TypeMirror[] allowedTypes; - private final TypeMirror valueType; private final boolean optional; private final Cardinality cardinality; - public ParameterSpec(String name, TypeMirror[] allowedTypes, TypeMirror valueType, boolean optional, Cardinality cardinality) { - this.valueType = valueType; + public ParameterSpec(String name, TypeMirror[] allowedTypes, boolean optional, Cardinality cardinality) { this.allowedTypes = allowedTypes; this.name = name; this.optional = optional; @@ -52,17 +50,17 @@ /** Type constructor. */ public ParameterSpec(String name, TypeMirror singleFixedType, boolean optional) { - this(name, new TypeMirror[]{singleFixedType}, singleFixedType, optional, Cardinality.ONE); + this(name, new TypeMirror[]{singleFixedType}, optional, Cardinality.ONE); } /** Type system value constructor. */ public ParameterSpec(String name, TypeSystemData typeSystem, boolean optional, Cardinality cardinality) { - this(name, typeSystem.getPrimitiveTypeMirrors(), typeSystem.getGenericType(), optional, cardinality); + this(name, typeSystem.getPrimitiveTypeMirrors(), optional, cardinality); } /** Node value constructor. */ public ParameterSpec(String name, NodeData nodeData, boolean optional, Cardinality cardinality) { - this(name, nodeTypeMirrors(nodeData), nodeData.getTypeSystem().getGenericType(), optional, cardinality); + this(name, nodeTypeMirrors(nodeData), optional, cardinality); } private static TypeMirror[] nodeTypeMirrors(NodeData nodeData) { @@ -103,7 +101,4 @@ return false; } - public TypeMirror getValueType() { - return valueType; - } } diff -r 8b48c8ebdff4 -r b891ec348f8a graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeData.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeData.java Fri Feb 15 16:48:22 2013 +0100 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeData.java Fri Feb 15 19:32:58 2013 +0100 @@ -89,4 +89,8 @@ return getClass().getSimpleName() + "[" + Utils.getSimpleName(primitiveType) + "]"; } + public boolean equalsType(TypeData actualTypeData) { + return Utils.typeEquals(boxedType, actualTypeData.boxedType); + } + } diff -r 8b48c8ebdff4 -r b891ec348f8a graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/ConditionalNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/ConditionalNode.java Fri Feb 15 16:48:22 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.sl.nodes; - -import java.math.*; - -import com.oracle.truffle.api.codegen.*; - -@SuppressWarnings("unused") -@ExecuteChildren({"conditionNode", "ifPartNode", "elsePartNode"}) -public abstract class ConditionalNode extends TypedNode { - - @Child protected ConditionNode conditionNode; - - @Child protected TypedNode ifPartNode; - - @Child protected TypedNode elsePartNode; - - public ConditionalNode(ConditionNode condition, TypedNode ifPart, TypedNode elsePart) { - this.conditionNode = adoptChild(condition); - this.ifPartNode = adoptChild(ifPart); - this.elsePartNode = adoptChild(elsePart); - } - - public ConditionalNode(ConditionalNode condition) { - this(condition.conditionNode, condition.ifPartNode, condition.elsePartNode); - } - - @ShortCircuit("ifPartNode") - public boolean needsIfPart(boolean condition) { - return condition; - } - - @ShortCircuit("ifPartNode") - public boolean needsIfPart(Object condition) { - throw new RuntimeException("operation not defined for type " + condition.getClass().getSimpleName()); - } - - @ShortCircuit("elsePartNode") - public boolean needsElsePart(Object condition, boolean hasIfPart, Object ifPart) { - return !hasIfPart; - } - - @ShortCircuit("elsePartNode") - public boolean needsElsePart(boolean condition, boolean hasIfPart, int ifPart) { - return !hasIfPart; - } - - @ShortCircuit("elsePartNode") - public boolean needsElsePart(boolean condition, boolean hasIfPart, BigInteger ifPart) { - return !hasIfPart; - } - - @Specialization - public int doInteger(boolean condition, boolean hasIfPart, int ifPart, boolean hasElsePart, int elsePart) { - return hasIfPart ? ifPart : elsePart; - } - - @Specialization - public BigInteger doBigInteger(boolean condition, boolean hasIfPart, BigInteger ifPart, boolean hasElsePart, BigInteger elsePart) { - return hasIfPart ? ifPart : elsePart; - } - - @Generic - public Object doGeneric(boolean condition, boolean hasIfPart, Object ifPart, boolean hasElsePart, Object elsePart) { - return hasIfPart ? ifPart : elsePart; - } -} diff -r 8b48c8ebdff4 -r b891ec348f8a graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/TernaryNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/TernaryNode.java Fri Feb 15 19:32:58 2013 +0100 @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.truffle.sl.nodes; + +import java.math.*; + +import com.oracle.truffle.api.codegen.*; + +@SuppressWarnings("unused") +@ExecuteChildren({"conditionNode", "ifPartNode", "elsePartNode"}) +public abstract class TernaryNode extends TypedNode { + + @Child protected ConditionNode conditionNode; + + @Child protected TypedNode ifPartNode; + + @Child protected TypedNode elsePartNode; + + public TernaryNode(ConditionNode condition, TypedNode ifPart, TypedNode elsePart) { + this.conditionNode = adoptChild(condition); + this.ifPartNode = adoptChild(ifPart); + this.elsePartNode = adoptChild(elsePart); + } + + public TernaryNode(TernaryNode condition) { + this(condition.conditionNode, condition.ifPartNode, condition.elsePartNode); + } + + @ShortCircuit("ifPartNode") + public boolean needsIfPart(boolean condition) { + return condition; + } + + @ShortCircuit("elsePartNode") + public boolean needsElsePart(boolean condition, boolean hasIfPart, Object ifPart) { + return !hasIfPart; + } + + @Specialization + public int doInteger(boolean condition, boolean hasIfPart, int ifPart, boolean hasElsePart, int elsePart) { + return hasIfPart ? ifPart : elsePart; + } + + @Specialization + public BigInteger doBigInteger(boolean condition, boolean hasIfPart, BigInteger ifPart, boolean hasElsePart, BigInteger elsePart) { + return hasIfPart ? ifPart : elsePart; + } + + @Generic + public Object doGeneric(boolean condition, boolean hasIfPart, Object ifPart, boolean hasElsePart, Object elsePart) { + return hasIfPart ? ifPart : elsePart; + } +}