# HG changeset patch # User Thomas Wuerthinger # Date 1424385608 -3600 # Node ID 7f168e4c5ddef08ea13ee95a27a44665eb87dbe1 # Parent 2d045c20b1fd089618ce2aac47dc32ee74e4fc4d Added flag FailedLoopExplosionIsFatal. Added support for graph builder canonicalization of integer switches. diff -r 2d045c20b1fd -r 7f168e4c5dde graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/GraalOptions.java --- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/GraalOptions.java Thu Feb 19 21:28:36 2015 +0100 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/GraalOptions.java Thu Feb 19 23:40:08 2015 +0100 @@ -334,6 +334,9 @@ @Option(help = "Max number of loop explosions per method.", type = OptionType.Debug) public static final OptionValue MaximumLoopExplosionCount = new OptionValue<>(10000); + @Option(help = "Do not bail out but throw an exception on failed loop explosion.", type = OptionType.Debug) + public static final OptionValue FailedLoopExplosionIsFatal = new OptionValue<>(false); + /** * Counts the various paths taken through snippets. */ diff -r 2d045c20b1fd -r 7f168e4c5dde graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java Thu Feb 19 21:28:36 2015 +0100 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java Thu Feb 19 23:40:08 2015 +0100 @@ -861,12 +861,13 @@ int[] keySuccessors = new int[nofCases + 1]; int deoptSuccessorIndex = -1; int nextSuccessorIndex = 0; + boolean constantValue = ((ValueNode) value).isConstant(); for (int i = 0; i < nofCases + 1; i++) { if (i < nofCases) { keys[i] = bs.keyAt(i); } - if (isNeverExecutedCode(keyProbabilities[i])) { + if (!constantValue && isNeverExecutedCode(keyProbabilities[i])) { if (deoptSuccessorIndex < 0) { deoptSuccessorIndex = nextSuccessorIndex++; actualSuccessors.add(null); diff -r 2d045c20b1fd -r 7f168e4c5dde 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 Thu Feb 19 21:28:36 2015 +0100 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Thu Feb 19 23:40:08 2015 +0100 @@ -1103,11 +1103,23 @@ @Override protected void genIntegerSwitch(ValueNode value, ArrayList actualSuccessors, int[] keys, double[] keyProbabilities, int[] keySuccessors) { - this.controlFlowSplit = true; - double[] successorProbabilities = successorProbabilites(actualSuccessors.size(), keySuccessors, keyProbabilities); - IntegerSwitchNode switchNode = append(new IntegerSwitchNode(value, actualSuccessors.size(), keys, keyProbabilities, keySuccessors)); - for (int i = 0; i < actualSuccessors.size(); i++) { - switchNode.setBlockSuccessor(i, createBlockTarget(successorProbabilities[i], actualSuccessors.get(i), frameState)); + if (value.isConstant()) { + JavaConstant constant = (JavaConstant) value.asConstant(); + int constantValue = constant.asInt(); + for (int i = 0; i < keys.length; ++i) { + if (keys[i] == constantValue) { + appendGoto(actualSuccessors.get(keySuccessors[i])); + return; + } + } + appendGoto(actualSuccessors.get(keySuccessors[keys.length])); + } else { + this.controlFlowSplit = true; + double[] successorProbabilities = successorProbabilites(actualSuccessors.size(), keySuccessors, keyProbabilities); + IntegerSwitchNode switchNode = append(new IntegerSwitchNode(value, actualSuccessors.size(), keys, keyProbabilities, keySuccessors)); + for (int i = 0; i < actualSuccessors.size(); i++) { + switchNode.setBlockSuccessor(i, createBlockTarget(successorProbabilities[i], actualSuccessors.get(i), frameState)); + } } } @@ -1445,7 +1457,12 @@ // iteration. context.targetPeelIteration = nextPeelIteration++; if (nextPeelIteration > MaximumLoopExplosionCount.getValue()) { - throw new BailoutException("too many loop explosion interations - does the explosion not terminate?"); + String message = "too many loop explosion interations - does the explosion not terminate for method " + method + "?"; + if (FailedLoopExplosionIsFatal.getValue()) { + throw new RuntimeException(message); + } else { + throw new BailoutException(message); + } } }