# HG changeset patch # User Thomas Wuerthinger # Date 1423861414 -3600 # Node ID bef4a591e0b3e0be8ec80ab11e99e596eb99db9a # Parent 2d6a2f18fe8c767f019fc9ed588b4bbd894f6252 Avoid creating the begin block for single predecessor returns when inlining during graph building. diff -r 2d6a2f18fe8c -r bef4a591e0b3 graal/com.oracle.graal.java/src/com/oracle/graal/java/BciBlockMapping.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/BciBlockMapping.java Fri Feb 13 21:32:50 2015 +0100 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/BciBlockMapping.java Fri Feb 13 22:03:34 2015 +0100 @@ -84,6 +84,7 @@ public int loopId; public int loopEnd; protected List successors; + private int predecessorCount; private FixedWithNextNode firstInstruction; private AbstractFrameStateBuilder entryState; @@ -127,6 +128,10 @@ return id; } + public int getPredecessorCount() { + return this.predecessorCount; + } + public int numNormalSuccessors() { if (exceptionDispatchBlock() != null) { return successors.size() - 1; @@ -391,6 +396,18 @@ public void setId(int i) { this.id = i; } + + public void addSuccessor(BciBlock sux) { + successors.add(sux); + sux.predecessorCount++; + } + + public void clearSucccessors() { + for (BciBlock sux : successors) { + sux.predecessorCount--; + } + successors.clear(); + } } public static class ExceptionDispatchBlock extends BciBlock { @@ -421,6 +438,7 @@ public LocalLiveness liveness; private int blocksNotYetAssignedId; private final boolean consecutiveLoopBlocks; + public int returnCount; /** * Creates a new BlockMap instance from bytecode of the given method . @@ -441,6 +459,10 @@ return this.blocks; } + public int getReturnCount() { + return this.returnCount; + } + /** * Builds the block map and conservative CFG and numbers blocks. */ @@ -527,6 +549,7 @@ case DRETURN: // fall through case ARETURN: // fall through case RETURN: { + returnCount++; current = null; break; } @@ -653,11 +676,13 @@ blocksNotYetAssignedId++; newBlock.startBci = startBci; newBlock.endBci = oldBlock.endBci; - newBlock.getSuccessors().addAll(oldBlock.getSuccessors()); + for (BciBlock oldSuccessor : oldBlock.getSuccessors()) { + newBlock.addSuccessor(oldSuccessor); + } oldBlock.endBci = startBci - 1; - oldBlock.getSuccessors().clear(); - oldBlock.getSuccessors().add(newBlock); + oldBlock.clearSucccessors(); + oldBlock.addSuccessor(newBlock); for (int i = startBci; i <= newBlock.endBci; i++) { blockMap[i] = newBlock; @@ -686,7 +711,7 @@ if (sux.isExceptionEntry) { throw new BailoutException("Exception handler can be reached by both normal and exceptional control flow"); } - predecessor.getSuccessors().add(sux); + predecessor.addSuccessor(sux); } private final ArrayList jsrVisited = new ArrayList<>(); @@ -697,7 +722,7 @@ if (block.endsWithRet()) { block.setRetSuccessor(blockMap[scope.nextReturnAddress()]); - block.getSuccessors().add(block.getRetSuccessor()); + block.addSuccessor(block.getRetSuccessor()); assert block.getRetSuccessor() != block.getJsrSuccessor(); } Debug.log("JSR alternatives block %s sux %s jsrSux %s retSux %s jsrScope %s", block, block.getSuccessors(), block.getJsrSuccessor(), block.getRetSuccessor(), block.getJsrScope()); @@ -766,9 +791,9 @@ curHandler.endBci = -1; curHandler.deoptBci = bci; curHandler.handler = h; - curHandler.getSuccessors().add(blockMap[h.getHandlerBCI()]); + curHandler.addSuccessor(blockMap[h.getHandlerBCI()]); if (lastHandler != null) { - curHandler.getSuccessors().add(lastHandler); + curHandler.addSuccessor(lastHandler); } exceptionDispatch.put(h, curHandler); } diff -r 2d6a2f18fe8c -r bef4a591e0b3 graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Fri Feb 13 21:32:50 2015 +0100 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Fri Feb 13 22:03:34 2015 +0100 @@ -204,6 +204,7 @@ private final boolean explodeLoops; private Stack explodeLoopsContext; private int nextPeelIteration = 1; + private int returnCount; public BytecodeParser(MetaAccessProvider metaAccess, ResolvedJavaMethod method, GraphBuilderConfiguration graphBuilderConfig, OptimisticOptimizations optimisticOpts, int entryBCI) { super(metaAccess, method, graphBuilderConfig, optimisticOpts); @@ -251,6 +252,7 @@ BciBlockMapping blockMap = BciBlockMapping.create(method, graphBuilderConfig.doLivenessAnalysis(), explodeLoops); loopHeaders = blockMap.getLoopHeaders(); liveness = blockMap.liveness; + returnCount = blockMap.getReturnCount(); lastInstr = startInstruction; this.setCurrentFrameState(startFrameState); @@ -628,7 +630,7 @@ @Override protected void genGoto() { - appendGoto(createTarget(currentBlock.getSuccessors().get(0), frameState)); + appendGoto(createTarget(currentBlock.getSuccessor(0), frameState)); assert currentBlock.numNormalSuccessors() == 1; } @@ -1003,10 +1005,18 @@ beforeReturn(x); append(new ReturnNode(x)); } else { - if (x != null) { - frameState.push(x.getKind(), x); + if (returnCount == 1) { + // There is only a single return. + this.returnValue = x; + this.beforeReturnNode = this.lastInstr; + this.lastInstr = null; + } else { + if (x != null) { + frameState.push(x.getKind(), x); + } + assert returnCount > 1; + appendGoto(createTarget(returnBlock(bci()), frameState)); } - appendGoto(createTarget(returnBlock(bci()), frameState)); } } @@ -1213,6 +1223,10 @@ } private FixedNode createTarget(BciBlock block, HIRFrameStateBuilder state) { + return createTarget(block, state, false); + } + + private FixedNode createTarget(BciBlock block, HIRFrameStateBuilder state, boolean isGoto) { assert block != null && state != null; assert !block.isExceptionEntry || state.stackSize() == 1; @@ -1257,7 +1271,11 @@ * this block again. */ FixedNode targetNode; - block.setFirstInstruction(operatingDimension, currentGraph.add(new BeginNode())); + if (isGoto && block.getPredecessorCount() == 1) { + block.setFirstInstruction(operatingDimension, lastInstr); + } else { + block.setFirstInstruction(operatingDimension, currentGraph.add(new BeginNode())); + } targetNode = block.getFirstInstruction(operatingDimension); Target target = checkLoopExit(targetNode, block, state); FixedNode result = target.fixed; @@ -1632,9 +1650,9 @@ protected void genIf(ValueNode x, Condition cond, ValueNode y) { // assert !x.isDeleted() && !y.isDeleted(); // assert currentBlock.numNormalSuccessors() == 2; - assert currentBlock.getSuccessors().size() == 2; - BciBlock trueBlock = currentBlock.getSuccessors().get(0); - BciBlock falseBlock = currentBlock.getSuccessors().get(1); + assert currentBlock.getSuccessorCount() == 2; + BciBlock trueBlock = currentBlock.getSuccessor(0); + BciBlock falseBlock = currentBlock.getSuccessor(1); if (trueBlock == falseBlock) { appendGoto(createTarget(trueBlock, frameState)); return;