# HG changeset patch # User Christian Humer # Date 1391024949 -3600 # Node ID 641f22b1c6b85a7e37ec78b1871e29bc6de803fc # Parent 44bcfc983adb4e010f6a1662814756a2e43a84df Truffle: further fixes to the new CallNode. diff -r 44bcfc983adb -r 641f22b1c6b8 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java Wed Jan 29 12:19:03 2014 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java Wed Jan 29 20:49:09 2014 +0100 @@ -56,7 +56,6 @@ super(rootNode); this.compiler = compiler; this.compilationProfile = new CompilationProfile(compilationThreshold, invokeCounter, rootNode.toString()); - this.getRootNode().setCallTarget(this); if (TruffleUseTimeForCompilationDecision.getValue()) { compilationPolicy = new TimedCompilationPolicy(); @@ -261,7 +260,7 @@ } int notInlinedCallSiteCount = TruffleInliningImpl.getInlinableCallSites(callTarget).size(); - int nodeCount = NodeUtil.countNodes(callTarget.getRootNode()); + int nodeCount = NodeUtil.countNodes(callTarget.getRootNode(), null, true); int inlinedCallSiteCount = countInlinedNodes(callTarget.getRootNode()); String comment = callTarget.installedCode == null ? " int" : ""; comment += callTarget.compilationEnabled ? "" : " fail"; @@ -283,6 +282,7 @@ for (CallNode callNode : callers) { if (callNode.isInlined()) { count++; + count += countInlinedNodes(callNode.getInlinedRoot()); } } return count; diff -r 44bcfc983adb -r 641f22b1c6b8 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java Wed Jan 29 12:19:03 2014 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java Wed Jan 29 20:49:09 2014 +0100 @@ -167,7 +167,7 @@ } if (TraceTruffleCompilation.getValue()) { - int nodeCountTruffle = NodeUtil.countNodes(compilable.getRootNode()); + int nodeCountTruffle = NodeUtil.countNodes(compilable.getRootNode(), null, true); byte[] code = compiledMethod.getCode(); OUT.printf("[truffle] optimized %-50s %x |Nodes %7d |Time %5.0f(%4.0f+%-4.0f)ms |Nodes %5d/%5d |CodeSize %d\n", compilable.getRootNode(), compilable.hashCode(), nodeCountTruffle, (timeCompilationFinished - timeCompilationStarted) / 1e6, (timePartialEvaluationFinished - timeCompilationStarted) / 1e6, @@ -193,6 +193,7 @@ OUT.print(" "); } OUT.println(callNode.getCallTarget()); + callNode.getInlinedRoot().accept(this); } } return true; @@ -200,9 +201,11 @@ private int indent(Node n) { if (n instanceof RootNode) { + CallNode inlinedParent = ((RootNode) n).getParentInlinedCall(); + if (inlinedParent != null) { + return indent(inlinedParent) + 1; + } return 0; - } else if (n instanceof CallNode && ((CallNode) n).isInlined()) { - return indent(n.getParent()) + 1; } else { return indent(n.getParent()); } diff -r 44bcfc983adb -r 641f22b1c6b8 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInliningImpl.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInliningImpl.java Wed Jan 29 12:19:03 2014 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInliningImpl.java Wed Jan 29 20:49:09 2014 +0100 @@ -84,9 +84,7 @@ if (inlined) { for (InlinableCallSiteInfo callSite : inlinableCallSites) { - if (callSite.getCallSite().isInlinable() && !callSite.getCallSite().isInlined()) { - CallNode.internalResetCallCount(callSite.getCallSite()); - } + CallNode.internalResetCallCount(callSite.getCallSite()); } } else { if (TraceTruffleInliningDetails.getValue()) { @@ -116,7 +114,7 @@ private final int callerInvocationCount; public InliningPolicy(OptimizedCallTarget caller) { - this.callerNodeCount = NodeUtil.countNodes(caller.getRootNode()); + this.callerNodeCount = NodeUtil.countNodes(caller.getRootNode(), null, true); this.callerInvocationCount = caller.getCompilationProfile().getOriginalInvokeCounter(); } @@ -177,19 +175,18 @@ private int calculateRecursiveDepth() { int depth = 0; - Node parent = ((Node) callSite).getParent(); - while (!(parent instanceof RootNode)) { - assert parent != null; - if (parent instanceof CallNode) { - CallNode parentCall = (CallNode) parent; - if (parentCall.isInlined() && parentCall.getCallTarget() == callSite.getCallTarget()) { + + Node parent = callSite.getParent(); + while (parent != null) { + if (parent instanceof RootNode) { + RootNode root = ((RootNode) parent); + if (root.getCallTarget() == callSite.getCallTarget()) { depth++; } + parent = root.getParentInlinedCall(); + } else { + parent = parent.getParent(); } - parent = parent.getParent(); - } - if (((RootNode) parent).getCallTarget() == callSite.getCallTarget()) { - depth++; } return depth; } @@ -215,8 +212,12 @@ public boolean visit(Node node) { if (node instanceof CallNode) { CallNode callNode = (CallNode) node; - if (callNode.isInlinable() && !callNode.isInlined()) { - inlinableCallSites.add(new InlinableCallSiteInfo(callNode)); + if (!callNode.isInlined()) { + if (callNode.isInlinable()) { + inlinableCallSites.add(new InlinableCallSiteInfo(callNode)); + } + } else { + callNode.getInlinedRoot().accept(this); } } return true; diff -r 44bcfc983adb -r 641f22b1c6b8 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/CallNode.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/CallNode.java Wed Jan 29 12:19:03 2014 +0100 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/CallNode.java Wed Jan 29 20:49:09 2014 +0100 @@ -85,6 +85,16 @@ public abstract boolean inline(); /** + * Returns the inlined root node if the call node was inlined. If the {@link CallNode} was not + * inlined null is returned. + * + * @return the inlined root node returned by {@link RootNode#inline()} + */ + public RootNode getInlinedRoot() { + return null; + } + + /** * Creates a new {@link CallNode} using a {@link CallTarget}. * * @param target the {@link CallTarget} to call @@ -116,7 +126,6 @@ ((InlinableCallNode) callNode).resetCallCount(); return; } - throw new UnsupportedOperationException(); } private static boolean isInlinable(CallTarget callTarget) { @@ -126,6 +135,11 @@ return false; } + @Override + public String toString() { + return getParent() != null ? getParent().toString() : super.toString(); + } + static final class DefaultCallNode extends CallNode { public DefaultCallNode(CallTarget target) { @@ -174,13 +188,14 @@ public boolean inline() { DefaultCallTarget defaultTarget = (DefaultCallTarget) getCallTarget(); RootNode originalRootNode = defaultTarget.getRootNode(); - boolean inlined = false; if (originalRootNode.isInlinable()) { RootNode inlinedRootNode = defaultTarget.getRootNode().inline(); + inlinedRootNode.setCallTarget(callTarget); + inlinedRootNode.setParentInlinedCall(this); replace(new InlinedCallNode(defaultTarget, inlinedRootNode)); - inlined = true; + return true; } - return inlined; + return false; } @Override @@ -225,6 +240,11 @@ } @Override + public RootNode getInlinedRoot() { + return inlinedRoot; + } + + @Override public boolean inline() { return false; } diff -r 44bcfc983adb -r 641f22b1c6b8 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java Wed Jan 29 12:19:03 2014 +0100 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java Wed Jan 29 20:49:09 2014 +0100 @@ -246,7 +246,7 @@ } private void reportReplace() { - RootNode rootNode = getRootNode(); + RootNode rootNode = NodeUtil.findOutermostRootNode(this); if (rootNode != null) { if (rootNode.getCallTarget() instanceof ReplaceObserver) { ((ReplaceObserver) rootNode.getCallTarget()).nodeReplaced(); diff -r 44bcfc983adb -r 641f22b1c6b8 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java Wed Jan 29 12:19:03 2014 +0100 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java Wed Jan 29 20:49:09 2014 +0100 @@ -451,6 +451,31 @@ return null; } + /** + * Returns the outermost not inlined {@link RootNode} which is a parent of this node. + * + * @see RootNode#getParentInlinedCall() + * @param node to search + * @return the outermost {@link RootNode} + */ + public static RootNode findOutermostRootNode(Node node) { + Node parent = node; + while (parent != null) { + if (parent instanceof RootNode) { + RootNode root = (RootNode) parent; + Node next = root.getParentInlinedCall(); + if (next != null) { + parent = next; + } else { + return root; + } + } else { + parent = parent.getParent(); + } + } + return null; + } + public static T findParent(Node start, Class clazz) { Node parent = start.getParent(); if (parent == null) { @@ -571,24 +596,26 @@ } public static int countNodes(Node root) { - return countNodes(root, null); + return countNodes(root, null, false); } - public static int countNodes(Node root, Class clazz) { - NodeCountVisitor nodeCount = new NodeCountVisitor(root, clazz); + public static int countNodes(Node root, Class clazz, boolean countInlinedCallNodes) { + NodeCountVisitor nodeCount = new NodeCountVisitor(root, clazz, countInlinedCallNodes); root.accept(nodeCount); return nodeCount.nodeCount; } private static final class NodeCountVisitor implements NodeVisitor { + private Node root; + private boolean inspectInlinedCalls; int nodeCount; - private final Node root; private final Class clazz; - private NodeCountVisitor(Node root, Class clazz) { + private NodeCountVisitor(Node root, Class clazz, boolean inspectInlinedCalls) { this.root = root; this.clazz = clazz; + this.inspectInlinedCalls = inspectInlinedCalls; } @Override @@ -596,9 +623,18 @@ if (node instanceof RootNode && node != root) { return false; } + if (clazz == null || clazz.isInstance(node)) { nodeCount++; } + + if (inspectInlinedCalls && node instanceof CallNode) { + CallNode call = (CallNode) node; + if (call.isInlined()) { + call.getInlinedRoot().getChildren().iterator().next().accept(this); + } + } + return true; } } diff -r 44bcfc983adb -r 641f22b1c6b8 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/RootNode.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/RootNode.java Wed Jan 29 12:19:03 2014 +0100 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/RootNode.java Wed Jan 29 20:49:09 2014 +0100 @@ -25,6 +25,7 @@ package com.oracle.truffle.api.nodes; import com.oracle.truffle.api.*; +import com.oracle.truffle.api.CompilerDirectives.*; import com.oracle.truffle.api.frame.*; /** @@ -37,6 +38,12 @@ private CallTarget callTarget; private final FrameDescriptor frameDescriptor; + /* + * Internal field to keep reference to the inlined call node. The inlined parent should not be + * the same as the Node parent to keep the same tree hierarchy if inlined vs not inlined. + */ + @CompilationFinal private CallNode parentInlinedCall; + protected RootNode() { this(null, null); } @@ -125,4 +132,20 @@ public void setCallTarget(CallTarget callTarget) { this.callTarget = callTarget; } + + /* Internal API. Do not use. */ + void setParentInlinedCall(CallNode inlinedParent) { + this.parentInlinedCall = inlinedParent; + } + + /** + * Returns the {@link CallNode} that uses this {@link RootNode} for an inlined call. Returns + * null if this {@link RootNode} is not inlined into a caller. This method can be + * used to also traverse parent {@link CallTarget} that have been inlined into this call. + * + * @return the responsible {@link CallNode} for inlining. + */ + public final CallNode getParentInlinedCall() { + return parentInlinedCall; + } }