Mercurial > hg > graal-compiler
changeset 14984:a5bebb69dc78
Truffle: instead of redirecting the call method. inlining is now performed by ignoring @SlowPath.
author | Christian Humer <christian.humer@gmail.com> |
---|---|
date | Sat, 05 Apr 2014 03:18:48 +0200 |
parents | a31d807757ee |
children | cceed4ebedb9 |
files | graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTargetImpl.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCacheImpl.java |
diffstat | 6 files changed, 62 insertions(+), 62 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallNode.java Thu Apr 03 19:06:58 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallNode.java Sat Apr 05 03:18:48 2014 +0200 @@ -25,7 +25,7 @@ import java.util.concurrent.atomic.*; import com.oracle.truffle.api.*; -import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; +import com.oracle.truffle.api.CompilerDirectives.*; import com.oracle.truffle.api.frame.*; import com.oracle.truffle.api.impl.*; import com.oracle.truffle.api.nodes.*; @@ -109,17 +109,6 @@ inliningCounter.decrementAndGet(); } - /** - * If the method was inlined the truffle magic redirects calls to - * {@link #call(PackedFrame, Arguments)} to this method. You should not call this method - * directly. - * - * @see PartialEvaluator#expandInlinableCallNode - */ - public Object callInlined(PackedFrame caller, Arguments arguments) { - return getCurrentCallTarget().callInlined(caller, arguments); - } - @Override public void inline() { inliningForced = true;
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java Thu Apr 03 19:06:58 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java Sat Apr 05 03:18:48 2014 +0200 @@ -46,7 +46,7 @@ protected InstalledCode installedCode; protected boolean compilationEnabled; protected int callCount; - private TruffleInliningResult inliningResult; + protected TruffleInliningResult inliningResult; protected final CompilationProfile compilationProfile; protected final CompilationPolicy compilationPolicy; private final SpeculationLog speculationLog = new SpeculationLog(); @@ -64,27 +64,27 @@ } } - public int getKnownCallSiteCount() { + public final int getKnownCallSiteCount() { return callSitesKnown.get(); } - public void incrementKnownCallSite() { + public final void incrementKnownCallSite() { callSitesKnown.incrementAndGet(); } - public void decrementKnownCallSite() { + public final void decrementKnownCallSite() { callSitesKnown.decrementAndGet(); } - public TruffleInliningResult getInliningResult() { + public final TruffleInliningResult getInliningResult() { return inliningResult; } - public OptimizedCallTarget getSplitSource() { + public final OptimizedCallTarget getSplitSource() { return splitSource; } - public void setSplitSource(OptimizedCallTarget splitSource) { + public final void setSplitSource(OptimizedCallTarget splitSource) { this.splitSource = splitSource; } @@ -109,7 +109,7 @@ public abstract InstalledCode compile(); - public Object callInlined(PackedFrame caller, Arguments arguments) { + public final Object callInlined(PackedFrame caller, Arguments arguments) { if (CompilerDirectives.inInterpreter()) { compilationProfile.reportInlinedCall(); } @@ -161,7 +161,7 @@ protected abstract void invalidate(Node oldNode, Node newNode, CharSequence reason); - public Object executeHelper(PackedFrame caller, Arguments args) { + public final Object executeHelper(PackedFrame caller, Arguments args) { VirtualFrame frame = createFrame(getRootNode().getFrameDescriptor(), caller, args); return getRootNode().execute(frame); }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTargetImpl.java Thu Apr 03 19:06:58 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTargetImpl.java Sat Apr 05 03:18:48 2014 +0200 @@ -51,7 +51,7 @@ @CompilerDirectives.SlowPath @Override public Object call(PackedFrame caller, Arguments args) { - return callHelper(caller, args); + return CompilerDirectives.inInterpreter() ? callHelper(caller, args) : executeHelper(caller, args); } private Object callHelper(PackedFrame caller, Arguments args) { @@ -90,6 +90,7 @@ if (m != null) { CompilerAsserts.neverPartOfCompilation(); installedCode = null; + inliningResult = null; compilationProfile.reportInvalidated(); logOptimizedInvalidated(this, oldNode, newNode, reason); }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Thu Apr 03 19:06:58 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Sat Apr 05 03:18:48 2014 +0200 @@ -56,7 +56,6 @@ import com.oracle.graal.truffle.phases.*; import com.oracle.graal.virtual.phases.ea.*; import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; import com.oracle.truffle.api.nodes.*; /** @@ -69,7 +68,6 @@ private Set<Constant> constantReceivers; private final TruffleCache truffleCache; private final ResolvedJavaType frameType; - private final ResolvedJavaMethod callInlinedMethod; public PartialEvaluator(Providers providers, TruffleCache truffleCache) { this.providers = providers; @@ -77,11 +75,6 @@ this.canonicalizer = new CanonicalizerPhase(!ImmutableCode.getValue(), customCanonicalizer); this.truffleCache = truffleCache; this.frameType = providers.getMetaAccess().lookupJavaType(FrameWithoutBoxing.class); - try { - callInlinedMethod = providers.getMetaAccess().lookupJavaMethod(OptimizedCallNode.class.getDeclaredMethod("callInlined", PackedFrame.class, Arguments.class)); - } catch (NoSuchMethodException ex) { - throw new RuntimeException(ex); - } } public StructuredGraph createGraph(final OptimizedCallTarget callTarget, final Assumptions assumptions) { @@ -179,6 +172,7 @@ if (TraceTruffleExpansion.getValue()) { expansionLogger = new TruffleExpansionLogger(graph); } + boolean inliningEnabled = target.getInliningResult() != null && target.getInliningResult().size() > 0; Map<Node, TruffleCallPath> methodTargetToStack = new HashMap<>(); boolean changed; do { @@ -205,18 +199,19 @@ } StructuredGraph inlineGraph = replacements.getMethodSubstitution(methodCallTargetNode.targetMethod()); - - if (inlineGraph == null) { + if (inliningEnabled && inlineGraph == null) { inlineGraph = expandInlinableCallNode(target, methodTargetToStack, assumptions, phaseContext, methodCallTargetNode); } if (inlineGraph == null && !Modifier.isNative(methodCallTargetNode.targetMethod().getModifiers())) { - inlineGraph = parseGraph(methodCallTargetNode.targetMethod(), methodCallTargetNode.arguments(), assumptions, phaseContext); + inlineGraph = parseGraph(methodCallTargetNode.targetMethod(), methodCallTargetNode.arguments(), assumptions, phaseContext, false); } if (inlineGraph != null) { try (Indent indent = Debug.logAndIndent("inline graph %s", methodCallTargetNode.targetMethod())) { - preExpandTruffleCallPath(inlineGraph, methodTargetToStack, methodTargetToStack.get(methodCallTargetNode)); + if (inliningEnabled) { + preExpandTruffleCallPath(inlineGraph, methodTargetToStack, methodTargetToStack.get(methodCallTargetNode)); + } int nodeCountBefore = graph.getNodeCount(); Mark mark = graph.getMark(); if (TraceTruffleExpansion.getValue()) { @@ -228,14 +223,16 @@ if (TraceTruffleExpansion.getValue()) { expansionLogger.postExpand(inlined); } - postExpandTruffleCallPath(methodTargetToStack, inlined); - // } + if (inliningEnabled) { + postExpandTruffleCallPath(methodTargetToStack, inlined); + } if (Debug.isDumpEnabled()) { Debug.log("dump enabled"); int nodeCountAfter = graph.getNodeCount(); Debug.dump(graph, "After inlining %s %+d (%d)", methodCallTargetNode.targetMethod().toString(), nodeCountAfter - nodeCountBefore, nodeCountAfter); } canonicalizer.applyIncremental(graph, phaseContext, invokeUsages, mark); + changed = true; } } @@ -270,49 +267,60 @@ private StructuredGraph expandInlinableCallNode(OptimizedCallTarget target, Map<Node, TruffleCallPath> methodCallToCallPath, Assumptions assumptions, PhaseContext phaseContext, MethodCallTargetNode methodCallTargetNode) { + ValueNode receiverNode = methodCallTargetNode.receiver(); if (receiverNode == null || !receiverNode.isConstant() || !receiverNode.asConstant().getKind().isObject()) { return null; } - Object receiverValue = receiverNode.asConstant().asObject(); - if (!(receiverValue instanceof OptimizedCallNode)) { - return null; - } ResolvedJavaMethod method = methodCallTargetNode.targetMethod(); if (!method.getName().equals("call") || method.getSignature().getParameterCount(false) != 2) { return null; } - assert method.getSignature().equals(callInlinedMethod.getSignature()) : "Signature of original and inlined method must match."; - OptimizedCallNode callNode = (OptimizedCallNode) receiverValue; - TruffleCallPath callPath = methodCallToCallPath.get(methodCallTargetNode); - if (callPath == null) { - callPath = new TruffleCallPath(target); - } - callPath = new TruffleCallPath(callPath, callNode); + Object receiverValue = receiverNode.asConstant().asObject(); + if (receiverValue instanceof OptimizedCallNode) { + OptimizedCallNode callNode = (OptimizedCallNode) receiverValue; + TruffleCallPath callPath = methodCallToCallPath.get(methodCallTargetNode); + if (callPath == null) { + callPath = new TruffleCallPath(target); + } + callPath = new TruffleCallPath(callPath, callNode); + methodCallToCallPath.put(methodCallTargetNode, callPath); + // let the normal expansion do the work + return null; + } else if (receiverValue instanceof OptimizedCallTarget) { + TruffleCallPath path = methodCallToCallPath.get(methodCallTargetNode); + // path unknown. direct call to OptimizedCallTarget without OptimizedCallNode? + if (path == null) { + return null; + } - TruffleInliningResult decision = target.getInliningResult(); - if (decision == null || !decision.isInlined(callPath)) { - // the call target decided not to inline this call - return null; + TruffleInliningResult decision = target.getInliningResult(); + if (decision == null) { // no inlining decision. inlining disabled? + return null; + } + + if (!decision.isInlined(path)) { + // the OptimizedCallTarget has decided not to inline this call path + return null; + } + + // inline truffle call + return parseGraph(methodCallTargetNode.targetMethod(), methodCallTargetNode.arguments(), assumptions, phaseContext, true); } - // inline truffle call -> redirect OptimizedCallNode#ca to OptimizedCallNode#inlinedCall - StructuredGraph graph = parseGraph(callInlinedMethod, methodCallTargetNode.arguments(), assumptions, phaseContext); - - methodCallToCallPath.put(methodCallTargetNode, callPath); - - return graph; + return null; } private boolean isFrame(ValueNode receiver) { return receiver instanceof NewFrameNode || Objects.equals(ObjectStamp.typeOrNull(receiver.stamp()), frameType); } - private StructuredGraph parseGraph(final ResolvedJavaMethod targetMethod, final NodeInputList<ValueNode> arguments, final Assumptions assumptions, final PhaseContext phaseContext) { + private StructuredGraph parseGraph(final ResolvedJavaMethod targetMethod, final NodeInputList<ValueNode> arguments, final Assumptions assumptions, final PhaseContext phaseContext, + boolean ignoreSlowPath) { - StructuredGraph graph = truffleCache.lookup(targetMethod, arguments, assumptions, canonicalizer); + StructuredGraph graph = truffleCache.lookup(targetMethod, arguments, assumptions, canonicalizer, ignoreSlowPath); if (graph != null && targetMethod.getAnnotation(ExplodeLoop.class) != null) { assert graph.hasLoops() : graph + " does not contain a loop";
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java Thu Apr 03 19:06:58 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java Sat Apr 05 03:18:48 2014 +0200 @@ -37,6 +37,7 @@ /** * Returns a cached graph for a method with given arguments. + * @param ignoreSlowPath TODO */ - StructuredGraph lookup(final ResolvedJavaMethod method, final NodeInputList<ValueNode> arguments, final Assumptions assumptions, final CanonicalizerPhase finalCanonicalizer); + StructuredGraph lookup(final ResolvedJavaMethod method, final NodeInputList<ValueNode> arguments, final Assumptions assumptions, final CanonicalizerPhase finalCanonicalizer, boolean ignoreSlowPath); }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCacheImpl.java Thu Apr 03 19:06:58 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCacheImpl.java Sat Apr 05 03:18:48 2014 +0200 @@ -89,9 +89,10 @@ } @SuppressWarnings("unused") - public StructuredGraph lookup(final ResolvedJavaMethod method, final NodeInputList<ValueNode> arguments, final Assumptions assumptions, final CanonicalizerPhase finalCanonicalizer) { + public StructuredGraph lookup(final ResolvedJavaMethod method, final NodeInputList<ValueNode> arguments, final Assumptions assumptions, final CanonicalizerPhase finalCanonicalizer, + boolean ignoreSlowPath) { - if (method.getAnnotation(CompilerDirectives.SlowPath.class) != null) { + if (!ignoreSlowPath && method.getAnnotation(CompilerDirectives.SlowPath.class) != null) { return null; } @@ -236,7 +237,7 @@ private void expandInvoke(MethodCallTargetNode methodCallTargetNode) { StructuredGraph inlineGraph = providers.getReplacements().getMethodSubstitution(methodCallTargetNode.targetMethod()); if (inlineGraph == null) { - inlineGraph = TruffleCacheImpl.this.lookup(methodCallTargetNode.targetMethod(), methodCallTargetNode.arguments(), null, null); + inlineGraph = TruffleCacheImpl.this.lookup(methodCallTargetNode.targetMethod(), methodCallTargetNode.arguments(), null, null, false); } if (inlineGraph == this.markerGraph) { // Can happen for recursive calls.