# HG changeset patch # User Gilles Duboscq # Date 1310487285 -7200 # Node ID 1ba9612f6d6ec6b4c1dc481caff988c8a3ffcd7d # Parent 1e5ca59c87690f46f7c0ff59c0979b275de321b8# Parent 76507b87dd2554e551fa6f712b6e1497361b2e28 Merge diff -r 76507b87dd25 -r 1ba9612f6d6e graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalOptions.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalOptions.java Tue Jul 12 17:00:25 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalOptions.java Tue Jul 12 18:14:45 2011 +0200 @@ -36,7 +36,6 @@ private static final boolean ____ = false; // Checkstyle: resume - public static boolean Lower = true; // inlining settings @@ -167,4 +166,5 @@ public static boolean OptOptimisticSchedule = ____; public static boolean OptReorderLoops = ____; public static boolean LoopPeeling = ____; + public static boolean LoopInversion = ____; } diff -r 76507b87dd25 -r 1ba9612f6d6e graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/LoopPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/LoopPhase.java Tue Jul 12 17:00:25 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/LoopPhase.java Tue Jul 12 18:14:45 2011 +0200 @@ -41,28 +41,21 @@ protected void run(Graph graph) { List loops = LoopUtil.computeLoops(graph); - // TODO (gd) currently counter detection is disabled when loop peeling is active - if (GraalOptions.LoopPeeling) { -peeling: + if (GraalOptions.LoopPeeling || GraalOptions.LoopInversion) { for (Loop loop : loops) { - GraalCompilation compilation = GraalCompilation.compilation(); - if (compilation.compiler.isObserved()) { - Map debug = new HashMap(); - debug.put("loopExits", loop.exits()); - debug.put("inOrBefore", loop.inOrBefore()); - debug.put("inOrAfter", loop.inOrAfter()); - debug.put("nodes", loop.nodes()); - compilation.compiler.fireCompilationEvent(new CompilationEvent(compilation, "Loop #" + loop.loopBegin().id(), graph, true, false, debug)); - } - //System.out.println("Peel loop : " + loop.loopBegin()); + boolean hasBadExit = false; for (Node exit : loop.exits()) { if (!(exit instanceof StateSplit) || ((StateSplit) exit).stateAfter() == null) { // TODO (gd) can not do loop peeling if an exit has no state. see LoopUtil.findNearestMergableExitPoint - continue peeling; + hasBadExit = true; + break; } } + if (hasBadExit) { + continue; + } boolean canInvert = false; - if (loop.loopBegin().next() instanceof If) { + if (GraalOptions.LoopInversion && loop.loopBegin().next() instanceof If) { If ifNode = (If) loop.loopBegin().next(); if (loop.exits().isMarked(ifNode.trueSuccessor()) || loop.exits().isMarked(ifNode.falseSuccessor())) { canInvert = true; @@ -70,16 +63,25 @@ } if (canInvert) { LoopUtil.inverseLoop(loop, (If) loop.loopBegin().next()); - } else { + } else if (GraalOptions.LoopPeeling) { + GraalCompilation compilation = GraalCompilation.compilation(); + if (compilation.compiler.isObserved()) { + Map debug = new HashMap(); + debug.put("loopExits", loop.exits()); + debug.put("inOrBefore", loop.inOrBefore()); + debug.put("inOrAfter", loop.inOrAfter()); + debug.put("nodes", loop.nodes()); + compilation.compiler.fireCompilationEvent(new CompilationEvent(compilation, "Loop #" + loop.loopBegin().id(), graph, true, false, debug)); + } LoopUtil.peelLoop(loop); } } - } else { -// loops = LoopUtil.computeLoops(graph); // TODO (gd) avoid recomputing loops - for (Loop loop : loops) { - doLoopCounters(loop); - } } + + /* + for (Loop loop : loops) { + doLoopCounters(loop); + }*/ } private void doLoopCounters(Loop loop) { @@ -172,7 +174,7 @@ useCounterAfterAdd = true; } } - if (stride != null && !loopNodes.isNotNewNotMarked(stride)) { + if (stride != null && loopNodes.isNotNewNotMarked(stride)) { Graph graph = loopBegin.graph(); LoopCounter counter = new LoopCounter(init.kind, init, stride, loopBegin, graph); counters.add(counter); diff -r 76507b87dd25 -r 1ba9612f6d6e 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 Tue Jul 12 17:00:25 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/LoopUtil.java Tue Jul 12 18:14:45 2011 +0200 @@ -176,7 +176,7 @@ loopNodes.mark(loopBegin); NodeBitMap inOrAfter = inOrAfter(loop, loopNodes, false); NodeBitMap inOrBefore = inOrBefore(loop, inOrAfter, loopNodes, false); - /*if (!recurse) { + if (!recurse) { recurse = true; GraalCompilation compilation = GraalCompilation.compilation(); if (compilation.compiler.isObserved()) { @@ -187,7 +187,7 @@ compilation.compiler.fireCompilationEvent(new CompilationEvent(compilation, "Compute loop nodes loop#" + loopBegin.id(), loopBegin.graph(), true, false, debug)); } recurse = false; - }*/ + } inOrAfter.setIntersect(inOrBefore); loopNodes.setUnion(inOrAfter); if (from == loopBegin.loopEnd()) { // fill the Loop cache value for loop nodes this is correct even if after/before were partial @@ -196,7 +196,11 @@ return loopNodes; } - private static NodeBitMap markUpCFG(LoopBegin loopBegin, FixedNode from) { + public static NodeBitMap markUpCFG(LoopBegin loopBegin) { + return markUpCFG(loopBegin, loopBegin.loopEnd()); + } + + public static NodeBitMap markUpCFG(LoopBegin loopBegin, FixedNode from) { NodeFlood workCFG = loopBegin.graph().createNodeFlood(); workCFG.add(from); NodeBitMap loopNodes = loopBegin.graph().createNodeBitMap(); @@ -285,6 +289,17 @@ } } + loop.invalidateCached(); + + // update parents + Loop parent = loop.parent(); + while (parent != null) { + parent.cfgNodes = markUpCFG(parent.loopBegin, parent.loopBegin.loopEnd()); + parent.invalidateCached(); + parent.exits = computeLoopExits(parent.loopBegin, parent.cfgNodes); + parent = parent.parent; + } + GraalMetrics.LoopsInverted++; } @@ -318,6 +333,7 @@ /*if (compilation.compiler.isObserved()) { compilation.compiler.fireCompilationEvent(new CompilationEvent(compilation, "After rewirePeeling", loopEnd.graph(), true, false)); }*/ + loop.invalidateCached(); // update parents Loop parent = loop.parent(); while (parent != null) { @@ -417,7 +433,7 @@ Value backValue = null; if (inversion && originalValue instanceof Phi && ((Phi) originalValue).merge() == loopBegin) { backValue = ((Phi) originalValue).valueAt(phiBackIndex); - if (!loop.nodes().isMarked(backValue) || peeling.peeledNodes.isNotNewMarked(backValue)) { + if (peeling.peeledNodes.isNotNewMarked(backValue)) { backValue = null; } } @@ -732,9 +748,13 @@ Value backValue = phi.valueAt(backIndex); if (marked.isMarked(backValue)) { phiInits.set(phi, duplicates.get(backValue)); - } else if (from == loopBegin.loopEnd() && backValue instanceof Phi && ((Phi) backValue).merge() == loopBegin) { - Phi backPhi = (Phi) backValue; - phiInits.set(phi, backPhi.valueAt(fowardIndex)); + } else if (from == loopBegin.loopEnd()) { + if (backValue instanceof Phi && ((Phi) backValue).merge() == loopBegin) { + Phi backPhi = (Phi) backValue; + phiInits.set(phi, backPhi.valueAt(fowardIndex)); + } else { + phiInits.set(phi, backValue); + } } } @@ -867,6 +887,21 @@ } } } + if (cfgNodes.isNotNewMarked(n)) { //add all values from the exits framestates + for (Node sux : n.cfgSuccessors()) { + if (loop.exits().isNotNewMarked(sux) && sux instanceof StateSplit) { + FrameState stateAfter = ((StateSplit) sux).stateAfter(); + while (stateAfter != null) { + for (Node in : stateAfter.inputs()) { + if (!(in instanceof FrameState)) { + work.add(in); + } + } + stateAfter = stateAfter.outerFrameState(); + } + } + } + } if (n instanceof Merge) { //add phis & counters for (Node usage : n.dataUsages()) { if (!(usage instanceof LoopEnd)) { diff -r 76507b87dd25 -r 1ba9612f6d6e graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/opt/OptimizerImpl.java --- a/graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/opt/OptimizerImpl.java Tue Jul 12 17:00:25 2011 +0200 +++ b/graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/opt/OptimizerImpl.java Tue Jul 12 18:14:45 2011 +0200 @@ -59,7 +59,7 @@ private boolean canOverflow(Phi phi, LoopBegin loopBegin) { - NodeBitMap nodes = LoopUtil.computeLoopNodes(loopBegin); + NodeBitMap nodes = LoopUtil.markUpCFG(loopBegin); NodeBitMap exits = LoopUtil.computeLoopExits(loopBegin, nodes); for (Node exit : exits) { TTY.println("exit: " + exit);