# HG changeset patch # User Thomas Wuerthinger # Date 1306178526 -7200 # Node ID 4f3053eef0debf17bbb4a50727b45d4af58b5c4e # Parent dd6419f4bfe27b7d621c12a1b53675d530361070# Parent 61f839853da8b4bc48dfd446be15d0e16713a5af Merge. diff -r 61f839853da8 -r 4f3053eef0de graal/GraalCompiler/src/com/sun/c1x/gen/LIRGenerator.java --- a/graal/GraalCompiler/src/com/sun/c1x/gen/LIRGenerator.java Mon May 23 18:08:10 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/gen/LIRGenerator.java Mon May 23 21:22:06 2011 +0200 @@ -29,6 +29,7 @@ import java.util.*; +import com.oracle.graal.graph.*; import com.oracle.max.asm.*; import com.sun.c1x.*; import com.sun.c1x.alloc.*; @@ -565,9 +566,6 @@ CiValue tag = load(x.value()); setNoResult(x); - // move values into phi locations - moveToPhi(x.stateAfter()); - if (x.numberOfCases() == 0 || x.numberOfCases() < C1XOptions.SequentialSwitchLimit) { int len = x.numberOfCases(); for (int i = 0; i < len; i++) { @@ -825,9 +823,6 @@ CiValue tag = value.result(); setNoResult(x); - // move values into phi locations - moveToPhi(x.stateAfter()); - // TODO: tune the defaults for the controls used to determine what kind of translation to use if (x.numberOfCases() == 0 || x.numberOfCases() <= C1XOptions.SequentialSwitchLimit) { int loKey = x.lowKey(); @@ -1244,12 +1239,20 @@ } } - void moveToPhi(PhiResolver resolver, Value curVal, Value suxVal) { + 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; + // curVal can be null without phi being null in conjunction with inlining if (!phi.isDeadPhi() && curVal != null && curVal != phi) { + + assert phis.contains(phi); + if (phi.valueAt(predIndex) != curVal) { + phi.print(TTY.out()); + } + assert phi.valueAt(predIndex) == curVal : "curVal=" + curVal + "valueAt(" + predIndex + ")=" + phi.valueAt(predIndex); + assert !phi.isIllegal() : "illegal phi cannot be marked as live"; if (curVal instanceof Phi) { operandForPhi((Phi) curVal); @@ -1269,6 +1272,22 @@ this.moveToPhi(lastState); } + private List getPhis(LIRBlock block) { + if (block.getInstructions().size() > 0) { + Instruction i = block.getInstructions().get(0); + if (i instanceof BlockBegin) { + List result = new ArrayList(); + for (Node n : i.usages()) { + if (n instanceof Phi) { + result.add((Phi) n); + } + } + return result; + } + } + return null; + } + protected void moveToPhi(FrameState curState) { // Moves all stack values into their phi position LIRBlock bb = currentBlock; @@ -1278,18 +1297,53 @@ // a block with only one predecessor never has phi functions if (sux.numberOfPreds() > 1) { + FrameState suxState = sux.stateBefore(); + + + List phis = getPhis(sux); + + int predIndex = 0; + for (; predIndex < sux.numberOfPreds(); ++predIndex) { + if (sux.predAt(predIndex) == bb) { + break; + } + } + assert predIndex < sux.numberOfPreds(); + + if (phis != null) { + PhiResolver resolver = new PhiResolver(this); + for (Phi phi : phis) { + if (!phi.isDeadPhi() && phi.valueCount() > predIndex) { + Value curVal = phi.valueAt(predIndex); + 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(); + } + + /*TTY.println("number of preds: " + sux.numberOfPreds()); + PhiResolver resolver = new PhiResolver(this); - FrameState suxState = sux.stateBefore(); for (int index = 0; index < suxState.stackSize(); index++) { - moveToPhi(resolver, curState.stackAt(index), suxState.stackAt(index)); + moveToPhi(resolver, curState.stackAt(index), suxState.stackAt(index), phis, predIndex); } for (int index = 0; index < suxState.localsSize(); index++) { - moveToPhi(resolver, curState.localAt(index), suxState.localAt(index)); + moveToPhi(resolver, curState.localAt(index), suxState.localAt(index), phis, predIndex); } - resolver.dispose(); + resolver.dispose();*/ } } } diff -r 61f839853da8 -r 4f3053eef0de graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java --- a/graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java Mon May 23 18:08:10 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java Mon May 23 21:22:06 2011 +0200 @@ -162,7 +162,7 @@ // 1. create the start block Block startBlock = nextBlock(Instruction.SYNCHRONIZATION_ENTRY_BCI); - BlockBegin startBlockBegin = new BlockBegin(0, startBlock.blockID, graph); + BlockBegin startBlockBegin = new BlockBegin(0, startBlock.blockID, false, graph); startBlock.firstInstruction = startBlockBegin; graph.start().setStart(startBlockBegin); @@ -199,7 +199,7 @@ // 4A.3 setup an exception handler to unlock the root method synchronized object syncBlock = nextBlock(Instruction.SYNCHRONIZATION_ENTRY_BCI); - syncHandler = new BlockBegin(Instruction.SYNCHRONIZATION_ENTRY_BCI, syncBlock.blockID, graph); + syncHandler = new BlockBegin(Instruction.SYNCHRONIZATION_ENTRY_BCI, syncBlock.blockID, false, graph); syncBlock.firstInstruction = syncHandler; markOnWorkList(syncBlock); @@ -302,6 +302,15 @@ } else { assert false; } + + + + + for (int j = 0; j < frameState.localsSize() + frameState.stackSize(); ++j) { + if (frameState.valueAt(j) != null) { + assert !frameState.valueAt(j).isDeleted(); + } + } } private void insertLoopPhis(BlockBegin merge, FrameState newState) { @@ -378,7 +387,7 @@ current--; } else { if (unwindBlock == null) { - unwindBlock = new BlockBegin(bci, ir.nextBlockNumber(), graph); + unwindBlock = new BlockBegin(bci, ir.nextBlockNumber(), false, graph); Unwind unwind = new Unwind(null, graph); unwindBlock.appendNext(unwind); } @@ -401,7 +410,7 @@ if (newSucc != null) { successor = newSucc; } else { - BlockBegin dispatchEntry = new BlockBegin(handler.handlerBCI(), ir.nextBlockNumber(), graph); + BlockBegin dispatchEntry = new BlockBegin(handler.handlerBCI(), ir.nextBlockNumber(), false, graph); if (handler.handler.catchType().isResolved()) { Instruction entry = createTarget(handler.entryBlock(), null); @@ -422,7 +431,7 @@ FrameState entryState = frameState.duplicateWithEmptyStack(bci); - BlockBegin entry = new BlockBegin(bci, ir.nextBlockNumber(), graph); + BlockBegin entry = new BlockBegin(bci, ir.nextBlockNumber(), false, graph); entry.setStateBefore(entryState); ExceptionObject exception = new ExceptionObject(graph); entry.appendNext(exception); @@ -672,9 +681,13 @@ } private void ifNode(Value x, Condition cond, Value y) { + assert !x.isDeleted() && !y.isDeleted(); + If ifNode = new If(x, cond, y, null, graph); + append(ifNode); Instruction tsucc = createTargetAt(stream().readBranchDest(), frameState); + ifNode.setBlockSuccessor(0, tsucc); Instruction fsucc = createTargetAt(stream().nextBCI(), frameState); - append(new If(x, cond, y, tsucc, fsucc, null, graph)); + ifNode.setBlockSuccessor(1, fsucc); } private void genIfZero(Condition cond) { @@ -692,6 +705,7 @@ private void genIfSame(CiKind kind, Condition cond) { Value y = frameState.pop(kind); Value x = frameState.pop(kind); + assert !x.isDeleted() && !y.isDeleted(); ifNode(x, cond, y); } @@ -1042,19 +1056,21 @@ BytecodeTableSwitch ts = new BytecodeTableSwitch(stream(), bci); int max = ts.numberOfCases(); List list = new ArrayList(max + 1); - boolean isBackwards = false; + List offsetList = new ArrayList(max + 1); for (int i = 0; i < max; i++) { // add all successors to the successor list int offset = ts.offsetAt(i); - list.add(createTargetAt(bci + offset, frameState)); - isBackwards |= offset < 0; // track if any of the successors are backwards + list.add(null); + offsetList.add(offset); } int offset = ts.defaultOffset(); - isBackwards |= offset < 0; // if the default successor is backwards - list.add(createTargetAt(bci + offset, frameState)); - boolean isSafepoint = isBackwards && !noSafepoints(); - FrameState stateAfter = isSafepoint ? frameState.create(bci()) : null; - append(new TableSwitch(value, list, ts.lowKey(), stateAfter, graph)); + list.add(null); + offsetList.add(offset); + TableSwitch tableSwitch = new TableSwitch(value, list, ts.lowKey(), null, graph); + for (int i = 0; i < offsetList.size(); ++i) { + tableSwitch.setBlockSuccessor(i, createTargetAt(bci + offsetList.get(i), frameState)); + } + append(tableSwitch); } private void genLookupswitch() { @@ -1063,21 +1079,23 @@ BytecodeLookupSwitch ls = new BytecodeLookupSwitch(stream(), bci); int max = ls.numberOfCases(); List list = new ArrayList(max + 1); + List offsetList = new ArrayList(max + 1); int[] keys = new int[max]; - boolean isBackwards = false; for (int i = 0; i < max; i++) { // add all successors to the successor list int offset = ls.offsetAt(i); - list.add(createTargetAt(bci + offset, frameState)); + list.add(null); + offsetList.add(offset); keys[i] = ls.keyAt(i); - isBackwards |= offset < 0; // track if any of the successors are backwards } int offset = ls.defaultOffset(); - isBackwards |= offset < 0; // if the default successor is backwards - list.add(createTargetAt(bci + offset, frameState)); - boolean isSafepoint = isBackwards && !noSafepoints(); - FrameState stateAfter = isSafepoint ? frameState.create(bci()) : null; - append(new LookupSwitch(value, list, keys, stateAfter, graph)); + list.add(null); + offsetList.add(offset); + LookupSwitch lookupSwitch = new LookupSwitch(value, list, keys, null, graph); + for (int i = 0; i < offsetList.size(); ++i) { + lookupSwitch.setBlockSuccessor(i, createTargetAt(bci + offsetList.get(i), frameState)); + } + append(lookupSwitch); } private Value appendConstant(CiConstant constant) { @@ -1122,7 +1140,7 @@ private Instruction createTarget(Block block, FrameStateAccess stateAfter) { if (block.firstInstruction == null) { - BlockBegin blockBegin = new BlockBegin(block.startBci, block.blockID, graph); + BlockBegin blockBegin = new BlockBegin(block.startBci, block.blockID, block.isLoopHeader, graph); block.firstInstruction = blockBegin; } if (stateAfter != null) { diff -r 61f839853da8 -r 4f3053eef0de graal/GraalCompiler/src/com/sun/c1x/graph/IR.java --- a/graal/GraalCompiler/src/com/sun/c1x/graph/IR.java Mon May 23 18:08:10 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/graph/IR.java Mon May 23 21:22:06 2011 +0200 @@ -142,6 +142,7 @@ int z = 0; for (BlockBegin bb : blocks) { LIRBlock lirBlock = new LIRBlock(z); + lirBlock.getInstructions().add(bb); valueToBlock.put(bb, lirBlock); lirBlock.setLinearScanNumber(bb.linearScanNumber()); // TODO(tw): Initialize LIRBlock.linearScanLoopHeader and LIRBlock.linearScanLoopEnd @@ -221,12 +222,20 @@ int backEdgeIndex = target.predecessors().indexOf(source.end()); // create new successor and mark it for special block order treatment - BlockBegin newSucc = new BlockBegin(bci, nextBlockNumber(), compilation.graph); + BlockBegin newSucc = new BlockBegin(bci, nextBlockNumber(), false, compilation.graph); + + List removePhiInputs = new ArrayList(); + for (int i = backEdgeIndex + 1; i < target.predecessors().size(); ++i) { + if (target.predecessors().get(i) == source.end()) { + removePhiInputs.add(i); + } + } // This goto is not a safepoint. Goto e = new Goto(target, null, compilation.graph); newSucc.appendNext(e); e.reorderSuccessor(0, backEdgeIndex); + // setup states FrameState s = source.end().stateAfter(); newSucc.setStateBefore(s); @@ -236,6 +245,20 @@ assert newSucc.stateBefore().locksSize() == s.locksSize(); // link predecessor to new block source.end().substituteSuccessor(target, newSucc); + if (removePhiInputs.size() > 0) { + + for (Node n : target.usages()) { + if (n instanceof Phi) { + Phi phi = (Phi) n; + int correction = 0; + for (int index : removePhiInputs) { + phi.removeInput(index - correction); + correction++; + } + } + } + + } return newSucc; } diff -r 61f839853da8 -r 4f3053eef0de graal/GraalCompiler/src/com/sun/c1x/ir/BlockBegin.java --- a/graal/GraalCompiler/src/com/sun/c1x/ir/BlockBegin.java Mon May 23 18:08:10 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/ir/BlockBegin.java Mon May 23 21:22:06 2011 +0200 @@ -73,6 +73,7 @@ */ public final int blockID; + public final boolean isLoopHeader; private int linearScanNumber; /** @@ -87,11 +88,12 @@ * @param blockID the ID of the block * @param graph */ - public BlockBegin(int bci, int blockID, Graph graph) { + public BlockBegin(int bci, int blockID, boolean isLoopHeader, Graph graph) { super(CiKind.Illegal, INPUT_COUNT, SUCCESSOR_COUNT, graph); this.blockID = blockID; linearScanNumber = -1; this.bci = bci; + this.isLoopHeader = isLoopHeader; } /** diff -r 61f839853da8 -r 4f3053eef0de graal/GraalCompiler/src/com/sun/c1x/ir/BlockEnd.java --- a/graal/GraalCompiler/src/com/sun/c1x/ir/BlockEnd.java Mon May 23 18:08:10 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/ir/BlockEnd.java Mon May 23 21:22:06 2011 +0200 @@ -129,13 +129,16 @@ * @param oldSucc the old successor to replace * @param newSucc the new successor */ - public void substituteSuccessor(BlockBegin oldSucc, BlockBegin newSucc) { + public int substituteSuccessor(BlockBegin oldSucc, BlockBegin newSucc) { assert newSucc != null; + int count = 0; for (int i = 0; i < blockSuccessorCount; i++) { if (blockSuccessor(i) == oldSucc) { setBlockSuccessor(i, newSucc); + count++; } } + return count; } /** diff -r 61f839853da8 -r 4f3053eef0de graal/GraalCompiler/src/com/sun/c1x/ir/If.java --- a/graal/GraalCompiler/src/com/sun/c1x/ir/If.java Mon May 23 18:08:10 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/ir/If.java Mon May 23 21:22:06 2011 +0200 @@ -80,19 +80,15 @@ * @param x the instruction producing the first input to the instruction * @param cond the condition (comparison operation) * @param y the instruction that produces the second input to this instruction - * @param trueSucc the block representing the true successor - * @param falseSucc the block representing the false successor * @param stateAfter the state before the branch but after the input values have been popped * @param graph */ - public If(Value x, Condition cond, Value y, Instruction trueSucc, Instruction falseSucc, FrameState stateAfter, Graph graph) { + public If(Value x, Condition cond, Value y, FrameState stateAfter, Graph graph) { super(CiKind.Illegal, stateAfter, 2, INPUT_COUNT, SUCCESSOR_COUNT, graph); assert Util.archKindsEqual(x, y); condition = cond; setX(x); setY(y); - setBlockSuccessor(0, trueSucc); - setBlockSuccessor(1, falseSucc); } /** diff -r 61f839853da8 -r 4f3053eef0de graal/GraalCompiler/src/com/sun/c1x/ir/Phi.java --- a/graal/GraalCompiler/src/com/sun/c1x/ir/Phi.java Mon May 23 18:08:10 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/ir/Phi.java Mon May 23 21:22:06 2011 +0200 @@ -26,6 +26,7 @@ import com.sun.c1x.debug.*; import com.sun.c1x.value.*; import com.sun.cri.ci.*; +import com.sun.xml.internal.messaging.saaj.packaging.mime.util.*; /** * The {@code Phi} instruction represents the merging of dataflow @@ -109,7 +110,14 @@ @Override public void print(LogStream out) { - out.print("phi function"); + out.print("phi function ("); + for (int i = 0; i < inputs().size(); ++i) { + if (i != 0) { + out.print(' '); + } + out.print((Value) inputs().get(i)); + } + out.print(')'); } @Override @@ -132,4 +140,12 @@ } return phi; } + + public void removeInput(int index) { + inputs().set(index, null); + for (int i = index + 1; i < usedInputCount; ++i) { + inputs().set(i - 1, inputs().get(i)); + } + usedInputCount--; + } } diff -r 61f839853da8 -r 4f3053eef0de graal/GraalCompiler/src/com/sun/c1x/lir/LIRBlock.java --- a/graal/GraalCompiler/src/com/sun/c1x/lir/LIRBlock.java Mon May 23 18:08:10 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/lir/LIRBlock.java Mon May 23 21:22:06 2011 +0200 @@ -41,8 +41,9 @@ private LIRList lir; private final int blockID; private List instructions = new ArrayList(4); - private List predecessors = new ArrayList(); - private List successors = new ArrayList(); + private List predecessors = new ArrayList(4); + private List successors = new ArrayList(4); + private List phis = new ArrayList(4); /** * Bit map specifying which {@linkplain OperandPool operands} are live upon entry to this block. diff -r 61f839853da8 -r 4f3053eef0de graal/GraalCompiler/src/com/sun/c1x/target/amd64/AMD64LIRGenerator.java --- a/graal/GraalCompiler/src/com/sun/c1x/target/amd64/AMD64LIRGenerator.java Mon May 23 18:08:10 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/target/amd64/AMD64LIRGenerator.java Mon May 23 21:22:06 2011 +0200 @@ -504,7 +504,6 @@ CiValue left = xin.result(); CiValue right = yin.result(); lir.cmp(cond, left, right); - moveToPhi(); if (x.x().kind.isFloat() || x.x().kind.isDouble()) { lir.branch(cond, right.kind, getLIRBlock(x.trueSuccessor()), getLIRBlock(x.unorderedSuccessor())); } else { diff -r 61f839853da8 -r 4f3053eef0de graal/GraalCompiler/src/com/sun/c1x/util/Util.java --- a/graal/GraalCompiler/src/com/sun/c1x/util/Util.java Mon May 23 18:08:10 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/util/Util.java Mon May 23 21:22:06 2011 +0200 @@ -422,6 +422,6 @@ * @return the instruction representation as a string */ public static String valueString(Value value) { - return value == null ? "-" : "" + value.kind.typeChar + value.id(); + return (value == null) ? "-" : ("" + value.kind.typeChar + value.id()); } } diff -r 61f839853da8 -r 4f3053eef0de graal/GraalCompiler/src/com/sun/c1x/value/FrameState.java --- a/graal/GraalCompiler/src/com/sun/c1x/value/FrameState.java Mon May 23 18:08:10 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/value/FrameState.java Mon May 23 21:22:06 2011 +0200 @@ -331,7 +331,7 @@ Value x = valueAt(i); if (x != null) { Value y = other.valueAt(i); - if (x != y) { + if (x != y || ((x instanceof Phi) && ((Phi) x).block() == block)) { if (typeMismatch(x, y)) { if (x instanceof Phi) { Phi phi = (Phi) x; @@ -360,9 +360,9 @@ for (int j = 0; j < size; ++j) { phi = phi.addInput(x); } - phi = phi.addInput(y); + phi = phi.addInput((x == y) ? phi : y); } else { - phi = phi.addInput(y); + phi = phi.addInput((x == y) ? phi : y); } if (originalPhi != phi) { for (int j = 0; j < other.localsSize() + other.stackSize(); ++j) { @@ -371,7 +371,9 @@ } } } - } + + assert phi.valueCount() == block.predecessors().size() + (blockAppended ? 0 : 1) : "valueCount=" + phi.valueCount() + " predSize= " + block.predecessors().size(); + } } } } diff -r 61f839853da8 -r 4f3053eef0de graal/GraalCompiler/src/com/sun/c1x/value/FrameStateBuilder.java --- a/graal/GraalCompiler/src/com/sun/c1x/value/FrameStateBuilder.java Mon May 23 18:08:10 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/value/FrameStateBuilder.java Mon May 23 21:22:06 2011 +0200 @@ -118,6 +118,7 @@ * @param x the instruction to push onto the stack */ public void xpush(Value x) { + assert x == null || !x.isDeleted(); stack[stackIndex++] = x; } @@ -204,7 +205,9 @@ * @return x the instruction popped off the stack */ public Value xpop() { - return stack[--stackIndex]; + Value result = stack[--stackIndex]; + assert result == null || !result.isDeleted(); + return result; } /** diff -r 61f839853da8 -r 4f3053eef0de graal/GraalGraph/src/com/oracle/graal/graph/NodeArray.java --- a/graal/GraalGraph/src/com/oracle/graal/graph/NodeArray.java Mon May 23 18:08:10 2011 +0200 +++ b/graal/GraalGraph/src/com/oracle/graal/graph/NodeArray.java Mon May 23 21:22:06 2011 +0200 @@ -46,7 +46,7 @@ public Node set(int index, Node node) { assert node == Node.Null || node.graph == self().graph; - assert node == Node.Null || node.id() != Node.DeletedID; + assert node == Node.Null || node.id() != Node.DeletedID : "inserted node must not be deleted"; Node old = nodes[index]; if (old != node) {