diff graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/CallNode.java @ 13983:f46cab39a9a2

Truffle: Updated inlining API. Pushed inlining implementation to the Truffle runtime.
author Christian Humer <christian.humer@gmail.com>
date Thu, 20 Feb 2014 01:21:49 +0100
parents e86d32f4803f
children c5411233cdf8
line wrap: on
line diff
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/CallNode.java	Wed Feb 19 00:39:44 2014 -0800
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/CallNode.java	Thu Feb 20 01:21:49 2014 +0100
@@ -26,12 +26,13 @@
 
 import com.oracle.truffle.api.*;
 import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.impl.*;
 
 /**
  * This node represents a call to a static {@link CallTarget}. This node should be used whenever a
  * {@link CallTarget} is considered constant at a certain location in the tree. This enables the
- * Truffle runtime to perform inlining or other optimizations for this call-site.
+ * Truffle runtime to perform inlining or other optimizations for this call-site. This class is
+ * intended to be implemented by truffle runtime implementors and not by guest languague
+ * implementors.
  * 
  * @see #create(CallTarget) to create a CallNode instance.
  */
@@ -39,7 +40,7 @@
 
     protected final CallTarget callTarget;
 
-    private CallNode(CallTarget callTarget) {
+    protected CallNode(CallTarget callTarget) {
         this.callTarget = callTarget;
     }
 
@@ -59,12 +60,6 @@
      */
     public abstract Object call(PackedFrame caller, Arguments arguments);
 
-    /**
-     * Returns <code>true</code> if the {@link CallTarget} contained in this {@link CallNode} can be
-     * inlined. A {@link CallTarget} is considered inlinable if it was created using
-     * {@link TruffleRuntime#createCallTarget(RootNode)} and if the enclosed {@link RootNode}
-     * returns <code>true</code> for {@link RootNode#isInlinable()}.
-     */
     public abstract boolean isInlinable();
 
     /**
@@ -72,209 +67,30 @@
      */
     public abstract boolean isInlined();
 
-    /**
-     * Enforces an inlining optimization on this {@link CallNode} instance. If not performed
-     * manually the Truffle runtime may perform inlining using an heuristic to optimize the
-     * performance of the execution. It is recommended to implement an version of
-     * {@link RootNode#inline()} that adapts the inlining for possible guest language specific
-     * behavior. If the this {@link CallNode} is not inlinable or is already inlined
-     * <code>false</code> is returned.
-     * 
-     * @return <code>true</code> if the inlining operation was successful.
-     */
-    public abstract boolean inline();
+    public abstract void inline();
+
+    public abstract boolean isSplittable();
 
-    /**
-     * Returns the inlined root node if the call node was inlined. If the {@link CallNode} was not
-     * inlined <code>null</code> is returned.
-     * 
-     * @return the inlined root node returned by {@link RootNode#inline()}
-     */
-    public RootNode getInlinedRoot() {
-        return null;
-    }
+    public abstract boolean split();
+
+    public abstract CallTarget getSplitCallTarget();
+
+    public abstract RootNode getInlinedRoot();
 
     /**
      * Creates a new {@link CallNode} using a {@link CallTarget}.
      * 
      * @param target the {@link CallTarget} to call
      * @return a call node that calls the provided target
-     */
-    public static CallNode create(CallTarget target) {
-        if (isInlinable(target)) {
-            return new InlinableCallNode((RootCallTarget) target);
-        } else {
-            return new DefaultCallNode(target);
-        }
-    }
-
-    /**
-     * Warning: this is internal API and may change without notice.
-     */
-    public interface CompilerCallView {
-
-        int getCallCount();
-
-        void resetCallCount();
-
-        void store(Object value);
-
-        Object load();
-    }
-
-    /**
-     * Warning: this is internal API and may change without notice.
+     * @deprecated use {@link TruffleRuntime#createCallNode(CallTarget)} instead
      */
-    public CompilerCallView getCompilerCallView() {
-        return null;
-    }
-
-    private static boolean isInlinable(CallTarget callTarget) {
-        if (callTarget instanceof RootCallTarget) {
-            return (((RootCallTarget) callTarget).getRootNode()).isInlinable();
-        }
-        return false;
-    }
-
-    @Override
-    public String toString() {
-        return getParent() != null ? getParent().toString() : super.toString();
-    }
-
-    static final class DefaultCallNode extends CallNode {
-
-        public DefaultCallNode(CallTarget target) {
-            super(target);
-        }
-
-        @Override
-        public Object call(PackedFrame caller, Arguments arguments) {
-            return callTarget.call(caller, arguments);
-        }
-
-        @Override
-        public boolean inline() {
-            return false;
-        }
-
-        @Override
-        public boolean isInlinable() {
-            return false;
-        }
-
-        @Override
-        public boolean isInlined() {
-            return false;
-        }
-
+    @Deprecated
+    public static CallNode create(CallTarget target) {
+        return Truffle.getRuntime().createCallNode(target);
     }
 
-    static final class InlinableCallNode extends CallNode implements CompilerCallView {
-
-        private int callCount;
-
-        public InlinableCallNode(RootCallTarget target) {
-            super(target);
-        }
-
-        @Override
-        public Object call(PackedFrame parentFrame, Arguments arguments) {
-            if (CompilerDirectives.inInterpreter()) {
-                callCount++;
-            }
-            return callTarget.call(parentFrame, arguments);
-        }
-
-        @Override
-        public boolean inline() {
-            DefaultCallTarget defaultTarget = (DefaultCallTarget) getCallTarget();
-            RootNode originalRootNode = defaultTarget.getRootNode();
-            if (originalRootNode.isInlinable()) {
-                RootNode inlinedRootNode = defaultTarget.getRootNode().inline();
-                inlinedRootNode.setCallTarget(callTarget);
-                inlinedRootNode.setParentInlinedCall(this);
-                replace(new InlinedCallNode(defaultTarget, inlinedRootNode));
-                return true;
-            }
-            return false;
-        }
-
-        @Override
-        public boolean isInlined() {
-            return false;
-        }
-
-        @Override
-        public boolean isInlinable() {
-            return true;
-        }
-
-        @Override
-        public CompilerCallView getCompilerCallView() {
-            return this;
-        }
-
-        /* Truffle internal API. */
-        public int getCallCount() {
-            return callCount;
-        }
-
-        /* Truffle internal API. */
-        public void resetCallCount() {
-            callCount = 0;
-        }
-
-        private Object storedCompilerInfo;
-
-        public void store(Object value) {
-            this.storedCompilerInfo = value;
-        }
-
-        public Object load() {
-            return storedCompilerInfo;
-        }
-
-    }
-
-    static final class InlinedCallNode extends CallNode {
-
-        private final RootNode inlinedRoot;
-
-        public InlinedCallNode(DefaultCallTarget callTarget, RootNode inlinedRoot) {
-            super(callTarget);
-            this.inlinedRoot = inlinedRoot;
-        }
-
-        @Override
-        public Object call(PackedFrame caller, Arguments arguments) {
-            return inlinedRoot.execute(Truffle.getRuntime().createVirtualFrame(caller, arguments, inlinedRoot.getFrameDescriptor()));
-        }
-
-        @Override
-        public InlinedCallNode copy() {
-            return new InlinedCallNode((DefaultCallTarget) getCallTarget(), NodeUtil.cloneNode(inlinedRoot));
-        }
-
-        @Override
-        public RootNode getInlinedRoot() {
-            return inlinedRoot;
-        }
-
-        @Override
-        public boolean inline() {
-            return false;
-        }
-
-        @Override
-        public boolean isInlinable() {
-            return true;
-        }
-
-        @Override
-        public boolean isInlined() {
-            return true;
-        }
-
+    protected final void installParentInlinedCall() {
+        getInlinedRoot().addParentInlinedCall(this);
     }
 
 }