# HG changeset patch # User Gilles Duboscq # Date 1310562529 -7200 # Node ID 0ab38d1437957678f5d3d9cdb3a004d7b9211d31 # Parent 0ca900bab9d09d347404655c5c7294ac575def61 Fix for loop inversion now runs tests, fop, lusearch, eclipse, avrora and scimark diff -r 0ca900bab9d0 -r 0ab38d143795 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/LoopUtil.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/LoopUtil.java Wed Jul 13 15:05:04 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/LoopUtil.java Wed Jul 13 15:08:49 2011 +0200 @@ -232,49 +232,18 @@ assert loop.cfgNodes().isMarked(noExit); PeelingResult peeling = preparePeeling(loop, split); - rewirePeeling(peeling, loop, split, true); + rewireInversion(peeling, loop, split); // move peeled part to the end LoopBegin loopBegin = loop.loopBegin(); LoopEnd loopEnd = loopBegin.loopEnd(); FixedNode lastNode = (FixedNode) loopEnd.singlePredecessor(); - Graph graph = loopBegin.graph(); if (loopBegin.next() != lastNode) { lastNode.successors().replace(loopEnd, loopBegin.next()); loopBegin.setNext(noExit); split.successors().replace(noExit, loopEnd); } - // rewire dataOut - NodeBitMap exitMergesPhis = graph.createNodeBitMap(); - for (Entry entry : peeling.exits.entries()) { - StateSplit newExit = entry.getValue(); - Merge merge = ((EndNode) newExit.next()).merge(); - exitMergesPhis.markAll(merge.phis()); - } - for (Entry entry : peeling.dataOut.entries()) { - Value originalValue = (Value) entry.getKey(); - if (originalValue instanceof Phi && ((Phi) originalValue).merge() == loopBegin) { - continue; - } - Value newValue = (Value) entry.getValue(); - Phi phi = null; - List usages = new ArrayList(originalValue.usages()); - for (Node usage : usages) { - if (exitMergesPhis.isMarked(usage) || ( - loop.nodes().isNotNewMarked(usage) - && peeling.peeledNodes.isNotNewNotMarked(usage) - && !(usage instanceof Phi && ((Phi) usage).merge() == loopBegin)) - && !(usage instanceof FrameState && ((FrameState) usage).block() == loopBegin)) { - if (phi == null) { - phi = new Phi(originalValue.kind, loopBegin, PhiType.Value, graph); - phi.addInput(newValue); - phi.addInput(originalValue); - } - usage.inputs().replace(originalValue, phi); - } - } - } //rewire phi usage in peeled part int backIndex = loopBegin.phiPredecessorIndex(loopBegin.loopEnd()); for (Phi phi : loopBegin.phis()) { @@ -329,7 +298,7 @@ for (Entry entry : peeling.dataOut.entries()) { System.out.println(" - " + entry.getKey() + " -> " + entry.getValue()); }*/ - rewirePeeling(peeling, loop, loopEnd, false); + rewirePeeling(peeling, loop); /*if (compilation.compiler.isObserved()) { compilation.compiler.fireCompilationEvent(new CompilationEvent(compilation, "After rewirePeeling", loopEnd.graph(), true, false)); }*/ @@ -345,6 +314,14 @@ GraalMetrics.LoopsPeeled++; } + private static void rewireInversion(PeelingResult peeling, Loop loop, FixedNode from) { + rewirePeeling(peeling, loop, from, true); + } + + private static void rewirePeeling(PeelingResult peeling, Loop loop) { + rewirePeeling(peeling, loop, loop.loopBegin().loopEnd(), false); + } + private static void rewirePeeling(PeelingResult peeling, Loop loop, FixedNode from, boolean inversion) { LoopBegin loopBegin = loop.loopBegin(); Graph graph = loopBegin.graph(); @@ -398,6 +375,7 @@ for (Node exit : peeling.unaffectedExits) { exitPoints.add(exit); } + for (Entry entry : peeling.exits.entries()) { StateSplit original = (StateSplit) entry.getKey(); StateSplit newExit = entry.getValue(); @@ -446,6 +424,43 @@ } } + if (inversion) { + // rewire dataOut in non-peeled body + NodeBitMap exitMergesPhis = graph.createNodeBitMap(); + for (Entry entry : peeling.exits.entries()) { + StateSplit newExit = entry.getValue(); + Merge merge = ((EndNode) newExit.next()).merge(); + exitMergesPhis.markAll(merge.phis()); + } + for (Entry entry : peeling.dataOut.entries()) { + Value originalValue = (Value) entry.getKey(); + if (originalValue instanceof Phi && ((Phi) originalValue).merge() == loopBegin) { + continue; + } + Value newValue = (Value) entry.getValue(); + Phi phi = null; + List usages = new ArrayList(originalValue.usages()); + for (Node usage : usages) { + if (exitMergesPhis.isMarked(usage) || ( + loop.nodes().isNotNewMarked(usage) + && peeling.peeledNodes.isNotNewNotMarked(usage) + && !(usage instanceof Phi && ((Phi) usage).merge() == loopBegin)) + && !(usage instanceof FrameState && ((FrameState) usage).block() == loopBegin)) { + if (phi == null) { + phi = new Phi(originalValue.kind, loopBegin, PhiType.Value, graph); + phi.addInput(newValue); + phi.addInput(originalValue); + NodeMap exitMap = newExitValues.get(originalValue); + for (Node exit : peeling.unaffectedExits) { + exitMap.set(exit, phi); + } + } + usage.inputs().replace(originalValue, phi); + } + } + } + } + for (Entry> entry : newExitValues.entries()) { Value original = (Value) entry.getKey(); NodeMap pointToValue = entry.getValue();