# HG changeset patch # User Christian Wimmer # Date 1347657693 25200 # Node ID e5768e9361478592890341b3ba488a348d8d84e2 # Parent 46d426e79bed44301e10cceb87ad9014865d594e Allow snippets to inherit the stateAfter and stamp from the replacee diff -r 46d426e79bed -r e5768e936147 graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetIntrinsificationPhase.java --- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetIntrinsificationPhase.java Fri Sep 14 14:14:01 2012 -0700 +++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetIntrinsificationPhase.java Fri Sep 14 14:21:33 2012 -0700 @@ -33,6 +33,7 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.java.*; +import com.oracle.graal.nodes.type.*; import com.oracle.graal.nodes.util.*; import com.oracle.graal.snippets.Snippet.Fold; @@ -334,7 +335,7 @@ } public void cleanUpReturnCheckCast(Node newInstance) { - if (newInstance instanceof ValueNode && ((ValueNode) newInstance).kind() != Kind.Object) { + if (newInstance instanceof ValueNode && (((ValueNode) newInstance).kind() != Kind.Object || ((ValueNode) newInstance).stamp() == StampFactory.forNodeIntrinsic())) { StructuredGraph graph = (StructuredGraph) newInstance.graph(); for (CheckCastNode checkCastNode : newInstance.usages().filter(CheckCastNode.class).snapshot()) { for (ValueProxyNode vpn : checkCastNode.usages().filter(ValueProxyNode.class).snapshot()) { @@ -363,6 +364,8 @@ checkCastCallTarget.safeDelete(); } else if (checkCastUsage instanceof FrameState) { checkCastUsage.replaceFirstInput(checkCastNode, null); + } else if (checkCastUsage instanceof ReturnNode && checkCastNode.object().stamp() == StampFactory.forNodeIntrinsic()) { + checkCastUsage.replaceFirstInput(checkCastNode, checkCastNode.object()); } else { assert false : sourceLocation(checkCastUsage) + " has unexpected usage " + checkCastUsage + " of checkcast at " + sourceLocation(checkCastNode); } diff -r 46d426e79bed -r e5768e936147 graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetTemplate.java --- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetTemplate.java Fri Sep 14 14:14:01 2012 -0700 +++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetTemplate.java Fri Sep 14 14:21:33 2012 -0700 @@ -33,7 +33,6 @@ import com.oracle.graal.compiler.phases.*; import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; -import com.oracle.graal.graph.Node.Verbosity; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.extended.*; @@ -327,11 +326,20 @@ // Remove all frame states from inlined snippet graph. Snippets must be atomic (i.e. free // of side-effects that prevent deoptimizing to a point before the snippet). + Node curSideEffectNode = null; + Node curStampNode = null; for (Node node : snippetCopy.getNodes()) { + if (node instanceof ValueNode && ((ValueNode) node).stamp() == StampFactory.forNodeIntrinsic()) { + assert curStampNode == null : "Currently limited to stamp node (but this can be converted to a List if necessary)"; + curStampNode = node; + } if (node instanceof StateSplit) { StateSplit stateSplit = (StateSplit) node; FrameState frameState = stateSplit.stateAfter(); - assert !stateSplit.hasSideEffect() : "snippets cannot contain side-effecting node " + node + "\n " + frameState.toString(Verbosity.Debugger); + if (stateSplit.hasSideEffect()) { + assert curSideEffectNode == null : "Currently limited to one side-effecting node (but this can be converted to a List if necessary)"; + curSideEffectNode = node; + } if (frameState != null) { stateSplit.setStateAfter(null); } @@ -386,6 +394,8 @@ } } + this.sideEffectNode = curSideEffectNode; + this.stampNode = curStampNode; this.returnNode = retNode; } @@ -436,6 +446,16 @@ private final ReturnNode returnNode; /** + * Node that inherits the {@link StateSplit#stateAfter()} from the replacee during instantiation. + */ + private final Node sideEffectNode; + + /** + * Node that inherits the {@link ValueNode#stamp()} from the replacee during instantiation. + */ + private final Node stampNode; + + /** * The nodes to be inlined when this specialization is instantiated. */ private final ArrayList nodes; @@ -514,6 +534,16 @@ FixedNode next = replacee.next(); replacee.setNext(null); + if (sideEffectNode != null) { + assert ((StateSplit) replacee).hasSideEffect(); + Node sideEffectDup = duplicates.get(sideEffectNode); + ((StateSplit) sideEffectDup).setStateAfter(((StateSplit) replacee).stateAfter()); + } + if (stampNode != null) { + Node stampDup = duplicates.get(stampNode); + ((ValueNode) stampDup).setStamp(((ValueNode) replacee).stamp()); + } + // Replace all usages of the replacee with the value returned by the snippet Node returnValue = null; if (returnNode != null) { @@ -567,6 +597,16 @@ FixedNode firstCFGNodeDuplicate = (FixedNode) duplicates.get(firstCFGNode); replaceeGraph.addAfterFixed(lastFixedNode, firstCFGNodeDuplicate); + if (sideEffectNode != null) { + assert ((StateSplit) replacee).hasSideEffect(); + Node sideEffectDup = duplicates.get(sideEffectNode); + ((StateSplit) sideEffectDup).setStateAfter(((StateSplit) replacee).stateAfter()); + } + if (stampNode != null) { + Node stampDup = duplicates.get(stampNode); + ((ValueNode) stampDup).setStamp(((ValueNode) replacee).stamp()); + } + // Replace all usages of the replacee with the value returned by the snippet assert returnNode != null : replaceeGraph; Node returnValue = null; @@ -618,6 +658,8 @@ controlSplitNode.replaceAtPredecessor(firstCFGNodeDuplicate); controlSplitNode.replaceAtUsages(null); + assert sideEffectNode == null; + assert stampNode == null; assert returnNode == null : replaceeGraph; GraphUtil.killCFG(controlSplitNode);