Mercurial > hg > truffle
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) {