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