"not x" as a condition (if, while, until) is optimized into "x==0", this avoids calculating the value

This commit is contained in:
Irmen de Jong 2021-11-06 23:25:32 +01:00
parent 57a9fed42b
commit f40620aa25
4 changed files with 61 additions and 19 deletions

View File

@ -185,7 +185,15 @@ internal class BeforeAsmGenerationAstChanger(val program: Program, private val o
return noModifications
}
@Suppress("DuplicatedCode")
override fun after(ifStatement: IfStatement, parent: Node): Iterable<IAstModification> {
val prefixExpr = ifStatement.condition as? PrefixExpression
if(prefixExpr!=null && prefixExpr.operator=="not") {
// if not x -> if x==0
val booleanExpr = BinaryExpression(prefixExpr.expression, "==", NumericLiteralValue.optimalInteger(0, ifStatement.condition.position), ifStatement.condition.position)
return listOf(IAstModification.ReplaceNode(ifStatement.condition, booleanExpr, ifStatement))
}
val binExpr = ifStatement.condition as? BinaryExpression
if(binExpr==null || binExpr.operator !in comparisonOperators) {
// if x -> if x!=0, if x+5 -> if x+5 != 0
@ -201,7 +209,15 @@ internal class BeforeAsmGenerationAstChanger(val program: Program, private val o
return noModifications
}
@Suppress("DuplicatedCode")
override fun after(untilLoop: UntilLoop, parent: Node): Iterable<IAstModification> {
val prefixExpr = untilLoop.condition as? PrefixExpression
if(prefixExpr!=null && prefixExpr.operator=="not") {
// until not x -> until x==0
val booleanExpr = BinaryExpression(prefixExpr.expression, "==", NumericLiteralValue.optimalInteger(0, untilLoop.condition.position), untilLoop.condition.position)
return listOf(IAstModification.ReplaceNode(untilLoop.condition, booleanExpr, untilLoop))
}
val binExpr = untilLoop.condition as? BinaryExpression
if(binExpr==null || binExpr.operator !in comparisonOperators) {
// until x -> until x!=0, until x+5 -> until x+5 != 0
@ -211,7 +227,15 @@ internal class BeforeAsmGenerationAstChanger(val program: Program, private val o
return noModifications
}
@Suppress("DuplicatedCode")
override fun after(whileLoop: WhileLoop, parent: Node): Iterable<IAstModification> {
val prefixExpr = whileLoop.condition as? PrefixExpression
if(prefixExpr!=null && prefixExpr.operator=="not") {
// while not x -> while x==0
val booleanExpr = BinaryExpression(prefixExpr.expression, "==", NumericLiteralValue.optimalInteger(0, whileLoop.condition.position), whileLoop.condition.position)
return listOf(IAstModification.ReplaceNode(whileLoop.condition, booleanExpr, whileLoop))
}
val binExpr = whileLoop.condition as? BinaryExpression
if(binExpr==null || binExpr.operator !in comparisonOperators) {
// while x -> while x!=0, while x+5 -> while x+5 != 0

View File

@ -324,7 +324,8 @@ private fun writeAssembly(program: Program,
program.processAstBeforeAsmGeneration(compilerOptions, errors)
errors.report()
// printAst(program)
// println("*********** AST RIGHT BEFORE ASM GENERATION *************")
// printAst(program)
compilerOptions.compTarget.machine.initializeZeropage(compilerOptions)
val assembly = asmGeneratorFor(compilerOptions.compTarget,

View File

@ -3,7 +3,7 @@ TODO
For next compiler release (7.2)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- optimize "if not x" / "while not x" to not actually calculate the whole "not x" value first --> transform in to "x==0" in these conditional statements?
...
Blocked by Commander-x16 v39 release

View File

@ -1,30 +1,47 @@
%import textio
%import floats
; %import floats
%zeropage basicsafe
main {
sub start() {
uword xx= $2000
ubyte yy=$30
ubyte zz=9
sys.memset(xx+200, yy*2, ~yy)
word xx=0
if yy & %10000 {
yy++
if not xx {
txt.print("xx is zero\n")
}
@($c030) = 10
@(~xx) *= 2
txt.print_ub(@($c030))
while not xx {
xx ++
}
float f1 = 1111.11
float f2 = 2222.22
float[] fa = [2222.22, 3333.33]
do {
xx--
} until not xx
swap(f1, fa[1])
floats.print_f(f1)
txt.nl()
floats.print_f(fa[1])
if not xx {
txt.print("xx is zero\n")
}
; ubyte yy=$30
; ubyte zz=9
; sys.memset(xx+200, yy*2, ~yy)
;
; if yy & %10000 {
; yy++
; }
;
; @($c030) = 10
; @(~xx) *= 2
; txt.print_ub(@($c030))
;
; float f1 = 1111.11
; float f2 = 2222.22
; float[] fa = [2222.22, 3333.33]
;
; swap(f1, fa[1])
; floats.print_f(f1)
; txt.nl()
; floats.print_f(fa[1])
}
}