Mercurial > hg > graal-compiler
changeset 23330:15964d565d42
GraphPE: support phi functions when creating loop exit state
author | Christian Wimmer <christian.wimmer@oracle.com> |
---|---|
date | Tue, 19 Jan 2016 11:36:05 -0800 |
parents | 3609732616e9 |
children | 8d31c062a05c |
files | graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GraphDecoder.java |
diffstat | 1 files changed, 17 insertions(+), 12 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GraphDecoder.java Tue Jan 19 10:57:09 2016 -0800 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GraphDecoder.java Tue Jan 19 11:36:05 2016 -0800 @@ -1294,26 +1294,20 @@ * not insert a LoopExit in such cases, we also do not have to insert a LoopExit. */ if (next instanceof EndNode) { - AbstractMergeNode merge = ((EndNode) next).merge(); - if (methodScope.loopExplosionMerges.contains(merge)) { - /* - * If this guarantee fails, we need to handle phi functions of the merge, - * i.e., take the phi function input for our EndNode and put it into the - * LoopExit state. - */ - JVMCIError.guarantee(merge.cfgPredecessors().count() == 1, merge.toString()); - + EndNode loopExplosionEnd = (EndNode) next; + AbstractMergeNode loopExplosionMerge = loopExplosionEnd.merge(); + if (methodScope.loopExplosionMerges.contains(loopExplosionMerge)) { LoopExitNode loopExit = methodScope.graph.add(new LoopExitNode(loopBegin)); next.replaceAtPredecessor(loopExit); loopExit.setNext(next); - assignLoopExitState(methodScope, loopExit, merge); + assignLoopExitState(methodScope, loopExit, loopExplosionMerge, loopExplosionEnd); } } } } } - private static void assignLoopExitState(MethodScope methodScope, LoopExitNode loopExit, AbstractMergeNode loopExplosionMerge) { + private static void assignLoopExitState(MethodScope methodScope, LoopExitNode loopExit, AbstractMergeNode loopExplosionMerge, AbstractEndNode loopExplosionEnd) { FrameState oldState = loopExplosionMerge.stateAfter(); JVMCIError.guarantee(loopExit.loopBegin().stateAfter().outerFrameState() == oldState.outerFrameState(), "LoopBegin and LoopExit must have the same outer frame state"); @@ -1326,9 +1320,20 @@ } List<ValueNode> newValues = new ArrayList<>(oldState.values().size()); - for (ValueNode value : oldState.values()) { + for (ValueNode v : oldState.values()) { + ValueNode value = v; ValueNode realValue = ProxyPlaceholder.unwrap(value); + /* + * The LoopExit is inserted before the existing merge, i.e., separately for every branch + * that leads to the merge. So for phi functions of the merge, we need to take the input + * that corresponds to our branch. + */ + if (realValue instanceof PhiNode && loopExplosionMerge.isPhiAtMerge(realValue)) { + value = ((PhiNode) realValue).valueAt(loopExplosionEnd); + realValue = ProxyPlaceholder.unwrap(value); + } + if (realValue == null || realValue.isConstant() || loopBeginValues.contains(realValue)) { newValues.add(realValue); } else {