changeset 4454:008a5ea590ca

fixed merge control flow for inlining
author Christian Haeubl <christian.haeubl@oracle.com>
date Mon, 30 Jan 2012 11:13:45 -0800
parents c0430421d43d
children b788ebbb7ef8
files graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/InliningUtil.java
diffstat 1 files changed, 38 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/InliningUtil.java	Fri Jan 27 21:17:33 2012 -0800
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/InliningUtil.java	Mon Jan 30 11:13:45 2012 -0800
@@ -223,6 +223,7 @@
             Node returnValue = null;
             if (numberOfMethods > 1) {
                 merge = graph.add(new MergeNode());
+                merge.setStateAfter(invoke.stateAfter());
                 merge.setNext(continuation);
                 if (hasReturnValue) {
                     returnValuePhi = graph.unique(new PhiNode(callTargetNode.kind(), merge, PhiType.Value));
@@ -230,13 +231,16 @@
                 }
             }
 
-            // TODO (ch) do not create merge nodes if not necessary. Otherwise GraphVisualizer seems to loose half of the phase outputs?
-
             // create a separate block for each invoked method
-            MergeNode[] successorMethods = new MergeNode[numberOfMethods];
+            BeginNode[] successorMethods = new BeginNode[numberOfMethods];
             for (int i = 0; i < numberOfMethods; i++) {
                 Invoke duplicatedInvoke = duplicateInvoke(invoke);
-                MergeNode calleeEntryNode = graph.add(new MergeNode());
+                BeginNode calleeEntryNode;
+                if (getPredecessorCount(i) > 1) {
+                    calleeEntryNode = graph.add(new MergeNode());
+                } else {
+                    calleeEntryNode = graph.add(new BeginNode());
+                }
                 calleeEntryNode.setNext(duplicatedInvoke.node());
                 successorMethods[i] = calleeEntryNode;
 
@@ -260,20 +264,28 @@
             graph.addBeforeFixed(invoke.node(), objectClassNode);
 
             int lastIndex = types.length - 1;
-            MergeNode tsux = successorMethods[typesToConcretes[lastIndex]];
+            BeginNode tsux = successorMethods[typesToConcretes[lastIndex]];
             IsTypeNode isTypeNode = graph.unique(new IsTypeNode(objectClassNode, types[lastIndex]));
-            EndNode endNode = graph.add(new EndNode());
             FixedGuardNode guardNode = graph.add(new FixedGuardNode(isTypeNode));
-            guardNode.setNext(endNode);
-            tsux.addEnd(endNode);
+            if (tsux instanceof MergeNode) {
+                EndNode endNode = graph.add(new EndNode());
+                guardNode.setNext(endNode);
+                ((MergeNode) tsux).addEnd(endNode);
+            } else {
+                guardNode.setNext(tsux);
+            }
 
             FixedNode nextNode = guardNode;
             for (int i = lastIndex - 1; i >= 0; i--) {
                 tsux = successorMethods[typesToConcretes[i]];
                 isTypeNode = graph.unique(new IsTypeNode(objectClassNode, types[i]));
-                endNode = graph.add(new EndNode());
-                nextNode = graph.add(new IfNode(isTypeNode, endNode, nextNode, probabilities[i]));
-                tsux.addEnd(endNode);
+                if (tsux instanceof MergeNode) {
+                    EndNode endNode = graph.add(new EndNode());
+                    nextNode = graph.add(new IfNode(isTypeNode, endNode, nextNode, probabilities[i]));
+                    ((MergeNode) tsux).addEnd(endNode);
+                } else {
+                    nextNode = graph.add(new IfNode(isTypeNode, tsux, nextNode, probabilities[i]));
+                }
             }
 
             // replace the original invocation with a cascade of if nodes and replace the usages of invoke with the return value (phi or duplicatedInvoke)
@@ -283,7 +295,7 @@
 
             // do the actual inlining for every invocation
             for (int i = 0; i < successorMethods.length; i++) {
-                MergeNode node = successorMethods[i];
+                BeginNode node = successorMethods[i];
                 Invoke invokeForInlining = (Invoke) node.next();
                 StructuredGraph calleeGraph = getGraph(invokeForInlining, concretes.get(i), callback);
                 InliningUtil.inline(invokeForInlining, calleeGraph, false);
@@ -294,6 +306,20 @@
             }
         }
 
+        private int getPredecessorCount(int concreteMethodIndex) {
+            if (concretes.size() == types.length) {
+                return 1;
+            } else {
+                int count = 0;
+                for (int i = 0; i < typesToConcretes.length; i++) {
+                    if (typesToConcretes[i] == concreteMethodIndex) {
+                        count++;
+                    }
+                }
+                return count;
+            }
+        }
+
         private static Invoke duplicateInvoke(Invoke invoke) {
             Invoke result = (Invoke) invoke.node().copyWithInputs();
             if (invoke instanceof InvokeWithExceptionNode) {