changeset 15957:cf51d3ade2fb

less canonicalization during InliningPhase
author Lukas Stadler <lukas.stadler@oracle.com>
date Wed, 28 May 2014 17:47:12 +0200
parents edc33e8715d5
children 8a39e009c142
files graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/AbstractInlineInfo.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/AssumptionInlineInfo.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/ExactInlineInfo.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/InlineInfo.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/MultiTypeGuardInlineInfo.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/TypeGuardInlineInfo.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/elem/InlineableGraph.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/InliningData.java
diffstat 8 files changed, 69 insertions(+), 38 deletions(-) [+]
line wrap: on
line diff
--- 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<Node> inline(Invoke invoke, ResolvedJavaMethod concrete, Inlineable inlineable, Assumptions assumptions, boolean receiverNullCheck) {
+        Collection<Node> parameterUsages = new ArrayList<>();
         if (inlineable instanceof InlineableGraph) {
             StructuredGraph calleeGraph = ((InlineableGraph) inlineable).getGraph();
-            InliningUtil.inline(invoke, calleeGraph, receiverNullCheck);
+            Map<Node, Node> 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<? extends FixedWithNextNode> 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;
     }
 }
--- 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<Node> inline(Providers providers, Assumptions assumptions) {
         assumptions.record(takenAssumption);
-        super.inline(providers, assumptions);
+        return super.inline(providers, assumptions);
     }
 
     @Override
--- 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<Node> inline(Providers providers, Assumptions assumptions) {
+        return inline(invoke, concrete, inlineableElement, assumptions, !suppressNullCheck);
     }
 
     @Override
--- 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<Node> inline(Providers providers, Assumptions assumptions);
 
     /**
      * Try to make the call static bindable to avoid interface and virtual method calls.
--- 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<Node> 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<Node> inlineMultipleMethods(StructuredGraph graph, Providers providers, Assumptions assumptions) {
         int numberOfMethods = concretes.size();
         FixedNode continuation = invoke.next();
 
@@ -222,6 +222,8 @@
 
         ArrayList<GuardedValueNode> replacementNodes = new ArrayList<>();
 
+        Collection<Node> 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<Node> 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) {
--- 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<Node> inline(Providers providers, Assumptions assumptions) {
         createGuard(graph(), providers.getMetaAccess());
-        inline(invoke, concrete, inlineableElement, assumptions, false);
+        return inline(invoke, concrete, inlineableElement, assumptions, false);
     }
 
     @Override
--- 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<ValueNode> args = invoke.callTarget().arguments();
+            ArrayList<Node> 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;
--- 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<Node> invokeUsages = calleeInfo.invoke().asNode().usages().snapshot();
-                calleeInfo.inline(new Providers(context), callerAssumptions);
+                Set<Node> canonicalizedNodes = new HashSet<>();
+                calleeInfo.invoke().asNode().usages().snapshotTo(canonicalizedNodes);
+                Collection<Node> 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)) {