# HG changeset patch # User Lukas Stadler # Date 1401292032 -7200 # Node ID cf51d3ade2fb9e9fe36bddaaec9235229ff116fc # Parent edc33e8715d5435d7654759982528cee4277070e less canonicalization during InliningPhase diff -r edc33e8715d5 -r cf51d3ade2fb graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/AbstractInlineInfo.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/AbstractInlineInfo.java Wed May 28 17:20:35 2014 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/AbstractInlineInfo.java Wed May 28 17:47:12 2014 +0200 @@ -22,13 +22,13 @@ */ package com.oracle.graal.phases.common.inlining.info; +import java.util.*; + import com.oracle.graal.api.code.Assumptions; import com.oracle.graal.api.meta.ResolvedJavaMethod; -import com.oracle.graal.nodes.FixedWithNextNode; -import com.oracle.graal.nodes.Invoke; -import com.oracle.graal.nodes.StructuredGraph; +import com.oracle.graal.graph.*; +import com.oracle.graal.nodes.*; import com.oracle.graal.phases.common.inlining.InliningUtil; - import com.oracle.graal.phases.common.inlining.info.elem.Inlineable; import com.oracle.graal.phases.common.inlining.info.elem.InlineableMacroNode; import com.oracle.graal.phases.common.inlining.info.elem.InlineableGraph; @@ -51,18 +51,29 @@ return invoke; } - protected static void inline(Invoke invoke, ResolvedJavaMethod concrete, Inlineable inlineable, Assumptions assumptions, boolean receiverNullCheck) { + protected static Collection inline(Invoke invoke, ResolvedJavaMethod concrete, Inlineable inlineable, Assumptions assumptions, boolean receiverNullCheck) { + Collection parameterUsages = new ArrayList<>(); if (inlineable instanceof InlineableGraph) { StructuredGraph calleeGraph = ((InlineableGraph) inlineable).getGraph(); - InliningUtil.inline(invoke, calleeGraph, receiverNullCheck); + Map duplicateMap = InliningUtil.inline(invoke, calleeGraph, receiverNullCheck); + for (ParameterNode parameter : calleeGraph.getNodes(ParameterNode.class)) { + for (Node usage : parameter.usages()) { + Node node = duplicateMap.get(usage); + if (node != null && node.isAlive()) { + parameterUsages.add(node); + } + } + } } else { assert inlineable instanceof InlineableMacroNode; Class macroNodeClass = ((InlineableMacroNode) inlineable).getMacroNodeClass(); - InliningUtil.inlineMacroNode(invoke, concrete, macroNodeClass); + FixedWithNextNode macroNode = InliningUtil.inlineMacroNode(invoke, concrete, macroNodeClass); + parameterUsages.add(macroNode); } InliningUtil.InlinedBytecodes.add(concrete.getCodeSize()); assumptions.recordMethodContents(concrete); + return parameterUsages; } } diff -r edc33e8715d5 -r cf51d3ade2fb graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/AssumptionInlineInfo.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/AssumptionInlineInfo.java Wed May 28 17:20:35 2014 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/AssumptionInlineInfo.java Wed May 28 17:47:12 2014 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.graal.phases.common.inlining.info; +import java.util.*; + import com.oracle.graal.api.code.Assumptions; import com.oracle.graal.api.meta.MetaAccessProvider; import com.oracle.graal.api.meta.MetaUtil; @@ -30,6 +32,7 @@ import com.oracle.graal.phases.common.inlining.InliningUtil; import com.oracle.graal.phases.util.Providers; import com.oracle.graal.api.code.Assumptions.Assumption; +import com.oracle.graal.graph.*; import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind; /** @@ -46,9 +49,9 @@ } @Override - public void inline(Providers providers, Assumptions assumptions) { + public Collection inline(Providers providers, Assumptions assumptions) { assumptions.record(takenAssumption); - super.inline(providers, assumptions); + return super.inline(providers, assumptions); } @Override diff -r edc33e8715d5 -r cf51d3ade2fb graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/ExactInlineInfo.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/ExactInlineInfo.java Wed May 28 17:20:35 2014 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/ExactInlineInfo.java Wed May 28 17:47:12 2014 +0200 @@ -22,10 +22,13 @@ */ package com.oracle.graal.phases.common.inlining.info; +import java.util.*; + import com.oracle.graal.api.code.Assumptions; import com.oracle.graal.api.meta.MetaAccessProvider; import com.oracle.graal.api.meta.MetaUtil; import com.oracle.graal.api.meta.ResolvedJavaMethod; +import com.oracle.graal.graph.*; import com.oracle.graal.nodes.Invoke; import com.oracle.graal.phases.common.inlining.info.elem.Inlineable; import com.oracle.graal.phases.util.Providers; @@ -51,8 +54,8 @@ } @Override - public void inline(Providers providers, Assumptions assumptions) { - inline(invoke, concrete, inlineableElement, assumptions, !suppressNullCheck); + public Collection inline(Providers providers, Assumptions assumptions) { + return inline(invoke, concrete, inlineableElement, assumptions, !suppressNullCheck); } @Override diff -r edc33e8715d5 -r cf51d3ade2fb graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/InlineInfo.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/InlineInfo.java Wed May 28 17:20:35 2014 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/InlineInfo.java Wed May 28 17:47:12 2014 +0200 @@ -22,9 +22,12 @@ */ package com.oracle.graal.phases.common.inlining.info; +import java.util.*; + import com.oracle.graal.api.code.Assumptions; import com.oracle.graal.api.meta.MetaAccessProvider; import com.oracle.graal.api.meta.ResolvedJavaMethod; +import com.oracle.graal.graph.*; import com.oracle.graal.nodes.Invoke; import com.oracle.graal.nodes.StructuredGraph; import com.oracle.graal.phases.common.inlining.info.elem.Inlineable; @@ -68,8 +71,10 @@ * Performs the inlining described by this object and returns the node that represents the * return value of the inlined method (or null for void methods and methods that have no * non-exceptional exit). + * + * @return a collection of nodes that need to be canonicalized after the inlining */ - void inline(Providers providers, Assumptions assumptions); + Collection inline(Providers providers, Assumptions assumptions); /** * Try to make the call static bindable to avoid interface and virtual method calls. diff -r edc33e8715d5 -r cf51d3ade2fb graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/MultiTypeGuardInlineInfo.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/MultiTypeGuardInlineInfo.java Wed May 28 17:20:35 2014 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/MultiTypeGuardInlineInfo.java Wed May 28 17:47:12 2014 +0200 @@ -132,11 +132,11 @@ } @Override - public void inline(Providers providers, Assumptions assumptions) { + public Collection inline(Providers providers, Assumptions assumptions) { if (hasSingleMethod()) { - inlineSingleMethod(graph(), providers.getMetaAccess(), assumptions); + return inlineSingleMethod(graph(), providers.getMetaAccess(), assumptions); } else { - inlineMultipleMethods(graph(), providers, assumptions); + return inlineMultipleMethods(graph(), providers, assumptions); } } @@ -157,7 +157,7 @@ return notRecordedTypeProbability > 0; } - private void inlineMultipleMethods(StructuredGraph graph, Providers providers, Assumptions assumptions) { + private Collection inlineMultipleMethods(StructuredGraph graph, Providers providers, Assumptions assumptions) { int numberOfMethods = concretes.size(); FixedNode continuation = invoke.next(); @@ -222,6 +222,8 @@ ArrayList replacementNodes = new ArrayList<>(); + Collection parameterUsages = new ArrayList<>(); + // do the actual inlining for every invoke for (int i = 0; i < numberOfMethods; i++) { BeginNode node = successors[i]; @@ -239,7 +241,7 @@ GuardedValueNode anchoredReceiver = InliningUtil.createAnchoredReceiver(graph, node, commonType, receiver, exact); invokeForInlining.callTarget().replaceFirstInput(receiver, anchoredReceiver); - inline(invokeForInlining, methodAt(i), inlineableElementAt(i), assumptions, false); + parameterUsages.addAll(inline(invokeForInlining, methodAt(i), inlineableElementAt(i), assumptions, false)); replacementNodes.add(anchoredReceiver); } @@ -272,6 +274,7 @@ TailDuplicationPhase.tailDuplicate(returnMerge, TailDuplicationPhase.TRUE_DECISION, replacementNodes, phaseContext, canonicalizer); } } + return parameterUsages; } private int getTypeCount(int concreteMethodIndex) { @@ -307,7 +310,7 @@ return result; } - private void inlineSingleMethod(StructuredGraph graph, MetaAccessProvider metaAccess, Assumptions assumptions) { + private Collection inlineSingleMethod(StructuredGraph graph, MetaAccessProvider metaAccess, Assumptions assumptions) { assert concretes.size() == 1 && inlineableElements.length == 1 && ptypes.size() > 1 && !shouldFallbackToInvoke() && notRecordedTypeProbability == 0; BeginNode calleeEntryNode = graph.add(new BeginNode()); @@ -318,7 +321,7 @@ calleeEntryNode.setNext(invoke.asNode()); - inline(invoke, methodAt(0), inlineableElementAt(0), assumptions, false); + return inline(invoke, methodAt(0), inlineableElementAt(0), assumptions, false); } private boolean createDispatchOnTypeBeforeInvoke(StructuredGraph graph, BeginNode[] successors, boolean invokeIsOnlySuccessor, MetaAccessProvider metaAccess) { diff -r edc33e8715d5 -r cf51d3ade2fb graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/TypeGuardInlineInfo.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/TypeGuardInlineInfo.java Wed May 28 17:20:35 2014 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/TypeGuardInlineInfo.java Wed May 28 17:47:12 2014 +0200 @@ -22,9 +22,12 @@ */ package com.oracle.graal.phases.common.inlining.info; +import java.util.*; + import com.oracle.graal.api.code.Assumptions; import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.calc.Condition; +import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.CompareNode; import com.oracle.graal.nodes.extended.LoadHubNode; @@ -87,9 +90,9 @@ } @Override - public void inline(Providers providers, Assumptions assumptions) { + public Collection inline(Providers providers, Assumptions assumptions) { createGuard(graph(), providers.getMetaAccess()); - inline(invoke, concrete, inlineableElement, assumptions, false); + return inline(invoke, concrete, inlineableElement, assumptions, false); } @Override diff -r edc33e8715d5 -r cf51d3ade2fb graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/elem/InlineableGraph.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/elem/InlineableGraph.java Wed May 28 17:20:35 2014 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/elem/InlineableGraph.java Wed May 28 17:47:12 2014 +0200 @@ -22,11 +22,13 @@ */ package com.oracle.graal.phases.common.inlining.info.elem; +import java.util.*; + import com.oracle.graal.api.meta.Constant; import com.oracle.graal.api.meta.ResolvedJavaMethod; import com.oracle.graal.compiler.common.type.Stamp; import com.oracle.graal.debug.Debug; -import com.oracle.graal.graph.NodeInputList; +import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.phases.common.CanonicalizerPhase; import com.oracle.graal.phases.common.DeadCodeEliminationPhase; @@ -71,31 +73,34 @@ boolean callerHasMoreInformationAboutArguments = false; NodeInputList args = invoke.callTarget().arguments(); + ArrayList parameterUsages = new ArrayList<>(); for (ParameterNode param : newGraph.getNodes(ParameterNode.class).snapshot()) { ValueNode arg = args.get(param.index()); if (arg.isConstant()) { Constant constant = arg.asConstant(); newGraph.replaceFloating(param, ConstantNode.forConstant(constant, context.getMetaAccess(), newGraph)); callerHasMoreInformationAboutArguments = true; + param.usages().snapshotTo(parameterUsages); } else { Stamp joinedStamp = param.stamp().join(arg.stamp()); if (joinedStamp != null && !joinedStamp.equals(param.stamp())) { param.setStamp(joinedStamp); callerHasMoreInformationAboutArguments = true; + param.usages().snapshotTo(parameterUsages); } } } - if (!callerHasMoreInformationAboutArguments) { + if (callerHasMoreInformationAboutArguments) { + if (OptCanonicalizer.getValue()) { + canonicalizer.applyIncremental(newGraph, context, parameterUsages); + } + } else { // TODO (chaeubl): if args are not more concrete, inlining should be avoided // in most cases or we could at least use the previous graph size + invoke // probability to check the inlining } - if (OptCanonicalizer.getValue()) { - canonicalizer.apply(newGraph, context); - } - return newGraph; } catch (Throwable e) { throw Debug.handle(e); @@ -117,12 +122,10 @@ * profiling info is mature, the resulting graph is cached. */ private static StructuredGraph parseBytecodes(StructuredGraph newGraph, HighTierContext context, CanonicalizerPhase canonicalizer) { - final boolean hasMatureProfilingInfo = newGraph.method().getProfilingInfo().isMature(); - if (context.getGraphBuilderSuite() != null) { context.getGraphBuilderSuite().apply(newGraph, context); } - assert newGraph.start().next() != null : "graph needs to be populated during PhasePosition.AFTER_PARSING"; + assert newGraph.start().next() != null : "graph needs to be populated the GraphBuilderSuite"; new DeadCodeEliminationPhase().apply(newGraph); @@ -130,7 +133,7 @@ canonicalizer.apply(newGraph, context); } - if (hasMatureProfilingInfo && context.getGraphCache() != null) { + if (context.getGraphCache() != null) { context.getGraphCache().put(newGraph.method(), newGraph.copy()); } return newGraph; diff -r edc33e8715d5 -r cf51d3ade2fb graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/InliningData.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/InliningData.java Wed May 28 17:20:35 2014 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/InliningData.java Wed May 28 17:47:12 2014 +0200 @@ -47,9 +47,7 @@ import com.oracle.graal.phases.tiers.HighTierContext; import com.oracle.graal.phases.util.Providers; -import java.util.ArrayDeque; -import java.util.ArrayList; -import java.util.List; +import java.util.*; import java.util.function.ToDoubleFunction; import static com.oracle.graal.compiler.common.GraalOptions.*; @@ -340,19 +338,21 @@ private void doInline(CallsiteHolder callerCallsiteHolder, MethodInvocation calleeInvocation, Assumptions callerAssumptions) { StructuredGraph callerGraph = callerCallsiteHolder.graph(); - Graph.Mark markBeforeInlining = callerGraph.getMark(); InlineInfo calleeInfo = calleeInvocation.callee(); try { try (Debug.Scope scope = Debug.scope("doInline", callerGraph)) { - List invokeUsages = calleeInfo.invoke().asNode().usages().snapshot(); - calleeInfo.inline(new Providers(context), callerAssumptions); + Set canonicalizedNodes = new HashSet<>(); + calleeInfo.invoke().asNode().usages().snapshotTo(canonicalizedNodes); + Collection parameterUsages = calleeInfo.inline(new Providers(context), callerAssumptions); + canonicalizedNodes.addAll(parameterUsages); callerAssumptions.record(calleeInvocation.assumptions()); metricInliningRuns.increment(); Debug.dump(callerGraph, "after %s", calleeInfo); if (OptCanonicalizer.getValue()) { Graph.Mark markBeforeCanonicalization = callerGraph.getMark(); - canonicalizer.applyIncremental(callerGraph, context, invokeUsages, markBeforeInlining); + + canonicalizer.applyIncremental(callerGraph, context, canonicalizedNodes); // process invokes that are possibly created during canonicalization for (Node newNode : callerGraph.getNewNodes(markBeforeCanonicalization)) {