optimizing for x in 0 to something

This commit is contained in:
Irmen de Jong 2023-11-25 21:09:19 +01:00
parent 45debff89f
commit 2764d235a9
3 changed files with 98 additions and 4 deletions

View File

@ -168,6 +168,52 @@ class StatementOptimizer(private val program: Program,
}
}
val loopvarDt = forLoop.loopVarDt(program)
if(loopvarDt.istype(DataType.UWORD) || loopvarDt.istype(DataType.UBYTE)) {
if (range != null && range.from.constValue(program)?.number == 0.0 && range.step.constValue(program)?.number==1.0) {
val toBinExpr = range.to as? BinaryExpression
if(toBinExpr!=null && toBinExpr.operator=="-" && toBinExpr.right.constValue(program)?.number==1.0) {
// FOR var IN 0 TO X-1 .... ---> var=0, DO {... , var++} UNTIL var==X
val pos = forLoop.position
val condition = BinaryExpression(forLoop.loopVar.copy(), "==", toBinExpr.left, pos)
val incOne = PostIncrDecr(AssignTarget(forLoop.loopVar.copy(), null, null, pos), "++", pos)
forLoop.body.statements.add(incOne)
val replacement = AnonymousScope(mutableListOf(
Assignment(AssignTarget(forLoop.loopVar.copy(), null, null, pos),
NumericLiteral.optimalNumeric(0.0, pos),
AssignmentOrigin.OPTIMIZER, pos),
UntilLoop(forLoop.body, condition, pos)
), pos)
return listOf(IAstModification.ReplaceNode(forLoop, replacement, parent))
}
if(options.compTarget.name!=VMTarget.NAME) {
// this optimization is not effective for the VM target.
val toConst = range.to.constValue(program)
if (toConst == null) {
// FOR var in 0 TO X ... ---> var=0, REPEAT { ... , IF var==X break , var++ }
val pos = forLoop.position
val incOne = PostIncrDecr(AssignTarget(forLoop.loopVar.copy(), null, null, pos), "++", pos)
val breakCondition = IfElse(
BinaryExpression(forLoop.loopVar, "==", range.to, pos),
AnonymousScope(mutableListOf(Break(pos)), pos),
AnonymousScope(mutableListOf(), pos),
pos
)
forLoop.body.statements.add(breakCondition)
forLoop.body.statements.add(incOne)
val replacement = AnonymousScope(mutableListOf(
Assignment(AssignTarget(forLoop.loopVar.copy(), null, null, pos),
NumericLiteral.optimalNumeric(0.0, pos),
AssignmentOrigin.OPTIMIZER, pos),
RepeatLoop(null, forLoop.body, pos)
), pos)
return listOf(IAstModification.ReplaceNode(forLoop, replacement, parent))
}
}
}
}
return noModifications
}

View File

@ -2,8 +2,6 @@
TODO
====
- optimize 6502 codegen: "for 0 to end" into repeat loops. (only for ubyte and uword, 6502 cpu)
- [on branch: shortcircuit] investigate McCarthy evaluation again? this may also reduce code size perhaps for things like if a>4 or a<2 ....
...

View File

@ -1,13 +1,31 @@
%import textio
%zeropage basicsafe
; $3d5
main {
ubyte counter
uword wcounter
ubyte end=10
uword wend=10
ubyte end
uword wend
sub start() {
end=10
for cx16.r2L in 0 to end-1 {
txt.print_ub(cx16.r2L)
txt.spc()
}
txt.nl()
cx16.r2L=0
labeltje:
txt.print_ub(cx16.r2L)
txt.spc()
cx16.r2L++
if cx16.r2L!=end
goto labeltje
txt.nl()
cx16.r0=0
forloops()
txt.print_uw(cx16.r0)
@ -24,19 +42,31 @@ main {
for counter in 0 to end {
cx16.r0++
}
for counter in 0 to end-1 {
cx16.r0++
}
end=0
for counter in 0 to end {
cx16.r0++
}
for counter in 0 to end-1 {
cx16.r0++
}
end=255
for counter in 0 to end {
cx16.r0++
}
for counter in 0 to end-1 {
cx16.r0++
}
wend=1000
for wcounter in 0 to wend {
cx16.r0++
}
for wcounter in 0 to wend-1 {
cx16.r0++
}
}
sub untilloops() {
@ -49,6 +79,11 @@ main {
break
counter++
}
counter = 0
do {
cx16.r0++
counter++
} until counter==end
end=0
counter = 0
@ -58,6 +93,11 @@ main {
break
counter++
}
counter = 0
do {
cx16.r0++
counter++
} until counter==end
counter = 0
end=255
@ -67,6 +107,11 @@ main {
break
counter++
}
counter = 0
do {
cx16.r0++
counter++
} until counter==end
wcounter = 0
wend=1000
@ -76,5 +121,10 @@ main {
break
wcounter++
}
wcounter = 0
do {
cx16.r0++
wcounter++
} until wcounter==wend
}
}