From a2c165839d20cf5dedf7837f25ff8b403a3e4519 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Tue, 25 Sep 2018 20:40:41 +0200 Subject: [PATCH] optimize for loop over 1-valued range --- compiler/src/prog8/ast/AST.kt | 4 ++++ compiler/src/prog8/ast/AstChecker.kt | 2 +- .../src/prog8/optimizing/SimplifyExpressions.kt | 1 - .../src/prog8/optimizing/StatementOptimizer.kt | 15 +++++++++++++++ 4 files changed, 20 insertions(+), 2 deletions(-) diff --git a/compiler/src/prog8/ast/AST.kt b/compiler/src/prog8/ast/AST.kt index 587a3c3f9..4d55e4ea7 100644 --- a/compiler/src/prog8/ast/AST.kt +++ b/compiler/src/prog8/ast/AST.kt @@ -333,6 +333,10 @@ class AnonymousStatementList(override var parent: Node, var statements: List, override val position: Position) : IStatement { + init { + linkParents(parent) + } + override fun linkParents(parent: Node) { this.parent = parent statements.forEach { it.linkParents(this) } diff --git a/compiler/src/prog8/ast/AstChecker.kt b/compiler/src/prog8/ast/AstChecker.kt index 2ca079cfc..70909e215 100644 --- a/compiler/src/prog8/ast/AstChecker.kt +++ b/compiler/src/prog8/ast/AstChecker.kt @@ -438,7 +438,7 @@ class AstChecker(private val namespace: INameScope, private val compilerOptions: when { from.asIntegerValue!=null && to.asIntegerValue!=null -> { if(from.asIntegerValue == to.asIntegerValue) - err("range is just a single value - don't use a loop here, use an assignment") // TODO optimize this away automatically in the statement optimizer + printWarning("range is just a single value, don't use a loop here", range.position) else if(from.asIntegerValue < to.asIntegerValue && step<=0) err("ascending range requires step > 0") else if(from.asIntegerValue > to.asIntegerValue && step>=0) diff --git a/compiler/src/prog8/optimizing/SimplifyExpressions.kt b/compiler/src/prog8/optimizing/SimplifyExpressions.kt index 469fce799..c35c84343 100644 --- a/compiler/src/prog8/optimizing/SimplifyExpressions.kt +++ b/compiler/src/prog8/optimizing/SimplifyExpressions.kt @@ -54,7 +54,6 @@ import prog8.ast.INameScope todo expression optimization: remove redundant builtin function calls - todo expression optimization: reduce expression nesting / flattening of parenthesis todo expression optimization: simplify logical expression when a term makes it always true or false (1 or 0) todo expression optimization: optimize some simple multiplications into shifts (A*8 -> A<<3, A/4 -> A>>2) todo optimize addition with self into shift 1 (A+=A -> A<<=1) diff --git a/compiler/src/prog8/optimizing/StatementOptimizer.kt b/compiler/src/prog8/optimizing/StatementOptimizer.kt index d37ab52d0..94117e871 100644 --- a/compiler/src/prog8/optimizing/StatementOptimizer.kt +++ b/compiler/src/prog8/optimizing/StatementOptimizer.kt @@ -75,6 +75,21 @@ class StatementOptimizer(private val globalNamespace: INameScope) : IAstProcesso return ifStatement } + override fun process(forLoop: ForLoop): IStatement { + super.process(forLoop) + val range = forLoop.iterable as? RangeExpr + if(range!=null) { + if(range.size()==1) { + // for loop over a (constant) range of just a single value-- optimize the loop away + // loopvar/reg = range value , follow by block + val assignment = Assignment(AssignTarget(forLoop.loopRegister, forLoop.loopVar, forLoop.position), null, range.from, forLoop.position) + forLoop.body.add(0, assignment) + return AnonymousStatementList(forLoop.parent, forLoop.body, forLoop.position) + } + } + return forLoop + } + override fun process(whileLoop: WhileLoop): IStatement { super.process(whileLoop) val constvalue = whileLoop.condition.constValue(globalNamespace)