GROOVY-8019: allow better optimization for nested loops with unoptimzable parents
Project: http://git-wip-us.apache.org/repos/asf/groovy/repo Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/07994e13 Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/07994e13 Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/07994e13 Branch: refs/heads/GROOVY_2_4_X Commit: 07994e13f28fb3e06435e8d995d8953e49fb9464 Parents: 6c41085 Author: Jochen Theodorou <[email protected]> Authored: Sun Dec 11 11:31:49 2016 +0100 Committer: Jochen Theodorou <[email protected]> Committed: Sun Dec 11 11:33:20 2016 +0100 ---------------------------------------------------------------------- .../classgen/asm/OptimizingStatementWriter.java | 16 +++-- .../classgen/asm/MethodPatternsTest.groovy | 64 ++++++++++++++++++++ 2 files changed, 75 insertions(+), 5 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/groovy/blob/07994e13/src/main/org/codehaus/groovy/classgen/asm/OptimizingStatementWriter.java ---------------------------------------------------------------------- diff --git a/src/main/org/codehaus/groovy/classgen/asm/OptimizingStatementWriter.java b/src/main/org/codehaus/groovy/classgen/asm/OptimizingStatementWriter.java index 17a9810..0efbcfd 100644 --- a/src/main/org/codehaus/groovy/classgen/asm/OptimizingStatementWriter.java +++ b/src/main/org/codehaus/groovy/classgen/asm/OptimizingStatementWriter.java @@ -269,18 +269,18 @@ public class OptimizingStatementWriter extends StatementWriter { @Override public void writeIfElse(IfStatement statement) { - if (controller.isFastPath()) { + StatementMeta meta = statement.getNodeMetaData(StatementMeta.class); + FastPathData fastPathData = writeGuards(meta, statement); + + if (fastPathData==null) { super.writeIfElse(statement); } else { - StatementMeta meta = (StatementMeta) statement.getNodeMetaData(StatementMeta.class); - FastPathData fastPathData = writeGuards(meta, statement); - boolean oldFastPathBlock = fastPathBlocked; fastPathBlocked = true; super.writeIfElse(statement); fastPathBlocked = oldFastPathBlock; - if (fastPathData==null) return; + if (fastPathData == null) return; writeFastPathPrelude(fastPathData); super.writeIfElse(statement); writeFastPathEpilogue(fastPathData); @@ -769,6 +769,12 @@ public class OptimizingStatementWriter extends StatementWriter { opt.pop(opt.shouldOptimize()); } + /*@Override + public void visitConstantExpression(ConstantExpression expression) { + super.visitConstantExpression(expression); + opt.chainShouldOptimize(true); + }*/ + @Override public void visitStaticMethodCallExpression(StaticMethodCallExpression expression) { if (expression.getNodeMetaData(StatementMeta.class)!=null) return; http://git-wip-us.apache.org/repos/asf/groovy/blob/07994e13/src/test/org/codehaus/groovy/classgen/asm/MethodPatternsTest.groovy ---------------------------------------------------------------------- diff --git a/src/test/org/codehaus/groovy/classgen/asm/MethodPatternsTest.groovy b/src/test/org/codehaus/groovy/classgen/asm/MethodPatternsTest.groovy index 6443f8b..ababe1b 100644 --- a/src/test/org/codehaus/groovy/classgen/asm/MethodPatternsTest.groovy +++ b/src/test/org/codehaus/groovy/classgen/asm/MethodPatternsTest.groovy @@ -24,6 +24,70 @@ import static org.codehaus.groovy.control.CompilerConfiguration.DEFAULT as confi */ class MethodPatternsTest extends AbstractBytecodeTestCase { + void testUnoptimizedIfWithNestedOptimizedLoop(){ + if (config.optimizationOptions.indy) return; + // in this example the if block contains statements that will not be optimized + // but we still want to optimize the for loops, which can. + // The test will check there is a optimized bytecode sequence for the loops. + assert compile(''' + + long sum = 0; + double m = 1; + + if( true ) { + + System.err.println( "START"); + long t0 = System.currentTimeMillis(); + + for( int j=0; j<1000; j++ ) { + for( int i=0; i<100_000; i++ ) { + sum = sum + i; + m = m*i; + } + } + + long t1 = System.currentTimeMillis(); + System.err.println( "END - " + (t1-t0)+"ms"); + } + + System.err.println( "Done: "+sum+" "+m ); + ''').hasSequence([ + // for (int j=0; j<1000; j++) start and condition + 'ICONST_0', + 'SIPUSH 1000', + 'IF_ICMPGE', + 'ICONST_1', + // for (int i=0; i<100_000; i++) start and condition + 'ICONST_0', + 'LDC 100000', + 'IF_ICMPGE', + 'ICONST_1', + 'GOTO', + 'ICONST_0', + 'IFEQ', + // sum = sum + i + 'LLOAD', + 'ILOAD', + 'I2L', + 'LADD', + // m = m * i + 'DLOAD', + 'ILOAD', + 'I2D', + 'DMUL', + // for (int i=0; i<100_000; i++) increment + 'ILOAD', + 'ICONST_1', + 'IADD', + 'ISTORE', + // for (int j=0; j<1000; j++) increment + 'ILOAD', + 'ICONST_1', + 'IADD', + 'ISTORE' + ]) + } + // make a test for native compilation of the ackerman function // and ensure the nested call is optimized void testAckerman() {
