Mercurial > hg > truffle
diff graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java @ 2842:7596ae867a7b
basic inlining passes all tests, including optimistic inlining
author | Lukas Stadler <lukas.stadler@jku.at> |
---|---|
date | Wed, 01 Jun 2011 16:26:17 +0200 |
parents | 75e0d39833a0 |
children | 7474789a8120 7f14e6b48a9c |
line wrap: on
line diff
--- a/graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java Tue May 31 16:54:15 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java Wed Jun 01 16:26:17 2011 +0200 @@ -61,24 +61,30 @@ */ public static final int TRACELEVEL_STATE = 2; - private final IR ir; private final C1XCompilation compilation; + private final CompilerGraph graph; + private final CiStatistics stats; + private final RiRuntime runtime; + private final RiMethod method; + private final RiConstantPool constantPool; private final BytecodeStream stream; // the bytecode stream + private final LogStream log; + private final FrameStateBuilder frameState; // the current execution state + // bci-to-block mapping private Block[] blockFromBci; private ArrayList<Block> blockList; - private Block syncBlock; + private int nextBlockNumber; + + private Value methodSynchronizedObject; private CiExceptionHandler syncHandler; private Block unwindBlock; private Block returnBlock; - // the constant pool - private final RiConstantPool constantPool; - // the worklist of blocks, sorted by depth first number private final PriorityQueue<Block> workList = new PriorityQueue<Block>(10, new Comparator<Block>() { public int compare(Block o1, Block o2) { @@ -86,14 +92,11 @@ } }); - private FrameStateBuilder frameState; // the current execution state private Instruction lastInstr; // the last instruction added - private final LogStream log; + private final Set<Block> blocksOnWorklist = new HashSet<Block>(); + private final Set<Block> blocksVisited = new HashSet<Block>(); - private Value rootMethodSynchronizedObject; - - private final CompilerGraph graph; /** * Creates a new, initialized, {@code GraphBuilder} instance for a given compilation. @@ -102,15 +105,18 @@ * @param ir the IR to build the graph into * @param graph */ - public GraphBuilder(C1XCompilation compilation, IR ir, CompilerGraph graph) { + public GraphBuilder(C1XCompilation compilation, RiMethod method, CompilerGraph graph) { this.compilation = compilation; - this.ir = ir; + this.graph = graph; + + this.runtime = compilation.runtime; + this.method = method; this.stats = compilation.stats; - log = C1XOptions.TraceBytecodeParserLevel > 0 ? new LogStream(TTY.out()) : null; - stream = new BytecodeStream(compilation.method.code()); - constantPool = compilation.runtime.getConstantPool(compilation.method); - this.graph = graph; - this.frameState = new FrameStateBuilder(compilation.method, graph); + this.log = C1XOptions.TraceBytecodeParserLevel > 0 ? new LogStream(TTY.out()) : null; + this.stream = new BytecodeStream(method.code()); + + this.constantPool = runtime.getConstantPool(method); + this.frameState = new FrameStateBuilder(method, graph); } /** @@ -118,20 +124,18 @@ * @param scope the top IRScope */ public void build() { - RiMethod rootMethod = compilation.method; - if (log != null) { log.println(); - log.println("Compiling " + compilation.method); + log.println("Compiling " + method); } // 2. compute the block map, setup exception handlers and get the entrypoint(s) - BlockMap blockMap = compilation.getBlockMap(rootMethod); + BlockMap blockMap = compilation.getBlockMap(method); blockList = new ArrayList<Block>(blockMap.blocks); - blockFromBci = new Block[rootMethod.code().length]; + blockFromBci = new Block[method.code().length]; for (int i = 0; i < blockList.size(); i++) { - int blockID = ir.nextBlockNumber(); + int blockID = nextBlockNumber(); assert blockID == i; Block block = blockList.get(i); if (block.startBci >= 0) { @@ -145,15 +149,15 @@ lastInstr = createTarget(startBlock, frameState); graph.start().setStart(lastInstr); - if (isSynchronized(rootMethod.accessFlags())) { + if (isSynchronized(method.accessFlags())) { // 4A.1 add a monitor enter to the start block - rootMethodSynchronizedObject = synchronizedObject(frameState, compilation.method); - genMonitorEnter(rootMethodSynchronizedObject, Instruction.SYNCHRONIZATION_ENTRY_BCI); + methodSynchronizedObject = synchronizedObject(frameState, method); + genMonitorEnter(methodSynchronizedObject, Instruction.SYNCHRONIZATION_ENTRY_BCI); // 4A.2 finish the start block finishStartBlock(startBlock); // 4A.3 setup an exception handler to unlock the root method synchronized object - syncHandler = new CiExceptionHandler(0, rootMethod.code().length, Instruction.SYNCHRONIZATION_ENTRY_BCI, 0, null); + syncHandler = new CiExceptionHandler(0, method.code().length, Instruction.SYNCHRONIZATION_ENTRY_BCI, 0, null); } else { // 4B.1 simply finish the start block finishStartBlock(startBlock); @@ -165,6 +169,7 @@ addToWorkList(blockFromBci[0]); iterateAllBlocks(); + // remove Placeholders for (Node n : graph.getNodes()) { if (n instanceof Placeholder) { Placeholder p = (Placeholder) n; @@ -176,21 +181,13 @@ } } - for (Node n : graph.getNodes()) { - assert !(n instanceof Placeholder); - } - - + // remove FrameStates for (Node n : graph.getNodes()) { if (n instanceof FrameState) { boolean delete = false; if (n.usages().size() == 0 && n.predecessors().size() == 0) { delete = true; } -// if (n.predecessors().size() == 0 && n.usages().size() == 1 && n.usages().get(0) instanceof BlockBegin) { -// n.usages().get(0).inputs().replace(n, null); -// delete = true; -// } if (delete) { n.delete(); } @@ -198,11 +195,16 @@ } } + private int nextBlockNumber() { + stats.blockCount++; + return nextBlockNumber++; + } + private Block nextBlock(int bci) { Block block = new Block(); block.startBci = bci; block.endBci = bci; - block.blockID = ir.nextBlockNumber(); + block.blockID = nextBlockNumber(); return block; } @@ -211,7 +213,7 @@ unwindBlock = new Block(); unwindBlock.startBci = Instruction.SYNCHRONIZATION_ENTRY_BCI; unwindBlock.endBci = Instruction.SYNCHRONIZATION_ENTRY_BCI; - unwindBlock.blockID = ir.nextBlockNumber(); + unwindBlock.blockID = nextBlockNumber(); addToWorkList(unwindBlock); } return unwindBlock; @@ -222,15 +224,12 @@ returnBlock = new Block(); returnBlock.startBci = Instruction.SYNCHRONIZATION_ENTRY_BCI; returnBlock.endBci = Instruction.SYNCHRONIZATION_ENTRY_BCI; - returnBlock.blockID = ir.nextBlockNumber(); + returnBlock.blockID = nextBlockNumber(); addToWorkList(returnBlock); } return returnBlock; } - - private Set<Block> blocksOnWorklist = new HashSet<Block>(); - private void markOnWorkList(Block block) { blocksOnWorklist.add(block); } @@ -239,8 +238,6 @@ return blocksOnWorklist.contains(block); } - private Set<Block> blocksVisited = new HashSet<Block>(); - private void markVisited(Block block) { blocksVisited.add(block); } @@ -328,10 +325,6 @@ } } - public RiMethod method() { - return compilation.method; - } - public BytecodeStream stream() { return stream; } @@ -360,7 +353,7 @@ assert bci == Instruction.SYNCHRONIZATION_ENTRY_BCI || bci == bci() : "invalid bci"; RiExceptionHandler firstHandler = null; - RiExceptionHandler[] exceptionHandlers = compilation.method.exceptionHandlers(); + RiExceptionHandler[] exceptionHandlers = method.exceptionHandlers(); // join with all potential exception handlers if (exceptionHandlers != null) { for (RiExceptionHandler handler : exceptionHandlers) { @@ -422,7 +415,7 @@ } private void genLoadConstant(int cpi) { - Object con = constantPool().lookupConstant(cpi); + Object con = constantPool.lookupConstant(cpi); if (con instanceof RiType) { // this is a load of class constant which might be unresolved @@ -550,7 +543,7 @@ private void genArithmeticOp(CiKind result, int opcode, CiKind x, CiKind y, boolean canTrap) { Value yValue = frameState.pop(y); Value xValue = frameState.pop(x); - Value result1 = append(new ArithmeticOp(opcode, result, xValue, yValue, isStrict(method().accessFlags()), canTrap, graph)); + Value result1 = append(new ArithmeticOp(opcode, result, xValue, yValue, isStrict(method.accessFlags()), canTrap, graph)); frameState.push(result, result1); } @@ -589,7 +582,7 @@ int delta = stream().readIncrement(); Value x = frameState.localAt(index); Value y = append(Constant.forInt(delta, graph)); - frameState.storeLocal(index, append(new ArithmeticOp(IADD, CiKind.Int, x, y, isStrict(method().accessFlags()), false, graph))); + frameState.storeLocal(index, append(new ArithmeticOp(IADD, CiKind.Int, x, y, isStrict(method.accessFlags()), false, graph))); } private void genGoto(int fromBCI, int toBCI) { @@ -641,7 +634,7 @@ private void genCheckCast() { int cpi = stream().readCPI(); - RiType type = constantPool().lookupType(cpi, CHECKCAST); + RiType type = constantPool.lookupType(cpi, CHECKCAST); boolean isInitialized = type.isResolved(); Value typeInstruction = genTypeOrDeopt(RiType.Representation.ObjectHub, type, isInitialized, cpi); Value object = frameState.apop(); @@ -654,7 +647,7 @@ private void genInstanceOf() { int cpi = stream().readCPI(); - RiType type = constantPool().lookupType(cpi, INSTANCEOF); + RiType type = constantPool.lookupType(cpi, INSTANCEOF); boolean isInitialized = type.isResolved(); Value typeInstruction = genTypeOrDeopt(RiType.Representation.ObjectHub, type, isInitialized, cpi); Value object = frameState.apop(); @@ -666,9 +659,9 @@ } void genNewInstance(int cpi) { - RiType type = constantPool().lookupType(cpi, NEW); + RiType type = constantPool.lookupType(cpi, NEW); if (type.isResolved()) { - NewInstance n = new NewInstance(type, cpi, constantPool(), graph); + NewInstance n = new NewInstance(type, cpi, constantPool, graph); frameState.apush(append(n)); } else { append(new Deoptimize(graph)); @@ -678,13 +671,13 @@ private void genNewTypeArray(int typeCode) { CiKind kind = CiKind.fromArrayTypeCode(typeCode); - RiType elementType = compilation.runtime.asRiType(kind); + RiType elementType = runtime.asRiType(kind); NewTypeArray nta = new NewTypeArray(frameState.ipop(), elementType, graph); frameState.apush(append(nta)); } private void genNewObjectArray(int cpi) { - RiType type = constantPool().lookupType(cpi, ANEWARRAY); + RiType type = constantPool.lookupType(cpi, ANEWARRAY); Value length = frameState.ipop(); if (type.isResolved()) { NewArray n = new NewObjectArray(type, length, graph); @@ -697,14 +690,14 @@ } private void genNewMultiArray(int cpi) { - RiType type = constantPool().lookupType(cpi, MULTIANEWARRAY); + RiType type = constantPool.lookupType(cpi, MULTIANEWARRAY); int rank = stream().readUByte(bci() + 3); Value[] dims = new Value[rank]; for (int i = rank - 1; i >= 0; i--) { dims[i] = frameState.ipop(); } if (type.isResolved()) { - NewArray n = new NewMultiArray(type, dims, cpi, constantPool(), graph); + NewArray n = new NewMultiArray(type, dims, cpi, constantPool, graph); frameState.apush(append(n)); } else { append(new Deoptimize(graph)); @@ -853,7 +846,7 @@ private void appendInvoke(int opcode, RiMethod target, Value[] args, int cpi, RiConstantPool constantPool) { CiKind resultType = returnKind(target); - Invoke invoke = new Invoke(bci(), opcode, resultType.stackKind(), args, target, target.signature().returnType(compilation.method.holder()), graph); + Invoke invoke = new Invoke(bci(), opcode, resultType.stackKind(), args, target, target.signature().returnType(method.holder()), graph); Value result = appendWithBCI(invoke); invoke.setExceptionEdge(handleException(null, bci())); frameState.pushReturn(resultType, result); @@ -865,7 +858,7 @@ exact = receiver.exactType(); if (exact == null) { if (receiver.isConstant()) { - exact = compilation.runtime.getTypeOf(receiver.asConstant()); + exact = runtime.getTypeOf(receiver.asConstant()); } if (exact == null) { RiType declared = receiver.declaredType(); @@ -886,7 +879,7 @@ } if (exactType == null && receiver instanceof Local && ((Local) receiver).index() == 0) { // the exact type isn't known, but the receiver is parameter 0 => use holder - receiverType = compilation.method.holder(); + receiverType = method.holder(); exactType = receiverType.exactType(); } boolean needsCheck = true; @@ -926,13 +919,13 @@ private void genMonitorEnter(Value x, int bci) { int lockNumber = frameState.locksSize(); MonitorAddress lockAddress = null; - if (compilation.runtime.sizeOfBasicObjectLock() != 0) { + if (runtime.sizeOfBasicObjectLock() != 0) { lockAddress = new MonitorAddress(lockNumber, graph); append(lockAddress); } MonitorEnter monitorEnter = new MonitorEnter(x, lockAddress, lockNumber, graph); appendWithBCI(monitorEnter); - frameState.lock(ir, x, lockNumber + 1); + frameState.lock(x); if (bci == Instruction.SYNCHRONIZATION_ENTRY_BCI) { monitorEnter.setStateAfter(frameState.create(0)); } @@ -944,7 +937,7 @@ throw new CiBailout("monitor stack underflow"); } MonitorAddress lockAddress = null; - if (compilation.runtime.sizeOfBasicObjectLock() != 0) { + if (runtime.sizeOfBasicObjectLock() != 0) { lockAddress = new MonitorAddress(lockNumber, graph); append(lockAddress); } @@ -1130,22 +1123,22 @@ } private void createUnwindBlock(Block block) { - if (Modifier.isSynchronized(method().accessFlags())) { - genMonitorExit(rootMethodSynchronizedObject); + if (Modifier.isSynchronized(method.accessFlags())) { + genMonitorExit(methodSynchronizedObject); } append(graph.createUnwind(frameState.apop())); } private void createReturnBlock(Block block) { - if (method().isConstructor() && method().holder().superType() == null) { + if (method.isConstructor() && method.holder().superType() == null) { callRegisterFinalizer(); } - CiKind returnKind = method().signature().returnKind().stackKind(); + CiKind returnKind = method.signature().returnKind().stackKind(); Value x = returnKind == CiKind.Void ? null : frameState.pop(returnKind); assert frameState.stackSize() == 0; - if (Modifier.isSynchronized(method().accessFlags())) { - genMonitorExit(rootMethodSynchronizedObject); + if (Modifier.isSynchronized(method.accessFlags())) { + genMonitorExit(methodSynchronizedObject); } append(graph.createReturn(x)); } @@ -1218,7 +1211,7 @@ private void traceState() { if (C1XOptions.TraceBytecodeParserLevel >= TRACELEVEL_STATE && !TTY.isSuppressed()) { - log.println(String.format("| state [nr locals = %d, stack depth = %d, method = %s]", frameState.localsSize(), frameState.stackSize(), method())); + log.println(String.format("| state [nr locals = %d, stack depth = %d, method = %s]", frameState.localsSize(), frameState.stackSize(), method)); for (int i = 0; i < frameState.localsSize(); ++i) { Value value = frameState.localAt(i); log.println(String.format("| local[%d] = %-8s : %s", i, value == null ? "bogus" : value.kind.javaName, value)); @@ -1417,14 +1410,14 @@ case DRETURN : genReturn(frameState.dpop()); break; case ARETURN : genReturn(frameState.apop()); break; case RETURN : genReturn(null ); break; - case GETSTATIC : cpi = stream.readCPI(); genGetStatic(cpi, constantPool().lookupField(cpi, opcode)); break; - case PUTSTATIC : cpi = stream.readCPI(); genPutStatic(cpi, constantPool().lookupField(cpi, opcode)); break; - case GETFIELD : cpi = stream.readCPI(); genGetField(cpi, constantPool().lookupField(cpi, opcode)); break; - case PUTFIELD : cpi = stream.readCPI(); genPutField(cpi, constantPool().lookupField(cpi, opcode)); break; - case INVOKEVIRTUAL : cpi = stream.readCPI(); genInvokeVirtual(constantPool().lookupMethod(cpi, opcode), cpi, constantPool()); break; - case INVOKESPECIAL : cpi = stream.readCPI(); genInvokeSpecial(constantPool().lookupMethod(cpi, opcode), null, cpi, constantPool()); break; - case INVOKESTATIC : cpi = stream.readCPI(); genInvokeStatic(constantPool().lookupMethod(cpi, opcode), cpi, constantPool()); break; - case INVOKEINTERFACE: cpi = stream.readCPI(); genInvokeInterface(constantPool().lookupMethod(cpi, opcode), cpi, constantPool()); break; + case GETSTATIC : cpi = stream.readCPI(); genGetStatic(cpi, constantPool.lookupField(cpi, opcode)); break; + case PUTSTATIC : cpi = stream.readCPI(); genPutStatic(cpi, constantPool.lookupField(cpi, opcode)); break; + case GETFIELD : cpi = stream.readCPI(); genGetField(cpi, constantPool.lookupField(cpi, opcode)); break; + case PUTFIELD : cpi = stream.readCPI(); genPutField(cpi, constantPool.lookupField(cpi, opcode)); break; + case INVOKEVIRTUAL : cpi = stream.readCPI(); genInvokeVirtual(constantPool.lookupMethod(cpi, opcode), cpi, constantPool); break; + case INVOKESPECIAL : cpi = stream.readCPI(); genInvokeSpecial(constantPool.lookupMethod(cpi, opcode), null, cpi, constantPool); break; + case INVOKESTATIC : cpi = stream.readCPI(); genInvokeStatic(constantPool.lookupMethod(cpi, opcode), cpi, constantPool); break; + case INVOKEINTERFACE: cpi = stream.readCPI(); genInvokeInterface(constantPool.lookupMethod(cpi, opcode), cpi, constantPool); break; case NEW : genNewInstance(stream.readCPI()); break; case NEWARRAY : genNewTypeArray(stream.readLocalIndex()); break; case ANEWARRAY : genNewObjectArray(stream.readCPI()); break; @@ -1468,10 +1461,6 @@ frameState.ipush(append(new ArrayLength(frameState.apop(), graph))); } - private RiConstantPool constantPool() { - return constantPool; - } - /** * Adds a block to the worklist, if it is not already in the worklist. * This method will keep the worklist topologically stored (i.e. the lower