Mercurial > hg > graal-compiler
changeset 23312:ddd530cc44c9
Remove loop explosion and merging during graph building and FastPE. GraphPE is the successor with equivalent capabilities.
author | Thomas Wuerthinger <thomas.wuerthinger@oracle.com> |
---|---|
date | Fri, 15 Jan 2016 18:02:41 +0100 |
parents | 2cc28cd4b483 |
children | 0ca595288320 |
files | graal/com.oracle.graal.java/src/com/oracle/graal/java/BytecodeParser.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java |
diffstat | 2 files changed, 42 insertions(+), 498 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/BytecodeParser.java Thu Jan 14 15:18:33 2016 -0800 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/BytecodeParser.java Fri Jan 15 18:02:41 2016 +0100 @@ -232,8 +232,6 @@ import static com.oracle.graal.compiler.common.GraalOptions.StressInvokeWithExceptionNode; import static com.oracle.graal.compiler.common.type.StampFactory.objectNonNull; import static com.oracle.graal.java.BytecodeParserOptions.DumpDuringGraphBuilding; -import static com.oracle.graal.java.BytecodeParserOptions.FailedLoopExplosionIsFatal; -import static com.oracle.graal.java.BytecodeParserOptions.MaximumLoopExplosionCount; import static com.oracle.graal.java.BytecodeParserOptions.TraceInlineDuringParsing; import static com.oracle.graal.java.BytecodeParserOptions.TraceParserPlugins; import static com.oracle.graal.nodes.graphbuilderconf.IntrinsicContext.CompilationContext.INLINE_DURING_PARSING; @@ -250,15 +248,11 @@ import static jdk.vm.ci.meta.DeoptimizationReason.UnreachedCode; import static jdk.vm.ci.meta.DeoptimizationReason.Unresolved; -import java.util.ArrayDeque; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.Comparator; -import java.util.Deque; import java.util.Formatter; import java.util.HashMap; -import java.util.IdentityHashMap; import java.util.List; import java.util.Map; @@ -310,7 +304,6 @@ import com.oracle.graal.graph.Graph.Mark; import com.oracle.graal.graph.Node; import com.oracle.graal.graph.Node.ValueNumberable; -import com.oracle.graal.graph.NodeBitMap; import com.oracle.graal.graph.iterators.NodeIterable; import com.oracle.graal.java.BciBlockMapping.BciBlock; import com.oracle.graal.java.BciBlockMapping.ExceptionDispatchBlock; @@ -388,7 +381,6 @@ import com.oracle.graal.nodes.graphbuilderconf.InlineInvokePlugin; import com.oracle.graal.nodes.graphbuilderconf.IntrinsicContext; import com.oracle.graal.nodes.graphbuilderconf.InvocationPlugin; -import com.oracle.graal.nodes.graphbuilderconf.LoopExplosionPlugin; import com.oracle.graal.nodes.graphbuilderconf.NodePlugin; import com.oracle.graal.nodes.graphbuilderconf.InlineInvokePlugin.InlineInfo; import com.oracle.graal.nodes.graphbuilderconf.InvocationPlugins.InvocationPluginReceiver; @@ -547,12 +539,6 @@ } } - private static class ExplodedLoopContext { - private BciBlock header; - private int[] targetPeelIteration; - private int peelIteration; - } - @SuppressWarnings("serial") public static class BytecodeParserError extends JVMCIError { @@ -585,18 +571,11 @@ private FixedWithNextNode beforeUnwindNode; protected FixedWithNextNode lastInstr; // the last instruction added - private final boolean explodeLoops; - private final boolean mergeExplosions; - private final Map<FrameStateBuilder, Integer> mergeExplosionsMap; - private Deque<ExplodedLoopContext> explodeLoopsContext; - private int nextPeelIteration = 1; private boolean controlFlowSplit; private final InvocationPluginReceiver invocationPluginReceiver = new InvocationPluginReceiver(this); private FixedWithNextNode[] firstInstructionArray; private FrameStateBuilder[] entryStateArray; - private FixedWithNextNode[][] firstInstructionMatrix; - private FrameStateBuilder[][] entryStateMatrix; protected BytecodeParser(GraphBuilderPhase.Instance graphBuilderInstance, StructuredGraph graph, BytecodeParser parent, ResolvedJavaMethod method, int entryBCI, IntrinsicContext intrinsicContext) { this.graphBuilderInstance = graphBuilderInstance; @@ -620,22 +599,6 @@ lnt = method.getLineNumberTable(); previousLineNumber = -1; } - - LoopExplosionPlugin loopExplosionPlugin = graphBuilderConfig.getPlugins().getLoopExplosionPlugin(); - if (loopExplosionPlugin != null) { - explodeLoops = loopExplosionPlugin.shouldExplodeLoops(method); - if (explodeLoops) { - mergeExplosions = loopExplosionPlugin.shouldMergeExplosions(method); - mergeExplosionsMap = new HashMap<>(); - } else { - mergeExplosions = false; - mergeExplosionsMap = null; - } - } else { - explodeLoops = false; - mergeExplosions = false; - mergeExplosionsMap = null; - } } protected GraphBuilderPhase.Instance getGraphBuilderInstance() { @@ -745,23 +708,16 @@ } currentBlock = blockMap.getStartBlock(); - setEntryState(startBlock, 0, frameState); - if (startBlock.isLoopHeader && !explodeLoops) { + setEntryState(startBlock, frameState); + if (startBlock.isLoopHeader) { appendGoto(startBlock); } else { - setFirstInstruction(startBlock, 0, lastInstr); + setFirstInstruction(startBlock, lastInstr); } - int index = 0; BciBlock[] blocks = blockMap.getBlocks(); - while (index < blocks.length) { - BciBlock block = blocks[index]; - index = iterateBlock(blocks, block); - } - - if (this.mergeExplosions) { - Debug.dump(graph, "Before loop detection"); - detectLoops(startInstruction); + for (BciBlock block : blocks) { + processBlock(block); } if (Debug.isDumpEnabled() && DumpDuringGraphBuilding.getValue() && this.beforeReturnNode != startInstruction) { @@ -901,233 +857,6 @@ return stateAfterStart; } - private void detectLoops(FixedNode startInstruction) { - NodeBitMap visited = graph.createNodeBitMap(); - NodeBitMap active = graph.createNodeBitMap(); - Deque<Node> stack = new ArrayDeque<>(); - stack.add(startInstruction); - visited.mark(startInstruction); - while (!stack.isEmpty()) { - Node next = stack.peek(); - assert next.isDeleted() || visited.isMarked(next); - if (next.isDeleted() || active.isMarked(next)) { - stack.pop(); - if (!next.isDeleted()) { - active.clear(next); - } - } else { - active.mark(next); - for (Node n : next.cfgSuccessors()) { - if (active.contains(n)) { - // Detected cycle. - assert n instanceof MergeNode; - assert next instanceof EndNode; - MergeNode merge = (MergeNode) n; - EndNode endNode = (EndNode) next; - merge.removeEnd(endNode); - FixedNode afterMerge = merge.next(); - if (!(afterMerge instanceof EndNode) || !(((EndNode) afterMerge).merge() instanceof LoopBeginNode)) { - merge.setNext(null); - LoopBeginNode newLoopBegin = this.appendLoopBegin(merge); - newLoopBegin.setNext(afterMerge); - } - LoopBeginNode loopBegin = (LoopBeginNode) ((EndNode) merge.next()).merge(); - LoopEndNode loopEnd = graph.add(new LoopEndNode(loopBegin)); - endNode.replaceAndDelete(loopEnd); - } else if (visited.contains(n)) { - // Normal merge into a branch we are already exploring. - } else { - visited.mark(n); - stack.push(n); - } - } - } - } - - Debug.dump(graph, "After loops detected"); - insertLoopEnds(startInstruction); - } - - private void insertLoopEnds(FixedNode startInstruction) { - NodeBitMap visited = graph.createNodeBitMap(); - Deque<Node> stack = new ArrayDeque<>(); - stack.add(startInstruction); - visited.mark(startInstruction); - List<LoopBeginNode> loopBegins = new ArrayList<>(); - while (!stack.isEmpty()) { - Node next = stack.pop(); - assert visited.isMarked(next); - if (next instanceof LoopBeginNode) { - loopBegins.add((LoopBeginNode) next); - } - for (Node n : next.cfgSuccessors()) { - if (visited.contains(n)) { - // Nothing to do. - } else { - visited.mark(n); - stack.push(n); - } - } - } - - IdentityHashMap<LoopBeginNode, List<LoopBeginNode>> innerLoopsMap = new IdentityHashMap<>(); - for (int i = loopBegins.size() - 1; i >= 0; --i) { - LoopBeginNode loopBegin = loopBegins.get(i); - insertLoopExits(loopBegin, innerLoopsMap); - if (DumpDuringGraphBuilding.getValue()) { - Debug.dump(graph, "After building loop exits for %s.", loopBegin); - } - } - - // Remove degenerated merges with only one predecessor. - for (LoopBeginNode loopBegin : loopBegins) { - Node pred = loopBegin.forwardEnd().predecessor(); - if (pred instanceof MergeNode) { - MergeNode.removeMergeIfDegenerated((MergeNode) pred); - } - } - } - - private void insertLoopExits(LoopBeginNode loopBegin, IdentityHashMap<LoopBeginNode, List<LoopBeginNode>> innerLoopsMap) { - NodeBitMap visited = graph.createNodeBitMap(); - Deque<Node> stack = new ArrayDeque<>(); - for (LoopEndNode loopEnd : loopBegin.loopEnds()) { - stack.push(loopEnd); - visited.mark(loopEnd); - } - - List<ControlSplitNode> controlSplits = new ArrayList<>(); - List<LoopBeginNode> innerLoopBegins = new ArrayList<>(); - - while (!stack.isEmpty()) { - Node current = stack.pop(); - if (current == loopBegin) { - continue; - } - for (Node pred : current.cfgPredecessors()) { - if (!visited.isMarked(pred)) { - visited.mark(pred); - if (pred instanceof LoopExitNode) { - // Inner loop - LoopExitNode loopExitNode = (LoopExitNode) pred; - LoopBeginNode innerLoopBegin = loopExitNode.loopBegin(); - if (!visited.isMarked(innerLoopBegin)) { - stack.push(innerLoopBegin); - visited.mark(innerLoopBegin); - innerLoopBegins.add(innerLoopBegin); - } - } else { - if (pred instanceof ControlSplitNode) { - ControlSplitNode controlSplitNode = (ControlSplitNode) pred; - controlSplits.add(controlSplitNode); - } - stack.push(pred); - } - } - } - } - - for (ControlSplitNode controlSplit : controlSplits) { - for (Node succ : controlSplit.cfgSuccessors()) { - if (!visited.isMarked(succ)) { - LoopExitNode loopExit = graph.add(new LoopExitNode(loopBegin)); - FixedNode next = ((FixedWithNextNode) succ).next(); - next.replaceAtPredecessor(loopExit); - loopExit.setNext(next); - } - } - } - - for (LoopBeginNode inner : innerLoopBegins) { - addLoopExits(loopBegin, inner, innerLoopsMap, visited); - if (DumpDuringGraphBuilding.getValue()) { - Debug.dump(graph, "After adding loop exits for %s.", inner); - } - } - - innerLoopsMap.put(loopBegin, innerLoopBegins); - } - - private void addLoopExits(LoopBeginNode loopBegin, LoopBeginNode inner, IdentityHashMap<LoopBeginNode, List<LoopBeginNode>> innerLoopsMap, NodeBitMap visited) { - for (LoopExitNode exit : inner.loopExits()) { - if (!visited.isMarked(exit)) { - LoopExitNode newLoopExit = graph.add(new LoopExitNode(loopBegin)); - FixedNode next = exit.next(); - next.replaceAtPredecessor(newLoopExit); - newLoopExit.setNext(next); - } - } - - for (LoopBeginNode innerInner : innerLoopsMap.get(inner)) { - addLoopExits(loopBegin, innerInner, innerLoopsMap, visited); - } - } - - private int iterateBlock(BciBlock[] blocks, BciBlock block) { - if (block.isLoopHeader && this.explodeLoops) { - return iterateExplodedLoopHeader(blocks, block); - } else { - processBlock(this, block); - return block.getId() + 1; - } - } - - private int iterateExplodedLoopHeader(BciBlock[] blocks, BciBlock header) { - if (explodeLoopsContext == null) { - explodeLoopsContext = new ArrayDeque<>(); - } - - ExplodedLoopContext context = new ExplodedLoopContext(); - context.header = header; - context.peelIteration = this.getCurrentDimension(); - if (this.mergeExplosions) { - this.addToMergeCache(getEntryState(context.header, context.peelIteration), context.peelIteration); - } - explodeLoopsContext.push(context); - if (Debug.isDumpEnabled() && DumpDuringGraphBuilding.getValue()) { - Debug.dump(graph, "before loop explosion dimension " + context.peelIteration); - } - peelIteration(blocks, header, context); - explodeLoopsContext.pop(); - return header.loopEnd + 1; - } - - private void addToMergeCache(FrameStateBuilder key, int dimension) { - mergeExplosionsMap.put(key, dimension); - } - - private void peelIteration(BciBlock[] blocks, BciBlock header, ExplodedLoopContext context) { - while (true) { - if (TraceParserPlugins.getValue()) { - traceWithContext("exploding loop, iteration %d", context.peelIteration); - } - processBlock(this, header); - int j = header.getId() + 1; - while (j <= header.loopEnd) { - BciBlock block = blocks[j]; - j = iterateBlock(blocks, block); - } - - int[] targets = context.targetPeelIteration; - if (targets != null) { - // We were reaching the backedge during explosion. Explode further. - for (int i = 0; i < targets.length; ++i) { - context.peelIteration = targets[i]; - context.targetPeelIteration = null; - if (Debug.isDumpEnabled() && DumpDuringGraphBuilding.getValue()) { - Debug.dump(graph, "next loop explosion iteration " + context.peelIteration); - } - if (i < targets.length - 1) { - peelIteration(blocks, header, context); - } - } - } else { - // We did not reach the backedge. Exit. - break; - } - } - } - /** * @param type the unresolved type of the constant */ @@ -2123,7 +1852,7 @@ } private Target checkLoopExit(FixedNode target, BciBlock targetBlock, FrameStateBuilder state) { - if (currentBlock != null && !explodeLoops) { + if (currentBlock != null) { long exits = currentBlock.loops & ~targetBlock.loops; if (exits != 0) { LoopExitNode firstLoopExit = null; @@ -2154,7 +1883,7 @@ } FrameStateBuilder newState = state.copy(); for (BciBlock loop : exitLoops) { - LoopBeginNode loopBegin = (LoopBeginNode) getFirstInstruction(loop, this.getCurrentDimension()); + LoopBeginNode loopBegin = (LoopBeginNode) getFirstInstruction(loop); LoopExitNode loopExit = graph.add(new LoopExitNode(loopBegin)); if (lastLoopExit != null) { lastLoopExit.setNext(loopExit); @@ -2164,7 +1893,7 @@ } lastLoopExit = loopExit; Debug.log("Target %s Exits %s, scanning framestates...", targetBlock, loop); - newState.insertLoopProxies(loopExit, getEntryState(loop, this.getCurrentDimension())); + newState.insertLoopProxies(loopExit, getEntryState(loop)); loopExit.setStateAfter(newState.create(bci, loopExit)); } @@ -2175,96 +1904,20 @@ return new Target(target, state); } - private FrameStateBuilder getEntryState(BciBlock block, int dimension) { - int id = block.id; - if (dimension == 0) { - return entryStateArray[id]; - } else { - return getEntryStateMultiDimension(dimension, id); - } - } - - private FrameStateBuilder getEntryStateMultiDimension(int dimension, int id) { - if (entryStateMatrix != null && dimension - 1 < entryStateMatrix.length) { - FrameStateBuilder[] entryStateArrayEntry = entryStateMatrix[dimension - 1]; - if (entryStateArrayEntry == null) { - return null; - } - return entryStateArrayEntry[id]; - } else { - return null; - } + private FrameStateBuilder getEntryState(BciBlock block) { + return entryStateArray[block.id]; } - private void setEntryState(BciBlock block, int dimension, FrameStateBuilder entryState) { - int id = block.id; - if (dimension == 0) { - this.entryStateArray[id] = entryState; - } else { - setEntryStateMultiDimension(dimension, entryState, id); - } - } - - private void setEntryStateMultiDimension(int dimension, FrameStateBuilder entryState, int id) { - if (entryStateMatrix == null) { - entryStateMatrix = new FrameStateBuilder[4][]; - } - if (dimension - 1 < entryStateMatrix.length) { - // We are within bounds. - } else { - // We are out of bounds. - entryStateMatrix = Arrays.copyOf(entryStateMatrix, Math.max(entryStateMatrix.length * 2, dimension)); - } - if (entryStateMatrix[dimension - 1] == null) { - entryStateMatrix[dimension - 1] = new FrameStateBuilder[blockMap.getBlockCount()]; - } - entryStateMatrix[dimension - 1][id] = entryState; + private void setEntryState(BciBlock block, FrameStateBuilder entryState) { + this.entryStateArray[block.id] = entryState; } - private void setFirstInstruction(BciBlock block, int dimension, FixedWithNextNode firstInstruction) { - int id = block.id; - if (dimension == 0) { - this.firstInstructionArray[id] = firstInstruction; - } else { - setFirstInstructionMultiDimension(dimension, firstInstruction, id); - } + private void setFirstInstruction(BciBlock block, FixedWithNextNode firstInstruction) { + this.firstInstructionArray[block.id] = firstInstruction; } - private void setFirstInstructionMultiDimension(int dimension, FixedWithNextNode firstInstruction, int id) { - if (firstInstructionMatrix == null) { - firstInstructionMatrix = new FixedWithNextNode[4][]; - } - if (dimension - 1 < firstInstructionMatrix.length) { - // We are within bounds. - } else { - // We are out of bounds. - firstInstructionMatrix = Arrays.copyOf(firstInstructionMatrix, Math.max(firstInstructionMatrix.length * 2, dimension)); - } - if (firstInstructionMatrix[dimension - 1] == null) { - firstInstructionMatrix[dimension - 1] = new FixedWithNextNode[blockMap.getBlockCount()]; - } - firstInstructionMatrix[dimension - 1][id] = firstInstruction; - } - - private FixedWithNextNode getFirstInstruction(BciBlock block, int dimension) { - int id = block.id; - if (dimension == 0) { - return firstInstructionArray[id]; - } else { - return getFirstInstructionMultiDimension(dimension, id); - } - } - - private FixedWithNextNode getFirstInstructionMultiDimension(int dimension, int id) { - if (firstInstructionMatrix != null && dimension - 1 < firstInstructionMatrix.length) { - FixedWithNextNode[] firstInstructionArrayEntry = firstInstructionMatrix[dimension - 1]; - if (firstInstructionArrayEntry == null) { - return null; - } - return firstInstructionArrayEntry[id]; - } else { - return null; - } + private FixedWithNextNode getFirstInstruction(BciBlock block) { + return firstInstructionArray[block.id]; } private FixedNode createTarget(double probability, BciBlock block, FrameStateBuilder stateAfter) { @@ -2285,25 +1938,23 @@ assert block != null && state != null; assert !block.isExceptionEntry || state.stackSize() == 1; - int operatingDimension = findOperatingDimension(block, state); - - if (getFirstInstruction(block, operatingDimension) == null) { + if (getFirstInstruction(block) == 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 this block again. */ FixedNode targetNode; if (canReuseInstruction && (block.getPredecessorCount() == 1 || !controlFlowSplit) && !block.isLoopHeader && (currentBlock.loops & ~block.loops) == 0) { - setFirstInstruction(block, operatingDimension, lastInstr); + setFirstInstruction(block, lastInstr); lastInstr = null; } else { - setFirstInstruction(block, operatingDimension, graph.add(new BeginNode())); + setFirstInstruction(block, graph.add(new BeginNode())); } - targetNode = getFirstInstruction(block, operatingDimension); + targetNode = getFirstInstruction(block); Target target = checkLoopExit(targetNode, block, state); FixedNode result = target.fixed; FrameStateBuilder currentEntryState = target.state == state ? (canReuseState ? state : state.copy()) : target.state; - setEntryState(block, operatingDimension, currentEntryState); + setEntryState(block, currentEntryState); currentEntryState.clearNonLiveLocals(block, liveness, true); Debug.log("createTarget %s: first visit, result: %s", block, targetNode); @@ -2311,34 +1962,34 @@ } // We already saw this block before, so we have to merge states. - if (!getEntryState(block, operatingDimension).isCompatibleWith(state)) { + if (!getEntryState(block).isCompatibleWith(state)) { throw bailout("stacks do not match; bytecodes would not verify"); } - if (getFirstInstruction(block, operatingDimension) instanceof LoopBeginNode) { - assert this.explodeLoops || (block.isLoopHeader && currentBlock.getId() >= block.getId()) : "must be backward branch"; + if (getFirstInstruction(block) instanceof LoopBeginNode) { + assert (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) getFirstInstruction(block, operatingDimension); + LoopBeginNode loopBegin = (LoopBeginNode) getFirstInstruction(block); LoopEndNode loopEnd = graph.add(new LoopEndNode(loopBegin)); Target target = checkLoopExit(loopEnd, block, state); FixedNode result = target.fixed; - getEntryState(block, operatingDimension).merge(loopBegin, target.state); + getEntryState(block).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() || this.mergeExplosions : "must not be backward branch"; - assert getFirstInstruction(block, operatingDimension).next() == null || this.mergeExplosions : "bytecodes already parsed for block"; - - if (getFirstInstruction(block, operatingDimension) instanceof AbstractBeginNode && !(getFirstInstruction(block, operatingDimension) instanceof AbstractMergeNode)) { + assert currentBlock == null || currentBlock.getId() < block.getId() : "must not be backward branch"; + assert getFirstInstruction(block).next() == null : "bytecodes already parsed for block"; + + if (getFirstInstruction(block) instanceof AbstractBeginNode && !(getFirstInstruction(block) instanceof AbstractMergeNode)) { /* * This is the second time we see this block. Create the actual MergeNode and the End * Node for the already existing edge. */ - AbstractBeginNode beginNode = (AbstractBeginNode) getFirstInstruction(block, operatingDimension); + AbstractBeginNode beginNode = (AbstractBeginNode) getFirstInstruction(block); // The EndNode for the already existing edge. EndNode end = graph.add(new EndNode()); @@ -2356,80 +2007,22 @@ mergeNode.addForwardEnd(end); mergeNode.setNext(next); - setFirstInstruction(block, operatingDimension, mergeNode); + setFirstInstruction(block, mergeNode); } - AbstractMergeNode mergeNode = (AbstractMergeNode) getFirstInstruction(block, operatingDimension); + AbstractMergeNode mergeNode = (AbstractMergeNode) getFirstInstruction(block); // The EndNode for the newly merged edge. EndNode newEnd = graph.add(new EndNode()); Target target = checkLoopExit(newEnd, block, state); FixedNode result = target.fixed; - getEntryState(block, operatingDimension).merge(mergeNode, target.state); + getEntryState(block).merge(mergeNode, target.state); mergeNode.addForwardEnd(newEnd); Debug.log("createTarget %s: merging state, result: %s", block, result); return result; } - private int findOperatingDimension(BciBlock block, FrameStateBuilder state) { - if (this.explodeLoops && this.explodeLoopsContext != null && !this.explodeLoopsContext.isEmpty()) { - return findOperatingDimensionWithLoopExplosion(block, state); - } - return this.getCurrentDimension(); - } - - private int findOperatingDimensionWithLoopExplosion(BciBlock block, FrameStateBuilder state) { - for (ExplodedLoopContext context : explodeLoopsContext) { - if (context.header == block) { - - if (this.mergeExplosions) { - state.clearNonLiveLocals(block, liveness, true); - Integer cachedDimension = mergeExplosionsMap.get(state); - if (cachedDimension != null) { - return cachedDimension; - } - } - - // We have a hit on our current explosion context loop begin. - if (context.targetPeelIteration == null) { - context.targetPeelIteration = new int[1]; - } else { - context.targetPeelIteration = Arrays.copyOf(context.targetPeelIteration, context.targetPeelIteration.length + 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. - if (this.mergeExplosions) { - this.addToMergeCache(state, nextPeelIteration); - } - context.targetPeelIteration[context.targetPeelIteration.length - 1] = nextPeelIteration++; - if (nextPeelIteration > MaximumLoopExplosionCount.getValue()) { - throw tooManyLoopExplosionIterations(); - } - - // Operate on the target dimension. - return context.targetPeelIteration[context.targetPeelIteration.length - 1]; - } 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; - } - - private RuntimeException tooManyLoopExplosionIterations() { - String message = "too many loop explosion iterations - does the explosion not terminate for method " + method + "?"; - if (FailedLoopExplosionIsFatal.getValue()) { - throw new RuntimeException(message); - } else { - throw bailout(message); - } - } - /** * Returns a block begin node with the specified state. If the specified probability is 0, the * block deoptimizes immediately. @@ -2452,10 +2045,9 @@ } @SuppressWarnings("try") - protected void processBlock(BytecodeParser parser, BciBlock block) { + protected void processBlock(BciBlock block) { // Ignore blocks that have no predecessors by the time their bytecodes are parsed - int currentDimension = this.getCurrentDimension(); - FixedWithNextNode firstInstruction = getFirstInstruction(block, currentDimension); + FixedWithNextNode firstInstruction = getFirstInstruction(block); if (firstInstruction == null) { Debug.log("Ignoring block %s", block); return; @@ -2463,8 +2055,8 @@ try (Indent indent = Debug.logAndIndent("Parsing block %s firstInstruction: %s loopHeader: %b", block, firstInstruction, block.isLoopHeader)) { lastInstr = firstInstruction; - frameState = getEntryState(block, currentDimension); - parser.setCurrentFrameState(frameState); + frameState = getEntryState(block); + setCurrentFrameState(frameState); currentBlock = block; if (firstInstruction instanceof AbstractMergeNode) { @@ -2588,7 +2180,7 @@ @SuppressWarnings("try") protected void iterateBytecodesForBlock(BciBlock block) { - if (block.isLoopHeader && !explodeLoops) { + if (block.isLoopHeader) { // Create the loop header block, which later will merge the backward branches of // the loop. controlFlowSplit = true; @@ -2603,16 +2195,14 @@ * We have seen all forward branches. All subsequent backward branches will merge to the * loop header. This ensures that the loop header has exactly one non-loop predecessor. */ - setFirstInstruction(block, this.getCurrentDimension(), loopBegin); + setFirstInstruction(block, 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. */ - setEntryState(block, this.getCurrentDimension(), frameState.copy()); + setEntryState(block, frameState.copy()); Debug.log(" created loop header %s", loopBegin); - } else if (block.isLoopHeader && explodeLoops && this.mergeExplosions) { - frameState = frameState.copy(); } else if (lastInstr instanceof MergeNode) { /* * All inputs of non-loop phi nodes are known by now. We can infer the stamp for the @@ -2962,14 +2552,6 @@ frameState.push(slotKind, value); } - private int getCurrentDimension() { - if (this.explodeLoopsContext == null || this.explodeLoopsContext.isEmpty()) { - return 0; - } else { - return this.explodeLoopsContext.peek().peelIteration; - } - } - public ConstantReflectionProvider getConstantReflection() { return constantReflection; }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Thu Jan 14 15:18:33 2016 -0800 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Fri Jan 15 18:02:41 2016 +0100 @@ -49,7 +49,6 @@ import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.debug.Indent; import com.oracle.graal.java.ComputeLoopFrequenciesClosure; -import com.oracle.graal.java.GraphBuilderPhase; import com.oracle.graal.nodes.ConstantNode; import com.oracle.graal.nodes.StructuredGraph; import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; @@ -67,9 +66,6 @@ import com.oracle.graal.nodes.java.MethodCallTargetNode; import com.oracle.graal.nodes.virtual.VirtualInstanceNode; import com.oracle.graal.nodes.virtual.VirtualObjectNode; -import com.oracle.graal.options.Option; -import com.oracle.graal.options.OptionType; -import com.oracle.graal.options.OptionValue; import com.oracle.graal.phases.OptimisticOptimizations; import com.oracle.graal.phases.PhaseSuite; import com.oracle.graal.phases.common.CanonicalizerPhase; @@ -102,9 +98,6 @@ */ public class PartialEvaluator { - @Option(help = "New partial evaluation on Graal graphs", type = OptionType.Expert)// - public static final OptionValue<Boolean> GraphPE = new OptionValue<>(true); - protected final Providers providers; protected final Architecture architecture; private final CanonicalizerPhase canonicalizer; @@ -113,7 +106,6 @@ private final ResolvedJavaMethod callInlinedMethod; private final ResolvedJavaMethod callSiteProxyMethod; private final ResolvedJavaMethod callRootMethod; - private final GraphBuilderConfiguration configForPartialEvaluation; private final GraphBuilderConfiguration configForParsing; private final InvocationPlugins decodingInvocationPlugins; @@ -132,7 +124,6 @@ throw new RuntimeException(ex); } - this.configForPartialEvaluation = createGraphBuilderConfig(configForRoot, false); this.configForParsing = createGraphBuilderConfig(configForRoot, true); this.decodingInvocationPlugins = createDecodingInvocationPlugins(); } @@ -331,31 +322,6 @@ } - protected void doFastPE(OptimizedCallTarget callTarget, StructuredGraph graph) { - GraphBuilderConfiguration newConfig = configForPartialEvaluation.copy(); - - Plugins plugins = newConfig.getPlugins(); - plugins.prependParameterPlugin(new InterceptReceiverPlugin(callTarget)); - callTarget.setInlining(new TruffleInlining(callTarget, new DefaultInliningPolicy())); - plugins.setLoopExplosionPlugin(new PELoopExplosionPlugin()); - - ReplacementsImpl replacements = (ReplacementsImpl) providers.getReplacements(); - plugins.clearInlineInvokePlugins(); - plugins.appendInlineInvokePlugin(replacements); - plugins.appendInlineInvokePlugin(new PEInlineInvokePlugin(callTarget.getInlining(), replacements)); - HistogramInlineInvokePlugin histogramPlugin = null; - if (PrintTruffleExpansionHistogram.getValue()) { - histogramPlugin = new HistogramInlineInvokePlugin(graph); - plugins.appendInlineInvokePlugin(histogramPlugin); - } - - new GraphBuilderPhase.Instance(providers.getMetaAccess(), providers.getStampProvider(), providers.getConstantReflection(), newConfig, TruffleCompiler.Optimizations, null).apply(graph); - - if (PrintTruffleExpansionHistogram.getValue()) { - histogramPlugin.print(callTarget); - } - } - protected PEGraphDecoder createGraphDecoder(StructuredGraph graph) { GraphBuilderConfiguration newConfig = configForParsing.copy(); InvocationPlugins parsingInvocationPlugins = newConfig.getPlugins().getInvocationPlugins(); @@ -427,11 +393,7 @@ @SuppressWarnings({"try", "unused"}) private void fastPartialEvaluation(OptimizedCallTarget callTarget, StructuredGraph graph, PhaseContext baseContext, HighTierContext tierContext) { - if (GraphPE.getValue()) { - doGraphPE(callTarget, graph); - } else { - doFastPE(callTarget, graph); - } + doGraphPE(callTarget, graph); Debug.dump(graph, "After FastPE"); graph.maybeCompress();