Mercurial > hg > truffle
changeset 19951:a252927dfbfd
Fix an issue when the result of canonicalization is appended in the graph builder. Introduce GraphBuilderPhase#recursiveAppend.
author | Thomas Wuerthinger <thomas.wuerthinger@oracle.com> |
---|---|
date | Wed, 18 Mar 2015 23:26:23 +0100 |
parents | 5ee90d1bf6cd |
children | a9145e7b14b4 |
files | graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/GraphBuilderContext.java graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/StandardGraphBuilderPlugins.java |
diffstat | 5 files changed, 65 insertions(+), 79 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java Wed Mar 18 21:36:35 2015 +0100 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java Wed Mar 18 23:26:23 2015 +0100 @@ -847,12 +847,19 @@ protected void afterClone(@SuppressWarnings("unused") Node other) { } + public boolean verifyInputs() { + for (Node input : inputs()) { + assertFalse(input.isDeleted(), "input was deleted"); + assertTrue(input.isAlive(), "input is not alive yet, i.e., it was not yet added to the graph"); + assertTrue(input.usages().contains(this), "missing usage in input %s", input); + } + return true; + } + public boolean verify() { assertTrue(isAlive(), "cannot verify inactive nodes (id=%d)", id); assertTrue(graph() != null, "null graph"); - for (Node input : inputs()) { - assertTrue(input.usages().contains(this), "missing usage in input %s", input); - } + verifyInputs(); for (Node successor : successors()) { assertTrue(successor.predecessor() == this, "missing predecessor in %s (actual: %s)", successor, successor.predecessor()); assertTrue(successor.graph() == graph(), "mismatching graph in successor %s", successor); @@ -864,7 +871,7 @@ while (iterator.hasNext()) { Position pos = iterator.nextPosition(); if (pos.get(usage) == this && pos.getInputType() != InputType.Unchecked) { - assert isAllowedUsageType(pos.getInputType()) : "invalid input of type " + pos.getInputType() + " from " + usage + " to " + this + " (" + pos.getName() + ")"; + assertTrue(isAllowedUsageType(pos.getInputType()), "invalid input of type " + pos.getInputType() + " from " + usage + " to " + this + " (" + pos.getName() + ")"); } } }
--- a/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/GraphBuilderContext.java Wed Mar 18 21:36:35 2015 +0100 +++ b/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/GraphBuilderContext.java Wed Mar 18 23:26:23 2015 +0100 @@ -26,7 +26,6 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.api.replacements.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; /** @@ -60,15 +59,15 @@ boolean isIntrinsic(); } - <T extends ControlSinkNode> T append(T fixed); - - <T extends ControlSplitNode> T append(T fixed); + <T extends ValueNode> T append(T value); - <T extends FixedWithNextNode> T append(T fixed); - - <T extends FloatingNode> T append(T value); - - <T extends ValueNode> T append(T value); + /** + * Adds the given floating node to the graph and also adds recursively all referenced inputs. + * + * @param value the floating node to be added to the graph + * @return either the node added or an equivalent node + */ + <T extends ValueNode> T recursiveAppend(T value); StampProvider getStampProvider();
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java Wed Mar 18 21:36:35 2015 +0100 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java Wed Mar 18 23:26:23 2015 +0100 @@ -1033,7 +1033,7 @@ protected abstract ValueNode appendConstant(JavaConstant constant); - protected abstract ValueNode append(ValueNode v); + protected abstract <T extends ValueNode> T append(T v); protected boolean isNeverExecutedCode(double probability) { return probability == 0 && optimisticOpts.removeNeverExecutedCode();
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Wed Mar 18 21:36:35 2015 +0100 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Wed Mar 18 23:26:23 2015 +0100 @@ -1444,61 +1444,41 @@ return ConstantNode.forConstant(constant, metaAccess, currentGraph); } - @SuppressWarnings("unchecked") @Override - public ValueNode append(ValueNode v) { + public <T extends ValueNode> T append(T v) { if (v.graph() != null) { - // This node was already appended to the graph. return v; } - if (v instanceof ControlSinkNode) { - return append((ControlSinkNode) v); - } - if (v instanceof ControlSplitNode) { - return append((ControlSplitNode) v); - } - if (v instanceof FixedWithNextNode) { - return append((FixedWithNextNode) v); + T added = currentGraph.addOrUnique(v); + if (added == v) { + updateLastInstruction(v); } - if (v instanceof FloatingNode) { - return append((FloatingNode) v); - } - throw GraalInternalError.shouldNotReachHere("Can not append Node of type: " + v.getClass().getName()); - } - - public <T extends ControlSinkNode> T append(T fixed) { - assert !fixed.isAlive() && !fixed.isDeleted() : "instruction should not have been appended yet"; - assert lastInstr.next() == null : "cannot append instruction to instruction which isn't end (" + lastInstr + "->" + lastInstr.next() + ")"; - T added = currentGraph.add(fixed); - lastInstr.setNext(added); - lastInstr = null; return added; } - public <T extends ControlSplitNode> T append(T fixed) { - assert !fixed.isAlive() && !fixed.isDeleted() : "instruction should not have been appended yet"; - assert lastInstr.next() == null : "cannot append instruction to instruction which isn't end (" + lastInstr + "->" + lastInstr.next() + ")"; - T added = currentGraph.add(fixed); - lastInstr.setNext(added); - lastInstr = null; + public <T extends ValueNode> T recursiveAppend(T v) { + if (v.graph() != null) { + return v; + } + T added = currentGraph.addOrUniqueWithInputs(v); + if (added == v) { + updateLastInstruction(v); + } return added; } - public <T extends FixedWithNextNode> T append(T fixed) { - assert !fixed.isAlive() && !fixed.isDeleted() : "instruction should not have been appended yet"; - assert lastInstr.next() == null : "cannot append instruction to instruction which isn't end (" + lastInstr + "->" + lastInstr.next() + ")"; - T added = currentGraph.add(fixed); - lastInstr.setNext(added); - lastInstr = added; - return added; - } - - public <T extends FloatingNode> T append(T v) { - if (v.graph() != null) { - return v; + private <T extends ValueNode> void updateLastInstruction(T v) { + if (v instanceof FixedNode) { + FixedNode fixedNode = (FixedNode) v; + lastInstr.setNext(fixedNode); + if (fixedNode instanceof FixedWithNextNode) { + FixedWithNextNode fixedWithNextNode = (FixedWithNextNode) fixedNode; + assert fixedWithNextNode.next() == null : "cannot append instruction to instruction which isn't end"; + lastInstr = fixedWithNextNode; + } else { + lastInstr = null; + } } - T added = currentGraph.unique(v); - return added; } private Target checkLoopExit(FixedNode target, BciBlock targetBlock, HIRFrameStateBuilder state) {
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/StandardGraphBuilderPlugins.java Wed Mar 18 21:36:35 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/StandardGraphBuilderPlugins.java Wed Mar 18 23:26:23 2015 +0100 @@ -151,25 +151,25 @@ Registration r = new Registration(plugins, declaringClass); r.register1("reverseBytes", type, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode value) { - b.push(kind, b.append(new ReverseBytesNode(value).canonical(null, value))); + b.push(kind, b.recursiveAppend(new ReverseBytesNode(value).canonical(null, value))); return true; } }); r.register1("bitCount", type, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode value) { - b.push(Kind.Int, b.append(new BitCountNode(value).canonical(null, value))); + b.push(Kind.Int, b.recursiveAppend(new BitCountNode(value).canonical(null, value))); return true; } }); r.register2("divideUnsigned", type, type, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode dividend, ValueNode divisor) { - b.push(kind, b.append(new UnsignedDivNode(dividend, divisor).canonical(null, dividend, divisor))); + b.push(kind, b.recursiveAppend(new UnsignedDivNode(dividend, divisor).canonical(null, dividend, divisor))); return true; } }); r.register2("remainderUnsigned", type, type, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode dividend, ValueNode divisor) { - b.push(kind, b.append(new UnsignedDivNode(dividend, divisor).canonical(null, dividend, divisor))); + b.push(kind, b.recursiveAppend(new UnsignedDivNode(dividend, divisor).canonical(null, dividend, divisor))); return true; } }); @@ -183,7 +183,7 @@ ReverseBytesNode reverse = b.append(new ReverseBytesNode(value)); RightShiftNode rightShift = b.append(new RightShiftNode(reverse, b.append(ConstantNode.forInt(16)))); ZeroExtendNode charCast = b.append(new ZeroExtendNode(b.append(new NarrowNode(rightShift, 16)), 32)); - b.push(Kind.Char.getStackKind(), b.append(charCast.canonical(null, value))); + b.push(Kind.Char.getStackKind(), b.recursiveAppend(charCast.canonical(null, value))); return true; } }); @@ -197,7 +197,7 @@ ReverseBytesNode reverse = b.append(new ReverseBytesNode(value)); RightShiftNode rightShift = b.append(new RightShiftNode(reverse, b.append(ConstantNode.forInt(16)))); SignExtendNode charCast = b.append(new SignExtendNode(b.append(new NarrowNode(rightShift, 16)), 32)); - b.push(Kind.Short.getStackKind(), b.append(charCast.canonical(null, value))); + b.push(Kind.Short.getStackKind(), b.recursiveAppend(charCast.canonical(null, value))); return true; } }); @@ -207,13 +207,13 @@ Registration r = new Registration(plugins, Float.class); r.register1("floatToRawIntBits", float.class, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode value) { - b.push(Kind.Int, b.append(new ReinterpretNode(Kind.Int, value).canonical(null, value))); + b.push(Kind.Int, b.recursiveAppend(new ReinterpretNode(Kind.Int, value).canonical(null, value))); return true; } }); r.register1("intBitsToFloat", int.class, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode value) { - b.push(Kind.Float, b.append(new ReinterpretNode(Kind.Float, value).canonical(null, value))); + b.push(Kind.Float, b.recursiveAppend(new ReinterpretNode(Kind.Float, value).canonical(null, value))); return true; } }); @@ -223,13 +223,13 @@ Registration r = new Registration(plugins, Double.class); r.register1("doubleToRawLongBits", double.class, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode value) { - b.push(Kind.Long, b.append(new ReinterpretNode(Kind.Long, value).canonical(null, value))); + b.push(Kind.Long, b.recursiveAppend(new ReinterpretNode(Kind.Long, value).canonical(null, value))); return true; } }); r.register1("longBitsToDouble", long.class, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode value) { - b.push(Kind.Double, b.append(new ReinterpretNode(Kind.Double, value).canonical(null, value))); + b.push(Kind.Double, b.recursiveAppend(new ReinterpretNode(Kind.Double, value).canonical(null, value))); return true; } }); @@ -239,32 +239,32 @@ Registration r = new Registration(plugins, Math.class); r.register1("abs", Float.TYPE, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode value) { - b.push(Kind.Float, b.append(new AbsNode(value).canonical(null, value))); + b.push(Kind.Float, b.recursiveAppend(new AbsNode(value).canonical(null, value))); return true; } }); r.register1("abs", Double.TYPE, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode value) { - b.push(Kind.Double, b.append(new AbsNode(value).canonical(null, value))); + b.push(Kind.Double, b.recursiveAppend(new AbsNode(value).canonical(null, value))); return true; } }); r.register1("sqrt", Double.TYPE, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode value) { - b.push(Kind.Double, b.append(new SqrtNode(value).canonical(null, value))); + b.push(Kind.Double, b.recursiveAppend(new SqrtNode(value).canonical(null, value))); return true; } }); if (getAndSetEnabled(arch)) { r.register1("log", Double.TYPE, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode value) { - b.push(Kind.Double, b.append(MathIntrinsicNode.create(value, LOG))); + b.push(Kind.Double, b.recursiveAppend(MathIntrinsicNode.create(value, LOG))); return true; } }); r.register1("log10", Double.TYPE, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode value) { - b.push(Kind.Double, b.append(MathIntrinsicNode.create(value, LOG10))); + b.push(Kind.Double, b.recursiveAppend(MathIntrinsicNode.create(value, LOG10))); return true; } }); @@ -313,25 +313,25 @@ r.register2("belowOrEqual", long.class, long.class, new UnsignedMathPlugin(Condition.BE)); r.register2("divide", int.class, int.class, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode x, ValueNode y) { - b.push(Kind.Int, b.append(new UnsignedDivNode(x, y).canonical(null, x, y))); + b.push(Kind.Int, b.recursiveAppend(new UnsignedDivNode(x, y).canonical(null, x, y))); return true; } }); r.register2("divide", long.class, long.class, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode x, ValueNode y) { - b.push(Kind.Long, b.append(new UnsignedDivNode(x, y).canonical(null, x, y))); + b.push(Kind.Long, b.recursiveAppend(new UnsignedDivNode(x, y).canonical(null, x, y))); return true; } }); r.register2("remainder", int.class, int.class, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode x, ValueNode y) { - b.push(Kind.Int, b.append(new UnsignedRemNode(x, y).canonical(null, x, y))); + b.push(Kind.Int, b.recursiveAppend(new UnsignedRemNode(x, y).canonical(null, x, y))); return true; } }); r.register2("remainder", long.class, long.class, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode x, ValueNode y) { - b.push(Kind.Long, b.append(new UnsignedRemNode(x, y).canonical(null, x, y))); + b.push(Kind.Long, b.recursiveAppend(new UnsignedRemNode(x, y).canonical(null, x, y))); return true; } }); @@ -366,14 +366,14 @@ public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode type, ValueNode object) { ValueNode nullCheckedType = nullCheckedValue(b, type); LogicNode condition = b.append(InstanceOfDynamicNode.create(b.getConstantReflection(), nullCheckedType, object)); - b.push(Kind.Boolean.getStackKind(), b.append(new ConditionalNode(condition).canonical(null))); + b.push(Kind.Boolean.getStackKind(), b.recursiveAppend(new ConditionalNode(condition).canonical(null))); return true; } }); r.register2("isAssignableFrom", Receiver.class, Class.class, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ValueNode type, ValueNode otherType) { - ClassIsAssignableFromNode condition = b.append(new ClassIsAssignableFromNode(nullCheckedValue(b, type), otherType)); - b.push(Kind.Boolean.getStackKind(), b.append(new ConditionalNode(condition).canonical(null))); + ClassIsAssignableFromNode condition = b.recursiveAppend(new ClassIsAssignableFromNode(nullCheckedValue(b, type), otherType)); + b.push(Kind.Boolean.getStackKind(), b.recursiveAppend(new ConditionalNode(condition).canonical(null))); return true; } });