# HG changeset patch # User Gilles Duboscq # Date 1308256616 -7200 # Node ID 0c519981c6cfad035eeb5a43c26cfbce8fddc8db # Parent 47aef13c569ca0a310d414b0cf84f3a4c4ca61b4 LoopBegin is not a merge diff -r 47aef13c569c -r 0c519981c6cf graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/IdealGraphPrinter.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/IdealGraphPrinter.java Thu Jun 16 13:09:18 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/IdealGraphPrinter.java Thu Jun 16 22:36:56 2011 +0200 @@ -130,14 +130,14 @@ } stream.println(" "); - stream.println(" "); if (schedule != null) { + stream.println(" "); for (Block block : schedule.getBlocks()) { printBlock(graph, block); } + printNoBlock(); + stream.println(" "); } - printNoBlock(); - stream.println(" "); stream.println(" "); flush(); @@ -209,7 +209,7 @@ stream.printf(" %n", block.blockID()); stream.printf(" %n"); for (Block sux : block.getSuccessors()) { - if (sux.firstNode() instanceof LoopBegin && block.lastNode() instanceof LoopEnd) { + if (sux.firstNode() instanceof LoopBegin && block.lastNode() instanceof LoopEnd) { //TODO gd // Skip back edges. } else { stream.printf(" %n", sux.blockID()); @@ -218,10 +218,10 @@ stream.printf(" %n"); stream.printf(" %n"); - ArrayList nodes = new ArrayList(block.getInstructions()); + Set nodes = new HashSet(block.getInstructions()); if (nodes.size() > 0) { // if this is the first block: add all locals to this block - if (nodes.get(0) == graph.start()) { + if (block.getInstructions() == graph.start()) { for (Node node : graph.getNodes()) { if (node instanceof Local) { nodes.add(node); @@ -239,7 +239,9 @@ if (merge.stateBefore() != null) { nodes.add(merge.stateBefore()); } - for (Node usage : merge.usages()) { + } + if (node instanceof PhiPoint) { + for (Node usage : node.usages()) { if (usage instanceof Phi || usage instanceof LoopCounter) { nodes.add(usage); } diff -r 47aef13c569c -r 0c519981c6cf graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java Thu Jun 16 13:09:18 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java Thu Jun 16 22:36:56 2011 +0200 @@ -33,7 +33,7 @@ import com.oracle.max.asm.*; import com.oracle.max.graal.compiler.*; import com.oracle.max.graal.compiler.alloc.*; -import com.oracle.max.graal.compiler.alloc.OperandPool.*; +import com.oracle.max.graal.compiler.alloc.OperandPool.VariableFlag; import com.oracle.max.graal.compiler.debug.*; import com.oracle.max.graal.compiler.globalstub.*; import com.oracle.max.graal.compiler.graph.*; @@ -43,11 +43,17 @@ import com.oracle.max.graal.compiler.util.*; import com.oracle.max.graal.compiler.value.*; import com.oracle.max.graal.graph.*; +import com.sun.cri.bytecode.Bytecodes.MemoryBarriers; import com.sun.cri.ci.*; import com.sun.cri.ri.*; -import com.sun.cri.ri.RiType.*; +import com.sun.cri.ri.RiType.Representation; +import com.sun.cri.xir.CiXirAssembler.XirConstant; +import com.sun.cri.xir.CiXirAssembler.XirInstruction; +import com.sun.cri.xir.CiXirAssembler.XirOperand; +import com.sun.cri.xir.CiXirAssembler.XirParameter; +import com.sun.cri.xir.CiXirAssembler.XirRegister; +import com.sun.cri.xir.CiXirAssembler.XirTemp; import com.sun.cri.xir.*; -import com.sun.cri.xir.CiXirAssembler.*; /** * This class traverses the HIR instructions and generates LIR instructions from them. @@ -267,6 +273,16 @@ } } } + if (block.blockSuccessors().size() == 1 && !(block.lastInstruction() instanceof LoopEnd)) { + Node firstInstruction = block.blockSuccessors().get(0).firstInstruction(); + if (firstInstruction instanceof Placeholder) { + firstInstruction = ((Placeholder) firstInstruction).next(); + } + //System.out.println("suxSz == 1, fst=" + firstInstruction); + if (firstInstruction instanceof LoopBegin) { + moveToPhi((LoopBegin) firstInstruction, block.lastInstruction()); + } + } if (block.blockSuccessors().size() >= 1 && !jumpsToNextBlock(block.lastInstruction())) { block.lir().jump(getLIRBlock((FixedNode) block.lastInstruction().successors().get(0))); } @@ -282,7 +298,9 @@ @Override public void visitMerge(Merge x) { - // Nothing to do. + if (x.next() instanceof LoopBegin) { + moveToPhi((LoopBegin) x.next(), x); + } } private static boolean jumpsToNextBlock(Node node) { @@ -1034,7 +1052,7 @@ lastState = fs; } else if (block.blockPredecessors().size() == 1) { FrameState fs = block.blockPredecessors().get(0).lastState(); - assert fs != null; + assert fs != null; //TODO gd maybe this assert should be removed if (GraalOptions.TraceLIRGeneratorLevel >= 2) { TTY.println("STATE CHANGE (singlePred)"); if (GraalOptions.TraceLIRGeneratorLevel >= 3) { @@ -1385,7 +1403,7 @@ } } - void moveToPhi(PhiResolver resolver, Value curVal, Value suxVal, List phis, int predIndex) { + /*void moveToPhi(PhiResolver resolver, Value curVal, Value suxVal, List phis, int predIndex) { // move current value to referenced phi function if (suxVal instanceof Phi) { Phi phi = (Phi) suxVal; @@ -1411,29 +1429,12 @@ resolver.move(operand, operandForPhi(phi)); } } - } - - private List getPhis(LIRBlock block) { - if (block.getInstructions().size() > 0) { - Node i = block.firstInstruction(); - if (i instanceof Merge) { - List result = new ArrayList(); - for (Node n : i.usages()) { - if (n instanceof Phi) { - result.add((Phi) n); - } - } - return result; - } - } - return null; - } + }*/ @Override public void visitEndNode(EndNode end) { setNoResult(end); - Merge merge = end.merge(); - moveToPhi(merge, merge.endIndex(end)); + moveToPhi(end.merge(), end); lir.jump(getLIRBlock(end.merge())); } @@ -1441,54 +1442,49 @@ @Override public void visitLoopEnd(LoopEnd x) { setNoResult(x); - //moveToPhi(x.loopBegin(), x.loopBegin().endCount()); //TODO gd + moveToPhi(x.loopBegin(), x); lir.jump(getLIRBlock(x.loopBegin())); } - private void moveToPhi(Merge merge, int nextSuccIndex) { + private void moveToPhi(PhiPoint merge, Node pred) { + int nextSuccIndex = merge.phiPointPredecessorIndex(pred); PhiResolver resolver = new PhiResolver(this); - for (Node n : merge.usages()) { - if (n instanceof Phi) { - Phi phi = (Phi) n; - if (!phi.isDead()) { - Value curVal = phi.valueAt(nextSuccIndex); - if (curVal != null && curVal != phi) { - if (curVal instanceof Phi) { - operandForPhi((Phi) curVal); - } - CiValue operand = curVal.operand(); - if (operand.isIllegal()) { - assert curVal instanceof Constant || curVal instanceof Local : "these can be produced lazily" + curVal + "/" + phi; - operand = operandForInstruction(curVal); - } - resolver.move(operand, operandForPhi(phi)); + for (Phi phi : merge.phis()) { + if (!phi.isDead()) { + Value curVal = phi.valueAt(nextSuccIndex); + if (curVal != null && curVal != phi) { + if (curVal instanceof Phi) { + operandForPhi((Phi) curVal); + } + CiValue operand = curVal.operand(); + if (operand.isIllegal()) { + assert curVal instanceof Constant || curVal instanceof Local : "these can be produced lazily" + curVal + "/" + phi; + operand = operandForInstruction(curVal); + } + resolver.move(operand, operandForPhi(phi)); + } + } + } + resolver.dispose(); + //TODO (gd) remove that later ? + if (merge instanceof LoopBegin) { + LoopBegin loopBegin = (LoopBegin) merge; + for (LoopCounter counter : loopBegin.counters()) { + if (counter.operand().isIllegal()) { + createResultVariable(counter); + } + if (nextSuccIndex == 0) { + lir.move(operandForInstruction(counter.init()), counter.operand()); + } else { + if (counter.kind == CiKind.Int) { + this.arithmeticOpInt(IADD, counter.operand(), counter.operand(), operandForInstruction(counter.stride()), CiValue.IllegalValue); + } else { + assert counter.kind == CiKind.Long; + this.arithmeticOpLong(LADD, counter.operand(), counter.operand(), operandForInstruction(counter.stride())); } } } } - resolver.dispose(); - /* - //TODO (gd) remove that later - if (merge instanceof LoopBegin) { - for (Node usage : merge.usages()) { - if (usage instanceof LoopCounter) { - LoopCounter counter = (LoopCounter) usage; - if (counter.operand().isIllegal()) { - createResultVariable(counter); - } - if (nextSuccIndex == 0) { // (gd) nasty - lir.move(operandForInstruction(counter.init()), counter.operand()); - } else { - if (counter.kind == CiKind.Int) { - this.arithmeticOpInt(IADD, counter.operand(), counter.operand(), operandForInstruction(counter.stride()), CiValue.IllegalValue); - } else { - assert counter.kind == CiKind.Long; - this.arithmeticOpLong(LADD, counter.operand(), counter.operand(), operandForInstruction(counter.stride())); - } - } - } - } - }*/ } /** diff -r 47aef13c569c -r 0c519981c6cf graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/BlockMap.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/BlockMap.java Thu Jun 16 13:09:18 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/BlockMap.java Thu Jun 16 22:36:56 2011 +0200 @@ -29,6 +29,7 @@ import com.oracle.max.graal.compiler.*; import com.oracle.max.graal.compiler.debug.*; import com.oracle.max.graal.compiler.ir.*; +import com.oracle.max.graal.compiler.value.*; import com.sun.cri.bytecode.*; import com.sun.cri.ci.*; import com.sun.cri.ri.*; diff -r 47aef13c569c -r 0c519981c6cf graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LoopBegin.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LoopBegin.java Thu Jun 16 13:09:18 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LoopBegin.java Thu Jun 16 22:36:56 2011 +0200 @@ -22,11 +22,14 @@ */ package com.oracle.max.graal.compiler.ir; +import java.util.*; + import com.oracle.max.graal.compiler.debug.*; +import com.oracle.max.graal.compiler.util.*; import com.oracle.max.graal.graph.*; import com.sun.cri.ci.*; -public class LoopBegin extends Instruction { +public class LoopBegin extends StateSplit implements PhiPoint{ private static final int INPUT_COUNT = 0; private static final int SUCCESSOR_COUNT = 0; @@ -68,4 +71,39 @@ LoopBegin x = new LoopBegin(into); return x; } + + @Override + public int phiPointPredecessorCount() { + return 2; + } + + @Override + public int phiPointPredecessorIndex(Node pred) { + Node singlePredecessor = this.singlePredecessor(); + if (pred == singlePredecessor) { + return 0; + } else if (pred == this.loopEnd()) { + return 1; + } else if (singlePredecessor instanceof Placeholder) { + singlePredecessor = singlePredecessor.singlePredecessor(); + if (pred == singlePredecessor) { + return 0; + } + } + throw Util.shouldNotReachHere("unknown pred : " + pred + "(sp=" + singlePredecessor + ", le=" + this.loopEnd() + ")"); + } + + @Override + public Node asNode() { + return this; + } + + @Override + public Collection phis() { + return Util.filter(this.usages(), Phi.class); + } + + public Collection counters() { + return Util.filter(this.usages(), LoopCounter.class); + } } diff -r 47aef13c569c -r 0c519981c6cf graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Merge.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Merge.java Thu Jun 16 13:09:18 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Merge.java Thu Jun 16 22:36:56 2011 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.max.graal.compiler.ir; +import java.util.*; + import com.oracle.max.graal.compiler.debug.*; import com.oracle.max.graal.compiler.util.*; import com.oracle.max.graal.compiler.value.*; @@ -33,7 +35,7 @@ * about the basic block, including the successor and * predecessor blocks, exception handlers, liveness information, etc. */ -public class Merge extends StateSplit { +public class Merge extends StateSplit implements PhiPoint{ private static final int INPUT_COUNT = 0; @@ -294,4 +296,25 @@ } } } + + @Override + public int phiPointPredecessorCount() { + return endCount(); + } + + @Override + public int phiPointPredecessorIndex(Node pred) { + EndNode end = (EndNode) pred; + return endIndex(end); + } + + @Override + public Node asNode() { + return this; + } + + @Override + public Collection phis() { + return Util.filter(this.usages(), Phi.class); + } } diff -r 47aef13c569c -r 0c519981c6cf graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Phi.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Phi.java Thu Jun 16 13:09:18 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Phi.java Thu Jun 16 22:36:56 2011 +0200 @@ -54,17 +54,18 @@ /** * The merge node for this phi. */ - public Merge merge() { - return (Merge) inputs().get(super.inputCount() + INPUT_MERGE); + public PhiPoint merge() { + return (PhiPoint) inputs().get(super.inputCount() + INPUT_MERGE); } - public void setMerge(Value n) { + public void setMerge(Node n) { + assert n instanceof PhiPoint; inputs().set(super.inputCount() + INPUT_MERGE, n); } - public Phi(CiKind kind, Merge merge, Graph graph) { + public Phi(CiKind kind, PhiPoint merge, Graph graph) { super(kind, INPUT_COUNT, SUCCESSOR_COUNT, graph); - setMerge(merge); + setMerge(merge.asNode()); } /** diff -r 47aef13c569c -r 0c519981c6cf graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java Thu Jun 16 13:09:18 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java Thu Jun 16 22:36:56 2011 +0200 @@ -264,28 +264,25 @@ } public void mergeOrClone(Block target, FrameStateAccess newState) { - Instruction first = target.firstInstruction; + StateSplit first = (StateSplit) target.firstInstruction; + if (target.isLoopHeader && isVisited(target)) { - first = ((LoopBegin) first).loopEnd(); + first = ((LoopBegin) target.firstInstruction.next()).loopEnd(); } - assert first instanceof StateSplit; - - int bci = target.startBci; - - FrameState existingState = ((StateSplit) first).stateBefore(); + FrameState existingState = first.stateBefore(); if (existingState == null) { // copy state because it is modified - FrameState duplicate = newState.duplicate(bci); + FrameState duplicate = newState.duplicate(target.startBci); // if the block is a loop header, insert all necessary phis - if (first instanceof LoopBegin && target.isLoopHeader) { - assert first instanceof Merge; - insertLoopPhis((Merge) first, duplicate); - ((Merge) first).setStateBefore(duplicate); - } else { - ((StateSplit) first).setStateBefore(duplicate); + if (target.isLoopHeader && !isVisited(target)) { + LoopBegin loopBegin = (LoopBegin) target.firstInstruction.next(); + assert target.firstInstruction instanceof Placeholder && loopBegin != null; + //System.out.println("insertLoopPhis with " + target.loopHeaderState); + insertLoopPhis(loopBegin, loopBegin.stateBefore()); } + first.setStateBefore(duplicate); } else { if (!GraalOptions.AssumeVerifiedBytecode && !existingState.isCompatibleWith(newState)) { // stacks or locks do not match--bytecodes would not verify @@ -300,8 +297,6 @@ assert !target.isLoopHeader; Merge merge = new Merge(graph); - - Placeholder p = (Placeholder) first; assert p.predecessors().size() == 1; assert p.next() == null; @@ -325,20 +320,20 @@ } } - private void insertLoopPhis(Merge merge, FrameState newState) { + private void insertLoopPhis(LoopBegin loopBegin, FrameState newState) { int stackSize = newState.stackSize(); for (int i = 0; i < stackSize; i++) { // always insert phis for the stack Value x = newState.stackAt(i); if (x != null) { - newState.setupPhiForStack(merge, i).addInput(x); + newState.setupPhiForStack(loopBegin, i).addInput(x); } } int localsSize = newState.localsSize(); for (int i = 0; i < localsSize; i++) { Value x = newState.localAt(i); if (x != null) { - newState.setupPhiForLocal(merge, i).addInput(x); + newState.setupPhiForLocal(loopBegin, i).addInput(x); } } } @@ -1129,7 +1124,10 @@ LoopBegin loopBegin = new LoopBegin(graph); LoopEnd loopEnd = new LoopEnd(graph); loopEnd.setLoopBegin(loopBegin); - block.firstInstruction = loopBegin; + Placeholder p = new Placeholder(graph); + p.setNext(loopBegin); + loopBegin.setStateBefore(stateAfter.duplicate(block.startBci)); + block.firstInstruction = p; } else { block.firstInstruction = new Placeholder(graph); } @@ -1138,8 +1136,8 @@ addToWorkList(block); FixedNode result = null; - if (block.firstInstruction instanceof LoopBegin && isVisited(block)) { - result = ((LoopBegin) block.firstInstruction).loopEnd(); + if (block.isLoopHeader && isVisited(block)) { + result = ((LoopBegin) block.firstInstruction.next()).loopEnd(); } else { result = block.firstInstruction; } @@ -1177,9 +1175,13 @@ if (!isVisited(block)) { markVisited(block); // now parse the block - frameState.initializeFrom(((StateSplit) block.firstInstruction).stateBefore()); - lastInstr = block.firstInstruction; - assert block.firstInstruction.next() == null : "instructions already appended at block " + block.blockID; + if (block.isLoopHeader) { + lastInstr = (LoopBegin) block.firstInstruction.next(); + } else { + lastInstr = block.firstInstruction; + } + frameState.initializeFrom(((StateSplit) lastInstr).stateBefore()); + assert lastInstr.next() == null : "instructions already appended at block " + block.blockID; if (block == returnBlock) { createReturnBlock(block); @@ -1196,7 +1198,8 @@ } for (Block b : blocksVisited) { if (b.isLoopHeader) { - LoopBegin begin = (LoopBegin) b.firstInstruction; + Instruction loopHeaderInstr = b.firstInstruction; + LoopBegin begin = (LoopBegin) loopHeaderInstr.next(); LoopEnd end = begin.loopEnd(); // This can happen with degenerated loops like this one: @@ -1207,6 +1210,8 @@ // } // } if (end.stateBefore() != null) { + //loopHeaderMerge.stateBefore().merge(begin, end.stateBefore()); + //assert loopHeaderMerge.equals(end.stateBefore()); begin.stateBefore().merge(begin, end.stateBefore()); } else { end.delete(); diff -r 47aef13c569c -r 0c519981c6cf graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/IdentifyBlocksPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/IdentifyBlocksPhase.java Thu Jun 16 13:09:18 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/IdentifyBlocksPhase.java Thu Jun 16 22:36:56 2011 +0200 @@ -126,6 +126,20 @@ return trueSuccessorCount(n) > 1 || n instanceof Anchor || n instanceof Return || n instanceof Unwind; } + private void print() { + System.out.println("nodeToBlock :"); + System.out.println(nodeToBlock); + System.out.println("Blocks :"); + for (Block b : blocks) { + System.out.println(b + " [S:" + b.getSuccessors() + ", P:" + b.getPredecessors() + ", D:" + b.getDominators()); + System.out.println(" f " + b.firstNode()); + for (Node n : b.getInstructions()) { + System.out.println(" - " + n); + } + System.out.println(" l " + b.lastNode()); + } + } + private void identifyBlocks() { // Identify blocks. @@ -143,6 +157,9 @@ // Either dead code or at a merge node => stop iteration. break; } + if (n instanceof LoopBegin) { + block = null; + } assert n.predecessors().size() == 1 : "preds: " + n; n = n.predecessors().get(0); } @@ -150,22 +167,31 @@ } } +// System.out.println("identify blocks"); +// print(); + // Connect blocks. + //TODO gd restructure this for (Block block : blocks) { Node n = block.firstNode(); - if (n instanceof Merge) { - for (Node usage : n.usages()) { - if (usage instanceof Phi || usage instanceof LoopCounter) { - nodeToBlock.set(usage, block); - } + LoopBegin loopBegin = null; + if (n instanceof Merge) { + Merge m = (Merge) n; + for (Phi phi : m.phis()) { + nodeToBlock.set(phi, block); } - Merge m = (Merge) n; for (int i = 0; i < m.endCount(); ++i) { EndNode end = m.endAt(i); Block predBlock = nodeToBlock.get(end); predBlock.addSuccessor(block); } + if (m.next() instanceof LoopBegin) { + loopBegin = (LoopBegin) m.next(); + } } else { + if (n instanceof LoopBegin) { + loopBegin = (LoopBegin) n; + } for (Node pred : n.predecessors()) { if (isFixed(pred)) { Block predBlock = nodeToBlock.get(pred); @@ -173,8 +199,19 @@ } } } + if (loopBegin != null) { + for (Phi phi : loopBegin.phis()) { + nodeToBlock.set(phi, block); + } + for (LoopCounter counter : loopBegin.counters()) { + nodeToBlock.set(counter, block); + } + } } +// System.out.println("connect"); +// print(); + for (Node n : graph.getNodes()) { if (n instanceof FrameState) { FrameState f = (FrameState) n; @@ -204,8 +241,15 @@ } } +// System.out.println("dom + cycles"); +// print(); + assignLatestPossibleBlockToNodes(); +// System.out.println("assign last"); +// print(); sortNodesWithinBlocks(); +// System.out.println("sort"); +// print(); } else { computeJavaBlocks(); } @@ -289,9 +333,9 @@ for (Node usage : n.usages()) { if (usage instanceof Phi) { Phi phi = (Phi) usage; - Merge merge = phi.merge(); - Block mergeBlock = nodeToBlock.get(merge); - assert mergeBlock != null : "no block for merge " + merge.id(); + PhiPoint merge = phi.merge(); + Block mergeBlock = nodeToBlock.get(merge.asNode()); + assert mergeBlock != null : "no block for merge " + merge.asNode().id(); for (int i = 0; i < phi.valueCount(); ++i) { if (phi.valueAt(i) == n) { if (mergeBlock.getPredecessors().size() == 0) { @@ -303,19 +347,19 @@ block = getCommonDominator(block, mergeBlock.getPredecessors().get(i)); } } - } else if (usage instanceof FrameState && ((FrameState) usage).block() != null) { + } else if (usage instanceof FrameState && ((FrameState) usage).block() != null && !(n instanceof Constant)) { //TODO gd humm.. Merge merge = ((FrameState) usage).block(); for (int i = 0; i < merge.endCount(); ++i) { EndNode pred = merge.endAt(i); block = getCommonDominator(block, nodeToBlock.get(pred)); } - /*} else if (usage instanceof LoopCounter) { //TODO gd + } else if (usage instanceof LoopCounter) { //TODO gd LoopCounter counter = (LoopCounter) usage; if (n == counter.init()) { LoopBegin loopBegin = counter.loopBegin(); Block mergeBlock = nodeToBlock.get(loopBegin); block = getCommonDominator(block, mergeBlock.dominator()); - }*/ + } } else { block = getCommonDominator(block, assignLatestPossibleBlockToNode(usage)); } @@ -356,7 +400,7 @@ if (b.firstNode() == b.lastNode()) { Node node = b.firstNode(); - if (!(node instanceof Merge) || node instanceof LoopEnd) { + if (!(node instanceof Merge || node instanceof LoopBegin) || node instanceof LoopEnd) { scheduleFirst = false; } } diff -r 47aef13c569c -r 0c519981c6cf graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/Util.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/Util.java Thu Jun 16 13:09:18 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/Util.java Thu Jun 16 22:36:56 2011 +0200 @@ -27,6 +27,7 @@ import com.oracle.max.graal.compiler.*; import com.oracle.max.graal.compiler.debug.*; import com.oracle.max.graal.compiler.ir.*; +import com.oracle.max.graal.graph.*; import com.sun.cri.ci.*; import com.sun.cri.ri.*; @@ -424,4 +425,15 @@ public static String valueString(Value value) { return (value == null) ? "-" : ("" + value.kind.typeChar + value.id()); } + + @SuppressWarnings("unchecked") + public static Collection filter(Collection nodes, Class clazz) { + ArrayList phis = new ArrayList(); + for (Node node : nodes) { + if (clazz.isInstance(node)) { + phis.add((T) node); + } + } + return phis; + } } diff -r 47aef13c569c -r 0c519981c6cf graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/value/FrameState.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/value/FrameState.java Thu Jun 16 13:09:18 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/value/FrameState.java Thu Jun 16 22:36:56 2011 +0200 @@ -187,6 +187,28 @@ return true; } + public boolean equals(FrameStateAccess other) { + if (stackSize() != other.stackSize() || localsSize() != other.localsSize() || locksSize() != other.locksSize()) { + return false; + } + for (int i = 0; i < stackSize(); i++) { + Value x = stackAt(i); + Value y = other.stackAt(i); + if (x != y) { + return false; + } + } + for (int i = 0; i < locksSize(); i++) { + if (lockAt(i) != other.lockAt(i)) { + return false; + } + } + if (other.outerFrameState() != outerFrameState()) { + return false; + } + return true; + } + /** * Gets the size of the local variables. */ @@ -282,7 +304,7 @@ * @param block the block begin for which we are creating the phi * @param i the index into the stack for which to create a phi */ - public Phi setupPhiForStack(Merge block, int i) { + public Phi setupPhiForStack(PhiPoint block, int i) { Value p = stackAt(i); if (p != null) { if (p instanceof Phi) { @@ -303,7 +325,7 @@ * @param block the block begin for which we are creating the phi * @param i the index of the local variable for which to create the phi */ - public Phi setupPhiForLocal(Merge block, int i) { + public Phi setupPhiForLocal(PhiPoint block, int i) { Value p = localAt(i); if (p instanceof Phi) { Phi phi = (Phi) p; @@ -351,7 +373,7 @@ } } - public void merge(Merge block, FrameStateAccess other) { + public void merge(PhiPoint block, FrameStateAccess other) { checkSize(other); for (int i = 0; i < valuesSize(); i++) { Value x = valueAt(i); @@ -378,7 +400,7 @@ } if (phi.valueCount() == 0) { - int size = block.endCount(); + int size = block.phiPointPredecessorCount(); for (int j = 0; j < size; ++j) { phi.addInput(x); } @@ -387,7 +409,7 @@ phi.addInput((x == y) ? phi : y); } - assert phi.valueCount() == block.endCount() + 1 : "valueCount=" + phi.valueCount() + " predSize= " + block.endCount(); + assert phi.valueCount() == block.phiPointPredecessorCount() + (block instanceof LoopBegin ? 0 : 1) : "valueCount=" + phi.valueCount() + " predSize= " + block.phiPointPredecessorCount(); } } } diff -r 47aef13c569c -r 0c519981c6cf graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/Node.java --- a/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/Node.java Thu Jun 16 13:09:18 2011 +0200 +++ b/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/Node.java Thu Jun 16 22:36:56 2011 +0200 @@ -53,6 +53,11 @@ public List predecessors() { return Collections.unmodifiableList(predecessors); } + + public Node singlePredecessor(){ + assert predecessors.size() == 1; + return predecessors.get(0); + } public List usages() { return Collections.unmodifiableList(usages);