# HG changeset patch # User Thomas Wuerthinger # Date 1367131588 -7200 # Node ID 4a9fd6d90284e345fb6788a692d4d8ce86e1fb95 # Parent 033b0cd7d34200134b90de0590bedf7bcc8d68c4 Implement alternative fix for removeIntermediateMaterialization. diff -r 033b0cd7d342 -r 4a9fd6d90284 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java Sun Apr 28 07:50:32 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java Sun Apr 28 08:46:28 2013 +0200 @@ -164,6 +164,10 @@ } } + if (removeIntermediateMaterialization(tool)) { + return; + } + if (falseSuccessor().usages().isEmpty() && (!(falseSuccessor() instanceof LoopExitNode)) && falseSuccessor().next() instanceof IfNode) { BeginNode intermediateBegin = falseSuccessor(); IfNode nextIf = (IfNode) intermediateBegin.next(); @@ -397,7 +401,7 @@ * * @return true if a transformation was made, false otherwise */ - public boolean removeIntermediateMaterialization(SimplifierTool tool) { + private boolean removeIntermediateMaterialization(SimplifierTool tool) { if (!(condition() instanceof CompareNode)) { return false; } @@ -449,6 +453,11 @@ return false; } + // Sanity check that both ends are not followed by a merge without frame state. + if (!checkFrameState(trueSuccessor()) && !checkFrameState(falseSuccessor())) { + return false; + } + List falseEnds = new ArrayList<>(mergePredecessors.size()); List trueEnds = new ArrayList<>(mergePredecessors.size()); Map phiValues = new HashMap<>(mergePredecessors.size()); @@ -485,6 +494,46 @@ return true; } + private static boolean checkFrameState(FixedNode start) { + FixedNode node = start; + while (true) { + if (node instanceof MergeNode) { + MergeNode mergeNode = (MergeNode) node; + if (mergeNode.stateAfter() == null) { + return false; + } else { + return true; + } + } else if (node instanceof StateSplit) { + StateSplit stateSplitNode = (StateSplit) node; + if (stateSplitNode.stateAfter() != null) { + return true; + } + } + + if (node instanceof ControlSplitNode) { + ControlSplitNode controlSplitNode = (ControlSplitNode) node; + for (Node succ : controlSplitNode.cfgSuccessors()) { + if (checkFrameState((FixedNode) succ)) { + return true; + } + } + return false; + } else if (node instanceof FixedWithNextNode) { + FixedWithNextNode fixedWithNextNode = (FixedWithNextNode) node; + node = fixedWithNextNode.next(); + } else if (node instanceof EndNode) { + EndNode endNode = (EndNode) node; + node = endNode.merge(); + } else if (node instanceof ControlSinkNode) { + return true; + } else { + TTY.println("node: " + node); + return false; + } + } + } + /** * Connects a set of ends to a given successor, inserting a merge node if there is more than one * end. If {@code ends} is empty, then {@code successor} is @@ -500,13 +549,6 @@ } else { if (ends.size() == 1) { EndNode end = ends.get(0); - FrameState stateAfter = oldMerge.stateAfter(); - if (stateAfter != null) { - stateAfter = stateAfter.duplicate(); - PhiNode oldPhi = (PhiNode) oldMerge.usages().first(); - stateAfter.replaceFirstInput(oldPhi, phiValues.get(end)); - successor.setStateAfter(stateAfter); - } ((FixedWithNextNode) end.predecessor()).setNext(successor); oldMerge.removeEnd(end); GraphUtil.killCFG(end);