Mercurial > hg > truffle
diff graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java @ 2781:bda5972a40a5
remove unnecessary BlockBegin nodes in frontend
author | Lukas Stadler <lukas.stadler@jku.at> |
---|---|
date | Tue, 24 May 2011 15:31:52 +0200 |
parents | 398b8fa5dc81 |
children | 9bc0c2eb00d6 |
line wrap: on
line diff
--- a/graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java Tue May 24 13:55:56 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java Tue May 24 15:31:52 2011 +0200 @@ -165,13 +165,6 @@ // System.out.println("block " + blockID + " @ " + block.startBci); } - // 1. create the start block - Block startBlock = nextBlock(Instruction.SYNCHRONIZATION_ENTRY_BCI); - BlockBegin startBlockBegin = new BlockBegin(0, startBlock.blockID, false, graph); - startBlock.firstInstruction = startBlockBegin; - - graph.start().setStart(startBlockBegin); - RiExceptionHandler[] handlers = rootMethod.exceptionHandlers(); if (handlers != null && handlers.length > 0) { exceptionHandlers = new ArrayList<ExceptionHandler>(handlers.length); @@ -187,13 +180,12 @@ flags |= Flag.HasHandler.mask; } - mergeOrClone(startBlock, frameState); + // 1. create the start block + Block startBlock = nextBlock(Instruction.SYNCHRONIZATION_ENTRY_BCI); + markOnWorkList(startBlock); + lastInstr = createTarget(startBlock, frameState); + graph.start().setStart(lastInstr); - // 3. setup internal state for appending instructions - lastInstr = startBlockBegin; - lastInstr.appendNext(null); - - BlockBegin syncHandler = null; Block syncBlock = null; if (isSynchronized(rootMethod.accessFlags())) { // 4A.1 add a monitor enter to the start block @@ -204,15 +196,8 @@ // 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, false, graph); - syncBlock.firstInstruction = syncHandler; markOnWorkList(syncBlock); - ExceptionBlock excBlock = new ExceptionBlock(); - excBlock.startBci = -1; - excBlock.endBci = -1; - excBlock.blockID = ir.nextBlockNumber(); - blockList.add(excBlock); ExceptionHandler h = new ExceptionHandler(new CiExceptionHandler(0, rootMethod.code().length, -1, 0, null)); h.setEntryBlock(syncBlock); addExceptionHandler(h); @@ -227,27 +212,45 @@ addToWorkList(blockFromBci[0]); iterateAllBlocks(); - if (syncBlock != null && syncHandler.stateBefore() != null) { + if (syncBlock != null && syncBlock.firstInstruction != null) { // generate unlocking code if the exception handler is reachable fillSyncHandler(rootMethodSynchronizedObject, syncBlock); } -// for (Node n : graph.getNodes()) { -// if (n instanceof FrameState) { -// boolean delete = false; -// if (n.usages().size() == 0 && n.predecessors().size() == 0) { -// delete = true; -// } + for (Node n : graph.getNodes()) { + if (n instanceof Placeholder) { + Placeholder p = (Placeholder) n; + + if (p == graph.start().successors().get(0)) { + // nothing to do... + } else if (p.blockPredecessors().size() == 0) { + assert p.next() == null; + p.delete(); + } else { + assert p.blockPredecessors().size() == 1; + for (Node pred : new ArrayList<Node>(p.predecessors())) { + pred.successors().replace(p, p.next()); + } + p.successors().clearAll(); + p.delete(); + } + } + } + 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(); -// System.out.println("deleted framestate"); -// } -// } -// } + if (delete) { + n.delete(); + } + } + } } private Block nextBlock(int bci) { @@ -287,44 +290,44 @@ public void mergeOrClone(Block target, FrameStateAccess newState) { Instruction first = target.firstInstruction; - int bci = target.startBci; - boolean loopHeader = target.isLoopHeader; + assert first instanceof StateSplit; - FrameState existingState; - if (first instanceof Placeholder) { - existingState = ((Placeholder) first).stateBefore(); - } else { - assert first instanceof BlockBegin; - existingState = ((BlockBegin) first).stateBefore(); - } + int bci = target.startBci; + + FrameState existingState = ((StateSplit) first).stateBefore(); if (existingState == null) { + assert first instanceof BlockBegin ^ !target.isLoopHeader : "isLoopHeader: " + target.isLoopHeader; + // copy state because it is modified FrameState duplicate = newState.duplicate(bci); // if the block is a loop header, insert all necessary phis - if (loopHeader) { + if (target.isLoopHeader) { assert first instanceof BlockBegin; insertLoopPhis((BlockBegin) first, duplicate); ((BlockBegin) first).setStateBefore(duplicate); } else { - if (first instanceof Placeholder) { - ((Placeholder) first).setStateBefore(duplicate); - } else { - ((BlockBegin) first).setStateBefore(duplicate); - } + ((StateSplit) first).setStateBefore(duplicate); } } else { - 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"); } - assert existingState.localsSize() == newState.localsSize(); assert existingState.stackSize() == newState.stackSize(); - existingState.merge((BlockBegin) first, newState); + if (first instanceof Placeholder) { + BlockBegin merge = new BlockBegin(existingState.bci, target.blockID, target.isLoopHeader, graph); + for (Node n : new ArrayList<Node>(first.predecessors())) { + n.successors().replace(first, merge); + } + target.firstInstruction = merge; + merge.setStateBefore(existingState); + } + + existingState.merge((BlockBegin) target.firstInstruction, newState); } for (int j = 0; j < frameState.localsSize() + frameState.stackSize(); ++j) { @@ -411,7 +414,7 @@ } FrameState entryState = frameState.duplicateWithEmptyStack(bci); - BlockBegin entry = new BlockBegin(bci, ir.nextBlockNumber(), false, graph); + StateSplit entry = new Placeholder(graph); entry.setStateBefore(entryState); ExceptionObject exception = new ExceptionObject(graph); entry.appendNext(exception); @@ -1054,12 +1057,14 @@ private Instruction createTarget(Block block, FrameStateAccess stateAfter) { assert block != null && stateAfter != null; + assert block.isLoopHeader || block.firstInstruction == null || block.firstInstruction.next() == null : "non-loop block must be iterated after all its predecessors"; + if (block.firstInstruction == null) { -// if (block.isLoopHeader) { + if (block.isLoopHeader) { block.firstInstruction = new BlockBegin(block.startBci, block.blockID, block.isLoopHeader, graph); -// } else { -// block.firstInstruction = new Placeholder(graph); -// } + } else { + block.firstInstruction = new Placeholder(graph); + } } mergeOrClone(block, stateAfter); addToWorkList(block); @@ -1119,9 +1124,9 @@ if (!isVisited(block)) { markVisited(block); // now parse the block - frameState.initializeFrom(((BlockBegin) block.firstInstruction).stateBefore()); + frameState.initializeFrom(((StateSplit) block.firstInstruction).stateBefore()); lastInstr = block.firstInstruction; - assert block.firstInstruction.next() == null; + assert block.firstInstruction.next() == null : "instructions already appended at block " + block.blockID; if (block instanceof ExceptionBlock) { createExceptionDispatch((ExceptionBlock) block);