mirror of
https://github.com/irmen/prog8.git
synced 2024-11-26 11:49:22 +00:00
optimizing for x in 0 to something
This commit is contained in:
parent
45debff89f
commit
2764d235a9
@ -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
|
||||
}
|
||||
|
||||
|
@ -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 ....
|
||||
|
||||
...
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user