# HG changeset patch # User Thomas Wuerthinger # Date 1399499936 -7200 # Node ID 3882866b6ff9af6414c136e8a4c13e16ad242632 # Parent ff05eeb654d4e4fdda38124ec885564be951ed0c# Parent 23dbc25b10a838950e0e1f2473a545041d59df4d Merge. diff -r ff05eeb654d4 -r 3882866b6ff9 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRBuilder.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRBuilder.java Wed May 07 23:58:43 2014 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRBuilder.java Wed May 07 23:58:56 2014 +0200 @@ -56,6 +56,36 @@ /** * This class traverses the HIR instructions and generates LIR instructions from them. */ +@MatchableNode(nodeClass = ConstantNode.class, shareable = true) +@MatchableNode(nodeClass = FloatConvertNode.class, inputs = {"input"}) +@MatchableNode(nodeClass = FloatSubNode.class, inputs = {"x", "y"}) +@MatchableNode(nodeClass = FloatingReadNode.class, inputs = {"object", "location"}) +@MatchableNode(nodeClass = IfNode.class, inputs = {"condition"}) +@MatchableNode(nodeClass = IntegerSubNode.class, inputs = {"x", "y"}) +@MatchableNode(nodeClass = LeftShiftNode.class, inputs = {"x", "y"}) +@MatchableNode(nodeClass = NarrowNode.class, inputs = {"input"}) +@MatchableNode(nodeClass = ReadNode.class, inputs = {"object", "location"}) +@MatchableNode(nodeClass = ReinterpretNode.class, inputs = {"value"}) +@MatchableNode(nodeClass = SignExtendNode.class, inputs = {"input"}) +@MatchableNode(nodeClass = UnsignedRightShiftNode.class, inputs = {"x", "y"}) +@MatchableNode(nodeClass = WriteNode.class, inputs = {"object", "location", "value"}) +@MatchableNode(nodeClass = ZeroExtendNode.class, inputs = {"input"}) +@MatchableNode(nodeClass = AndNode.class, inputs = {"x", "y"}, commutative = true) +@MatchableNode(nodeClass = FloatAddNode.class, inputs = {"x", "y"}, commutative = true) +@MatchableNode(nodeClass = FloatEqualsNode.class, inputs = {"x", "y"}, commutative = true) +@MatchableNode(nodeClass = FloatLessThanNode.class, inputs = {"x", "y"}, commutative = true) +@MatchableNode(nodeClass = FloatMulNode.class, inputs = {"x", "y"}, commutative = true) +@MatchableNode(nodeClass = IntegerAddNode.class, inputs = {"x", "y"}, commutative = true) +@MatchableNode(nodeClass = IntegerBelowThanNode.class, inputs = {"x", "y"}, commutative = true) +@MatchableNode(nodeClass = IntegerEqualsNode.class, inputs = {"x", "y"}, commutative = true) +@MatchableNode(nodeClass = IntegerLessThanNode.class, inputs = {"x", "y"}, commutative = true) +@MatchableNode(nodeClass = IntegerMulNode.class, inputs = {"x", "y"}, commutative = true) +@MatchableNode(nodeClass = IntegerTestNode.class, inputs = {"x", "y"}, commutative = true) +@MatchableNode(nodeClass = ObjectEqualsNode.class, inputs = {"x", "y"}, commutative = true) +@MatchableNode(nodeClass = OrNode.class, inputs = {"x", "y"}, commutative = true) +@MatchableNode(nodeClass = XorNode.class, inputs = {"x", "y"}, commutative = true) +@MatchableNode(nodeClass = PiNode.class, inputs = {"object"}) +@MatchableNode(nodeClass = ConstantLocationNode.class, shareable = true) public abstract class NodeLIRBuilder implements NodeLIRBuilderTool { private final NodeMap nodeOperands; diff -r ff05eeb654d4 -r 3882866b6ff9 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/GraalMatchableNodes.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/GraalMatchableNodes.java Wed May 07 23:58:43 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,160 +0,0 @@ -/* - * Copyright (c) 2014, 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.graal.compiler.match; - -import com.oracle.graal.compiler.common.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.extended.*; - -/** - * Helper class to describe the matchable nodes in the core Graal IR. These could possibly live in - * their respective classes but for simplicity in the {@link MatchProcessor} they are grouped here. - */ -@MatchableNode(nodeClass = ConstantNode.class, inputs = 0, shareable = true) -@MatchableNode(nodeClass = FloatConvertNode.class, inputs = 1, adapter = GraalMatchableNodes.ConvertNodeAdapter.class) -@MatchableNode(nodeClass = FloatSubNode.class, inputs = 2, adapter = GraalMatchableNodes.BinaryNodeAdapter.class) -@MatchableNode(nodeClass = FloatingReadNode.class, inputs = 2, adapter = GraalMatchableNodes.AccessAdapter.class) -@MatchableNode(nodeClass = IfNode.class, inputs = 1, adapter = GraalMatchableNodes.IfNodeAdapter.class) -@MatchableNode(nodeClass = IntegerSubNode.class, inputs = 2, adapter = GraalMatchableNodes.BinaryNodeAdapter.class) -@MatchableNode(nodeClass = LeftShiftNode.class, inputs = 2, adapter = GraalMatchableNodes.BinaryNodeAdapter.class) -@MatchableNode(nodeClass = NarrowNode.class, inputs = 1, adapter = GraalMatchableNodes.ConvertNodeAdapter.class) -@MatchableNode(nodeClass = ReadNode.class, inputs = 2, adapter = GraalMatchableNodes.AccessAdapter.class) -@MatchableNode(nodeClass = ReinterpretNode.class, inputs = 1, adapter = GraalMatchableNodes.ReinterpretNodeAdapter.class) -@MatchableNode(nodeClass = SignExtendNode.class, inputs = 1, adapter = GraalMatchableNodes.ConvertNodeAdapter.class) -@MatchableNode(nodeClass = UnsignedRightShiftNode.class, inputs = 2, adapter = GraalMatchableNodes.BinaryNodeAdapter.class) -@MatchableNode(nodeClass = WriteNode.class, inputs = 3, adapter = GraalMatchableNodes.WriteNodeAdapter.class) -@MatchableNode(nodeClass = ZeroExtendNode.class, inputs = 1, adapter = GraalMatchableNodes.ConvertNodeAdapter.class) -@MatchableNode(nodeClass = AndNode.class, inputs = 2, adapter = GraalMatchableNodes.BinaryNodeAdapter.class, commutative = true) -@MatchableNode(nodeClass = FloatAddNode.class, inputs = 2, adapter = GraalMatchableNodes.BinaryNodeAdapter.class, commutative = true) -@MatchableNode(nodeClass = FloatEqualsNode.class, inputs = 2, adapter = GraalMatchableNodes.BinaryOpLogicNodeAdapter.class, commutative = true) -@MatchableNode(nodeClass = FloatLessThanNode.class, inputs = 2, adapter = GraalMatchableNodes.BinaryOpLogicNodeAdapter.class, commutative = true) -@MatchableNode(nodeClass = FloatMulNode.class, inputs = 2, adapter = GraalMatchableNodes.BinaryNodeAdapter.class, commutative = true) -@MatchableNode(nodeClass = IntegerAddNode.class, inputs = 2, adapter = GraalMatchableNodes.BinaryNodeAdapter.class, commutative = true) -@MatchableNode(nodeClass = IntegerBelowThanNode.class, inputs = 2, adapter = GraalMatchableNodes.BinaryOpLogicNodeAdapter.class, commutative = true) -@MatchableNode(nodeClass = IntegerEqualsNode.class, inputs = 2, adapter = GraalMatchableNodes.BinaryOpLogicNodeAdapter.class, commutative = true) -@MatchableNode(nodeClass = IntegerLessThanNode.class, inputs = 2, adapter = GraalMatchableNodes.BinaryOpLogicNodeAdapter.class, commutative = true) -@MatchableNode(nodeClass = IntegerMulNode.class, inputs = 2, adapter = GraalMatchableNodes.BinaryNodeAdapter.class, commutative = true) -@MatchableNode(nodeClass = IntegerTestNode.class, inputs = 2, adapter = GraalMatchableNodes.BinaryOpLogicNodeAdapter.class, commutative = true) -@MatchableNode(nodeClass = ObjectEqualsNode.class, inputs = 2, adapter = GraalMatchableNodes.BinaryOpLogicNodeAdapter.class, commutative = true) -@MatchableNode(nodeClass = OrNode.class, inputs = 2, adapter = GraalMatchableNodes.BinaryNodeAdapter.class, commutative = true) -@MatchableNode(nodeClass = XorNode.class, inputs = 2, adapter = GraalMatchableNodes.BinaryNodeAdapter.class, commutative = true) -@MatchableNode(nodeClass = PiNode.class, inputs = 1, adapter = GraalMatchableNodes.PiNodeAdapter.class) -@MatchableNode(nodeClass = ConstantLocationNode.class, shareable = true) -public class GraalMatchableNodes { - public static class PiNodeAdapter extends MatchNodeAdapter { - @Override - public ValueNode getInput(int input, ValueNode node) { - if (input == 0) { - return ((PiNode) node).object(); - } - throw GraalInternalError.shouldNotReachHere(); - } - } - - public static class BinaryNodeAdapter extends MatchNodeAdapter { - @Override - public ValueNode getInput(int input, ValueNode node) { - if (input == 0) { - return ((BinaryNode) node).x(); - } - if (input == 1) { - return ((BinaryNode) node).y(); - } - throw GraalInternalError.shouldNotReachHere(); - } - } - - public static class WriteNodeAdapter extends MatchNodeAdapter { - @Override - public ValueNode getInput(int input, ValueNode node) { - if (input == 0) { - return ((WriteNode) node).object(); - } - if (input == 1) { - return ((WriteNode) node).location(); - } - if (input == 2) { - return ((WriteNode) node).value(); - } - throw GraalInternalError.shouldNotReachHere(); - } - } - - public static class ConvertNodeAdapter extends MatchNodeAdapter { - @Override - public ValueNode getInput(int input, ValueNode node) { - if (input == 0) { - return ((ConvertNode) node).getInput(); - } - throw GraalInternalError.shouldNotReachHere(); - } - } - - public static class ReinterpretNodeAdapter extends MatchNodeAdapter { - @Override - public ValueNode getInput(int input, ValueNode node) { - if (input == 0) { - return ((ReinterpretNode) node).value(); - } - throw GraalInternalError.shouldNotReachHere(); - } - } - - public static class IfNodeAdapter extends MatchNodeAdapter { - @Override - public ValueNode getInput(int input, ValueNode node) { - if (input == 0) { - return ((IfNode) node).condition(); - } - throw GraalInternalError.shouldNotReachHere(); - } - } - - public static class AccessAdapter extends MatchNodeAdapter { - - @Override - public ValueNode getInput(int input, ValueNode node) { - if (input == 0) { - return ((Access) node).object(); - } - if (input == 1) { - return ((Access) node).accessLocation(); - } - throw GraalInternalError.shouldNotReachHere(); - } - } - - public static class BinaryOpLogicNodeAdapter extends MatchNodeAdapter { - @Override - public ValueNode getInput(int input, ValueNode node) { - if (input == 0) { - return ((BinaryOpLogicNode) node).x(); - } - if (input == 1) { - return ((BinaryOpLogicNode) node).y(); - } - throw GraalInternalError.shouldNotReachHere(); - } - } -} diff -r ff05eeb654d4 -r 3882866b6ff9 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchNodeAdapter.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchNodeAdapter.java Wed May 07 23:58:43 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2014, 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.graal.compiler.match; - -import com.oracle.graal.compiler.common.*; -import com.oracle.graal.nodes.*; - -/** - * Helper class to visit the matchable inputs of a node in a specified order. This may not be needed - * in the end since this could probably be done using the inputs iterator but it simplifies things - * for the moment. - */ -public class MatchNodeAdapter { - @SuppressWarnings("unused") - public ValueNode getInput(int input, ValueNode node) { - throw GraalInternalError.shouldNotReachHere(); - } -} diff -r ff05eeb654d4 -r 3882866b6ff9 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchPattern.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchPattern.java Wed May 07 23:58:43 2014 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchPattern.java Wed May 07 23:58:56 2014 +0200 @@ -22,8 +22,10 @@ */ package com.oracle.graal.compiler.match; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.debug.*; import com.oracle.graal.graph.Node.Verbosity; +import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; /** @@ -124,11 +126,9 @@ private final MatchPattern[] patterns; /** - * Helper class to visit the inputs. + * The inputs to match the patterns against. */ - private final MatchNodeAdapter adapter; - - private static final MatchPattern[] EMPTY_PATTERNS = new MatchPattern[0]; + private final NodeClass.Position[] inputs; /** * Can there only be one user of the node. Constant nodes can be matched even if there are other @@ -136,6 +136,8 @@ */ private final boolean singleUser; + private static final MatchPattern[] EMPTY_PATTERNS = new MatchPattern[0]; + public MatchPattern(String name, boolean singleUser) { this(null, name, singleUser); } @@ -145,37 +147,28 @@ this.name = name; this.singleUser = singleUser; this.patterns = EMPTY_PATTERNS; - this.adapter = null; + this.inputs = null; } - public MatchPattern(Class nodeClass, String name, MatchPattern first, MatchNodeAdapter adapter, boolean singleUser) { - this.nodeClass = nodeClass; - this.name = name; - this.singleUser = singleUser; - this.patterns = new MatchPattern[1]; - patterns[0] = first; - this.adapter = adapter; - } - - public MatchPattern(Class nodeClass, String name, MatchPattern first, MatchPattern second, MatchNodeAdapter adapter, boolean singleUser) { + private MatchPattern(Class nodeClass, String name, boolean singleUser, MatchPattern[] patterns, NodeClass.Position[] inputs) { + assert inputs == null || inputs.length == patterns.length; this.nodeClass = nodeClass; this.name = name; this.singleUser = singleUser; - this.patterns = new MatchPattern[2]; - patterns[0] = first; - patterns[1] = second; - this.adapter = adapter; + this.patterns = patterns; + this.inputs = inputs; } - public MatchPattern(Class nodeClass, String name, MatchPattern first, MatchPattern second, MatchPattern third, MatchNodeAdapter adapter, boolean singleUser) { - this.nodeClass = nodeClass; - this.name = name; - this.singleUser = singleUser; - this.patterns = new MatchPattern[3]; - patterns[0] = first; - patterns[1] = second; - patterns[2] = third; - this.adapter = adapter; + public MatchPattern(Class nodeClass, String name, MatchPattern first, NodeClass.Position[] inputs, boolean singleUser) { + this(nodeClass, name, singleUser, new MatchPattern[]{first}, inputs); + } + + public MatchPattern(Class nodeClass, String name, MatchPattern first, MatchPattern second, NodeClass.Position[] inputs, boolean singleUser) { + this(nodeClass, name, singleUser, new MatchPattern[]{first, second}, inputs); + } + + public MatchPattern(Class nodeClass, String name, MatchPattern first, MatchPattern second, MatchPattern third, NodeClass.Position[] inputs, boolean singleUser) { + this(nodeClass, name, singleUser, new MatchPattern[]{first, second, third}, inputs); } Class nodeClass() { @@ -204,6 +197,36 @@ return result; } + /** + * Convert a list of field names into {@link com.oracle.graal.graph.NodeClass.Position} objects + * that can be used to read them during a match. The names should already have been confirmed to + * exist in the type. + * + * @param theClass + * @param names + * @return an array of Position objects corresponding to the named fields. + */ + public static NodeClass.Position[] findPositions(Class theClass, String[] names) { + NodeClass.Position[] result = new NodeClass.Position[names.length]; + NodeClass nodeClass = NodeClass.get(theClass); + for (int i = 0; i < names.length; i++) { + for (NodeClass.Position position : nodeClass.getFirstLevelInputPositions()) { + String name = nodeClass.getName(position); + if (name.endsWith("#NDF")) { + name = name.substring(0, name.length() - 4); + } + if (name.equals(names[i])) { + result[i] = position; + break; + } + } + if (result[i] == null) { + throw new GraalInternalError("unknown field \"%s\" in class %s", names[i], theClass); + } + } + return result; + } + private Result matchUsage(ValueNode node, MatchContext context, boolean atRoot) { Result result = matchType(node); if (result != Result.OK) { @@ -221,7 +244,7 @@ } for (int input = 0; input < patterns.length; input++) { - result = patterns[input].matchUsage(adapter.getInput(input, node), context, false); + result = patterns[input].matchUsage(getInput(input, node), context, false); if (result != Result.OK) { return result; } @@ -255,7 +278,7 @@ } for (int input = 0; input < patterns.length; input++) { - result = patterns[input].matchShape(adapter.getInput(input, node), statement, false); + result = patterns[input].matchShape(getInput(input, node), statement, false); if (result != Result.OK) { return result; } @@ -279,13 +302,17 @@ sb.append(result); for (int input = 0; input < patterns.length; input++) { sb.append(" "); - sb.append(patterns[input].formatMatch(adapter.getInput(input, root))); + sb.append(patterns[input].formatMatch(getInput(input, root))); } sb.append(")"); return sb.toString(); } } + private ValueNode getInput(int index, ValueNode node) { + return (ValueNode) inputs[index].get(node); + } + @Override public String toString() { if (nodeClass == null) { diff -r ff05eeb654d4 -r 3882866b6ff9 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchProcessor.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchProcessor.java Wed May 07 23:58:43 2014 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchProcessor.java Wed May 07 23:58:56 2014 +0200 @@ -36,6 +36,7 @@ import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.gen.*; +import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; /** @@ -50,7 +51,8 @@ * } * */ -@SupportedAnnotationTypes({"com.oracle.graal.compiler.match.MatchRule", "com.oracle.graal.compiler.match.MatchRules", "com.oracle.graal.compiler.match.MatchableNode"}) +@SupportedAnnotationTypes({"com.oracle.graal.compiler.match.MatchRule", "com.oracle.graal.compiler.match.MatchRules", "com.oracle.graal.compiler.match.MatchableNode", + "com.oracle.graal.compiler.match.MatchableNodes"}) public class MatchProcessor extends AbstractProcessor { public MatchProcessor() { @@ -72,6 +74,8 @@ } } + private static Pattern tokenizer = Pattern.compile("\\s*([()=]|[A-Za-z][A-Za-z0-9]*)\\s*"); + private class RuleParser { private ArrayList capturedTypes = new ArrayList<>(); @@ -95,7 +99,7 @@ m.region(m.end(), m.regionEnd()); } if (end != m.regionEnd()) { - throw new RuleParseError("Unnexpected tokens :" + rule.substring(m.end(), m.regionEnd())); + throw new RuleParseError("Unexpected tokens :" + rule.substring(m.end(), m.regionEnd())); } tokens = list.toArray(new String[0]); @@ -129,14 +133,14 @@ if (peek("(").equals("(")) { next(); MatchDescriptor descriptor = parseType(true); - for (int n = 0; n < descriptor.nodeType.inputs; n++) { + for (int n = 0; n < descriptor.nodeType.inputs.length; n++) { if (peek("(").equals("(")) { descriptor.inputs[n] = parseExpression(); } else { descriptor.inputs[n] = parseType(false); } } - for (int n = 0; n < descriptor.nodeType.inputs; n++) { + for (int n = 0; n < descriptor.nodeType.inputs.length; n++) { if (descriptor.inputs[n] == null) { throw new RuleParseError("not enough inputs for " + descriptor.name); } @@ -189,6 +193,13 @@ } /** + * Recursively accumulate any required NodeClass.Position declarations. + */ + void generatePositionDeclarations(Set declarations) { + matchDescriptor.generatePositionDeclarations(declarations); + } + + /** * * @return the list of node types which are captured by name */ @@ -201,7 +212,63 @@ } } - static Pattern tokenizer = Pattern.compile("\\s*([()=]|[A-Za-z][A-Za-z0-9]*)\\s*"); + /** + * Set to true to enable logging to a local file during annotation processing. There's no normal + * channel for any debug messages and debugging annotation processors requires some special + * setup. + */ + private static final boolean DEBUG = false; + + private static final String MATCHPROCESSOR_LOG = "/tmp/matchprocessor.log"; + + private static PrintWriter log; + + /** + * Logging facility for the debugging the annotation processor. + */ + + private static synchronized PrintWriter getLog() { + if (log == null) { + try { + log = new PrintWriter(new FileWriter(MATCHPROCESSOR_LOG, true)); + } catch (IOException e) { + // Do nothing + } + } + return log; + } + + private static synchronized void logMessage(String format, Object... args) { + if (!DEBUG) { + return; + } + PrintWriter bw = getLog(); + if (bw != null) { + bw.printf(format, args); + bw.flush(); + } + } + + private static synchronized void logException(Throwable t) { + if (!DEBUG) { + return; + } + PrintWriter bw = getLog(); + if (bw != null) { + t.printStackTrace(bw); + bw.flush(); + } + } + + /** + * Bugs in an annotation processor can cause silent failure so try to report any exception + * throws as errors. + */ + private void reportExceptionThrow(Element element, Throwable t) { + logMessage("throw for %s:\n", element); + logException(t); + processingEnv.getMessager().printMessage(Kind.ERROR, "Exception throw during processing: " + t.toString() + " " + Arrays.toString(Arrays.copyOf(t.getStackTrace(), 4)), element); + } static class TypeDescriptor { final TypeMirror mirror; @@ -210,25 +277,21 @@ * The name uses in match expressions to refer to this type. */ final String shortName; + /** - * The {@link ValueNode} class represented by this type. + * The simple name of the {@link ValueNode} class represented by this type. */ final String nodeClass; /** - * The {@link ValueNode} class represented by this type. + * The package of {@link ValueNode} class represented by this type. */ final String nodePackage; /** - * Expected number of matchable inputs. Should be less <= 2 at the moment. + * The matchable inputs of the node. */ - final int inputs; - - /** - * An adapter class to read the proper matchable inputs of the class. - */ - final String adapter; + final String[] inputs; /** * Should swapped variants of this match be generated. The user of the match is expected to @@ -245,16 +308,15 @@ final Set originatingElements = new HashSet<>(); - TypeDescriptor(TypeMirror mirror, String shortName, String nodeClass, String nodePackage, int inputs, String adapter, boolean commutative, boolean shareable) { + TypeDescriptor(TypeMirror mirror, String shortName, String nodeClass, String nodePackage, String[] inputs, boolean commutative, boolean shareable) { this.mirror = mirror; this.shortName = shortName; this.nodeClass = nodeClass; this.nodePackage = nodePackage; this.inputs = inputs; - this.adapter = adapter; this.commutative = commutative; this.shareable = shareable; - assert !commutative || inputs == 2; + assert !commutative || inputs.length == 2; } } @@ -279,8 +341,12 @@ private TypeMirror matchRuleTypeMirror; - private void declareType(TypeMirror mirror, String shortName, String nodeClass, String nodePackage, int inputs, String adapter, boolean commutative, boolean shareable, Element element) { - TypeDescriptor descriptor = new TypeDescriptor(mirror, shortName, nodeClass, nodePackage, inputs, adapter, commutative, shareable); + private TypeMirror matchableNodeTypeMirror; + + private TypeMirror matchableNodesTypeMirror; + + private void declareType(TypeMirror mirror, String shortName, String nodeClass, String nodePackage, String[] inputs, boolean commutative, boolean shareable, Element element) { + TypeDescriptor descriptor = new TypeDescriptor(mirror, shortName, nodeClass, nodePackage, inputs, commutative, shareable); descriptor.originatingElements.add(element); knownTypes.put(shortName, descriptor); if (!requiredPackages.contains(descriptor.nodePackage)) { @@ -305,12 +371,43 @@ this.nodeType = nodeType; this.name = name; if (forExpression) { - this.inputs = new MatchDescriptor[nodeType.inputs]; + this.inputs = new MatchDescriptor[nodeType.inputs.length]; } else { this.inputs = new MatchDescriptor[0]; } } + public void generatePositionDeclarations(Set declarations) { + if (inputs.length == 0) { + return; + } + declarations.add(generatePositionDeclaration()); + for (MatchDescriptor desc : inputs) { + desc.generatePositionDeclarations(declarations); + } + } + + List recurseVariants(int index) { + if (inputs.length == 0) { + return new ArrayList<>(); + } + List currentVariants = inputs[index].generateVariants(); + if (index == inputs.length - 1) { + return currentVariants; + } + List subVariants = recurseVariants(index + 1); + List result = new ArrayList<>(); + for (String current : currentVariants) { + for (String sub : subVariants) { + result.add(current + ", " + sub); + if (nodeType.commutative) { + result.add(sub + ", " + current); + } + } + } + return result; + } + /** * Recursively generate all the variants of this rule pattern. Currently that just means to * swap the inputs for commutative rules, producing all possible permutations. @@ -321,32 +418,15 @@ String prefix = formatPrefix(); String suffix = formatSuffix(); ArrayList variants = new ArrayList<>(); - if (inputs.length == 3) { - for (String first : inputs[0].generateVariants()) { - for (String second : inputs[1].generateVariants()) { - for (String third : inputs[2].generateVariants()) { - variants.add(prefix + ", " + first + ", " + second + ", " + third + suffix); - } - } - } - } else if (inputs.length == 2) { - // Generate this version and a swapped version - for (String first : inputs[0].generateVariants()) { - for (String second : inputs[1].generateVariants()) { - variants.add(prefix + ", " + first + ", " + second + suffix); - if (nodeType.commutative) { - variants.add(prefix + ", " + second + ", " + first + suffix); - } - } - } - } else if (inputs.length == 1) { - for (String first : inputs[0].generateVariants()) { - variants.add(prefix + ", " + first + suffix); + if (inputs.length > 0) { + for (String var : recurseVariants(0)) { + variants.add(prefix + ", " + var + suffix); } } else { assert inputs.length == 0; variants.add(prefix + suffix); } + return variants; } @@ -360,11 +440,11 @@ private String formatSuffix() { if (nodeType != null) { - if (inputs.length != nodeType.inputs) { + if (inputs.length != nodeType.inputs.length) { return ", true)"; } else { - if (nodeType.adapter != null) { - return ", " + nodeType.adapter + "," + !nodeType.shareable + ")"; + if (nodeType.inputs.length > 0) { + return ", " + nodeType.nodeClass + "_positions, " + !nodeType.shareable + ")"; } if (nodeType.shareable) { return ", false)"; @@ -374,6 +454,10 @@ return ")"; } + String generatePositionDeclaration() { + return String.format("private static final NodeClass.Position[] %s_positions = MatchPattern.findPositions(%s.class, new String[]{\"%s\"});", nodeType.nodeClass, nodeType.nodeClass, + String.join("\", \"", nodeType.inputs)); + } } /** @@ -406,12 +490,23 @@ out.println("import " + MatchStatementSet.class.getPackage().getName() + ".*;"); out.println("import " + GraalInternalError.class.getName() + ";"); out.println("import " + NodeLIRBuilder.class.getName() + ";"); + out.println("import " + NodeClass.class.getName() + ";"); for (String p : requiredPackages) { out.println("import " + p + ".*;"); } out.println(""); out.println("public class " + matchStatementClassName + " implements " + MatchStatementSet.class.getSimpleName() + " {"); + out.println(); + out.println(" private static Method lookupMethod(Class theClass, String name, Class... args) {"); + out.println(" try {"); + out.println(" return theClass.getDeclaredMethod(name, args);"); + out.println(" } catch (Exception e) {"); + out.println(" throw new GraalInternalError(e);"); + out.println(" }"); + out.println(" }"); + out.println(); + // Generate declarations for the reflective invocation of the code generation methods. for (MethodInvokerItem invoker : invokers.values()) { StringBuilder args = new StringBuilder(); @@ -428,22 +523,17 @@ types.append(", "); } } - out.printf(" private static final String[] %s = new String[] {%s};\n", invoker.argumentsListName(), args); - out.printf(" private static final Method %s;\n", invoker.reflectiveMethodName()); - out.printf(" static {\n"); - out.printf(" Method result = null;\n"); - out.printf(" try {\n"); - out.printf(" result = %s.class.getDeclaredMethod(\"%s\", %s);\n", invoker.nodeLIRBuilderClass, invoker.methodName, types); - out.printf(" } catch (Exception e) {\n"); - out.printf(" throw new GraalInternalError(e);\n"); - out.printf(" }\n"); - out.printf(" %s = result;\n", invoker.reflectiveMethodName()); - out.printf(" }\n"); - + out.printf(" private static final String[] %s = new String[] {%s};\n", invoker.argumentsListName(), args); + out.printf(" private static final Method %s = lookupMethod(%s.class, \"%s\", %s);\n", invoker.reflectiveMethodName(), invoker.nodeLIRBuilderClass, invoker.methodName, types); out.println(); } + for (String positionDeclaration : info.positionDeclarations) { + out.println(" " + positionDeclaration); + } + out.println(); + String desc = MatchStatement.class.getSimpleName(); out.println(" // CheckStyle: stop line length check"); out.println(" private static final List<" + desc + "> statements = Collections.unmodifiableList(Arrays.asList("); @@ -551,6 +641,7 @@ final TypeElement topDeclaringType; final List matchRules = new ArrayList<>(); private final Set originatingElements = new HashSet<>(); + public Set positionDeclarations = new LinkedHashSet<>(); public MatchRuleDescriptor(TypeElement topDeclaringType) { this.topDeclaringType = topDeclaringType; @@ -580,32 +671,20 @@ if (roundEnv.processingOver()) { return true; } + logMessage("Starting round %s\n", roundEnv); matchRulesTypeMirror = processingEnv.getElementUtils().getTypeElement(MatchRules.class.getCanonicalName()).asType(); matchRuleTypeMirror = processingEnv.getElementUtils().getTypeElement(MatchRule.class.getCanonicalName()).asType(); - try { - // Define a TypeDescriptor the generic node but don't enter it into the nodeTypes table - // since it shouldn't mentioned in match rules. - TypeMirror valueTypeMirror = processingEnv.getElementUtils().getTypeElement(ValueNode.class.getName()).asType(); - valueType = new TypeDescriptor(valueTypeMirror, "Value", ValueNode.class.getSimpleName(), ValueNode.class.getPackage().getName(), 0, null, false, false); + matchableNodeTypeMirror = processingEnv.getElementUtils().getTypeElement(MatchableNode.class.getCanonicalName()).asType(); + matchableNodesTypeMirror = processingEnv.getElementUtils().getTypeElement(MatchableNodes.class.getCanonicalName()).asType(); - // Import default definitions - processMatchableNode(processingEnv.getElementUtils().getTypeElement(GraalMatchableNodes.class.getName())); - for (Element element : roundEnv.getElementsAnnotatedWith(MatchableNodeImport.class)) { - // Import any other definitions required by this element - String[] imports = element.getAnnotation(MatchableNodeImport.class).value(); - for (String m : imports) { - TypeElement el = processingEnv.getElementUtils().getTypeElement(m); - processMatchableNode(el); - } - } + try { + // Define a TypeDescriptor for the generic node but don't enter it into the nodeTypes + // table since it shouldn't be mentioned in match rules. + TypeMirror valueTypeMirror = processingEnv.getElementUtils().getTypeElement(ValueNode.class.getName()).asType(); + valueType = new TypeDescriptor(valueTypeMirror, "Value", ValueNode.class.getSimpleName(), ValueNode.class.getPackage().getName(), new String[0], false, false); - // Process any local MatchableNode declarations - for (Element element : roundEnv.getElementsAnnotatedWith(MatchableNode.class)) { - processMatchableNode(element); - } - - Map map = new HashMap<>(); + Map map = new LinkedHashMap<>(); for (Element element : roundEnv.getElementsAnnotatedWith(MatchRule.class)) { processMatchRule(map, element, findAnnotationMirror(element, matchRuleTypeMirror)); @@ -632,46 +711,23 @@ if (!processedMatchableNode.contains(element)) { try { processedMatchableNode.add(element); + + AnnotationMirror mirror = findAnnotationMirror(element, matchableNodesTypeMirror); + if (mirror == null) { + mirror = findAnnotationMirror(element, matchableNodeTypeMirror); + } + if (mirror == null) { + return; + } TypeElement topDeclaringType = topDeclaringType(element); - MatchableNode[] matchables = element.getAnnotationsByType(MatchableNode.class); - for (MatchableNode matchable : matchables) { - String nodeClass; - String nodePackage; - TypeMirror nodeClassMirror = null; - try { - matchable.nodeClass(); - } catch (MirroredTypeException e) { - nodeClassMirror = e.getTypeMirror(); - } - if (nodeClassMirror == null) { - throw new GraalInternalError("Can't get mirror for node class %s", element); - } - if (nodeClassMirror.toString().equals(MatchableNode.class.getName())) { - nodeClass = topDeclaringType.getQualifiedName().toString(); - } else { - nodeClass = nodeClassMirror.toString(); - } - nodePackage = findPackage(processingEnv.getElementUtils().getTypeElement(nodeClass)); - assert nodeClass.startsWith(nodePackage); - nodeClass = nodeClass.substring(nodePackage.length() + 1); - assert nodeClass.endsWith("Node"); - String shortName = nodeClass.substring(0, nodeClass.length() - 4); - - TypeMirror nodeAdapterMirror = null; - try { - matchable.adapter(); - } catch (MirroredTypeException e) { - nodeAdapterMirror = e.getTypeMirror(); - } - if (nodeAdapterMirror == null) { - throw new GraalInternalError("Can't get mirror for adapter %s", element); - } - String nodeAdapter = null; - if (!nodeAdapterMirror.toString().equals(MatchableNode.class.getName())) { - nodeAdapter = String.format("new %s()", nodeAdapterMirror.toString()); - } - - declareType(nodeClassMirror, shortName, nodeClass, nodePackage, matchable.inputs(), nodeAdapter, matchable.commutative(), matchable.shareable(), element); + List mirrors = null; + if (typeUtils().isSameType(mirror.getAnnotationType(), matchableNodesTypeMirror)) { + // Unpack the mirrors for a repeatable annotation + mirrors = getAnnotationValueList(AnnotationMirror.class, mirror, "value"); + } + int i = 0; + for (MatchableNode matchableNode : element.getAnnotationsByType(MatchableNode.class)) { + processMatchableNode(element, topDeclaringType, matchableNode, mirrors != null ? mirrors.get(i++) : mirror); } } catch (Throwable t) { reportExceptionThrow(element, t); @@ -679,8 +735,52 @@ } } - private void reportExceptionThrow(Element element, Throwable t) { - processingEnv.getMessager().printMessage(Kind.ERROR, "Exception throw during processing: " + t.toString() + " " + Arrays.toString(Arrays.copyOf(t.getStackTrace(), 2)), element); + private void processMatchableNode(Element element, TypeElement topDeclaringType, MatchableNode matchable, AnnotationMirror mirror) throws GraalInternalError { + logMessage("processMatchableNode %s %s %s\n", topDeclaringType, element, matchable); + String nodeClass; + String nodePackage; + TypeMirror nodeClassMirror = null; + try { + matchable.nodeClass(); + } catch (MirroredTypeException e) { + nodeClassMirror = e.getTypeMirror(); + } + if (nodeClassMirror == null) { + throw new GraalInternalError("Can't get mirror for node class %s", element); + } + if (nodeClassMirror.toString().equals(MatchableNode.class.getName())) { + nodeClass = topDeclaringType.getQualifiedName().toString(); + } else { + nodeClass = nodeClassMirror.toString(); + } + nodePackage = findPackage(processingEnv.getElementUtils().getTypeElement(nodeClass)); + assert nodeClass.startsWith(nodePackage); + nodeClass = nodeClass.substring(nodePackage.length() + 1); + assert nodeClass.endsWith("Node"); + String shortName = nodeClass.substring(0, nodeClass.length() - 4); + + Types typeUtils = processingEnv.getTypeUtils(); + TypeElement nodeClassElement = (TypeElement) typeUtils.asElement(nodeClassMirror); + for (String input : matchable.inputs()) { + boolean ok = false; + TypeElement current = nodeClassElement; + while (!ok && current != null) { + for (Element fieldElement : ElementFilter.fieldsIn(current.getEnclosedElements())) { + if (fieldElement.getSimpleName().toString().equals(input)) { + ok = true; + break; + } + } + TypeMirror theSuper = current.getSuperclass(); + current = (TypeElement) typeUtils.asElement(theSuper); + } + if (!ok) { + String msg = String.format("Input named \"%s\" doesn't exist in %s", input, nodeClassElement.getSimpleName()); + processingEnv.getMessager().printMessage(Kind.ERROR, msg, element, mirror); + } + } + + declareType(nodeClassMirror, shortName, nodeClass, nodePackage, matchable.inputs(), matchable.commutative(), matchable.shareable(), element); } private void processMatchRule(Map map, Element element, AnnotationMirror mirror) { @@ -691,22 +791,22 @@ // The annotation element type should ensure this is true. assert element instanceof ExecutableElement; + findMatchableNodes(element); + TypeElement topDeclaringType = topDeclaringType(element); MatchRuleDescriptor info = map.get(topDeclaringType); if (info == null) { info = new MatchRuleDescriptor(topDeclaringType); map.put(topDeclaringType, info); } + List mirrors = null; if (typeUtils().isSameType(mirror.getAnnotationType(), matchRulesTypeMirror)) { - List value = getAnnotationValueList(AnnotationMirror.class, mirror, "value"); - int i = 0; - for (MatchRule matchRule : element.getAnnotationsByType(MatchRule.class)) { - processMethodMatchRule((ExecutableElement) element, info, matchRule, value.get(i++)); - } - } else { - for (MatchRule matchRule : element.getAnnotationsByType(MatchRule.class)) { - processMethodMatchRule((ExecutableElement) element, info, matchRule, mirror); - } + // Unpack the mirrors for a repeatable annotation + mirrors = getAnnotationValueList(AnnotationMirror.class, mirror, "value"); + } + int i = 0; + for (MatchRule matchRule : element.getAnnotationsByType(MatchRule.class)) { + processMethodMatchRule((ExecutableElement) element, info, matchRule, mirrors != null ? mirrors.get(i++) : mirror); } } catch (Throwable t) { reportExceptionThrow(element, t); @@ -714,11 +814,41 @@ } } + /** + * Search the super types of element for MatchableNode definitions. Any superclass or super + * interface can contain definitions of matchable nodes. + * + * @param element + */ + private void findMatchableNodes(Element element) { + processMatchableNode(element); + Element enclosing = element.getEnclosingElement(); + while (enclosing != null) { + if (enclosing.getKind() == ElementKind.CLASS || enclosing.getKind() == ElementKind.INTERFACE) { + TypeElement current = (TypeElement) enclosing; + while (current != null) { + processMatchableNode(current); + for (TypeMirror intf : current.getInterfaces()) { + Element interfaceElement = typeUtils().asElement(intf); + processMatchableNode(interfaceElement); + // Recurse + findMatchableNodes(interfaceElement); + } + TypeMirror theSuper = current.getSuperclass(); + current = (TypeElement) typeUtils().asElement(theSuper); + } + } + enclosing = enclosing.getEnclosingElement(); + } + } + private Types typeUtils() { return processingEnv.getTypeUtils(); } private void processMethodMatchRule(ExecutableElement method, MatchRuleDescriptor info, MatchRule matchRule, AnnotationMirror mirror) { + logMessage("processMethodMatchRule %s %s\n", method, mirror); + Types typeUtils = typeUtils(); if (!method.getModifiers().contains(Modifier.PUBLIC)) { @@ -799,6 +929,9 @@ originatingElementsList.addAll(parser.originatingElements); + // Accumulate any position declarations. + parser.generatePositionDeclarations(info.positionDeclarations); + List matches = parser.generateVariants(); for (String match : matches) { info.matchRules.add(new MatchRuleItem(match, invoker)); diff -r ff05eeb654d4 -r 3882866b6ff9 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchStatement.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchStatement.java Wed May 07 23:58:43 2014 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchStatement.java Wed May 07 23:58:56 2014 +0200 @@ -30,7 +30,8 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.gen.*; -import com.oracle.graal.compiler.match.MatchPattern.*; +import com.oracle.graal.compiler.match.MatchPattern.MatchResultCode; +import com.oracle.graal.compiler.match.MatchPattern.Result; import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.Node.Verbosity; diff -r ff05eeb654d4 -r 3882866b6ff9 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchStatementSet.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchStatementSet.java Wed May 07 23:58:43 2014 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchStatementSet.java Wed May 07 23:58:56 2014 +0200 @@ -34,7 +34,7 @@ public Class forClass(); /** - * @return the {@link MatchStatement}s available with this {@link NodeLIRBuilder} subclass. + * @return the {@link MatchStatement}s available for this {@link NodeLIRBuilder} subclass. */ public List statements(); } diff -r ff05eeb654d4 -r 3882866b6ff9 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchableNode.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchableNode.java Wed May 07 23:58:43 2014 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchableNode.java Wed May 07 23:58:56 2014 +0200 @@ -27,7 +27,9 @@ import com.oracle.graal.nodes.*; /** - * Describes the properties of a node for use when building a {@link MatchPattern}. + * Describes the properties of a node for use when building a {@link MatchPattern}. These + * declarations are required when parsing a {@link MatchRule}. They are expected to be found on a + * super type of the holder of the method declaring the {@link MatchRule}. */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) @@ -42,15 +44,9 @@ Class nodeClass(); /** - * The number of matchable inputs, which may be less than the real number of inputs. + * The names of the inputs in the order they should appear in the match. */ - int inputs() default 0; - - /** - * A helper class to visit the inputs in a specified order. Should be a subclass of - * {@link MatchNodeAdapter}. - */ - Class adapter() default MatchableNode.class; + String[] inputs() default {}; /** * Can a pattern be matched with the operands swapped. This will cause swapped versions of diff -r ff05eeb654d4 -r 3882866b6ff9 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchableNodeImport.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchableNodeImport.java Wed May 07 23:58:43 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2014, 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.graal.compiler.match; - -import java.lang.annotation.*; - -/** - * A list of classes which contain one or more {@link MatchableNode} annotations describing nodes - * that may be used in match expressions. Those {@link MatchableNode} declarations are parsed before - * processing any {@link MatchRule}s. - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.TYPE) -public @interface MatchableNodeImport { - String[] value() default {}; -} diff -r ff05eeb654d4 -r 3882866b6ff9 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchableNodes.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchableNodes.java Wed May 07 23:58:43 2014 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchableNodes.java Wed May 07 23:58:56 2014 +0200 @@ -25,7 +25,7 @@ import java.lang.annotation.*; /** - * The repeatable representation of {@link MatchableNode}. Should never be used directly. + * The repeatable representation of {@link MatchableNode}. */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) diff -r ff05eeb654d4 -r 3882866b6ff9 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotNodeLIRBuilder.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotNodeLIRBuilder.java Wed May 07 23:58:43 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotNodeLIRBuilder.java Wed May 07 23:58:56 2014 +0200 @@ -55,7 +55,6 @@ /** * LIR generator specialized for AMD64 HotSpot. */ -@MatchableNodeImport({"com.oracle.graal.hotspot.nodes.HotSpotMatchableNodes"}) public class AMD64HotSpotNodeLIRBuilder extends AMD64NodeLIRBuilder implements HotSpotNodeLIRBuilder { private static ValueNode filterCompression(ValueNode node) { diff -r ff05eeb654d4 -r 3882866b6ff9 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotNodeLIRBuilder.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotNodeLIRBuilder.java Wed May 07 23:58:43 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotNodeLIRBuilder.java Wed May 07 23:58:56 2014 +0200 @@ -22,6 +22,7 @@ */ package com.oracle.graal.hotspot; +import com.oracle.graal.compiler.match.*; import com.oracle.graal.hotspot.nodes.*; import com.oracle.graal.lir.gen.*; import com.oracle.graal.nodes.*; @@ -31,6 +32,7 @@ * This interface defines the contract a HotSpot backend LIR generator needs to fulfill in addition * to abstract methods from {@link LIRGenerator} and {@link NodeLIRBuilderTool}. */ +@MatchableNode(nodeClass = CompressionNode.class, inputs = {"input"}) public interface HotSpotNodeLIRBuilder { void emitPatchReturnAddress(ValueNode address); diff -r ff05eeb654d4 -r 3882866b6ff9 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/HotSpotMatchableNodes.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/HotSpotMatchableNodes.java Wed May 07 23:58:43 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2014, 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.graal.hotspot.nodes; - -import com.oracle.graal.compiler.common.*; -import com.oracle.graal.compiler.match.*; -import com.oracle.graal.nodes.*; - -@MatchableNode(nodeClass = CompressionNode.class, inputs = 1, adapter = HotSpotMatchableNodes.CompressionNodeAdapter.class) -public class HotSpotMatchableNodes { - public static class CompressionNodeAdapter extends MatchNodeAdapter { - @Override - public ValueNode getInput(int input, ValueNode node) { - if (input == 0) { - return ((CompressionNode) node).getInput(); - } - throw GraalInternalError.shouldNotReachHere(); - } - } - -}