# HG changeset patch # User Gilles Duboscq # Date 1341240792 -7200 # Node ID c84c75339af1cb99ad9ae11c24fde7ff93898d3f # Parent 98325620b7e2103d3024d3f4078ad6bf5fc33c28 Work on loop unswitching, things look ok, still disabled until FloatingRead preserves loop-closed form diff -r 98325620b7e2 -r c84c75339af1 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Mon Jul 02 15:08:05 2012 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Mon Jul 02 16:53:12 2012 +0200 @@ -188,18 +188,17 @@ if (GraalOptions.CheckCastElimination) { new CheckCastEliminationPhase().apply(graph); } + if (GraalOptions.OptCanonicalizer) { + new CanonicalizerPhase(target, runtime, assumptions).apply(graph); + } + if (GraalOptions.OptCanonicalizer) { + new CanonicalizerPhase(target, runtime, assumptions).apply(graph); + } if (GraalOptions.OptLoopTransform) { new LoopTransformLowPhase().apply(graph); } new RemoveValueProxyPhase().apply(graph); - if (GraalOptions.OptCanonicalizer) { - new CanonicalizerPhase(target, runtime, assumptions).apply(graph); - } - if (GraalOptions.CheckCastElimination) { - new CheckCastEliminationPhase().apply(graph); - } - plan.runPhases(PhasePosition.MID_LEVEL, graph); diff -r 98325620b7e2 -r c84c75339af1 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalOptions.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalOptions.java Mon Jul 02 15:08:05 2012 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalOptions.java Mon Jul 02 16:53:12 2012 +0200 @@ -97,11 +97,11 @@ //rematerialize settings public static float MinimumUsageProbability = 0.95f; - //loop transform settings + //loop transform settings TODO (gd) tune public static float MinimumPeelProbability = 0.35f; public static boolean ReassociateInvariants = true; public static boolean FullUnroll = true; - public static int FullUnrollMaxNodes = 150; // TODO (gd) tune + public static int FullUnrollMaxNodes = 150; public static boolean LoopUnswitch = ____; public static int LoopUnswitchMaxIncrease = 50; public static int LoopUnswitchUncertaintyBoost = 5; diff -r 98325620b7e2 -r c84c75339af1 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopFragment.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopFragment.java Mon Jul 02 15:08:05 2012 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopFragment.java Mon Jul 02 16:53:12 2012 +0200 @@ -89,7 +89,13 @@ public abstract NodeIterable nodes(); public StructuredGraph graph() { - return (StructuredGraph) loop.loopBegin().graph(); + LoopEx l; + if (isDuplicate()) { + l = original().loop(); + } else { + l = loop(); + } + return (StructuredGraph) l.loopBegin().graph(); } protected abstract DuplicationReplacement getDuplicationReplacement(); @@ -99,11 +105,13 @@ protected void patchNodes(final DuplicationReplacement dataFix) { if (isDuplicate() && !nodesReady) { assert !original.isDuplicate(); - final DuplicationReplacement cfgFix = getDuplicationReplacement(); + final DuplicationReplacement cfgFix = original().getDuplicationReplacement(); DuplicationReplacement dr; - if (cfgFix == null) { + if (cfgFix == null && dataFix != null) { dr = dataFix; - } else { + } else if (cfgFix != null && dataFix == null) { + dr = cfgFix; + } else if (cfgFix != null && dataFix != null) { dr = new DuplicationReplacement() { @Override public Node replacement(Node o) { @@ -119,8 +127,15 @@ return o; } }; + } else { + dr = new DuplicationReplacement() { + @Override + public Node replacement(Node o) { + return o; + } + }; } - duplicationMap = graph().addDuplicates(nodes(), dr); + duplicationMap = graph().addDuplicates(original().nodes(), dr); finishDuplication(); nodesReady = true; } else { @@ -221,11 +236,13 @@ StructuredGraph graph = graph(); for (BeginNode earlyExit : LoopFragment.toHirBlocks(original().loop().lirLoop().exits)) { FixedNode next = earlyExit.next(); - if (earlyExit.isDeleted() || !this.contains(earlyExit)) { + if (earlyExit.isDeleted() || !this.original().contains(earlyExit)) { continue; } BeginNode newEarlyExit = getDuplicatedNode(earlyExit); - assert newEarlyExit != null; + if (newEarlyExit == null) { + continue; + } MergeNode merge = graph.add(new MergeNode()); merge.setProbability(next.probability()); EndNode originalEnd = graph.add(new EndNode()); diff -r 98325620b7e2 -r c84c75339af1 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopFragmentInside.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopFragmentInside.java Mon Jul 02 15:08:05 2012 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopFragmentInside.java Mon Jul 02 16:53:12 2012 +0200 @@ -41,7 +41,7 @@ * In the unrolling case they will be used as the value that replace the loop-phis of the duplicated inside fragment */ private Map mergedInitializers; - private final DuplicationReplacement dataFix = new DuplicationReplacement() { + private final DuplicationReplacement dataFixBefore = new DuplicationReplacement() { @Override public Node replacement(Node oriInput) { if (!(oriInput instanceof ValueNode)) { @@ -56,7 +56,7 @@ } public LoopFragmentInside(LoopFragmentInside original) { - super(original.loop(), original); + super(null, original); } @Override @@ -76,11 +76,16 @@ } @Override + public LoopEx loop() { + assert !this.isDuplicate(); + return super.loop(); + } + + @Override public void insertBefore(LoopEx loop) { - if (this.loop() != loop) { - throw new UnsupportedOperationException(); - } - patchNodes(dataFix); + assert this.isDuplicate() && this.original().loop() == loop; + + patchNodes(dataFixBefore); BeginNode end = mergeEnds(); @@ -88,7 +93,7 @@ mergeEarlyExits(); - BeginNode entry = getDuplicatedNode(this.loop().loopBegin()); + BeginNode entry = getDuplicatedNode(loop.loopBegin()); FrameState state = entry.stateAfter(); if (state != null) { entry.setStateAfter(null); @@ -137,7 +142,6 @@ @Override protected void finishDuplication() { // TODO (gd) ? - } private void patchPeeling(LoopFragmentInside peel) { @@ -187,7 +191,8 @@ * @return corresponding value in the peel */ private ValueNode prim(ValueNode b) { - LoopBeginNode loopBegin = loop().loopBegin(); + assert isDuplicate(); + LoopBeginNode loopBegin = original().loop().loopBegin(); if (loopBegin.isPhiAtMerge(b)) { PhiNode phi = (PhiNode) b; return phi.valueAt(loopBegin.forwardEnd()); @@ -203,9 +208,10 @@ } private BeginNode mergeEnds() { + assert isDuplicate(); List endsToMerge = new LinkedList<>(); Map reverseEnds = new HashMap<>(); // map peel's exit to the corresponding loop exits - LoopBeginNode loopBegin = loop().loopBegin(); + LoopBeginNode loopBegin = original().loop().loopBegin(); for (LoopEndNode le : loopBegin.loopEnds()) { EndNode duplicate = getDuplicatedNode(le); if (duplicate != null) { diff -r 98325620b7e2 -r c84c75339af1 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopFragmentWhole.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopFragmentWhole.java Mon Jul 02 15:08:05 2012 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopFragmentWhole.java Mon Jul 02 16:53:12 2012 +0200 @@ -26,6 +26,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.graph.iterators.*; import com.oracle.graal.lir.cfg.*; +import com.oracle.graal.nodes.*; public class LoopFragmentWhole extends LoopFragment { @@ -34,10 +35,23 @@ super(loop); } + public LoopFragmentWhole(LoopFragmentWhole original) { + super(null, original); + } + @Override public LoopFragmentWhole duplicate() { - // TODO (gd) do not forget to make a FULL loop : do not forget the forward end which is not part of the original loop stricto sensus - return null; + LoopFragmentWhole loopFragmentWhole = new LoopFragmentWhole(this); + loopFragmentWhole.reify(); + return loopFragmentWhole; + } + + private void reify() { + assert this.isDuplicate(); + + patchNodes(null); + + mergeEarlyExits(); } @Override @@ -51,13 +65,29 @@ @Override protected DuplicationReplacement getDuplicationReplacement() { - return null; + final FixedNode entry = loop().entryPoint(); + final Graph graph = this.graph(); + return new DuplicationReplacement() { + @Override + public Node replacement(Node o) { + if (o == entry) { + return graph.add(new EndNode()); + } + return o; + } + }; + } + + public FixedNode entryPoint() { + if (isDuplicate()) { + return getDuplicatedNode(original().loop().loopBegin()).forwardEnd(); + } + return loop().entryPoint(); } @Override protected void finishDuplication() { - // TODO Auto-generated method stub - + // TODO (gd) ? } @Override diff -r 98325620b7e2 -r c84c75339af1 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopTransformations.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopTransformations.java Mon Jul 02 15:08:05 2012 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopTransformations.java Mon Jul 02 16:53:12 2012 +0200 @@ -23,13 +23,43 @@ package com.oracle.graal.compiler.loop; import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.*; import com.oracle.graal.compiler.phases.*; +import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.util.*; public abstract class LoopTransformations { private static final int UNROLL_LIMIT = GraalOptions.FullUnrollMaxNodes * 2; + private static final SimplifierTool simplifier = new SimplifierTool() { + @Override + public TargetDescription target() { + return null; + } + @Override + public CodeCacheProvider runtime() { + return null; + } + @Override + public boolean isImmutable(Constant objectConstant) { + return false; + } + @Override + public Assumptions assumptions() { + return null; + } + @Override + public void deleteBranch(FixedNode branch) { + branch.predecessor().replaceFirstSuccessor(branch, null); + GraphUtil.killCFG(branch); + } + @Override + public void addToWorkList(Node node) { + } + }; private LoopTransformations() { // does not need to be instantiated @@ -64,16 +94,19 @@ public static void unswitch(LoopEx loop, IfNode ifNode) { // duplicate will be true case, original will be false case - LoopFragmentWhole duplicateLoop = loop.whole().duplicate(); + LoopFragmentWhole originalLoop = loop.whole(); + LoopFragmentWhole duplicateLoop = originalLoop.duplicate(); StructuredGraph graph = (StructuredGraph) ifNode.graph(); BeginNode tempBegin = graph.add(new BeginNode()); - loop.entryPoint().replaceAtPredecessor(tempBegin); + originalLoop.entryPoint().replaceAtPredecessor(tempBegin); double takenProbability = ifNode.probability(ifNode.blockSuccessorIndex(ifNode.trueSuccessor())); - IfNode newIf = graph.add(new IfNode(ifNode.compare(), duplicateLoop.loop().entryPoint(), loop.entryPoint(), takenProbability, ifNode.leafGraphId())); + IfNode newIf = graph.add(new IfNode(ifNode.compare(), duplicateLoop.entryPoint(), originalLoop.entryPoint(), takenProbability, ifNode.leafGraphId())); tempBegin.setNext(newIf); ifNode.setCompare(graph.unique(ConstantNode.forBoolean(false, graph))); IfNode duplicateIf = duplicateLoop.getDuplicatedNode(ifNode); duplicateIf.setCompare(graph.unique(ConstantNode.forBoolean(true, graph))); + ifNode.simplify(simplifier); + duplicateIf.simplify(simplifier); // TODO (gd) probabilities need some amount of fixup.. (probably also in other transforms) } diff -r 98325620b7e2 -r c84c75339af1 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LoopTransformLowPhase.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LoopTransformLowPhase.java Mon Jul 02 15:08:05 2012 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LoopTransformLowPhase.java Mon Jul 02 16:53:12 2012 +0200 @@ -25,7 +25,6 @@ import com.oracle.graal.compiler.*; import com.oracle.graal.compiler.loop.*; import com.oracle.graal.debug.*; -import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; public class LoopTransformLowPhase extends Phase { @@ -46,7 +45,6 @@ }); } if (GraalOptions.LoopUnswitch) { - NodeBitMap unswitchedDebug = graph.createNodeBitMap(); boolean unswitched; do { unswitched = false; @@ -54,12 +52,11 @@ for (LoopEx loop : dataUnswitch.loops()) { if (LoopPolicies.shouldTryUnswitch(loop)) { IfNode ifNode = LoopTransformations.findUnswitchableIf(loop); - if (ifNode != null && !unswitchedDebug.isMarked(ifNode) && LoopPolicies.shouldUnswitch(loop, ifNode)) { - unswitchedDebug.mark(ifNode); + if (ifNode != null && LoopPolicies.shouldUnswitch(loop, ifNode)) { Debug.log("Unswitching %s at %s [%f - %f]", loop, ifNode, ifNode.probability(0), ifNode.probability(1)); - //LoopTransformations.unswitch(loop, ifNode); + LoopTransformations.unswitch(loop, ifNode); UNSWITCHED.increment(); - //Debug.dump(graph, "After unswitch %s", loop); + Debug.dump(graph, "After unswitch %s", loop); unswitched = true; break; } diff -r 98325620b7e2 -r c84c75339af1 src/share/tools/IdealGraphVisualizer/nbproject/project.properties --- a/src/share/tools/IdealGraphVisualizer/nbproject/project.properties Mon Jul 02 15:08:05 2012 +0200 +++ b/src/share/tools/IdealGraphVisualizer/nbproject/project.properties Mon Jul 02 16:53:12 2012 +0200 @@ -40,5 +40,5 @@ # Disable assertions for RequestProcessor to prevent annoying messages in case # of multiple SceneAnimator update tasks in the default RequestProcessor. -run.args.extra = -J-server -J-da:org.openide.util.RequestProcessor -J-Xms2g -J-Xmx2g +run.args.extra = -J-server -J-da:org.openide.util.RequestProcessor -J-Xms2g -J-Xmx4g debug.args.extra = -J-server -J-da:org.openide.util.RequestProcessor