changeset 19482:63965fcb019b

Create helper methods in graph builder to support pending refactoring.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Wed, 18 Feb 2015 18:23:05 +0100
parents b0ba6f39cb60
children 625633886e25
files graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java
diffstat 1 files changed, 77 insertions(+), 57 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Wed Feb 18 18:10:42 2015 +0100
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Wed Feb 18 18:23:05 2015 +0100
@@ -290,11 +290,11 @@
                     }
 
                     currentBlock = blockMap.getStartBlock();
-                    startBlock.setEntryState(0, frameState);
+                    setEntryState(startBlock, 0, frameState);
                     if (startBlock.isLoopHeader && !explodeLoops) {
                         appendGoto(startBlock);
                     } else {
-                        startBlock.setFirstInstruction(0, lastInstr);
+                        setFirstInstruction(startBlock, 0, lastInstr);
                     }
 
                     int index = 0;
@@ -1204,7 +1204,7 @@
                         }
                         HIRFrameStateBuilder newState = state.copy();
                         for (BciBlock loop : exitLoops) {
-                            LoopBeginNode loopBegin = (LoopBeginNode) loop.getFirstInstruction(this.getCurrentDimension());
+                            LoopBeginNode loopBegin = (LoopBeginNode) getFirstInstruction(loop, this.getCurrentDimension());
                             LoopExitNode loopExit = currentGraph.add(new LoopExitNode(loopBegin));
                             if (lastLoopExit != null) {
                                 lastLoopExit.setNext(loopExit);
@@ -1214,7 +1214,7 @@
                             }
                             lastLoopExit = loopExit;
                             Debug.log("Target %s Exits %s, scanning framestates...", targetBlock, loop);
-                            newState.insertLoopProxies(loopExit, (HIRFrameStateBuilder) loop.getEntryState(this.getCurrentDimension()));
+                            newState.insertLoopProxies(loopExit, (HIRFrameStateBuilder) getEntryState(loop, this.getCurrentDimension()));
                             loopExit.setStateAfter(newState.create(bci));
                         }
 
@@ -1225,6 +1225,18 @@
                 return new Target(target, state);
             }
 
+            private void setEntryState(BciBlock block, int operatingDimension, AbstractFrameStateBuilder<?, ?> entryState) {
+                block.setEntryState(operatingDimension, entryState);
+            }
+
+            private void setFirstInstruction(BciBlock block, int operatingDimension, FixedWithNextNode firstInstruction) {
+                block.setFirstInstruction(operatingDimension, firstInstruction);
+            }
+
+            private FixedWithNextNode getFirstInstruction(BciBlock block, int dimension) {
+                return block.getFirstInstruction(dimension);
+            }
+
             private FixedNode createTarget(double probability, BciBlock block, HIRFrameStateBuilder stateAfter) {
                 assert probability >= 0 && probability <= 1.01 : probability;
                 if (isNeverExecutedCode(probability)) {
@@ -1243,41 +1255,9 @@
                 assert block != null && state != null;
                 assert !block.isExceptionEntry || state.stackSize() == 1;
 
-                int operatingDimension = this.getCurrentDimension();
-                if (this.explodeLoops && this.explodeLoopsContext != null && !this.explodeLoopsContext.isEmpty()) {
-                    int i;
-                    for (i = explodeLoopsContext.size() - 1; i >= 0; --i) {
-                        ExplodedLoopContext context = explodeLoopsContext.elementAt(i);
-                        if (context.header == block) {
-
-                            // We have a hit on our current explosion context loop begin.
-                            if (context.targetPeelIteration == -1) {
-                                // This is the first hit => allocate a new dimension and at the same
-                                // time mark the context loop begin as hit during the current
-                                // iteration.
-                                context.targetPeelIteration = nextPeelIteration++;
-                                if (nextPeelIteration > MaximumLoopExplosionCount.getValue()) {
-                                    throw new BailoutException("too many loop explosion interations - does the explosion not terminate?");
-                                }
-                            }
+                int operatingDimension = findOperatingDimension(block);
 
-                            // Operate on the target dimension.
-                            operatingDimension = context.targetPeelIteration;
-                            break;
-                        } else if (block.getId() > context.header.getId() && block.getId() <= context.header.loopEnd) {
-                            // We hit the range of this context.
-                            operatingDimension = context.peelIteration;
-                            break;
-                        }
-                    }
-
-                    if (i == -1) {
-                        // I did not find a dimension.
-                        operatingDimension = 0;
-                    }
-                }
-
-                if (block.getFirstInstruction(operatingDimension) == null) {
+                if (getFirstInstruction(block, operatingDimension) == null) {
                     /*
                      * This is the first time we see this block as a branch target. Create and
                      * return a placeholder that later can be replaced with a MergeNode when we see
@@ -1285,16 +1265,16 @@
                      */
                     FixedNode targetNode;
                     if (isGoto && (block.getPredecessorCount() == 1 || !controlFlowSplit) && !block.isLoopHeader && (currentBlock.loops & ~block.loops) == 0) {
-                        block.setFirstInstruction(operatingDimension, lastInstr);
+                        setFirstInstruction(block, operatingDimension, lastInstr);
                         lastInstr = null;
                     } else {
-                        block.setFirstInstruction(operatingDimension, currentGraph.add(new BeginNode()));
+                        setFirstInstruction(block, operatingDimension, currentGraph.add(new BeginNode()));
                     }
-                    targetNode = block.getFirstInstruction(operatingDimension);
+                    targetNode = getFirstInstruction(block, operatingDimension);
                     Target target = checkLoopExit(targetNode, block, state);
                     FixedNode result = target.fixed;
                     AbstractFrameStateBuilder<?, ?> entryState = target.state == state ? state.copy() : target.state;
-                    block.setEntryState(operatingDimension, entryState);
+                    setEntryState(block, operatingDimension, entryState);
                     entryState.clearNonLiveLocals(block, liveness, true);
 
                     Debug.log("createTarget %s: first visit, result: %s", block, targetNode);
@@ -1302,34 +1282,34 @@
                 }
 
                 // We already saw this block before, so we have to merge states.
-                if (!((HIRFrameStateBuilder) block.getEntryState(operatingDimension)).isCompatibleWith(state)) {
+                if (!((HIRFrameStateBuilder) getEntryState(block, operatingDimension)).isCompatibleWith(state)) {
                     throw new BailoutException("stacks do not match; bytecodes would not verify");
                 }
 
-                if (block.getFirstInstruction(operatingDimension) instanceof LoopBeginNode) {
+                if (getFirstInstruction(block, operatingDimension) instanceof LoopBeginNode) {
                     assert this.explodeLoops || (block.isLoopHeader && currentBlock.getId() >= block.getId()) : "must be backward branch";
                     /*
                      * Backward loop edge. We need to create a special LoopEndNode and merge with
                      * the loop begin node created before.
                      */
-                    LoopBeginNode loopBegin = (LoopBeginNode) block.getFirstInstruction(operatingDimension);
+                    LoopBeginNode loopBegin = (LoopBeginNode) getFirstInstruction(block, operatingDimension);
                     Target target = checkLoopExit(currentGraph.add(new LoopEndNode(loopBegin)), block, state);
                     FixedNode result = target.fixed;
-                    ((HIRFrameStateBuilder) block.getEntryState(operatingDimension)).merge(loopBegin, target.state);
+                    ((HIRFrameStateBuilder) getEntryState(block, operatingDimension)).merge(loopBegin, target.state);
 
                     Debug.log("createTarget %s: merging backward branch to loop header %s, result: %s", block, loopBegin, result);
                     return result;
                 }
                 assert currentBlock == null || currentBlock.getId() < block.getId() : "must not be backward branch";
-                assert block.getFirstInstruction(operatingDimension).next() == null : "bytecodes already parsed for block";
+                assert getFirstInstruction(block, operatingDimension).next() == null : "bytecodes already parsed for block";
 
-                if (block.getFirstInstruction(operatingDimension) instanceof AbstractBeginNode && !(block.getFirstInstruction(operatingDimension) instanceof AbstractMergeNode)) {
+                if (getFirstInstruction(block, operatingDimension) instanceof AbstractBeginNode && !(getFirstInstruction(block, operatingDimension) instanceof AbstractMergeNode)) {
                     /*
                      * This is the second time we see this block. Create the actual MergeNode and
                      * the End Node for the already existing edge. For simplicity, we leave the
                      * placeholder in the graph and just append the new nodes after the placeholder.
                      */
-                    AbstractBeginNode placeholder = (AbstractBeginNode) block.getFirstInstruction(operatingDimension);
+                    AbstractBeginNode placeholder = (AbstractBeginNode) getFirstInstruction(block, operatingDimension);
 
                     // The EndNode for the already existing edge.
                     AbstractEndNode end = currentGraph.add(new EndNode());
@@ -1347,22 +1327,62 @@
                     mergeNode.addForwardEnd(end);
                     mergeNode.setNext(next);
 
-                    block.setFirstInstruction(operatingDimension, mergeNode);
+                    setFirstInstruction(block, operatingDimension, mergeNode);
                 }
 
-                AbstractMergeNode mergeNode = (AbstractMergeNode) block.getFirstInstruction(operatingDimension);
+                AbstractMergeNode mergeNode = (AbstractMergeNode) getFirstInstruction(block, operatingDimension);
 
                 // The EndNode for the newly merged edge.
                 AbstractEndNode newEnd = currentGraph.add(new EndNode());
                 Target target = checkLoopExit(newEnd, block, state);
                 FixedNode result = target.fixed;
-                ((HIRFrameStateBuilder) block.getEntryState(operatingDimension)).merge(mergeNode, target.state);
+                ((HIRFrameStateBuilder) getEntryState(block, operatingDimension)).merge(mergeNode, target.state);
                 mergeNode.addForwardEnd(newEnd);
 
                 Debug.log("createTarget %s: merging state, result: %s", block, result);
                 return result;
             }
 
+            private AbstractFrameStateBuilder<?, ?> getEntryState(BciBlock block, int operatingDimension) {
+                return block.getEntryState(operatingDimension);
+            }
+
+            private int findOperatingDimension(BciBlock block) {
+                if (this.explodeLoops && this.explodeLoopsContext != null && !this.explodeLoopsContext.isEmpty()) {
+                    return findOperatingDimensionWithLoopExplosion(block);
+                }
+                return this.getCurrentDimension();
+            }
+
+            private int findOperatingDimensionWithLoopExplosion(BciBlock block) {
+                int i;
+                for (i = explodeLoopsContext.size() - 1; i >= 0; --i) {
+                    ExplodedLoopContext context = explodeLoopsContext.elementAt(i);
+                    if (context.header == block) {
+
+                        // We have a hit on our current explosion context loop begin.
+                        if (context.targetPeelIteration == -1) {
+                            // This is the first hit => allocate a new dimension and at the same
+                            // time mark the context loop begin as hit during the current
+                            // iteration.
+                            context.targetPeelIteration = nextPeelIteration++;
+                            if (nextPeelIteration > MaximumLoopExplosionCount.getValue()) {
+                                throw new BailoutException("too many loop explosion interations - does the explosion not terminate?");
+                            }
+                        }
+
+                        // Operate on the target dimension.
+                        return context.targetPeelIteration;
+                    } else if (block.getId() > context.header.getId() && block.getId() <= context.header.loopEnd) {
+                        // We hit the range of this context.
+                        return context.peelIteration;
+                    }
+                }
+
+                // No dimension found.
+                return 0;
+            }
+
             /**
              * Returns a block begin node with the specified state. If the specified probability is
              * 0, the block deoptimizes immediately.
@@ -1386,14 +1406,14 @@
 
             protected void processBlock(BytecodeParser parser, BciBlock block) {
                 // Ignore blocks that have no predecessors by the time their bytecodes are parsed
-                if (block == null || block.getFirstInstruction(this.getCurrentDimension()) == null) {
+                if (block == null || getFirstInstruction(block, this.getCurrentDimension()) == null) {
                     Debug.log("Ignoring block %s", block);
                     return;
                 }
                 try (Indent indent = Debug.logAndIndent("Parsing block %s  firstInstruction: %s  loopHeader: %b", block, block.getFirstInstruction(this.getCurrentDimension()), block.isLoopHeader)) {
 
-                    lastInstr = block.getFirstInstruction(this.getCurrentDimension());
-                    frameState = (HIRFrameStateBuilder) block.getEntryState(this.getCurrentDimension());
+                    lastInstr = getFirstInstruction(block, this.getCurrentDimension());
+                    frameState = (HIRFrameStateBuilder) getEntryState(block, this.getCurrentDimension());
                     parser.setCurrentFrameState(frameState);
                     currentBlock = block;
 
@@ -1553,12 +1573,12 @@
                      * merge to the loop header. This ensures that the loop header has exactly one
                      * non-loop predecessor.
                      */
-                    block.setFirstInstruction(this.getCurrentDimension(), loopBegin);
+                    setFirstInstruction(block, this.getCurrentDimension(), loopBegin);
                     /*
                      * We need to preserve the frame state builder of the loop header so that we can
                      * merge values for phi functions, so make a copy of it.
                      */
-                    block.setEntryState(this.getCurrentDimension(), frameState.copy());
+                    setEntryState(block, this.getCurrentDimension(), frameState.copy());
 
                     Debug.log("  created loop header %s", loopBegin);
                 }