# HG changeset patch # User Thomas Wuerthinger # Date 1304600771 -7200 # Node ID dac9bcc6bd4a87e152b847e26a4768fdb6fe9c8e # Parent d559fac496990c2efe0f48c2f1a25989f7f6c653# Parent 51ebe5f0516f8c9399ddbf1152732365f171ea59 Merge. diff -r d559fac49699 -r dac9bcc6bd4a doc/design/graal_compiler.pdf diff -r d559fac49699 -r dac9bcc6bd4a doc/design/graal_compiler.tex diff -r d559fac49699 -r dac9bcc6bd4a graal/GraalCompiler/src/com/sun/c1x/alloc/ControlFlowOptimizer.java --- a/graal/GraalCompiler/src/com/sun/c1x/alloc/ControlFlowOptimizer.java Thu May 05 15:05:40 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/alloc/ControlFlowOptimizer.java Thu May 05 15:06:11 2011 +0200 @@ -148,7 +148,7 @@ } // update the block references in any branching LIR instructions - for (BlockBegin pred : block.predecessors()) { + for (BlockBegin pred : block.blockPredecessors()) { for (LIRInstruction instr : pred.lir().instructionsList()) { if (instr instanceof LIRBranch) { ((LIRBranch) instr).substitute(block, newTarget); @@ -269,11 +269,11 @@ } } - for (BlockBegin sux : block.end().successors()) { + for (BlockBegin sux : block.end().blockSuccessors()) { assert code.contains(sux) : "missing successor from: " + block + "to: " + sux; } - for (BlockBegin pred : block.predecessors()) { + for (BlockBegin pred : block.blockPredecessors()) { assert code.contains(pred) : "missing predecessor from: " + block + "to: " + pred; } } diff -r d559fac49699 -r dac9bcc6bd4a graal/GraalCompiler/src/com/sun/c1x/alloc/RegisterVerifier.java --- a/graal/GraalCompiler/src/com/sun/c1x/alloc/RegisterVerifier.java Thu May 05 15:05:40 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/alloc/RegisterVerifier.java Thu May 05 15:06:11 2011 +0200 @@ -129,7 +129,7 @@ processOperations(block.lir(), inputState); // iterate all successors - for (BlockBegin succ : block.end().successors()) { + for (BlockBegin succ : block.end().blockSuccessors()) { processSuccessor(succ, inputState); } } diff -r d559fac49699 -r dac9bcc6bd4a graal/GraalCompiler/src/com/sun/c1x/debug/CFGPrinter.java --- a/graal/GraalCompiler/src/com/sun/c1x/debug/CFGPrinter.java Thu May 05 15:05:40 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/debug/CFGPrinter.java Thu May 05 15:06:11 2011 +0200 @@ -132,7 +132,7 @@ out.print("to_bci ").println(block.end() == null ? -1 : block.end().bci()); out.print("predecessors "); - for (BlockBegin pred : block.predecessors()) { + for (BlockBegin pred : block.blockPredecessors()) { out.print("\"B").print(pred.blockID).print("\" "); } out.println(); @@ -590,7 +590,7 @@ out.print("name \"").print(label).println('"'); startBlock.iteratePreOrder(new BlockClosure() { public void apply(BlockBegin block) { - List successors = block.end() != null ? block.end().successors() : new ArrayList(0); + List successors = block.end() != null ? block.end().blockSuccessors() : new ArrayList(0); printBlock(block, successors, block.exceptionHandlerBlocks(), printHIR, printLIR); } }); diff -r d559fac49699 -r dac9bcc6bd4a graal/GraalCompiler/src/com/sun/c1x/gen/LIRGenerator.java --- a/graal/GraalCompiler/src/com/sun/c1x/gen/LIRGenerator.java Thu May 05 15:05:40 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/gen/LIRGenerator.java Thu May 05 15:06:11 2011 +0200 @@ -834,7 +834,7 @@ if (rangeDensity >= C1XOptions.RangeTestsSwitchDensity) { visitSwitchRanges(switchRanges, tag, x.defaultSuccessor()); } else { - List nonDefaultSuccessors = x.successors().subList(0, x.numberOfCases()); + List nonDefaultSuccessors = x.blockSuccessors().subList(0, x.numberOfCases()); BlockBegin[] targets = nonDefaultSuccessors.toArray(new BlockBegin[nonDefaultSuccessors.size()]); lir.tableswitch(tag, x.lowKey(), x.defaultSuccessor(), targets); } diff -r d559fac49699 -r dac9bcc6bd4a graal/GraalCompiler/src/com/sun/c1x/graph/BlockUtil.java --- a/graal/GraalCompiler/src/com/sun/c1x/graph/BlockUtil.java Thu May 05 15:05:40 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/graph/BlockUtil.java Thu May 05 15:06:11 2011 +0200 @@ -36,11 +36,11 @@ * @param block the block to remove from the graph */ public static void disconnectFromGraph(BlockBegin block) { - for (BlockBegin p : block.predecessors()) { - p.end().successors().remove(block); + for (BlockBegin p : block.blockPredecessors()) { + p.end().blockSuccessors().remove(block); } - for (BlockBegin s : block.end().successors()) { - s.predecessors().remove(block); + for (BlockBegin s : block.end().blockSuccessors()) { + s.blockPredecessors().remove(block); } } } diff -r d559fac49699 -r dac9bcc6bd4a graal/GraalCompiler/src/com/sun/c1x/graph/CriticalEdgeFinder.java --- a/graal/GraalCompiler/src/com/sun/c1x/graph/CriticalEdgeFinder.java Thu May 05 15:05:40 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/graph/CriticalEdgeFinder.java Thu May 05 15:06:11 2011 +0200 @@ -54,7 +54,7 @@ public void apply(BlockBegin block) { if (block.numberOfSux() >= 2) { - for (BlockBegin succ : block.end().successors()) { + for (BlockBegin succ : block.end().blockSuccessors()) { if (succ.numberOfPreds() >= 2) { // TODO: (tw) probably we don't have to make it a critical edge if succ only contains the _same_ predecessor multiple times. recordCriticalEdge(block, succ); diff -r d559fac49699 -r dac9bcc6bd4a graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java --- a/graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java Thu May 05 15:05:40 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java Thu May 05 15:06:11 2011 +0200 @@ -28,6 +28,7 @@ import java.lang.reflect.*; import java.util.*; +import com.oracle.graal.graph.*; import com.sun.c1x.*; import com.sun.c1x.debug.*; import com.sun.c1x.ir.*; @@ -122,6 +123,12 @@ boolean skipBlock; // skip processing of the rest of this block private Value rootMethodSynchronizedObject; + + + + private Graph graph = new Graph(); + + /** * Creates a new, initialized, {@code GraphBuilder} instance for a given compilation. * @@ -182,7 +189,7 @@ // 3. setup internal state for appending instructions curBlock = startBlock; lastInstr = startBlock; - lastInstr.setNext(null, -1); + lastInstr.appendNext(null, -1); curState = initialState; if (isSynchronized(rootMethod.accessFlags())) { @@ -385,7 +392,7 @@ curBlock.addExceptionHandler(entry); // add back-edge from exception handler entry to this block - if (!entry.predecessors().contains(curBlock)) { + if (!entry.blockPredecessors().contains(curBlock)) { entry.addPredecessor(curBlock); } @@ -548,31 +555,31 @@ void genArithmeticOp(CiKind result, int opcode, CiKind x, CiKind y, FrameState state) { Value yValue = pop(y); Value xValue = pop(x); - Value result1 = append(new ArithmeticOp(opcode, result, xValue, yValue, isStrict(method().accessFlags()), state)); + Value result1 = append(new ArithmeticOp(opcode, result, xValue, yValue, isStrict(method().accessFlags()), state, graph)); push(result, result1); } void genNegateOp(CiKind kind) { - push(kind, append(new NegateOp(pop(kind)))); + push(kind, append(new NegateOp(pop(kind), graph))); } void genShiftOp(CiKind kind, int opcode) { Value s = ipop(); Value x = pop(kind); // note that strength reduction of e << K >>> K is correctly handled in canonicalizer now - push(kind, append(new ShiftOp(opcode, x, s))); + push(kind, append(new ShiftOp(opcode, x, s, graph))); } void genLogicOp(CiKind kind, int opcode) { Value y = pop(kind); Value x = pop(kind); - push(kind, append(new LogicOp(opcode, x, y))); + push(kind, append(new LogicOp(opcode, x, y, graph))); } void genCompareOp(CiKind kind, int opcode, CiKind resultKind) { Value y = pop(kind); Value x = pop(kind); - Value value = append(new CompareOp(opcode, resultKind, x, y)); + Value value = append(new CompareOp(opcode, resultKind, x, y, graph)); if (!resultKind.isVoid()) { ipush(value); } @@ -588,7 +595,7 @@ int delta = stream().readIncrement(); Value x = curState.localAt(index); Value y = append(Constant.forInt(delta)); - curState.storeLocal(index, append(new ArithmeticOp(IADD, CiKind.Int, x, y, isStrict(method().accessFlags()), null))); + curState.storeLocal(index, append(new ArithmeticOp(IADD, CiKind.Int, x, y, isStrict(method().accessFlags()), null, graph))); } void genGoto(int fromBCI, int toBCI) { @@ -1165,7 +1172,7 @@ if (lastInstr instanceof Base) { assert false : "may only happen when inlining intrinsics"; } else { - lastInstr = lastInstr.setNext(x, bci); + lastInstr = lastInstr.appendNext(x, bci); } if (++stats.nodeCount >= C1XOptions.MaximumInstructionCount) { // bailout if we've exceeded the maximum inlining size @@ -1289,7 +1296,7 @@ curBlock = b; curState = b.stateBefore().copy(); lastInstr = b; - b.setNext(null, -1); + b.appendNext(null, -1); iterateBytecodesForBlock(b.bci(), false); } @@ -1321,7 +1328,7 @@ if (nextBlock != null && nextBlock != block) { // we fell through to the next block, add a goto and break end = new Goto(nextBlock, null, false); - lastInstr = lastInstr.setNext(end, prevBCI); + lastInstr = lastInstr.appendNext(end, prevBCI); break; } // read the opcode @@ -1366,8 +1373,8 @@ end.setStateAfter(curState.immutableCopy(bci())); curBlock.setEnd(end); // propagate the state - for (BlockBegin succ : end.successors()) { - assert succ.predecessors().contains(curBlock); + for (BlockBegin succ : end.blockSuccessors()) { + assert succ.blockPredecessors().contains(curBlock); succ.mergeOrClone(end.stateAfter(), method()); addToWorkList(succ); } diff -r d559fac49699 -r dac9bcc6bd4a graal/GraalCompiler/src/com/sun/c1x/graph/IR.java --- a/graal/GraalCompiler/src/com/sun/c1x/graph/IR.java Thu May 05 15:05:40 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/graph/IR.java Thu May 05 15:06:11 2011 +0200 @@ -166,7 +166,7 @@ */ public BlockBegin splitEdge(BlockBegin source, BlockBegin target) { int bci; - if (target.predecessors().size() == 1) { + if (target.blockPredecessors().size() == 1) { bci = target.bci(); } else { bci = source.end().bci(); @@ -179,7 +179,7 @@ // This goto is not a safepoint. Goto e = new Goto(target, null, false); - newSucc.setNext(e, bci); + newSucc.appendNext(e, bci); newSucc.setEnd(e); // setup states FrameState s = source.end().stateAfter(); @@ -199,7 +199,7 @@ // the successor could be the target of a switch so it might have // multiple copies of this predecessor, so substitute the new_sux // for the first and delete the rest. - List list = target.predecessors(); + List list = target.blockPredecessors(); int x = list.indexOf(source); assert x >= 0; list.set(x, newSucc); @@ -216,18 +216,18 @@ public void replaceBlock(BlockBegin oldBlock, BlockBegin newBlock) { assert !oldBlock.isExceptionEntry() : "cannot replace exception handler blocks (yet)"; - for (BlockBegin succ : oldBlock.end().successors()) { + for (BlockBegin succ : oldBlock.end().blockSuccessors()) { succ.removePredecessor(oldBlock); } - for (BlockBegin pred : oldBlock.predecessors()) { + for (BlockBegin pred : oldBlock.blockPredecessors()) { // substitute the new successor for this block in each predecessor pred.end().substituteSuccessor(oldBlock, newBlock); // and add each predecessor to the successor newBlock.addPredecessor(pred); } // this block is now disconnected; remove all its incoming and outgoing edges - oldBlock.predecessors().clear(); - oldBlock.end().successors().clear(); + oldBlock.blockPredecessors().clear(); + oldBlock.end().blockSuccessors().clear(); } /** @@ -235,11 +235,11 @@ * @param block the block to remove from the graph */ public void disconnectFromGraph(BlockBegin block) { - for (BlockBegin p : block.predecessors()) { - p.end().successors().remove(block); + for (BlockBegin p : block.blockPredecessors()) { + p.end().blockSuccessors().remove(block); } - for (BlockBegin s : block.end().successors()) { - s.predecessors().remove(block); + for (BlockBegin s : block.end().blockSuccessors()) { + s.blockPredecessors().remove(block); } } diff -r d559fac49699 -r dac9bcc6bd4a graal/GraalCompiler/src/com/sun/c1x/ir/ArithmeticOp.java --- a/graal/GraalCompiler/src/com/sun/c1x/ir/ArithmeticOp.java Thu May 05 15:05:40 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/ir/ArithmeticOp.java Thu May 05 15:06:11 2011 +0200 @@ -22,6 +22,7 @@ */ package com.sun.c1x.ir; +import com.oracle.graal.graph.*; import com.sun.c1x.debug.*; import com.sun.c1x.value.*; import com.sun.cri.bytecode.*; @@ -32,6 +33,9 @@ */ public final class ArithmeticOp extends Op2 { + private static final int INPUT_COUNT = 0; + private static final int SUCCESSOR_COUNT = 0; + private final FrameState stateBefore; private final boolean isStrictFP; @@ -44,8 +48,8 @@ * @param isStrictFP indicates this operation has strict rounding semantics * @param stateBefore the state for instructions that may trap */ - public ArithmeticOp(int opcode, CiKind kind, Value x, Value y, boolean isStrictFP, FrameState stateBefore) { - super(kind, opcode, x, y); + public ArithmeticOp(int opcode, CiKind kind, Value x, Value y, boolean isStrictFP, FrameState stateBefore, Graph graph) { + super(kind, opcode, x, y, INPUT_COUNT, SUCCESSOR_COUNT, graph); this.isStrictFP = isStrictFP; this.stateBefore = stateBefore; } diff -r d559fac49699 -r dac9bcc6bd4a graal/GraalCompiler/src/com/sun/c1x/ir/Base.java --- a/graal/GraalCompiler/src/com/sun/c1x/ir/Base.java Thu May 05 15:05:40 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/ir/Base.java Thu May 05 15:06:11 2011 +0200 @@ -67,7 +67,7 @@ @Override public void print(LogStream out) { out.print("std entry B").print(standardEntry().blockID); - if (successors().size() > 1) { + if (blockSuccessors().size() > 1) { out.print(" osr entry B").print(osrEntry().blockID); } } diff -r d559fac49699 -r dac9bcc6bd4a graal/GraalCompiler/src/com/sun/c1x/ir/BlockBegin.java --- a/graal/GraalCompiler/src/com/sun/c1x/ir/BlockBegin.java Thu May 05 15:05:40 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/ir/BlockBegin.java Thu May 05 15:06:11 2011 +0200 @@ -118,7 +118,7 @@ * Gets the list of predecessors of this block. * @return the predecessor list */ - public List predecessors() { + public List blockPredecessors() { return predecessors; } @@ -240,13 +240,13 @@ // disconnect this block from the old end old.setBegin(null); // disconnect this block from its current successors - for (BlockBegin s : old.successors()) { - s.predecessors().remove(this); + for (BlockBegin s : old.blockSuccessors()) { + s.blockPredecessors().remove(this); } } this.end = end; end.setBegin(this); - for (BlockBegin s : end.successors()) { + for (BlockBegin s : end.blockSuccessors()) { s.addPredecessor(this); } } @@ -304,7 +304,7 @@ while ((block = queue.poll()) != null) { closure.apply(block); queueBlocks(queue, block.exceptionHandlerBlocks(), mark); - queueBlocks(queue, block.end.successors(), mark); + queueBlocks(queue, block.end.blockSuccessors(), mark); queueBlocks(queue, predecessors ? block.predecessors : null, mark); } } @@ -329,7 +329,7 @@ iterateReverse(mark, closure, exceptionHandlerBlocks); } assert e != null : "block must have block end"; - iterateReverse(mark, closure, e.successors()); + iterateReverse(mark, closure, e.blockSuccessors()); } } @@ -427,7 +427,7 @@ stateBefore = newState; } else { - if (!C1XOptions.AssumeVerifiedBytecode && !existingState.isSame(newState)) { + if (!C1XOptions.AssumeVerifiedBytecode && !existingState.isCompatibleWith(newState)) { // stacks or locks do not match--bytecodes would not verify throw new CiBailout("stack or locks do not match"); } @@ -592,7 +592,7 @@ if (end != null) { builder.append(" -> "); boolean hasSucc = false; - for (BlockBegin s : end.successors()) { + for (BlockBegin s : end.blockSuccessors()) { if (hasSucc) { builder.append(", "); } @@ -724,9 +724,9 @@ out.print('[').print(bci()).print(", ").print(end == null ? -1 : end.bci()).print(']'); // print block successors - if (end != null && end.successors().size() > 0) { + if (end != null && end.blockSuccessors().size() > 0) { out.print(" ."); - for (BlockBegin successor : end.successors()) { + for (BlockBegin successor : end.blockSuccessors()) { out.print(" B").print(successor.blockID); } } @@ -745,9 +745,9 @@ } // print predecessors - if (!predecessors().isEmpty()) { + if (!blockPredecessors().isEmpty()) { out.print(" pred:"); - for (BlockBegin pred : predecessors()) { + for (BlockBegin pred : blockPredecessors()) { out.print(" B").print(pred.blockID); } } @@ -842,7 +842,7 @@ /** * Formats a given instruction as a value in a {@linkplain FrameState frame state}. If the instruction is a phi defined at a given - * block, its {@linkplain Phi#inputCount() inputs} are appended to the returned string. + * block, its {@linkplain Phi#phiInputCount() inputs} are appended to the returned string. * * @param index the index of the value in the frame state * @param value the frame state value @@ -858,7 +858,7 @@ // print phi operands if (phi.block() == this) { sb.append(" ["); - for (int j = 0; j < phi.inputCount(); j++) { + for (int j = 0; j < phi.phiInputCount(); j++) { sb.append(' '); Value operand = phi.inputAt(j); if (operand != null) { diff -r d559fac49699 -r dac9bcc6bd4a graal/GraalCompiler/src/com/sun/c1x/ir/BlockEnd.java --- a/graal/GraalCompiler/src/com/sun/c1x/ir/BlockEnd.java Thu May 05 15:05:40 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/ir/BlockEnd.java Thu May 05 15:06:11 2011 +0200 @@ -134,7 +134,7 @@ * Gets this block end's list of successors. * @return the successor list */ - public List successors() { + public List blockSuccessors() { return successors; } diff -r d559fac49699 -r dac9bcc6bd4a graal/GraalCompiler/src/com/sun/c1x/ir/CompareOp.java --- a/graal/GraalCompiler/src/com/sun/c1x/ir/CompareOp.java Thu May 05 15:05:40 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/ir/CompareOp.java Thu May 05 15:06:11 2011 +0200 @@ -22,6 +22,7 @@ */ package com.sun.c1x.ir; +import com.oracle.graal.graph.*; import com.sun.c1x.debug.*; import com.sun.cri.bytecode.*; import com.sun.cri.ci.*; @@ -31,6 +32,9 @@ */ public final class CompareOp extends Op2 { + private static final int INPUT_COUNT = 0; + private static final int SUCCESSOR_COUNT = 0; + /** * Creates a new compare operation. * @param opcode the bytecode opcode @@ -38,8 +42,8 @@ * @param x the first input * @param y the second input */ - public CompareOp(int opcode, CiKind kind, Value x, Value y) { - super(kind, opcode, x, y); + public CompareOp(int opcode, CiKind kind, Value x, Value y, Graph graph) { + super(kind, opcode, x, y, INPUT_COUNT, SUCCESSOR_COUNT, graph); } @Override diff -r d559fac49699 -r dac9bcc6bd4a graal/GraalCompiler/src/com/sun/c1x/ir/ComputeLinearScanOrder.java --- a/graal/GraalCompiler/src/com/sun/c1x/ir/ComputeLinearScanOrder.java Thu May 05 15:05:40 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/ir/ComputeLinearScanOrder.java Thu May 05 15:06:11 2011 +0200 @@ -696,7 +696,7 @@ assert cur.linearScanNumber() == i : "incorrect linearScanNumber"; assert cur.linearScanNumber() >= 0 && cur.linearScanNumber() == linearScanOrder.indexOf(cur) : "incorrect linearScanNumber"; - for (BlockBegin sux : cur.end().successors()) { + for (BlockBegin sux : cur.end().blockSuccessors()) { assert sux.linearScanNumber() >= 0 && sux.linearScanNumber() == linearScanOrder.indexOf(sux) : "incorrect linearScanNumber"; if (!cur.checkBlockFlag(BlockBegin.BlockFlag.LinearScanLoopEnd)) { assert cur.linearScanNumber() < sux.linearScanNumber() : "invalid order"; @@ -706,7 +706,7 @@ } } - for (BlockBegin pred : cur.predecessors()) { + for (BlockBegin pred : cur.blockPredecessors()) { assert pred.linearScanNumber() >= 0 && pred.linearScanNumber() == linearScanOrder.indexOf(pred) : "incorrect linearScanNumber"; if (!cur.checkBlockFlag(BlockBegin.BlockFlag.LinearScanLoopHeader)) { assert cur.linearScanNumber() > pred.linearScanNumber() : "invalid order"; diff -r d559fac49699 -r dac9bcc6bd4a graal/GraalCompiler/src/com/sun/c1x/ir/If.java --- a/graal/GraalCompiler/src/com/sun/c1x/ir/If.java Thu May 05 15:05:40 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/ir/If.java Thu May 05 15:06:11 2011 +0200 @@ -171,9 +171,9 @@ print(' '). print(y()). print(" then B"). - print(successors().get(0).blockID). + print(blockSuccessors().get(0).blockID). print(" else B"). - print(successors().get(1).blockID); + print(blockSuccessors().get(1).blockID); if (isSafepoint()) { out.print(" (safepoint)"); } diff -r d559fac49699 -r dac9bcc6bd4a graal/GraalCompiler/src/com/sun/c1x/ir/IfOp.java --- a/graal/GraalCompiler/src/com/sun/c1x/ir/IfOp.java Thu May 05 15:05:40 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/ir/IfOp.java Thu May 05 15:06:11 2011 +0200 @@ -22,6 +22,7 @@ */ package com.sun.c1x.ir; +import com.oracle.graal.graph.*; import com.sun.c1x.debug.*; import com.sun.c1x.util.*; import com.sun.cri.bytecode.*; @@ -35,24 +36,62 @@ */ public final class IfOp extends Op2 { + private static final int INPUT_COUNT = 2; + private static final int INPUT_TRUE_VALUE = 0; + private static final int INPUT_FALSE_VALUE = 1; + + private static final int SUCCESSOR_COUNT = 0; + + @Override + protected int inputCount() { + return super.inputCount() + INPUT_COUNT; + } + + @Override + protected int successorCount() { + return super.successorCount() + SUCCESSOR_COUNT; + } + + + /** + * The instruction that produces the value if the comparison is true. + */ + public Value trueValue() { + return (Value) inputs().get(super.inputCount() + INPUT_TRUE_VALUE); + } + + public Value setTrueValue(Value n) { + return (Value) inputs().set(super.inputCount() + INPUT_TRUE_VALUE, n); + } + + /** + * The instruction that produces the value if the comparison is false. + */ + public Value falseValue() { + return (Value) inputs().get(super.inputCount() + INPUT_FALSE_VALUE); + } + + public Value setFalseValue(Value n) { + return (Value) inputs().set(super.inputCount() + INPUT_FALSE_VALUE, n); + } + + Condition cond; - Value trueVal; - Value falseVal; /** * Constructs a new IfOp. * @param x the instruction producing the first value to be compared * @param cond the condition of the comparison * @param y the instruction producing the second value to be compared - * @param tval the value produced if the condition is true - * @param fval the value produced if the condition is false + * @param trueValue the value produced if the condition is true + * @param falseValue the value produced if the condition is false */ - public IfOp(Value x, Condition cond, Value y, Value tval, Value fval) { + public IfOp(Value x, Condition cond, Value y, Value trueValue, Value falseValue, Graph graph) { // TODO: return the appropriate bytecode IF_ICMPEQ, etc - super(tval.kind.meet(fval.kind), Bytecodes.ILLEGAL, x, y); + super(trueValue.kind.meet(falseValue.kind), Bytecodes.ILLEGAL, x, y, INPUT_COUNT, SUCCESSOR_COUNT, graph); this.cond = cond; - this.trueVal = tval; - falseVal = fval; + setTrueValue(trueValue); + setFalseValue(falseValue); } /** @@ -64,22 +103,6 @@ } /** - * Gets the instruction that produces the value if the comparison is true. - * @return the instruction producing the value upon true - */ - public Value trueValue() { - return trueVal; - } - - /** - * Gets the instruction that produces the value if the comparison is false. - * @return the instruction producing the value upon false - */ - public Value falseValue() { - return falseVal; - } - - /** * Checks whether this comparison operator is commutative (i.e. it is either == or !=). * @return {@code true} if this comparison is commutative */ @@ -88,27 +111,20 @@ } @Override - public void inputValuesDo(ValueClosure closure) { - super.inputValuesDo(closure); - trueVal = closure.apply(trueVal); - falseVal = closure.apply(falseVal); - } - - @Override public void accept(ValueVisitor v) { v.visitIfOp(this); } @Override public int valueNumber() { - return Util.hash4(cond.hashCode(), x, y, trueVal, falseVal); + return Util.hash4(cond.hashCode(), x(), y(), trueValue(), falseValue()); } @Override public boolean valueEqual(Instruction i) { if (i instanceof IfOp) { IfOp o = (IfOp) i; - return opcode == o.opcode && x == o.x && y == o.y && trueVal == o.trueVal && falseVal == o.falseVal; + return opcode == o.opcode && x() == o.x() && y() == o.y() && trueValue() == o.trueValue() && falseValue() == o.falseValue(); } return false; } diff -r d559fac49699 -r dac9bcc6bd4a graal/GraalCompiler/src/com/sun/c1x/ir/Instruction.java --- a/graal/GraalCompiler/src/com/sun/c1x/ir/Instruction.java Thu May 05 15:05:40 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/ir/Instruction.java Thu May 05 15:06:11 2011 +0200 @@ -24,6 +24,7 @@ import java.util.*; +import com.oracle.graal.graph.*; import com.sun.c1x.*; import com.sun.c1x.value.*; import com.sun.cri.ci.*; @@ -42,6 +43,34 @@ */ public abstract class Instruction extends Value { + private static final int INPUT_COUNT = 0; + + private static final int SUCCESSOR_COUNT = 1; + private static final int SUCCESSOR_NEXT = 0; + + @Override + protected int inputCount() { + return super.inputCount() + INPUT_COUNT; + } + + @Override + protected int successorCount() { + return super.successorCount() + SUCCESSOR_COUNT; + } + + /** + * Links to next instruction in a basic block, to {@code null} if this instruction is the end of a basic block or to + * itself if not in a block. + */ + public Instruction next() { + return (Instruction) successors().get(super.successorCount() + SUCCESSOR_NEXT); + } + + private Node setNext(Instruction next) { + return successors().set(super.successorCount() + SUCCESSOR_NEXT, next); + } + + public static final int SYNCHRONIZATION_ENTRY_BCI = -1; /** @@ -51,22 +80,25 @@ private int bci; /** - * Links to next instruction in a basic block or to {@code} itself if not in a block. - */ - private Instruction next = this; - - /** * List of associated exception handlers. */ private List exceptionHandlers = ExceptionHandler.ZERO_HANDLERS; + private boolean isAppended = false; + /** * Constructs a new instruction with the specified value type. * @param kind the value type for this instruction + * @param inputCount + * @param successorCount */ + public Instruction(CiKind kind, int inputCount, int successorCount, Graph graph) { + super(kind, inputCount + INPUT_COUNT, successorCount + SUCCESSOR_COUNT, graph); + C1XMetrics.HIRInstructions++; + } + public Instruction(CiKind kind) { - super(kind); - C1XMetrics.HIRInstructions++; + this(kind, 0, 0, null); } /** @@ -91,20 +123,9 @@ * @return {@code true} if this instruction has been added to the basic block containing it */ public final boolean isAppended() { - return next != this; + return isAppended; } - /** - * Gets the next instruction after this one in the basic block, or {@code null} - * if this instruction is the end of a basic block. - * @return the next instruction after this one in the basic block - */ - public final Instruction next() { - if (next == this) { - return null; - } - return next; - } /** * Sets the next instruction for this instruction. Note that it is illegal to @@ -113,14 +134,12 @@ * @param bci the bytecode index of the next instruction * @return the new next instruction */ - public final Instruction setNext(Instruction next, int bci) { - this.next = next; + public final Instruction appendNext(Instruction next, int bci) { + setNext(next); if (next != null) { assert !(this instanceof BlockEnd); next.setBCI(bci); - if (next.next == next) { - next.next = null; - } + next.isAppended = true; } return next; } @@ -134,7 +153,7 @@ public final Instruction resetNext(Instruction next) { if (next != null) { assert !(this instanceof BlockEnd); - this.next = next; + setNext(next); } return next; } @@ -164,7 +183,7 @@ // TODO(tw): Make this more efficient. Instruction cur = this; while (!(cur instanceof BlockEnd)) { - cur = cur.next; + cur = cur.next(); } return ((BlockEnd) cur).begin; } diff -r d559fac49699 -r dac9bcc6bd4a graal/GraalCompiler/src/com/sun/c1x/ir/LogicOp.java --- a/graal/GraalCompiler/src/com/sun/c1x/ir/LogicOp.java Thu May 05 15:05:40 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/ir/LogicOp.java Thu May 05 15:06:11 2011 +0200 @@ -22,9 +22,9 @@ */ package com.sun.c1x.ir; +import com.oracle.graal.graph.*; import com.sun.c1x.debug.*; import com.sun.cri.bytecode.*; -import com.sun.cri.ci.*; /** * The {@code LogicOp} class definition. @@ -33,18 +33,17 @@ */ public final class LogicOp extends Op2 { + private static final int INPUT_COUNT = 0; + private static final int SUCCESSOR_COUNT = 0; + /** * Constructs a new logic operation instruction. * @param opcode the opcode of the logic operation * @param x the first input into this instruction - * @param s the second input into this instruction + * @param y the second input into this instruction */ - public LogicOp(int opcode, Value x, Value s) { - super(x.kind, opcode, x, s); - } - - public LogicOp(CiKind kind, int opcode, Value x, Value s) { - super(kind, opcode, x, s); + public LogicOp(int opcode, Value x, Value y, Graph graph) { + super(x.kind, opcode, x, y, INPUT_COUNT, SUCCESSOR_COUNT, graph); } @Override diff -r d559fac49699 -r dac9bcc6bd4a graal/GraalCompiler/src/com/sun/c1x/ir/LookupSwitch.java --- a/graal/GraalCompiler/src/com/sun/c1x/ir/LookupSwitch.java Thu May 05 15:05:40 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/ir/LookupSwitch.java Thu May 05 15:06:11 2011 +0200 @@ -80,7 +80,7 @@ int l = numberOfCases(); for (int i = 0; i < l; i++) { INSTRUCTION.advance(out); - out.printf("case %5d: B%d%n", keyAt(i), successors().get(i).blockID); + out.printf("case %5d: B%d%n", keyAt(i), blockSuccessors().get(i).blockID); } INSTRUCTION.advance(out); out.print("default : B").print(defaultSuccessor().blockID); diff -r d559fac49699 -r dac9bcc6bd4a graal/GraalCompiler/src/com/sun/c1x/ir/NegateOp.java --- a/graal/GraalCompiler/src/com/sun/c1x/ir/NegateOp.java Thu May 05 15:05:40 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/ir/NegateOp.java Thu May 05 15:06:11 2011 +0200 @@ -22,6 +22,7 @@ */ package com.sun.c1x.ir; +import com.oracle.graal.graph.*; import com.sun.c1x.debug.*; import com.sun.c1x.util.*; import com.sun.cri.bytecode.*; @@ -33,28 +34,40 @@ */ public final class NegateOp extends Instruction { - Value x; + private static final int INPUT_COUNT = 2; + private static final int INPUT_X = 0; + private static final int INPUT_Y = 1; + + private static final int SUCCESSOR_COUNT = 0; + + @Override + protected int inputCount() { + return super.inputCount() + INPUT_COUNT; + } + + @Override + protected int successorCount() { + return super.successorCount() + SUCCESSOR_COUNT; + } + + /** + * The instruction producing input to this instruction. + */ + public Value x() { + return (Value) inputs().get(super.inputCount() + INPUT_X); + } + + public Value setX(Value n) { + return (Value) inputs().set(super.inputCount() + INPUT_X, n); + } /** * Creates new NegateOp instance. * @param x the instruction producing the value that is input to this instruction */ - public NegateOp(Value x) { - super(x.kind); - this.x = x; - } - - /** - * Gets the instruction producing input to this instruction. - * @return the instruction that produces this instruction's input - */ - public Value x() { - return x; - } - - @Override - public void inputValuesDo(ValueClosure closure) { - x = closure.apply(x); + public NegateOp(Value x, Graph graph) { + super(x.kind, INPUT_COUNT, SUCCESSOR_COUNT, graph); + setX(x); } @Override @@ -64,14 +77,14 @@ @Override public int valueNumber() { - return Util.hash1(Bytecodes.INEG, x); + return Util.hash1(Bytecodes.INEG, x()); } @Override public boolean valueEqual(Instruction i) { if (i instanceof NegateOp) { NegateOp o = (NegateOp) i; - return x == o.x; + return x() == o.x(); } return false; } diff -r d559fac49699 -r dac9bcc6bd4a graal/GraalCompiler/src/com/sun/c1x/ir/Op2.java --- a/graal/GraalCompiler/src/com/sun/c1x/ir/Op2.java Thu May 05 15:05:40 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/ir/Op2.java Thu May 05 15:06:11 2011 +0200 @@ -22,6 +22,7 @@ */ package com.sun.c1x.ir; +import com.oracle.graal.graph.*; import com.sun.c1x.util.*; import com.sun.cri.bytecode.*; import com.sun.cri.ci.*; @@ -33,14 +34,49 @@ */ public abstract class Op2 extends Instruction { + private static final int INPUT_COUNT = 2; + private static final int INPUT_X = 0; + private static final int INPUT_Y = 1; + + private static final int SUCCESSOR_COUNT = 0; + + @Override + protected int inputCount() { + return super.inputCount() + INPUT_COUNT; + } + + @Override + protected int successorCount() { + return super.successorCount() + SUCCESSOR_COUNT; + } + + /** + * The first input to this instruction + */ + public Value x() { + return (Value) inputs().get(super.inputCount() + INPUT_X); + } + + public Value setX(Value n) { + return (Value) inputs().set(super.inputCount() + INPUT_X, n); + } + + /** + * The second input to this instruction + */ + public Value y() { + return (Value) inputs().get(super.inputCount() + INPUT_Y); + } + + public Value setY(Value n) { + return (Value) inputs().set(super.inputCount() + INPUT_Y, n); + } + /** * The opcode of this instruction. */ public final int opcode; - Value x; - Value y; - /** * Creates a new Op2 instance. * @param kind the result type of this instruction @@ -48,27 +84,11 @@ * @param x the first input instruction * @param y the second input instruction */ - public Op2(CiKind kind, int opcode, Value x, Value y) { - super(kind); + public Op2(CiKind kind, int opcode, Value x, Value y, int inputCount, int successorCount, Graph graph) { + super(kind, inputCount + INPUT_COUNT, successorCount + SUCCESSOR_COUNT, graph); this.opcode = opcode; - this.x = x; - this.y = y; - } - - /** - * Gets the first input to this instruction. - * @return the first input to this instruction - */ - public final Value x() { - return x; - } - - /** - * Gets the second input to this instruction. - * @return the second input to this instruction - */ - public final Value y() { - return y; + setX(x); + setY(y); } /** @@ -76,31 +96,21 @@ */ public void swapOperands() { assert Bytecodes.isCommutative(opcode); - Value t = x; - x = y; - y = t; - } - - /** - * Iterates over the inputs to this instruction. - * @param closure the closure to apply to each input value - */ - @Override - public void inputValuesDo(ValueClosure closure) { - x = closure.apply(x); - y = closure.apply(y); + Value t = x(); + setX(y()); + setY(t); } @Override public int valueNumber() { - return Util.hash2(opcode, x, y); + return Util.hash2(opcode, x(), y()); } @Override public boolean valueEqual(Instruction i) { if (i instanceof Op2) { Op2 o = (Op2) i; - return opcode == o.opcode && x == o.x && y == o.y; + return opcode == o.opcode && x() == o.x() && y() == o.y(); } return false; } diff -r d559fac49699 -r dac9bcc6bd4a graal/GraalCompiler/src/com/sun/c1x/ir/Phi.java --- a/graal/GraalCompiler/src/com/sun/c1x/ir/Phi.java Thu May 05 15:05:40 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/ir/Phi.java Thu May 05 15:06:11 2011 +0200 @@ -103,7 +103,7 @@ if (block.isExceptionEntry()) { state = block.exceptionHandlerStates().get(i); } else { - state = block.predecessors().get(i).end().stateAfter(); + state = block.blockPredecessors().get(i).end().stateAfter(); } return inputIn(state); } @@ -125,11 +125,11 @@ * Get the number of inputs to this phi (i.e. the number of predecessors to the join block). * @return the number of inputs in this phi */ - public int inputCount() { + public int phiInputCount() { if (block.isExceptionEntry()) { return block.exceptionHandlerStates().size(); } else { - return block.predecessors().size(); + return block.blockPredecessors().size(); } } diff -r d559fac49699 -r dac9bcc6bd4a graal/GraalCompiler/src/com/sun/c1x/ir/ShiftOp.java --- a/graal/GraalCompiler/src/com/sun/c1x/ir/ShiftOp.java Thu May 05 15:05:40 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/ir/ShiftOp.java Thu May 05 15:06:11 2011 +0200 @@ -22,6 +22,7 @@ */ package com.sun.c1x.ir; +import com.oracle.graal.graph.*; import com.sun.c1x.debug.*; import com.sun.cri.bytecode.*; @@ -32,14 +33,17 @@ */ public final class ShiftOp extends Op2 { + private static final int INPUT_COUNT = 0; + private static final int SUCCESSOR_COUNT = 0; + /** * Creates a new shift operation. * @param opcode the opcode of the shift * @param x the first input value * @param y the second input value */ - public ShiftOp(int opcode, Value x, Value y) { - super(x.kind, opcode, x, y); + public ShiftOp(int opcode, Value x, Value y, Graph graph) { + super(x.kind, opcode, x, y, INPUT_COUNT, SUCCESSOR_COUNT, graph); } @Override diff -r d559fac49699 -r dac9bcc6bd4a graal/GraalCompiler/src/com/sun/c1x/ir/TableSwitch.java --- a/graal/GraalCompiler/src/com/sun/c1x/ir/TableSwitch.java Thu May 05 15:05:40 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/ir/TableSwitch.java Thu May 05 15:06:11 2011 +0200 @@ -82,7 +82,7 @@ int l = numberOfCases(); for (int i = 0; i < l; i++) { INSTRUCTION.advance(out); - out.printf("case %5d: B%d%n", lowKey() + i, successors().get(i).blockID); + out.printf("case %5d: B%d%n", lowKey() + i, blockSuccessors().get(i).blockID); } INSTRUCTION.advance(out); out.print("default : B").print(defaultSuccessor().blockID); diff -r d559fac49699 -r dac9bcc6bd4a graal/GraalCompiler/src/com/sun/c1x/ir/Value.java --- a/graal/GraalCompiler/src/com/sun/c1x/ir/Value.java Thu May 05 15:05:40 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/ir/Value.java Thu May 05 15:06:11 2011 +0200 @@ -22,7 +22,7 @@ */ package com.sun.c1x.ir; -import com.sun.c1x.*; +import com.oracle.graal.graph.*; import com.sun.c1x.debug.*; import com.sun.c1x.opt.*; import com.sun.cri.ci.*; @@ -32,7 +32,7 @@ * This class represents a value within the HIR graph, including local variables, phis, and * all other instructions. */ -public abstract class Value { +public abstract class Value extends Node { public enum Flag { NonNull, // this value is non-null @@ -51,11 +51,6 @@ public final CiKind kind; /** - * Unique identifier for this value. This field's value is lazily initialized by {@link #id()}. - */ - private int id; - - /** * A mask of {@linkplain Flag flags} denoting extra properties of this value. */ private int flags; @@ -72,12 +67,35 @@ /** * Creates a new value with the specified kind. * @param kind the type of this value + * @param inputCount + * @param successorCount + * @param graph */ - public Value(CiKind kind) { + public Value(CiKind kind, int inputCount, int successorCount, Graph graph) { + super(inputCount, successorCount, graph == null ? new Graph() : graph); assert kind == kind.stackKind() : kind + " != " + kind.stackKind(); this.kind = kind; } + /////////////// + // TODO: remove when Value class changes are completed + + public Value(CiKind kind) { + this(kind, 0, 0, null); + } + + @Override + public Node copy(Graph into) { + throw new UnsupportedOperationException(); + } + + @Override + protected Object clone() throws CloneNotSupportedException { + throw new CloneNotSupportedException(); + } + + ///////////////// + /** * Gets the instruction that should be substituted for this one. Note that this * method is recursive; if the substituted instruction has a substitution, then @@ -253,7 +271,9 @@ * @param closure the closure to apply */ public void inputValuesDo(ValueClosure closure) { - // default: do nothing. + for (int i = 0; i < inputs().size(); i++) { + inputs().set(i, closure.apply((Value) inputs().get(i))); + } } @Override @@ -297,19 +317,4 @@ public abstract void print(LogStream out); - /** - * This method returns a unique identification number for this value. The number returned is unique - * only to the compilation that produced this node and is computed lazily by using the current compilation - * for the current thread. Thus the first access is a hash lookup using {@link java.lang.ThreadLocal} and - * should not be considered fast. Because of the potentially slow first access, use of this ID should be - * restricted to debugging output. - * @return a unique ID for this value - */ - public int id() { - if (id == 0) { - C1XMetrics.UniqueValueIdsAssigned++; - id = C1XCompilation.compilation().nextID(); - } - return id; - } } diff -r d559fac49699 -r dac9bcc6bd4a graal/GraalCompiler/src/com/sun/c1x/opt/PhiSimplifier.java --- a/graal/GraalCompiler/src/com/sun/c1x/opt/PhiSimplifier.java Thu May 05 15:05:40 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/opt/PhiSimplifier.java Thu May 05 15:06:11 2011 +0200 @@ -78,7 +78,7 @@ // attempt to simplify the phi by recursively simplifying its operands phi.setFlag(Value.Flag.PhiVisited); Value phiSubst = null; - int max = phi.inputCount(); + int max = phi.phiInputCount(); boolean cannotSimplify = false; for (int i = 0; i < max; i++) { Value oldInstr = phi.inputAt(i); diff -r d559fac49699 -r dac9bcc6bd4a graal/GraalCompiler/src/com/sun/c1x/value/FrameState.java --- a/graal/GraalCompiler/src/com/sun/c1x/value/FrameState.java Thu May 05 15:05:40 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/value/FrameState.java Thu May 05 15:06:11 2011 +0200 @@ -110,10 +110,7 @@ final MutableFrameState other = new MutableFrameState(bci, localsSize(), maxStackSize()); if (withLocals && withStack) { // fast path: use array copy - int valuesSize = valuesSize(); - assert other.values.length >= valuesSize : "array size: " + other.values.length + ", valuesSize: " + valuesSize + ", maxStackSize: " + maxStackSize() + ", localsSize: " + localsSize(); - assert values.length >= valuesSize : "array size: " + values.length + ", valuesSize: " + valuesSize + ", maxStackSize: " + maxStackSize() + ", localsSize: " + localsSize(); - System.arraycopy(values, 0, other.values, 0, valuesSize); + System.arraycopy(values, 0, other.values, 0, valuesSize()); other.stackIndex = stackIndex; } else { if (withLocals) { @@ -150,10 +147,10 @@ return copy(bci, false, false, false); } - public boolean isSame(FrameState other) { - assert stackSize() == other.stackSize(); - assert localsSize() == other.localsSize(); - assert locksSize() == other.locksSize(); + public boolean isCompatibleWith(FrameState other) { + if (stackSize() != other.stackSize() || localsSize() != other.localsSize() || locksSize() != other.locksSize()) { + return false; + } for (int i = 0; i < stackIndex; i++) { Value x = stackAt(i); Value y = other.stackAt(i); @@ -366,7 +363,7 @@ if (x instanceof Phi) { Phi phi = (Phi) x; if (phi.block() == block) { - for (int j = 0; j < phi.inputCount(); j++) { + for (int j = 0; j < phi.phiInputCount(); j++) { if (phi.inputIn(other) == null) { throw new CiBailout("phi " + phi + " has null operand at new predecessor"); } diff -r d559fac49699 -r dac9bcc6bd4a graal/GraalGraph/src/com/oracle/graal/graph/Node.java --- a/graal/GraalGraph/src/com/oracle/graal/graph/Node.java Thu May 05 15:05:40 2011 +0200 +++ b/graal/GraalGraph/src/com/oracle/graal/graph/Node.java Thu May 05 15:06:11 2011 +0200 @@ -161,7 +161,8 @@ } public Node set(int index, Node node) { - assert node == Null || node.graph == self().graph; + // TODO: re-enable after Value class layout changes +// assert node == Null || node.graph == self().graph; Node old = nodes[index]; if (old != node) { diff -r d559fac49699 -r dac9bcc6bd4a src/share/vm/runtime/arguments.cpp --- a/src/share/vm/runtime/arguments.cpp Thu May 05 15:05:40 2011 +0200 +++ b/src/share/vm/runtime/arguments.cpp Thu May 05 15:06:11 2011 +0200 @@ -2692,6 +2692,8 @@ scp_p->add_prefix(temp); sprintf(temp, "%s/graal/GraalRuntime/bin", graal_dir); scp_p->add_prefix(temp); + sprintf(temp, "%s/graal/GraalGraph/bin", graal_dir); + scp_p->add_prefix(temp); *scp_assembly_required_p = true; } else if (match_option(option, "-C1X:", &tail)) { // -C1X:xxxx // Option for the C1X compiler.