changeset 18922:fede93375dcb

Initial version of inlining during parsing.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Thu, 22 Jan 2015 16:24:36 +0100
parents 13e43d2a413e
children 837d2b18a171
files graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXWrapperBuilder.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractFrameStateBuilder.java graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java graal/com.oracle.graal.java/src/com/oracle/graal/java/HIRFrameStateBuilder.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java
diffstat 7 files changed, 122 insertions(+), 32 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java	Wed Jan 21 14:29:00 2015 +0100
+++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java	Thu Jan 22 16:24:36 2015 +0100
@@ -1153,7 +1153,7 @@
             locks[i] = lirValueToHirNode.apply(lockValue);
             monitorIds[i] = getMonitorIdForHotSpotMonitorValueFromFrame(lockValue, hsailFrame, hostGraph);
         }
-        FrameState frameState = hostGraph.add(new FrameState(lowLevelFrame.getMethod(), lowLevelFrame.getBCI(), locals, stack, locks, monitorIds, lowLevelFrame.rethrowException, false));
+        FrameState frameState = hostGraph.add(new FrameState(null, lowLevelFrame.getMethod(), lowLevelFrame.getBCI(), locals, stack, locks, monitorIds, lowLevelFrame.rethrowException, false));
         if (outterFrameState != null) {
             frameState.setOuterFrameState(outterFrameState);
         }
--- a/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXWrapperBuilder.java	Wed Jan 21 14:29:00 2015 +0100
+++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXWrapperBuilder.java	Thu Jan 22 16:24:36 2015 +0100
@@ -242,7 +242,7 @@
             append(new WriteNode(buf, nullWord, location, BarrierType.NONE, false));
         }
 
-        HIRFrameStateBuilder fsb = new HIRFrameStateBuilder(method, getGraph());
+        HIRFrameStateBuilder fsb = new HIRFrameStateBuilder(method, getGraph(), null);
         fsb.initializeForMethodStart(true);
         FrameState fs = fsb.create(0);
         getGraph().start().setStateAfter(fs);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java	Wed Jan 21 14:29:00 2015 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java	Thu Jan 22 16:24:36 2015 +0100
@@ -512,7 +512,7 @@
                         callTarget = graph.add(new MethodCallTargetNode(InvokeKind.Static, checkCounter.getMethod(), new ValueNode[]{errMsg}, returnType));
                         invoke = graph.add(new InvokeNode(callTarget, 0));
                         List<ValueNode> stack = Collections.emptyList();
-                        FrameState stateAfter = new FrameState(graph.method(), BytecodeFrame.AFTER_BCI, new ValueNode[0], stack, new ValueNode[0], new MonitorIdNode[0], false, false);
+                        FrameState stateAfter = new FrameState(null, graph.method(), BytecodeFrame.AFTER_BCI, new ValueNode[0], stack, new ValueNode[0], new MonitorIdNode[0], false, false);
                         invoke.setStateAfter(graph.add(stateAfter));
                         graph.addBeforeFixed(ret, invoke);
 
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractFrameStateBuilder.java	Wed Jan 21 14:29:00 2015 +0100
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractFrameStateBuilder.java	Thu Jan 22 16:24:36 2015 +0100
@@ -171,6 +171,7 @@
      */
     public T loadLocal(int i) {
         T x = locals[i];
+        assert x != null : i;
         assert x.getKind().getSlotCount() == 1 || locals[i + 1] == null;
         assert i == 0 || locals[i - 1] == null || locals[i - 1].getKind().getSlotCount() == 1;
         return x;
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Wed Jan 21 14:29:00 2015 +0100
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Thu Jan 22 16:24:36 2015 +0100
@@ -104,12 +104,22 @@
             int entryBCI = graph.getEntryBCI();
             assert method.getCode() != null : "method must contain bytecodes: " + method;
             this.currentGraph = graph;
-            HIRFrameStateBuilder frameState = new HIRFrameStateBuilder(method, graph);
+            HIRFrameStateBuilder frameState = new HIRFrameStateBuilder(method, graph, null);
             frameState.initializeForMethodStart(graphBuilderConfig.eagerResolving());
             TTY.Filter filter = new TTY.Filter(PrintFilter.getValue(), method);
             try {
                 BytecodeParser parser = new BytecodeParser(metaAccess, method, graphBuilderConfig, optimisticOpts, entryBCI);
                 parser.build(0, graph.start(), frameState);
+
+                parser.connectLoopEndToBegin();
+
+                // remove dead parameters
+                for (ParameterNode param : currentGraph.getNodes(ParameterNode.class)) {
+                    if (param.usages().isEmpty()) {
+                        assert param.inputs().isEmpty();
+                        param.safeDelete();
+                    }
+                }
             } finally {
                 filter.remove();
             }
@@ -146,6 +156,11 @@
 
             private ValueNode methodSynchronizedObject;
             private ExceptionDispatchBlock unwindBlock;
+            private BciBlock returnBlock;
+            private ValueNode returnValue;
+            private FixedWithNextNode beforeReturnNode;
+            private ValueNode unwindValue;
+            private FixedWithNextNode beforeUnwindNode;
 
             private FixedWithNextNode lastInstr;                 // the last instruction added
 
@@ -159,6 +174,22 @@
                 }
             }
 
+            public ValueNode getReturnValue() {
+                return returnValue;
+            }
+
+            public FixedWithNextNode getBeforeReturnNode() {
+                return this.beforeReturnNode;
+            }
+
+            public ValueNode getUnwindValue() {
+                return unwindValue;
+            }
+
+            public FixedWithNextNode getBeforeUnwindNode() {
+                return this.beforeUnwindNode;
+            }
+
             protected void build(int depth, FixedWithNextNode startInstruction, HIRFrameStateBuilder startFrameState) {
                 this.currentDepth = depth;
                 if (PrintProfilingInformation.getValue()) {
@@ -190,7 +221,10 @@
                     if (method.isSynchronized()) {
                         // add a monitor enter to the start block
                         methodSynchronizedObject = synchronizedObject(frameState, method);
-                        genMonitorEnter(methodSynchronizedObject);
+                        MonitorEnterNode monitorEnter = genMonitorEnter(methodSynchronizedObject);
+                        frameState.clearNonLiveLocals(blockMap.startBlock, liveness, true);
+                        assert bci() == 0;
+                        monitorEnter.setStateAfter(frameState.create(bci()));
                     }
 
                     if (graphBuilderConfig.insertNonSafepointDebugInfo()) {
@@ -208,20 +242,22 @@
                     for (BciBlock block : blockMap.getBlocks()) {
                         processBlock(this, block);
                     }
+                    processBlock(this, returnBlock);
                     processBlock(this, unwindBlock);
 
                     Debug.dump(currentGraph, "After bytecode parsing");
 
-                    connectLoopEndToBegin();
+                }
+            }
 
-                    // remove dead parameters
-                    for (ParameterNode param : currentGraph.getNodes(ParameterNode.class)) {
-                        if (param.usages().isEmpty()) {
-                            assert param.inputs().isEmpty();
-                            param.safeDelete();
-                        }
-                    }
+            private BciBlock returnBlock(int bci) {
+                if (returnBlock == null) {
+                    returnBlock = new BciBlock();
+                    returnBlock.startBci = bci;
+                    returnBlock.endBci = bci;
+                    returnBlock.setId(Integer.MAX_VALUE);
                 }
+                return returnBlock;
             }
 
             private BciBlock unwindBlock() {
@@ -368,8 +404,8 @@
                     dispatchBegin.setStateAfter(dispatchState.create(bci));
                     dispatchState.setRethrowException(true);
                 }
+                FixedNode target = createTarget(dispatchBlock, dispatchState);
                 FixedWithNextNode finishedDispatch = finishInstruction(dispatchBegin, dispatchState);
-                FixedNode target = createTarget(dispatchBlock, dispatchState);
                 finishedDispatch.setNext(target);
                 return dispatchBegin;
             }
@@ -720,11 +756,33 @@
                     if (targetMethod.getCode().length <= GraalOptions.TrivialInliningSize.getValue() && currentDepth < GraalOptions.InlineDuringParsingMaxDepth.getValue() &&
                                     graphBuilderConfig.shouldInlineTrivial()) {
                         BytecodeParser parser = new BytecodeParser(metaAccess, targetMethod, graphBuilderConfig, optimisticOpts, StructuredGraph.INVOCATION_ENTRY_BCI);
-                        HIRFrameStateBuilder startFrameState = new HIRFrameStateBuilder(targetMethod, currentGraph);
-                        System.out.println(args + ", " + args.length + ", " + targetMethod);
+                        final FrameState[] lazyFrameState = new FrameState[1];
+                        HIRFrameStateBuilder startFrameState = new HIRFrameStateBuilder(targetMethod, currentGraph, () -> {
+                            if (lazyFrameState[0] == null) {
+                                lazyFrameState[0] = frameState.create(bci());
+                            }
+                            return lazyFrameState[0];
+                        });
                         startFrameState.initializeFromArgumentsArray(args);
-                        System.out.println("try inline trivial: " + targetMethod);
                         parser.build(currentDepth + 1, this.lastInstr, startFrameState);
+
+                        FixedWithNextNode calleeBeforeReturnNode = parser.getBeforeReturnNode();
+                        this.lastInstr = calleeBeforeReturnNode;
+                        if (calleeBeforeReturnNode != null) {
+                            ValueNode calleeReturnValue = parser.getReturnValue();
+                            if (calleeReturnValue != null) {
+                                frameState.push(calleeReturnValue.getKind().getStackKind(), calleeReturnValue);
+                            }
+                        }
+
+                        FixedWithNextNode calleeBeforeUnwindNode = parser.getBeforeUnwindNode();
+                        if (calleeBeforeUnwindNode != null) {
+                            ValueNode calleeUnwindValue = parser.getUnwindValue();
+                            assert calleeUnwindValue != null;
+                            calleeBeforeUnwindNode.setNext(handleException(calleeUnwindValue, bci()));
+                        }
+
+                        return;
                     }
                 }
 
@@ -764,6 +822,19 @@
             protected void genReturn(ValueNode x) {
                 frameState.setRethrowException(false);
                 frameState.clearStack();
+
+                if (this.currentDepth == 0) {
+                    beforeReturn(x);
+                    append(new ReturnNode(x));
+                } else {
+                    if (x != null) {
+                        frameState.push(x.getKind(), x);
+                    }
+                    appendGoto(createTarget(returnBlock(bci()), frameState));
+                }
+            }
+
+            private void beforeReturn(ValueNode x) {
                 if (graphBuilderConfig.insertNonSafepointDebugInfo()) {
                     append(createInfoPointNode(InfopointReason.METHOD_END));
                 }
@@ -772,8 +843,6 @@
                 if (frameState.lockDepth() != 0) {
                     throw new BailoutException("unbalanced monitors");
                 }
-
-                append(new ReturnNode(x));
             }
 
             @Override
@@ -785,13 +854,13 @@
             }
 
             @Override
-            protected MonitorExitNode genMonitorExit(ValueNode x, ValueNode returnValue) {
+            protected MonitorExitNode genMonitorExit(ValueNode x, ValueNode escapedReturnValue) {
                 MonitorIdNode monitorId = frameState.peekMonitorId();
                 ValueNode lockedObject = frameState.popLock();
                 if (GraphUtil.originalValue(lockedObject) != GraphUtil.originalValue(x)) {
                     throw new BailoutException("unbalanced monitors: mismatch at monitorexit, %s != %s", GraphUtil.originalValue(x), GraphUtil.originalValue(lockedObject));
                 }
-                MonitorExitNode monitorExit = append(new MonitorExitNode(x, monitorId, returnValue));
+                MonitorExitNode monitorExit = append(new MonitorExitNode(x, monitorId, escapedReturnValue));
                 return monitorExit;
             }
 
@@ -1090,9 +1159,22 @@
                         ((MergeNode) lastInstr).setStateAfter(frameState.create(bci));
                     }
 
-                    if (block == unwindBlock) {
-                        frameState.setRethrowException(false);
-                        createUnwind();
+                    if (block == returnBlock) {
+                        Kind returnKind = method.getSignature().getReturnKind().getStackKind();
+                        ValueNode x = returnKind == Kind.Void ? null : frameState.pop(returnKind);
+                        assert frameState.stackSize() == 0;
+                        beforeReturn(x);
+                        this.returnValue = x;
+                        this.beforeReturnNode = this.lastInstr;
+                    } else if (block == unwindBlock) {
+                        if (currentDepth == 0) {
+                            frameState.setRethrowException(false);
+                            createUnwind();
+                        } else {
+                            ValueNode exception = frameState.apop();
+                            this.unwindValue = exception;
+                            this.beforeUnwindNode = this.lastInstr;
+                        }
                     } else if (block instanceof ExceptionDispatchBlock) {
                         createExceptionDispatch((ExceptionDispatchBlock) block);
                     } else {
@@ -1133,11 +1215,11 @@
                 append(new UnwindNode(exception));
             }
 
-            private void synchronizedEpilogue(int bci, ValueNode returnValue) {
+            private void synchronizedEpilogue(int bci, ValueNode currentReturnValue) {
                 if (method.isSynchronized()) {
-                    MonitorExitNode monitorExit = genMonitorExit(methodSynchronizedObject, returnValue);
-                    if (returnValue != null) {
-                        frameState.push(returnValue.getKind(), returnValue);
+                    MonitorExitNode monitorExit = genMonitorExit(methodSynchronizedObject, currentReturnValue);
+                    if (currentReturnValue != null) {
+                        frameState.push(currentReturnValue.getKind(), currentReturnValue);
                     }
                     monitorExit.setStateAfter(frameState.create(bci));
                     assert !frameState.rethrowException();
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/HIRFrameStateBuilder.java	Wed Jan 21 14:29:00 2015 +0100
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/HIRFrameStateBuilder.java	Thu Jan 22 16:24:36 2015 +0100
@@ -25,6 +25,7 @@
 import static com.oracle.graal.graph.iterators.NodePredicates.*;
 
 import java.util.*;
+import java.util.function.*;
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
@@ -43,6 +44,7 @@
 
     private MonitorIdNode[] monitorIds;
     private final StructuredGraph graph;
+    private final Supplier<FrameState> outerFrameStateSupplier;
 
     /**
      * Creates a new frame state builder for the given method and the given target graph.
@@ -50,13 +52,14 @@
      * @param method the method whose frame is simulated
      * @param graph the target graph of Graal nodes created by the builder
      */
-    public HIRFrameStateBuilder(ResolvedJavaMethod method, StructuredGraph graph) {
+    public HIRFrameStateBuilder(ResolvedJavaMethod method, StructuredGraph graph, Supplier<FrameState> outerFrameStateSupplier) {
         super(method);
 
         assert graph != null;
 
         this.monitorIds = EMPTY_MONITOR_ARRAY;
         this.graph = graph;
+        this.outerFrameStateSupplier = outerFrameStateSupplier;
     }
 
     public final void initializeFromArgumentsArray(ValueNode[] arguments) {
@@ -116,6 +119,7 @@
         assert other.graph != null;
         graph = other.graph;
         monitorIds = other.monitorIds.length == 0 ? other.monitorIds : other.monitorIds.clone();
+        this.outerFrameStateSupplier = other.outerFrameStateSupplier;
 
         assert locals.length == method.getMaxLocals();
         assert stack.length == Math.max(1, method.getMaxStackSize());
@@ -151,7 +155,8 @@
     }
 
     public FrameState create(int bci) {
-        return graph.add(new FrameState(method, bci, locals, Arrays.asList(stack).subList(0, stackSize), lockedObjects, monitorIds, rethrowException, false));
+        return graph.add(new FrameState(this.outerFrameStateSupplier == null ? null : outerFrameStateSupplier.get(), method, bci, locals, Arrays.asList(stack).subList(0, stackSize), lockedObjects,
+                        monitorIds, rethrowException, false));
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java	Wed Jan 21 14:29:00 2015 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java	Thu Jan 22 16:24:36 2015 +0100
@@ -98,8 +98,10 @@
                         bci == BytecodeFrame.INVALID_FRAMESTATE_BCI;
     }
 
-    public FrameState(ResolvedJavaMethod method, int bci, ValueNode[] locals, List<ValueNode> stack, ValueNode[] locks, MonitorIdNode[] monitorIds, boolean rethrowException, boolean duringCall) {
-        this(null, method, bci, createValues(locals, stack, locks), locals.length, stack.size(), rethrowException, duringCall, Arrays.asList(monitorIds), Collections.<EscapeObjectState> emptyList());
+    public FrameState(FrameState outerFrameState, ResolvedJavaMethod method, int bci, ValueNode[] locals, List<ValueNode> stack, ValueNode[] locks, MonitorIdNode[] monitorIds,
+                    boolean rethrowException, boolean duringCall) {
+        this(outerFrameState, method, bci, createValues(locals, stack, locks), locals.length, stack.size(), rethrowException, duringCall, Arrays.asList(monitorIds),
+                        Collections.<EscapeObjectState> emptyList());
     }
 
     private static List<ValueNode> createValues(ValueNode[] locals, List<ValueNode> stack, ValueNode[] locks) {