# HG changeset patch # User Tom Rodriguez # Date 1399331629 25200 # Node ID 4cdc787681d41a8e085d1bf5f15cc321a5bc8ccd # Parent f8cf483ba31ec3350f392f1bbc49626ff3b93e22 add support for more nodes inputs diff -r f8cf483ba31e -r 4cdc787681d4 graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64NodeLIRBuilder.java --- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64NodeLIRBuilder.java Mon May 05 16:13:41 2014 -0700 +++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64NodeLIRBuilder.java Mon May 05 16:13:49 2014 -0700 @@ -455,7 +455,7 @@ return null; } - @MatchRule("(Write Narrow=narrow value)") + @MatchRule("(Write Narrow=narrow location value)") public ComplexMatchResult writeNarrow(WriteNode root, NarrowNode narrow) { return builder -> { PlatformKind writeKind = getLIRGeneratorTool().getPlatformKind(root.value().stamp()); diff -r f8cf483ba31e -r 4cdc787681d4 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 Mon May 05 16:13:41 2014 -0700 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/GraalMatchableNodes.java Mon May 05 16:13:49 2014 -0700 @@ -22,6 +22,7 @@ */ 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.*; @@ -30,19 +31,19 @@ * 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) +@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 = 1, adapter = GraalMatchableNodes.ReadNodeAdapter.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 = 1, adapter = GraalMatchableNodes.ReadNodeAdapter.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 = 2, adapter = GraalMatchableNodes.WriteNodeAdapter.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) @@ -61,71 +62,87 @@ public class GraalMatchableNodes { public static class BinaryNodeAdapter extends MatchNodeAdapter { @Override - protected ValueNode getFirstInput(ValueNode node) { - return ((BinaryNode) node).x(); - } - - @Override - protected ValueNode getSecondInput(ValueNode node) { - return ((BinaryNode) node).y(); + 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 - protected ValueNode getFirstInput(ValueNode node) { - return ((WriteNode) node).object(); - } - - @Override - protected ValueNode getSecondInput(ValueNode node) { - return ((WriteNode) node).value(); + 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 - protected ValueNode getFirstInput(ValueNode node) { - return ((ConvertNode) node).getInput(); + public ValueNode getInput(int input, ValueNode node) { + if (input == 0) { + return ((ConvertNode) node).getInput(); + } + throw GraalInternalError.shouldNotReachHere(); } } public static class ReinterpretNodeAdapter extends MatchNodeAdapter { - @Override - protected ValueNode getFirstInput(ValueNode node) { - return ((ReinterpretNode) node).value(); + public ValueNode getInput(int input, ValueNode node) { + if (input == 0) { + return ((ReinterpretNode) node).value(); + } + throw GraalInternalError.shouldNotReachHere(); } } public static class IfNodeAdapter extends MatchNodeAdapter { - @Override - protected ValueNode getFirstInput(ValueNode node) { - return ((IfNode) node).condition(); + public ValueNode getInput(int input, ValueNode node) { + if (input == 0) { + return ((IfNode) node).condition(); + } + throw GraalInternalError.shouldNotReachHere(); } } - public static class ReadNodeAdapter extends MatchNodeAdapter { + public static class AccessAdapter extends MatchNodeAdapter { @Override - protected ValueNode getFirstInput(ValueNode node) { - return ((Access) node).object(); + 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 - protected ValueNode getFirstInput(ValueNode node) { - return ((BinaryOpLogicNode) node).x(); - } - - @Override - protected ValueNode getSecondInput(ValueNode node) { - return ((BinaryOpLogicNode) node).y(); + 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 f8cf483ba31e -r 4cdc787681d4 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 Mon May 05 16:13:41 2014 -0700 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchNodeAdapter.java Mon May 05 16:13:49 2014 -0700 @@ -22,6 +22,7 @@ */ package com.oracle.graal.compiler.match; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.nodes.*; /** @@ -31,12 +32,7 @@ */ public class MatchNodeAdapter { @SuppressWarnings("unused") - protected ValueNode getFirstInput(ValueNode node) { - throw new InternalError(); - } - - @SuppressWarnings("unused") - protected ValueNode getSecondInput(ValueNode node) { - throw new InternalError(); + public ValueNode getInput(int input, ValueNode node) { + throw GraalInternalError.shouldNotReachHere(); } } diff -r f8cf483ba31e -r 4cdc787681d4 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 Mon May 05 16:13:41 2014 -0700 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchPattern.java Mon May 05 16:13:49 2014 -0700 @@ -111,23 +111,25 @@ * The expected type of the node. It must match exactly. */ private final Class nodeClass; + /** * An optional name for this node. A name can occur multiple times in a match and that name must * always refer to the same node of the match will fail. */ private final String name; + /** - * An optional pattern for the first input. + * Patterns to match the inputs. */ - private final MatchPattern first; - /** - * An optional pattern for the second input. - */ - private final MatchPattern second; + private final MatchPattern[] patterns; + /** * Helper class to visit the inputs. */ private final MatchNodeAdapter adapter; + + private static final MatchPattern[] EMPTY_PATTERNS = new MatchPattern[0]; + /** * Can there only be one user of the node. Constant nodes can be matched even if there are other * users. @@ -135,23 +137,44 @@ private final boolean singleUser; public MatchPattern(String name, boolean singleUser) { - this(null, name, null, null, null, singleUser); + this(null, name, singleUser); } public MatchPattern(Class nodeClass, String name, boolean singleUser) { - this(nodeClass, name, null, null, null, singleUser); + this.nodeClass = nodeClass; + this.name = name; + this.singleUser = singleUser; + this.patterns = EMPTY_PATTERNS; + this.adapter = null; } public MatchPattern(Class nodeClass, String name, MatchPattern first, MatchNodeAdapter adapter, boolean singleUser) { - this(nodeClass, name, first, null, adapter, 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) { this.nodeClass = nodeClass; this.name = name; this.singleUser = singleUser; - this.first = first; - this.second = second; + this.patterns = new MatchPattern[2]; + patterns[0] = first; + patterns[1] = second; + this.adapter = adapter; + } + + 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; } @@ -197,10 +220,10 @@ result = context.captureNamedValue(name, nodeClass, node); } - if (first != null) { - result = first.matchUsage(adapter.getFirstInput(node), context, false); - if (result == Result.OK && second != null) { - result = second.matchUsage(adapter.getSecondInput(node), context, false); + for (int input = 0; input < patterns.length; input++) { + result = patterns[input].matchUsage(adapter.getInput(input, node), context, false); + if (result != Result.OK) { + return result; } } @@ -231,10 +254,10 @@ } } - if (first != null) { - result = first.matchShape(adapter.getFirstInput(node), statement, false); - if (result == Result.OK && second != null) { - result = second.matchShape(adapter.getSecondInput(node), statement, false); + for (int input = 0; input < patterns.length; input++) { + result = patterns[input].matchShape(adapter.getInput(input, node), statement, false); + if (result != Result.OK) { + return result; } } @@ -248,10 +271,18 @@ */ public String formatMatch(ValueNode root) { String result = String.format("%s", root); - if (first == null && second == null) { + if (patterns.length == 0) { return result; } else { - return "(" + result + (first != null ? " " + first.formatMatch(adapter.getFirstInput(root)) : "") + (second != null ? " " + second.formatMatch(adapter.getSecondInput(root)) : "") + ")"; + StringBuilder sb = new StringBuilder(); + sb.append("("); + sb.append(result); + for (int input = 0; input < patterns.length; input++) { + sb.append(" "); + sb.append(patterns[input].formatMatch(adapter.getInput(input, root))); + } + sb.append(")"); + return sb.toString(); } } @@ -260,11 +291,21 @@ if (nodeClass == null) { return name; } else { - String pre = first != null || second != null ? "(" : ""; - String post = first != null || second != null ? ")" : ""; String nodeName = nodeClass.getSimpleName(); nodeName = nodeName.substring(0, nodeName.length() - 4); - return pre + nodeName + (name != null ? "=" + name : "") + (first != null ? (" " + first.toString()) : "") + (second != null ? (" " + second.toString()) : "") + post; + if (patterns.length == 0) { + return nodeName + (name != null ? "=" + name : ""); + } else { + StringBuilder sb = new StringBuilder(); + sb.append("("); + sb.append(nodeName); + for (int index = 0; index < patterns.length; index++) { + sb.append(" "); + sb.append(patterns[index].toString()); + } + sb.append(")"); + return sb.toString(); + } } } } diff -r f8cf483ba31e -r 4cdc787681d4 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 Mon May 05 16:13:41 2014 -0700 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchProcessor.java Mon May 05 16:13:49 2014 -0700 @@ -237,11 +237,11 @@ * Can multiple users of this node subsume it. Constants can be swallowed into a match even * if there are multiple users. */ - final boolean cloneable; + final boolean shareable; final Set originatingElements = new HashSet<>(); - TypeDescriptor(TypeMirror mirror, String shortName, String nodeClass, String nodePackage, int inputs, String adapter, boolean commutative) { + TypeDescriptor(TypeMirror mirror, String shortName, String nodeClass, String nodePackage, int inputs, String adapter, boolean commutative, boolean shareable) { this.mirror = mirror; this.shortName = shortName; this.nodeClass = nodeClass; @@ -249,7 +249,7 @@ this.inputs = inputs; this.adapter = adapter; this.commutative = commutative; - this.cloneable = (nodePackage + "." + nodeClass).equals(ConstantNode.class.getName()); + this.shareable = shareable; assert !commutative || inputs == 2; } } @@ -270,8 +270,8 @@ private Map invokers = new LinkedHashMap<>(); private TypeDescriptor valueType; - private void declareType(TypeMirror mirror, String shortName, String nodeClass, String nodePackage, int inputs, String adapter, boolean commutative, Element element) { - TypeDescriptor descriptor = new TypeDescriptor(mirror, shortName, nodeClass, nodePackage, inputs, adapter, commutative); + 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); descriptor.originatingElements.add(element); knownTypes.put(shortName, descriptor); if (!requiredPackages.contains(descriptor.nodePackage)) { @@ -315,7 +315,15 @@ String prefix = formatPrefix(); String suffix = formatSuffix(); ArrayList variants = new ArrayList<>(); - if (inputs.length == 2) { + 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()) { @@ -330,6 +338,7 @@ variants.add(prefix + ", " + first + suffix); } } else { + assert inputs.length == 0; variants.add(prefix + suffix); } return variants; @@ -349,9 +358,9 @@ return ", true)"; } else { if (nodeType.adapter != null) { - return ", " + nodeType.adapter + "," + !nodeType.cloneable + ")"; + return ", " + nodeType.adapter + "," + !nodeType.shareable + ")"; } - if (nodeType.cloneable) { + if (nodeType.shareable) { return ", false)"; } } @@ -561,7 +570,7 @@ // Define a TypeDescriptor the generic node but don't enter it into the nodeTypes table // since it shouldn't mentioned in match rules. TypeMirror mirror = processingEnv.getElementUtils().getTypeElement(ValueNode.class.getName()).asType(); - valueType = new TypeDescriptor(mirror, "Value", ValueNode.class.getSimpleName(), ValueNode.class.getPackage().getName(), 0, null, false); + valueType = new TypeDescriptor(mirror, "Value", ValueNode.class.getSimpleName(), ValueNode.class.getPackage().getName(), 0, null, false, false); // Import default definitions processMatchableNode(processingEnv.getElementUtils().getTypeElement(GraalMatchableNodes.class.getName())); @@ -644,7 +653,7 @@ nodeAdapter = String.format("new %s()", nodeAdapterMirror.toString()); } - declareType(nodeClassMirror, shortName, nodeClass, nodePackage, matchable.inputs(), nodeAdapter, matchable.commutative(), element); + declareType(nodeClassMirror, shortName, nodeClass, nodePackage, matchable.inputs(), nodeAdapter, matchable.commutative(), matchable.shareable(), element); } } catch (Throwable t) { reportExceptionThrow(element, t); diff -r f8cf483ba31e -r 4cdc787681d4 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 Mon May 05 16:13:41 2014 -0700 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchableNode.java Mon May 05 16:13:49 2014 -0700 @@ -57,4 +57,9 @@ * patterns to be automatically generated. */ boolean commutative() default false; + + /** + * Can a node with multiple users be safely match by a rule. + */ + boolean shareable() default false; } diff -r f8cf483ba31e -r 4cdc787681d4 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 Mon May 05 16:13:41 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/HotSpotMatchableNodes.java Mon May 05 16:13:49 2014 -0700 @@ -22,6 +22,7 @@ */ package com.oracle.graal.hotspot.nodes; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.match.*; import com.oracle.graal.nodes.*; @@ -29,8 +30,11 @@ public class HotSpotMatchableNodes { public static class CompressionNodeAdapter extends MatchNodeAdapter { @Override - protected ValueNode getFirstInput(ValueNode node) { - return ((CompressionNode) node).getInput(); + public ValueNode getInput(int input, ValueNode node) { + if (input == 0) { + return ((CompressionNode) node).getInput(); + } + throw GraalInternalError.shouldNotReachHere(); } }