Mercurial > hg > graal-compiler
changeset 20054:c816aca2a3db
Remove old version of partial evaluation.
author | Thomas Wuerthinger <thomas.wuerthinger@oracle.com> |
---|---|
date | Sat, 28 Mar 2015 17:35:14 +0100 |
parents | eea134855f85 |
children | 4042339df317 |
files | graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/ConditionAnchoringTest.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 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java |
diffstat | 7 files changed, 7 insertions(+), 790 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java Fri Mar 27 17:02:53 2015 +0100 +++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java Sat Mar 28 17:35:14 2015 +0100 @@ -83,7 +83,6 @@ private HotSpotTruffleRuntime() { installOptimizedCallTargetCallMethod(); - installOptimizedCallTargetCallDirect(); lookupCallMethods(getGraalProviders().getMetaAccess()); installDefaultListeners(); @@ -115,12 +114,6 @@ } - private static void installOptimizedCallTargetCallDirect() { - if (TruffleCompilerOptions.TruffleFunctionInlining.getValue() && !TruffleCompilerOptions.FastPE.getValue()) { - ((HotSpotResolvedJavaMethod) getGraalProviders().getMetaAccess().lookupJavaMethod(OptimizedCallTarget.getCallDirectMethod())).setNotInlineable(); - } - } - @Override public String getName() { return "Graal Truffle Runtime";
--- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/ConditionAnchoringTest.java Fri Mar 27 17:02:53 2015 +0100 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/ConditionAnchoringTest.java Sat Mar 28 17:35:14 2015 +0100 @@ -22,8 +22,6 @@ */ package com.oracle.graal.truffle.test; -import static com.oracle.graal.graph.test.matchers.NodeIterableCount.*; -import static com.oracle.graal.graph.test.matchers.NodeIterableIsEmpty.*; import static org.hamcrest.core.IsInstanceOf.*; import static org.junit.Assert.*;
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Fri Mar 27 17:02:53 2015 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Sat Mar 28 17:35:14 2015 +0100 @@ -27,7 +27,6 @@ import java.util.*; -import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.Assumptions.AssumptionResult; import com.oracle.graal.api.meta.*; import com.oracle.graal.api.meta.MethodHandleAccessProvider.IntrinsicMethod; @@ -36,27 +35,19 @@ import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.debug.*; import com.oracle.graal.debug.Debug.Scope; -import com.oracle.graal.debug.internal.*; -import com.oracle.graal.graph.Graph.Mark; -import com.oracle.graal.graph.*; -import com.oracle.graal.graph.Node; import com.oracle.graal.graphbuilderconf.*; import com.oracle.graal.graphbuilderconf.GraphBuilderConfiguration.Plugins; import com.oracle.graal.java.*; -import com.oracle.graal.loop.*; -import com.oracle.graal.nodes.CallTargetNode.InvokeKind; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; -import com.oracle.graal.nodes.util.*; import com.oracle.graal.nodes.virtual.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.common.inlining.*; -import com.oracle.graal.phases.common.inlining.info.*; import com.oracle.graal.phases.tiers.*; import com.oracle.graal.phases.util.*; import com.oracle.graal.truffle.debug.*; @@ -77,8 +68,6 @@ private final Providers providers; private final CanonicalizerPhase canonicalizer; - private Set<JavaConstant> constantReceivers; - private final TruffleCache truffleCache; private final SnippetReflectionProvider snippetReflection; private final ResolvedJavaMethod callDirectMethod; private final ResolvedJavaMethod callInlinedMethod; @@ -86,11 +75,10 @@ protected final ResolvedJavaMethod callRootMethod; private final GraphBuilderConfiguration configForRoot; - public PartialEvaluator(Providers providers, GraphBuilderConfiguration configForRoot, TruffleCache truffleCache, SnippetReflectionProvider snippetReflection) { + public PartialEvaluator(Providers providers, GraphBuilderConfiguration configForRoot, SnippetReflectionProvider snippetReflection) { this.providers = providers; this.canonicalizer = new CanonicalizerPhase(); this.snippetReflection = snippetReflection; - this.truffleCache = truffleCache; this.callDirectMethod = providers.getMetaAccess().lookupJavaMethod(OptimizedCallTarget.getCallDirectMethod()); this.callInlinedMethod = providers.getMetaAccess().lookupJavaMethod(OptimizedCallTarget.getCallInlinedMethod()); this.callSiteProxyMethod = providers.getMetaAccess().lookupJavaMethod(GraalFrameInstance.CallNodeFrame.METHOD); @@ -104,10 +92,6 @@ } public StructuredGraph createGraph(final OptimizedCallTarget callTarget, AllowAssumptions allowAssumptions) { - if (TraceTruffleCompilationHistogram.getValue() || TraceTruffleCompilationDetails.getValue()) { - constantReceivers = new HashSet<>(); - } - try (Scope c = Debug.scope("TruffleTree")) { Debug.dump(callTarget, "truffle tree"); } catch (Throwable e) { @@ -126,21 +110,13 @@ PhaseContext baseContext = new PhaseContext(providers); HighTierContext tierContext = new HighTierContext(providers, graphCache, new PhaseSuite<HighTierContext>(), OptimisticOptimizations.NONE); - if (TruffleCompilerOptions.FastPE.getValue()) { - fastPartialEvaluation(callTarget, graph, baseContext, tierContext); - } else { - createRootGraph(graph); - partialEvaluation(callTarget, graph, baseContext, tierContext); - } + fastPartialEvaluation(callTarget, graph, baseContext, tierContext); if (Thread.currentThread().isInterrupted()) { return null; } new VerifyFrameDoesNotEscapePhase().apply(graph, false); - if (TraceTruffleCompilationHistogram.getValue() && constantReceivers != null) { - createHistogram(); - } postPartialEvaluation(graph); } catch (Throwable e) { @@ -362,48 +338,6 @@ ComputeLoopFrequenciesClosure.compute(graph); } - private void partialEvaluation(final OptimizedCallTarget callTarget, final StructuredGraph graph, PhaseContext baseContext, HighTierContext tierContext) { - injectConstantCallTarget(graph, callTarget, baseContext); - - Debug.dump(graph, "Before expansion"); - - TruffleExpansionLogger expansionLogger = null; - if (TraceTruffleExpansion.getValue()) { - expansionLogger = new TruffleExpansionLogger(providers, graph); - } - - expandTree(graph, expansionLogger); - - TruffleInliningCache inliningCache = null; - if (TruffleFunctionInlining.getValue()) { - callTarget.setInlining(new TruffleInlining(callTarget, new DefaultInliningPolicy())); - if (TruffleFunctionInliningCache.getValue()) { - inliningCache = new TruffleInliningCache(); - } - } - - expandDirectCalls(graph, expansionLogger, callTarget.getInlining(), inliningCache); - - if (Thread.currentThread().isInterrupted()) { - return; - } - - canonicalizer.apply(graph, baseContext); - // EA frame and clean up. - do { - try (Scope pe = Debug.scope("TrufflePartialEscape", graph)) { - new PartialEscapePhase(true, canonicalizer).apply(graph, tierContext); - new IncrementalCanonicalizerPhase<>(canonicalizer, new ConditionalEliminationPhase()).apply(graph, tierContext); - } catch (Throwable t) { - Debug.handle(t); - } - } while (expandTree(graph, expansionLogger)); - - if (expansionLogger != null) { - expansionLogger.print(callTarget); - } - } - public StructuredGraph createRootGraph(StructuredGraph graph) { new GraphBuilderPhase.Instance(providers.getMetaAccess(), providers.getStampProvider(), providers.getConstantReflection(), configForRoot, TruffleCompilerImpl.Optimizations, null).apply(graph); return graph; @@ -442,223 +376,6 @@ } } - private void injectConstantCallTarget(final StructuredGraph graph, final OptimizedCallTarget constantCallTarget, PhaseContext baseContext) { - ParameterNode thisNode = graph.getParameter(0); - - /* - * Converting the call target to a Constant using the SnippetReflectionProvider is a - * workaround, we should think about a better solution. Since object constants are - * VM-specific, only the hosting VM knows how to do the conversion. - */ - thisNode.replaceAndDelete(ConstantNode.forConstant(snippetReflection.forObject(constantCallTarget), providers.getMetaAccess(), graph)); - - canonicalizer.apply(graph, baseContext); - - new IncrementalCanonicalizerPhase<>(canonicalizer, new ReplaceIntrinsicsPhase(providers.getReplacements())).apply(graph, baseContext); - } - - private void createHistogram() { - DebugHistogram histogram = Debug.createHistogram("Expanded Truffle Nodes"); - for (JavaConstant c : constantReceivers) { - String javaName = providers.getMetaAccess().lookupJavaType(c).toJavaName(false); - - // The DSL uses nested classes with redundant names - only show the inner class - int index = javaName.indexOf('$'); - if (index != -1) { - javaName = javaName.substring(index + 1); - } - - histogram.add(javaName); - - } - new DebugHistogramAsciiPrinter(TTY.out().out()).print(histogram); - } - - private boolean expandTree(StructuredGraph graph, TruffleExpansionLogger expansionLogger) { - PhaseContext phaseContext = new PhaseContext(providers); - boolean changed = false; - boolean changedInIteration; - ArrayDeque<MethodCallTargetNode> queue = new ArrayDeque<>(); - MetaAccessProvider metaAccess = providers.getMetaAccess(); - ResolvedJavaType profileClass = metaAccess.lookupJavaType(NodeCloneable.class); - do { - changedInIteration = false; - - Mark mark = null; - while (true) { - - for (MethodCallTargetNode methodCallTargetNode : graph.getNewNodes(mark).filter(MethodCallTargetNode.class)) { - if (methodCallTargetNode.invokeKind().isDirect()) { - ValueNode receiver = methodCallTargetNode.receiver(); - if (receiver != null && receiver.isConstant() && profileClass.isAssignableFrom(receiver.stamp().javaType(metaAccess))) { - queue.addFirst(methodCallTargetNode); - } else { - queue.addLast(methodCallTargetNode); - } - } - } - mark = graph.getMark(); - - if (queue.isEmpty()) { - break; - } - MethodCallTargetNode methodCallTargetNode = queue.removeFirst(); - if (!methodCallTargetNode.isAlive()) { - continue; - } - InvokeKind kind = methodCallTargetNode.invokeKind(); - try (Indent id1 = Debug.logAndIndent("try inlining %s, kind = %s", methodCallTargetNode.targetMethod(), kind)) { - if (kind.isDirect()) { - if ((TraceTruffleCompilationHistogram.getValue() || TraceTruffleCompilationDetails.getValue()) && kind == InvokeKind.Special && methodCallTargetNode.receiver().isConstant()) { - constantReceivers.add(methodCallTargetNode.receiver().asJavaConstant()); - } - - Replacements replacements = providers.getReplacements(); - StructuredGraph inlineGraph = replacements.getMethodSubstitution(methodCallTargetNode.targetMethod()); - - ResolvedJavaMethod targetMethod = methodCallTargetNode.targetMethod(); - if (inlineGraph == null && targetMethod.hasBytecodes() && targetMethod.canBeInlined()) { - inlineGraph = parseGraph(methodCallTargetNode.targetMethod(), methodCallTargetNode.arguments(), phaseContext); - } - - if (inlineGraph != null) { - expandTreeInline(graph, phaseContext, expansionLogger, methodCallTargetNode, inlineGraph); - changed = changedInIteration = true; - } - } - } - - if (graph.getNodeCount() > TruffleCompilerOptions.TruffleGraphMaxNodes.getValue()) { - throw new BailoutException("Truffle compilation is exceeding maximum node count: %d", graph.getNodeCount()); - } - } - - } while (changedInIteration); - - return changed; - } - - private void expandTreeInline(StructuredGraph graph, PhaseContext phaseContext, TruffleExpansionLogger expansionLogger, MethodCallTargetNode methodCallTargetNode, StructuredGraph inlineGraph) { - try (Indent indent = Debug.logAndIndent("expand graph %s", methodCallTargetNode.targetMethod())) { - int nodeCountBefore = graph.getNodeCount(); - if (expansionLogger != null) { - expansionLogger.preExpand(methodCallTargetNode, inlineGraph); - } - List<Node> canonicalizedNodes = methodCallTargetNode.invoke().asNode().usages().snapshot(); - - Map<Node, Node> inlined = InliningUtil.inline(methodCallTargetNode.invoke(), inlineGraph, false, canonicalizedNodes); - if (expansionLogger != null) { - expansionLogger.postExpand(inlined); - } - if (Debug.isDumpEnabled()) { - int nodeCountAfter = graph.getNodeCount(); - Debug.dump(graph, "After expand %s %+d (%d)", methodCallTargetNode.targetMethod().toString(), nodeCountAfter - nodeCountBefore, nodeCountAfter); - } - AbstractInlineInfo.getInlinedParameterUsages(canonicalizedNodes, inlineGraph, inlined); - canonicalizer.applyIncremental(graph, phaseContext, canonicalizedNodes); - } - } - - private StructuredGraph parseGraph(final ResolvedJavaMethod targetMethod, final NodeInputList<ValueNode> arguments, final PhaseContext phaseContext) { - StructuredGraph graph = truffleCache.lookup(targetMethod, arguments, canonicalizer); - - if (graph != null && targetMethod.getAnnotation(ExplodeLoop.class) != null) { - assert graph.hasLoops() : graph + " does not contain a loop"; - final StructuredGraph graphCopy = graph.copy(); - final List<Node> modifiedNodes = new ArrayList<>(); - for (ParameterNode param : graphCopy.getNodes(ParameterNode.TYPE).snapshot()) { - ValueNode arg = arguments.get(param.index()); - if (arg.isConstant()) { - Constant constant = arg.asConstant(); - param.usages().snapshotTo(modifiedNodes); - param.replaceAndDelete(ConstantNode.forConstant(arg.stamp(), constant, phaseContext.getMetaAccess(), graphCopy)); - } else { - ValueNode length = GraphUtil.arrayLength(arg); - if (length != null && length.isConstant()) { - param.usages().snapshotTo(modifiedNodes); - ParameterNode newParam = graphCopy.addWithoutUnique(new ParameterNode(param.index(), param.stamp())); - param.replaceAndDelete(graphCopy.addWithoutUnique(new PiArrayNode(newParam, ConstantNode.forInt(length.asJavaConstant().asInt(), graphCopy), param.stamp()))); - } - } - } - try (Scope s = Debug.scope("TruffleUnrollLoop", targetMethod)) { - - canonicalizer.applyIncremental(graphCopy, phaseContext, modifiedNodes); - boolean unrolled; - do { - unrolled = false; - LoopsData loopsData = new LoopsData(graphCopy); - loopsData.detectedCountedLoops(); - for (LoopEx ex : innerLoopsFirst(loopsData.countedLoops())) { - if (ex.counted().isConstantMaxTripCount()) { - long constant = ex.counted().constantMaxTripCount(); - LoopTransformations.fullUnroll(ex, phaseContext, canonicalizer); - Debug.dump(graphCopy, "After loop unrolling %d times", constant); - unrolled = true; - break; - } - } - loopsData.deleteUnusedNodes(); - } while (unrolled); - } catch (Throwable e) { - throw Debug.handle(e); - } - - return graphCopy; - } else { - return graph; - } - } - - private void expandDirectCalls(StructuredGraph graph, TruffleExpansionLogger expansionLogger, TruffleInlining inlining, TruffleInliningCache inliningCache) { - PhaseContext phaseContext = new PhaseContext(providers); - - for (MethodCallTargetNode methodCallTargetNode : graph.getNodes(MethodCallTargetNode.TYPE).snapshot()) { - StructuredGraph inlineGraph = parseDirectCallGraph(phaseContext, graph, inlining, inliningCache, methodCallTargetNode); - - if (inlineGraph != null) { - expandTreeInline(graph, phaseContext, expansionLogger, methodCallTargetNode, inlineGraph); - } - } - // non inlined direct calls need to be expanded until TruffleCallBoundary. - expandTree(graph, expansionLogger); - assert noDirectCallsLeft(graph); - } - - private boolean noDirectCallsLeft(StructuredGraph graph) { - for (MethodCallTargetNode methodCallTargetNode : graph.getNodes(MethodCallTargetNode.TYPE).snapshot()) { - if (methodCallTargetNode.targetMethod().equals(callDirectMethod)) { - return false; - } - } - return true; - } - - private StructuredGraph parseDirectCallGraph(PhaseContext phaseContext, StructuredGraph caller, TruffleInlining inlining, TruffleInliningCache inliningCache, - MethodCallTargetNode methodCallTargetNode) { - OptimizedDirectCallNode callNode = resolveConstantCallNode(methodCallTargetNode); - if (callNode == null) { - return null; - } - - TruffleInliningDecision decision = getDecision(inlining, callNode); - - StructuredGraph graph; - if (decision != null && decision.isInline()) { - if (inliningCache == null) { - graph = createInlineGraph(phaseContext, caller, null, decision); - } else { - graph = inliningCache.getCachedGraph(phaseContext, caller, decision); - } - caller.getAssumptions().record(new AssumptionValidAssumption((OptimizedAssumption) decision.getTarget().getNodeRewritingAssumption())); - } else { - // we continue expansion of callDirect until we reach the callBoundary. - graph = parseGraph(methodCallTargetNode.targetMethod(), methodCallTargetNode.arguments(), phaseContext); - } - - return graph; - } - private static TruffleInliningDecision getDecision(TruffleInlining inlining, OptimizedDirectCallNode callNode) { TruffleInliningDecision decision = inlining.findByCall(callNode); if (decision == null) { @@ -680,125 +397,4 @@ } return decision; } - - private OptimizedDirectCallNode resolveConstantCallNode(MethodCallTargetNode methodCallTargetNode) { - if (!methodCallTargetNode.targetMethod().equals(callDirectMethod)) { - return null; - } - - Invoke invoke = methodCallTargetNode.invoke(); - if (invoke == null) { - return null; - } - - FrameState directCallState = invoke.stateAfter(); - while (directCallState != null && !directCallState.method().equals(callSiteProxyMethod)) { - directCallState = directCallState.outerFrameState(); - } - - if (directCallState == null) { - // not a direct call. May be indirect call. - return null; - } - - if (directCallState.values().isEmpty()) { - throw new AssertionError(String.format("Frame state of method '%s' is invalid.", callDirectMethod.toString())); - } - - ValueNode node = directCallState.values().get(0); - if (!node.isConstant()) { - throw new AssertionError(String.format("Method argument for method '%s' is not constant.", callDirectMethod.toString())); - } - - JavaConstant constantCallNode = node.asJavaConstant(); - Object value = snippetReflection.asObject(Object.class, constantCallNode); - - if (!(value instanceof OptimizedDirectCallNode)) { - // might be an indirect call. - return null; - } - - return (OptimizedDirectCallNode) value; - } - - private StructuredGraph createInlineGraph(PhaseContext phaseContext, StructuredGraph caller, TruffleInliningCache cache, TruffleInliningDecision decision) { - try (Scope s = Debug.scope("GuestLanguageInlinedGraph", new DebugDumpScope(decision.getTarget().toString()))) { - OptimizedCallTarget target = decision.getTarget(); - StructuredGraph inlineGraph = createInlineGraph(target.toString(), caller); - injectConstantCallTarget(inlineGraph, decision.getTarget(), phaseContext); - TruffleExpansionLogger expansionLogger = null; - if (TraceTruffleExpansion.getValue()) { - expansionLogger = new TruffleExpansionLogger(providers, inlineGraph); - } - expandTree(inlineGraph, expansionLogger); - expandDirectCalls(inlineGraph, expansionLogger, decision, cache); - - if (expansionLogger != null) { - expansionLogger.print(target); - } - return inlineGraph; - } catch (Throwable e) { - throw Debug.handle(e); - } - } - - private static List<LoopEx> innerLoopsFirst(Collection<LoopEx> loops) { - ArrayList<LoopEx> sortedLoops = new ArrayList<>(loops); - Collections.sort(sortedLoops, new Comparator<LoopEx>() { - - @Override - public int compare(LoopEx o1, LoopEx o2) { - return o2.loop().getDepth() - o1.loop().getDepth(); - } - }); - return sortedLoops; - } - - private final class TruffleInliningCache { - - private final Map<CacheKey, StructuredGraph> cache; - - public TruffleInliningCache() { - this.cache = new HashMap<>(); - } - - public StructuredGraph getCachedGraph(PhaseContext phaseContext, StructuredGraph caller, TruffleInliningDecision decision) { - CacheKey cacheKey = new CacheKey(decision); - StructuredGraph inlineGraph = cache.get(cacheKey); - if (inlineGraph == null) { - inlineGraph = createInlineGraph(phaseContext, caller, this, decision); - cache.put(cacheKey, inlineGraph); - } - return inlineGraph; - } - - private final class CacheKey { - - public final TruffleInliningDecision decision; - - public CacheKey(TruffleInliningDecision decision) { - this.decision = decision; - /* - * If decision.isInline() is not true CacheKey#hashCode does not match - * CacheKey#equals - */ - assert decision.isInline(); - } - - @Override - public int hashCode() { - return decision.getTarget().hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (!(obj instanceof CacheKey)) { - return false; - } - CacheKey other = (CacheKey) obj; - return decision.isSameAs(other.decision); - } - } - } - }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java Fri Mar 27 17:02:53 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.truffle; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.phases.common.*; - -public interface TruffleCache { - - /** - * Returns a cached graph for a method with given arguments. - */ - StructuredGraph lookup(final ResolvedJavaMethod method, final NodeInputList<ValueNode> arguments, final CanonicalizerPhase finalCanonicalizer); -}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCacheImpl.java Fri Mar 27 17:02:53 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,314 +0,0 @@ -/* - * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.truffle; - -import java.util.*; -import java.util.Map.Entry; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.debug.*; -import com.oracle.graal.debug.Debug.Scope; -import com.oracle.graal.graph.Graph.Mark; -import com.oracle.graal.graph.*; -import com.oracle.graal.graph.Node; -import com.oracle.graal.graph.spi.*; -import com.oracle.graal.graphbuilderconf.*; -import com.oracle.graal.java.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; -import com.oracle.graal.nodes.java.*; -import com.oracle.graal.nodes.type.*; -import com.oracle.graal.nodes.util.*; -import com.oracle.graal.phases.*; -import com.oracle.graal.phases.common.*; -import com.oracle.graal.phases.common.inlining.*; -import com.oracle.graal.phases.tiers.*; -import com.oracle.graal.phases.util.*; -import com.oracle.graal.truffle.debug.*; -import com.oracle.graal.truffle.phases.*; -import com.oracle.graal.virtual.phases.ea.*; -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.nodes.*; - -/** - * Implementation of a cache for Truffle graphs for improving partial evaluation time. - */ -public class TruffleCacheImpl implements TruffleCache { - - private final Providers providers; - private final GraphBuilderConfiguration config; - private final OptimisticOptimizations optimisticOptimizations; - - private final HashMap<List<Object>, StructuredGraph> cache = new HashMap<>(); - private final HashMap<List<Object>, Long> lastUsed = new HashMap<>(); - private final StructuredGraph markerGraph = new StructuredGraph(AllowAssumptions.NO); - - private final ResolvedJavaType stringBuilderClass; - private final ResolvedJavaType runtimeExceptionClass; - private final ResolvedJavaType errorClass; - private final ResolvedJavaType controlFlowExceptionClass; - - private long counter; - - public TruffleCacheImpl(Providers providers, GraphBuilderConfiguration config, OptimisticOptimizations optimisticOptimizations) { - this.providers = providers; - this.config = config; - this.optimisticOptimizations = optimisticOptimizations; - - this.stringBuilderClass = providers.getMetaAccess().lookupJavaType(StringBuilder.class); - this.runtimeExceptionClass = providers.getMetaAccess().lookupJavaType(RuntimeException.class); - this.errorClass = providers.getMetaAccess().lookupJavaType(Error.class); - this.controlFlowExceptionClass = providers.getMetaAccess().lookupJavaType(ControlFlowException.class); - } - - private static List<Object> computeCacheKey(ResolvedJavaMethod method, NodeInputList<ValueNode> arguments) { - List<Object> key = new ArrayList<>(arguments.size() + 1); - key.add(method); - for (ValueNode v : arguments) { - if (v.getKind() == Kind.Object) { - key.add(v.stamp()); - } - } - return key; - } - - public StructuredGraph lookup(ResolvedJavaMethod method, NodeInputList<ValueNode> arguments, CanonicalizerPhase canonicalizer) { - List<Object> key = computeCacheKey(method, arguments); - StructuredGraph resultGraph = cache.get(key); - if (resultGraph == markerGraph) { - // compilation failed previously, don't try again - return null; - } - StructuredGraph graph = cacheLookup(method, arguments, canonicalizer); - assert graph != markerGraph : "markerGraph should not leak out"; - return graph; - } - - private StructuredGraph cacheLookup(ResolvedJavaMethod method, NodeInputList<ValueNode> arguments, CanonicalizerPhase canonicalizer) { - if (method.getAnnotation(CompilerDirectives.TruffleBoundary.class) != null) { - return null; - } - - List<Object> key = computeCacheKey(method, arguments); - StructuredGraph resultGraph = cache.get(key); - if (resultGraph != null) { - lastUsed.put(key, counter++); - return resultGraph; - } - - if (lastUsed.values().size() >= TruffleCompilerOptions.TruffleMaxCompilationCacheSize.getValue()) { - lookupExceedsMaxSize(); - } - - StructuredGraph graph = new StructuredGraph(method, AllowAssumptions.NO); - PhaseContext phaseContext = new PhaseContext(providers); - try (Scope s = Debug.scope("TruffleCache", providers.getMetaAccess(), method)) { - - graph = parseGraph(graph, phaseContext); - if (graph == null) { - return null; - } - } catch (Throwable e) { - throw Debug.handle(e); - } - - try (Scope s = Debug.scope("TruffleCache", providers.getMetaAccess(), method, graph)) { - - lastUsed.put(key, counter++); - cache.put(key, markerGraph); - - for (ParameterNode param : graph.getNodes(ParameterNode.TYPE)) { - if (param.getKind() == Kind.Object) { - ValueNode actualArgument = arguments.get(param.index()); - param.setStamp(param.stamp().join(actualArgument.stamp())); - } - } - - // Intrinsify methods. - new ReplaceIntrinsicsPhase(providers.getReplacements()).apply(graph); - - // Convert deopt to guards. - new ConvertDeoptimizeToGuardPhase().apply(graph, phaseContext); - - PartialEscapePhase partialEscapePhase = new PartialEscapePhase(false, canonicalizer); - - Mark mark = null; - while (true) { - - partialEscapePhase.apply(graph, phaseContext); - - // Conditional elimination. - ConditionalEliminationPhase conditionalEliminationPhase = new ConditionalEliminationPhase(); - conditionalEliminationPhase.apply(graph); - - // Canonicalize / constant propagate. - canonicalizer.apply(graph, phaseContext); - - boolean inliningProgress = false; - for (MethodCallTargetNode methodCallTarget : graph.getNodes(MethodCallTargetNode.TYPE)) { - if (!graph.getMark().equals(mark)) { - mark = lookupProcessMacroSubstitutions(graph, mark); - } - if (methodCallTarget.isAlive() && methodCallTarget.invoke() != null && shouldInline(methodCallTarget)) { - inliningProgress = true; - lookupDoInline(graph, phaseContext, canonicalizer, methodCallTarget); - } - } - - // Convert deopt to guards. - new ConvertDeoptimizeToGuardPhase().apply(graph, phaseContext); - - new EarlyReadEliminationPhase(canonicalizer).apply(graph, phaseContext); - - if (!inliningProgress) { - break; - } - } - - if (TruffleCompilerOptions.TraceTrufflePerformanceWarnings.getValue()) { - int warnNodeCount = TruffleCompilerOptions.TrufflePerformanceWarningGraalNodeCount.getValue(); - if (graph.getNodeCount() > warnNodeCount) { - Map<String, Object> map = new LinkedHashMap<>(); - map.put("nodeCount", graph.getNodeCount()); - map.put("method", method.toString()); - TracePerformanceWarningsListener.logPerformanceWarning(String.format("Method on fast path contains more than %d graal nodes.", warnNodeCount), map); - - try (Scope s2 = Debug.scope("TrufflePerformanceWarnings")) { - Debug.dump(graph, "performance warning"); - } - } - } - - cache.put(key, graph); - if (TruffleCompilerOptions.TraceTruffleCacheDetails.getValue()) { - TTY.println(String.format("[truffle] added to graph cache method %s with %d nodes.", method, graph.getNodeCount())); - } - return graph; - } catch (Throwable e) { - throw Debug.handle(e); - } - } - - private void lookupExceedsMaxSize() { - List<Long> lastUsedList = new ArrayList<>(); - for (long l : lastUsed.values()) { - lastUsedList.add(l); - } - Collections.sort(lastUsedList); - long mid = lastUsedList.get(lastUsedList.size() / 2); - - List<List<Object>> toRemoveList = new ArrayList<>(); - for (Entry<List<Object>, Long> entry : lastUsed.entrySet()) { - if (entry.getValue() < mid) { - toRemoveList.add(entry.getKey()); - } - } - - for (List<Object> entry : toRemoveList) { - cache.remove(entry); - lastUsed.remove(entry); - } - } - - private Mark lookupProcessMacroSubstitutions(StructuredGraph graph, Mark mark) { - // Make sure macro substitutions such as - // CompilerDirectives.transferToInterpreter get processed first. - for (Node newNode : graph.getNewNodes(mark)) { - if (newNode instanceof MethodCallTargetNode) { - MethodCallTargetNode methodCallTargetNode = (MethodCallTargetNode) newNode; - tryCutOffRuntimeExceptionsAndErrors(methodCallTargetNode); - } - } - return graph.getMark(); - } - - private void lookupDoInline(StructuredGraph graph, PhaseContext phaseContext, CanonicalizerPhase canonicalizer, MethodCallTargetNode methodCallTarget) { - List<Node> canonicalizerUsages = new ArrayList<>(); - for (Node n : methodCallTarget.invoke().asNode().usages()) { - if (n instanceof Canonicalizable) { - canonicalizerUsages.add(n); - } - } - List<ValueNode> argumentSnapshot = methodCallTarget.arguments().snapshot(); - Mark beforeInvokeMark = graph.getMark(); - expandInvoke(methodCallTarget, canonicalizer); - for (Node arg : argumentSnapshot) { - if (arg != null) { - for (Node argUsage : arg.usages()) { - if (graph.isNew(beforeInvokeMark, argUsage) && argUsage instanceof Canonicalizable) { - canonicalizerUsages.add(argUsage); - } - } - } - } - canonicalizer.applyIncremental(graph, phaseContext, canonicalizerUsages); - } - - protected StructuredGraph parseGraph(StructuredGraph graph, final PhaseContext phaseContext) { - new GraphBuilderPhase.Instance(phaseContext.getMetaAccess(), phaseContext.getStampProvider(), null, config, optimisticOptimizations, null).apply(graph); - return graph; - } - - private void expandInvoke(MethodCallTargetNode methodCallTargetNode, CanonicalizerPhase canonicalizer) { - StructuredGraph inlineGraph = providers.getReplacements().getMethodSubstitution(methodCallTargetNode.targetMethod()); - if (inlineGraph == null) { - inlineGraph = cacheLookup(methodCallTargetNode.targetMethod(), methodCallTargetNode.arguments(), canonicalizer); - } - if (inlineGraph == null) { - return; - } - if (inlineGraph == this.markerGraph) { - // Can happen for recursive calls. - throw GraphUtil.approxSourceException(methodCallTargetNode, new IllegalStateException("Found illegal recursive call to " + methodCallTargetNode.targetMethod() + - ", must annotate such calls with @TruffleBoundary!")); - } - Invoke invoke = methodCallTargetNode.invoke(); - InliningUtil.inline(invoke, inlineGraph, true, null); - } - - private boolean tryCutOffRuntimeExceptionsAndErrors(MethodCallTargetNode methodCallTargetNode) { - if (methodCallTargetNode.targetMethod().isConstructor()) { - ResolvedJavaType declaringClass = methodCallTargetNode.targetMethod().getDeclaringClass(); - ResolvedJavaType exceptionType = Objects.requireNonNull(StampTool.typeOrNull(methodCallTargetNode.receiver().stamp())); - - boolean removeAllocation = runtimeExceptionClass.isAssignableFrom(declaringClass) || errorClass.isAssignableFrom(declaringClass); - boolean isControlFlowException = controlFlowExceptionClass.isAssignableFrom(exceptionType); - if (removeAllocation && !isControlFlowException) { - DeoptimizeNode deoptNode = methodCallTargetNode.graph().add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.UnreachedCode)); - FixedNode invokeNode = methodCallTargetNode.invoke().asNode(); - invokeNode.replaceAtPredecessor(deoptNode); - GraphUtil.killCFG(invokeNode); - return true; - } - } - return false; - } - - protected boolean shouldInline(MethodCallTargetNode methodCallTargetNode) { - boolean result = methodCallTargetNode.invokeKind().isDirect() && methodCallTargetNode.targetMethod().hasBytecodes() && methodCallTargetNode.targetMethod().canBeInlined() && - methodCallTargetNode.targetMethod().getAnnotation(ExplodeLoop.class) == null && - methodCallTargetNode.targetMethod().getAnnotation(CompilerDirectives.TruffleBoundary.class) == null && - !methodCallTargetNode.targetMethod().getDeclaringClass().equals(stringBuilderClass); - return result; - } -}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java Fri Mar 27 17:02:53 2015 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java Sat Mar 28 17:35:14 2015 +0100 @@ -43,7 +43,6 @@ import com.oracle.graal.lir.phases.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; -import com.oracle.graal.nodes.spi.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.tiers.*; import com.oracle.graal.phases.util.*; @@ -66,7 +65,6 @@ private final Backend backend; private final GraphBuilderConfiguration config; private final RuntimeProvider runtime; - private final TruffleCache truffleCache; private final GraalTruffleCompilationListener compilationNotify; // @formatter:off @@ -89,34 +87,22 @@ this.runtime = Graal.getRequiredCapability(RuntimeProvider.class); this.compilationNotify = graalTruffleRuntime.getCompilationNotify(); this.backend = runtime.getHostBackend(); - Replacements truffleReplacements = graalTruffleRuntime.getReplacements(); Providers backendProviders = backend.getProviders(); ConstantReflectionProvider constantReflection = new TruffleConstantReflectionProvider(backendProviders.getConstantReflection(), backendProviders.getMetaAccess()); - if (!TruffleCompilerOptions.FastPE.getValue()) { - backendProviders = backendProviders.copyWith(truffleReplacements); - } this.providers = backendProviders.copyWith(constantReflection); this.suites = backend.getSuites().getDefaultSuites(); this.lirSuites = backend.getSuites().getDefaultLIRSuites(); ResolvedJavaType[] skippedExceptionTypes = getSkippedExceptionTypes(providers.getMetaAccess()); - Plugins plugins; - if (TruffleCompilerOptions.FastPE.getValue()) { - GraphBuilderPhase phase = (GraphBuilderPhase) backend.getSuites().getDefaultGraphBuilderSuite().findPhase(GraphBuilderPhase.class).previous(); - InvocationPlugins invocationPlugins = new InvocationPlugins(phase.getGraphBuilderConfig().getPlugins().getInvocationPlugins()); - plugins = new Plugins(invocationPlugins); - TruffleGraphBuilderPlugins.registerInvocationPlugins(providers.getMetaAccess(), invocationPlugins); - } else { - plugins = new Plugins(new InvocationPlugins(backendProviders.getMetaAccess())); - } + GraphBuilderPhase phase = (GraphBuilderPhase) backend.getSuites().getDefaultGraphBuilderSuite().findPhase(GraphBuilderPhase.class).previous(); + InvocationPlugins invocationPlugins = new InvocationPlugins(phase.getGraphBuilderConfig().getPlugins().getInvocationPlugins()); + Plugins plugins = new Plugins(invocationPlugins); + TruffleGraphBuilderPlugins.registerInvocationPlugins(providers.getMetaAccess(), invocationPlugins); this.config = GraphBuilderConfiguration.getDefault(plugins).withSkippedExceptionTypes(skippedExceptionTypes); - GraphBuilderConfiguration eagerConfig = GraphBuilderConfiguration.getEagerDefault(plugins).withSkippedExceptionTypes(skippedExceptionTypes); - this.truffleCache = new TruffleCacheImpl(providers, eagerConfig, TruffleCompilerImpl.Optimizations); - - this.partialEvaluator = new PartialEvaluator(providers, config, truffleCache, Graal.getRequiredCapability(SnippetReflectionProvider.class)); + this.partialEvaluator = new PartialEvaluator(providers, config, Graal.getRequiredCapability(SnippetReflectionProvider.class)); if (Debug.isEnabled()) { DebugEnvironment.initialize(System.out);
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java Fri Mar 27 17:02:53 2015 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java Sat Mar 28 17:35:14 2015 +0100 @@ -138,9 +138,6 @@ @Option(help = "Print information for compilation queuing", type = OptionType.Debug) public static final OptionValue<Boolean> TraceTruffleCompilationDetails = new OptionValue<>(false); - @Option(help = "Print a node count histogram after each compilation", type = OptionType.Debug) - public static final OptionValue<Boolean> TraceTruffleCompilationHistogram = new OptionValue<>(false); - @Option(help = "Print all polymorphic and generic nodes after each compilation", type = OptionType.Debug) public static final OptionValue<Boolean> TraceTruffleCompilationPolymorphism = new OptionValue<>(false); @@ -191,8 +188,5 @@ @Option(help = "Print additional more verbose Truffle compilation statistics at the end of a run.", type = OptionType.Debug) public static final OptionValue<Boolean> TruffleCompilationStatisticDetails = new OptionValue<>(false); - - @Option(help = "Experimental new version of the partial evaluator.", type = OptionType.Debug) - public static final OptionValue<Boolean> FastPE = new OptionValue<>(true); // @formatter:on }