changeset 16320:fcac781d3592

Merge
author Stefan Anzinger <stefan.anzinger@gmail.com>
date Tue, 03 Jun 2014 14:31:36 +0200
parents a4bd33d52985 (current diff) 2e1957c8ccb8 (diff)
children fac4af29aeb8
files graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/GraalOptions.java graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/UnsafeAccess.java graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/AbstractObjectStamp.java graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/FloatStamp.java graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IllegalStamp.java graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IntegerStamp.java graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/ObjectStamp.java graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/PrimitiveStamp.java graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/StampFactory.java graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/StampProvider.java graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/VoidStamp.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/DefaultHotSpotLoweringProvider.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleNode.java graal/com.oracle.graal.hotspotvmconfig/src/com/oracle/graal/hotspotvmconfig/HotSpotVMConstant.java graal/com.oracle.graal.hotspotvmconfig/src/com/oracle/graal/hotspotvmconfig/HotSpotVMField.java graal/com.oracle.graal.hotspotvmconfig/src/com/oracle/graal/hotspotvmconfig/HotSpotVMFlag.java graal/com.oracle.graal.hotspotvmconfig/src/com/oracle/graal/hotspotvmconfig/HotSpotVMType.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BinaryOpLogicNode.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningPhase.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningUtil.java test/whitelist_baseline.txt
diffstat 3 files changed, 50 insertions(+), 43 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java	Tue Jun 03 14:29:40 2014 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java	Tue Jun 03 14:31:36 2014 +0200
@@ -53,6 +53,7 @@
 import com.oracle.graal.nodes.spi.*;
 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.schedule.*;
 import com.oracle.graal.phases.tiers.*;
@@ -124,7 +125,9 @@
 
     protected Suites createSuites() {
         Suites ret = backend.getSuites().createSuites();
-        ret.getHighTier().findPhase(InliningPhase.class).add(new Phase("ComputeLoopFrequenciesPhase") {
+        ListIterator<BasePhase<? super HighTierContext>> iter = ret.getHighTier().findPhase(InliningPhase.class);
+        PhaseSuite.findNextPhase(iter, CanonicalizerPhase.class);
+        iter.add(new Phase("ComputeLoopFrequenciesPhase") {
 
             @Override
             protected void run(StructuredGraph graph) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java	Tue Jun 03 14:29:40 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java	Tue Jun 03 14:31:36 2014 +0200
@@ -42,8 +42,6 @@
     private ResolvedJavaMethod targetMethod;
     private InvokeKind invokeKind;
 
-    private transient Stamp lastCanonicalizedReceiverStamp;
-
     /**
      * @param arguments
      */
@@ -140,17 +138,12 @@
             }
 
             // check if the type of the receiver can narrow the result
-            Stamp receiverStamp = receiver().stamp();
-            if (receiverStamp.equals(lastCanonicalizedReceiverStamp)) {
-                return this;
-            }
-            lastCanonicalizedReceiverStamp = receiverStamp;
-
-            ResolvedJavaType type = StampTool.typeOrNull(receiverStamp);
+            ValueNode receiver = receiver();
+            ResolvedJavaType type = StampTool.typeOrNull(receiver);
             if (type != null && (invoke().stateAfter() != null || invoke().stateDuring() != null)) {
                 // either the holder class is exact, or the receiver object has an exact type
                 ResolvedJavaMethod resolvedMethod = type.resolveMethod(targetMethod, invoke().getContextType());
-                if (resolvedMethod != null && (resolvedMethod.canBeStaticallyBound() || StampTool.isExactType(receiverStamp))) {
+                if (resolvedMethod != null && (resolvedMethod.canBeStaticallyBound() || StampTool.isExactType(receiver))) {
                     invokeKind = InvokeKind.Special;
                     targetMethod = resolvedMethod;
                     return this;
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/elem/InlineableGraph.java	Tue Jun 03 14:29:40 2014 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/elem/InlineableGraph.java	Tue Jun 03 14:31:36 2014 +0200
@@ -42,48 +42,48 @@
     private final StructuredGraph graph;
 
     public InlineableGraph(final ResolvedJavaMethod method, final Invoke invoke, final HighTierContext context, CanonicalizerPhase canonicalizer) {
-        this.graph = buildGraph(method, invoke, context, canonicalizer);
+        StructuredGraph original = getOriginalGraph(method, context, canonicalizer);
+        // TODO copying the graph is only necessary if it is modified or if it contains any invokes
+        this.graph = original.copy();
+        specializeGraphToArguments(invoke, context, canonicalizer);
     }
 
     /**
-     * @return a (possibly cached) graph. The caller is responsible for cloning before modification.
+     * This method looks up in a cache the graph for the argument, if not found bytecode is parsed.
+     * The graph thus obtained is returned, ie the caller is responsible for cloning before
+     * modification.
      */
-    private static StructuredGraph getOriginalGraph(final ResolvedJavaMethod method, final HighTierContext context) {
-        StructuredGraph intrinsicGraph = InliningUtil.getIntrinsicGraph(context.getReplacements(), method);
-        if (intrinsicGraph != null) {
-            return intrinsicGraph;
+    private static StructuredGraph getOriginalGraph(final ResolvedJavaMethod method, final HighTierContext context, CanonicalizerPhase canonicalizer) {
+        StructuredGraph result = InliningUtil.getIntrinsicGraph(context.getReplacements(), method);
+        if (result != null) {
+            return result;
         }
-        StructuredGraph cachedGraph = getCachedGraph(method, context);
-        if (cachedGraph != null) {
-            return cachedGraph;
+        result = getCachedGraph(method, context);
+        if (result != null) {
+            return result;
         }
-        return null;
+        return parseBytecodes(method, context, canonicalizer);
     }
 
-    private static StructuredGraph buildGraph(final ResolvedJavaMethod method, final Invoke invoke, final HighTierContext context, CanonicalizerPhase canonicalizer) {
-        StructuredGraph newGraph = getOriginalGraph(method, context);
-        if (newGraph == null) {
-            newGraph = new StructuredGraph(method);
-            parseBytecodes(newGraph, context, canonicalizer);
-        }
-        newGraph = newGraph.copy();
+    /**
+     * @return true iff one or more parameters <code>newGraph</code> were specialized to account for
+     *         a constant argument, or an argument with a more specific stamp.
+     */
+    private boolean specializeGraphToArguments(final Invoke invoke, final HighTierContext context, CanonicalizerPhase canonicalizer) {
+        try (Debug.Scope s = Debug.scope("InlineGraph", graph)) {
 
-        // TODO (chaeubl): copying the graph is only necessary if it is modified or if it contains
-        // any invokes
-
-        try (Debug.Scope s = Debug.scope("InlineGraph", newGraph)) {
-
-            ArrayList<Node> parameterUsages = replaceParamsWithMoreInformativeArguments(invoke, newGraph, context);
+            ArrayList<Node> parameterUsages = replaceParamsWithMoreInformativeArguments(invoke, context);
             if (parameterUsages != null && OptCanonicalizer.getValue()) {
                 assert !parameterUsages.isEmpty() : "The caller didn't have more information about arguments after all";
-                canonicalizer.applyIncremental(newGraph, context, parameterUsages);
+                canonicalizer.applyIncremental(graph, context, parameterUsages);
+                return true;
             } 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
+                return false;
             }
 
-            return newGraph;
         } catch (Throwable e) {
             throw Debug.handle(e);
         }
@@ -119,17 +119,26 @@
      * @return null if no incremental canonicalization is need, a list of nodes for such
      *         canonicalization otherwise.
      */
-    private static ArrayList<Node> replaceParamsWithMoreInformativeArguments(final Invoke invoke, final StructuredGraph newGraph, final HighTierContext context) {
+    private ArrayList<Node> replaceParamsWithMoreInformativeArguments(final Invoke invoke, final HighTierContext context) {
         NodeInputList<ValueNode> args = invoke.callTarget().arguments();
         ArrayList<Node> parameterUsages = null;
-        for (ParameterNode param : newGraph.getNodes(ParameterNode.class).snapshot()) {
+        List<ParameterNode> params = graph.getNodes(ParameterNode.class).snapshot();
+        assert params.size() <= args.size();
+        /*
+         * param-nodes that aren't used (eg, as a result of canonicalization) don't occur in
+         * `params`. Thus, in general, the sizes of `params` and `args` don't always match. Still,
+         * it's always possible to pair a param-node with its corresponding arg-node using
+         * param.index() as index into `args`.
+         */
+        for (ParameterNode param : params) {
             if (param.usages().isNotEmpty()) {
                 ValueNode arg = args.get(param.index());
                 if (arg.isConstant()) {
                     Constant constant = arg.asConstant();
                     parameterUsages = trackParameterUsages(param, parameterUsages);
                     // collect param usages before replacing the param
-                    newGraph.replaceFloating(param, ConstantNode.forConstant(constant, context.getMetaAccess(), newGraph));
+                    graph.replaceFloating(param, ConstantNode.forConstant(constant, context.getMetaAccess(), graph));
+                    // param-node gone, leaving a gap in the sequence given by param.index()
                 } else {
                     Stamp joinedStamp = param.stamp().join(arg.stamp());
                     if (joinedStamp != null && !joinedStamp.equals(param.stamp())) {
@@ -141,6 +150,7 @@
                 }
             }
         }
+        assert (parameterUsages == null) || (!parameterUsages.isEmpty());
         return parameterUsages;
     }
 
@@ -161,11 +171,12 @@
     }
 
     /**
-     * This method builds the IR nodes for <code>newGraph</code> and canonicalizes them. Provided
-     * profiling info is mature, the resulting graph is cached. The caller is responsible for
-     * cloning before modification.</p>
+     * This method builds the IR nodes for the given <code>method</code> and canonicalizes them.
+     * Provided profiling info is mature, the resulting graph is cached. The caller is responsible
+     * for cloning before modification.</p>
      */
-    private static StructuredGraph parseBytecodes(StructuredGraph newGraph, HighTierContext context, CanonicalizerPhase canonicalizer) {
+    private static StructuredGraph parseBytecodes(ResolvedJavaMethod method, HighTierContext context, CanonicalizerPhase canonicalizer) {
+        StructuredGraph newGraph = new StructuredGraph(method);
         try (Debug.Scope s = Debug.scope("InlineGraph", newGraph)) {
             if (context.getGraphBuilderSuite() != null) {
                 context.getGraphBuilderSuite().apply(newGraph, context);