# HG changeset patch # User Thomas Wuerthinger # Date 1421940276 -3600 # Node ID fede93375dcb9359e113d4b316b706eeb938d9fa # Parent 13e43d2a413e20d53794a6590d5557d9bc38345f Initial version of inlining during parsing. diff -r 13e43d2a413e -r fede93375dcb graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java --- 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); } diff -r 13e43d2a413e -r fede93375dcb graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXWrapperBuilder.java --- 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); diff -r 13e43d2a413e -r fede93375dcb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java --- 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 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); diff -r 13e43d2a413e -r fede93375dcb graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractFrameStateBuilder.java --- 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; diff -r 13e43d2a413e -r fede93375dcb graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java --- 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(); diff -r 13e43d2a413e -r fede93375dcb graal/com.oracle.graal.java/src/com/oracle/graal/java/HIRFrameStateBuilder.java --- 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 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 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 diff -r 13e43d2a413e -r fede93375dcb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java --- 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 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. emptyList()); + public FrameState(FrameState outerFrameState, ResolvedJavaMethod method, int bci, ValueNode[] locals, List 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. emptyList()); } private static List createValues(ValueNode[] locals, List stack, ValueNode[] locks) {