optimized code for variable comparisons to zero

This commit is contained in:
Irmen de Jong 2022-01-09 13:10:01 +01:00
parent c1a39c269e
commit a9b45630d7
3 changed files with 109 additions and 22 deletions

View File

@ -1840,7 +1840,11 @@ $label nop""")
operator: String,
jumpIfFalseLabel: String
) {
when(val dt = left.inferType(program).getOr(DataType.UNDEFINED)) {
val dt = left.inferType(program).getOr(DataType.UNDEFINED)
if(dt in IntegerDatatypes && left is IdentifierReference)
return testVariableZeroAndJump(left, dt, operator, jumpIfFalseLabel)
when(dt) {
DataType.UBYTE, DataType.UWORD -> {
if(operator=="<") {
out(" jmp $jumpIfFalseLabel")
@ -1924,6 +1928,66 @@ $label nop""")
}
}
private fun testVariableZeroAndJump(variable: IdentifierReference, dt: DataType, operator: String, jumpIfFalseLabel: String) {
// optimized code if the expression is just an identifier (variable)
val varname = asmVariableName(variable)
when(dt) {
DataType.UBYTE -> when(operator) {
"==" -> out(" lda $varname | bne $jumpIfFalseLabel")
"!=" -> out(" lda $varname | beq $jumpIfFalseLabel")
">" -> out(" lda $varname | beq $jumpIfFalseLabel")
"<" -> out(" bra $jumpIfFalseLabel")
">=" -> {}
"<=" -> out(" lda $varname | bne $jumpIfFalseLabel")
else -> throw AssemblyError("invalid operator")
}
DataType.BYTE -> when(operator) {
"==" -> out(" lda $varname | bne $jumpIfFalseLabel")
"!=" -> out(" lda $varname | beq $jumpIfFalseLabel")
">" -> out(" lda $varname | beq $jumpIfFalseLabel | bmi $jumpIfFalseLabel")
"<" -> out(" lda $varname | bpl $jumpIfFalseLabel")
">=" -> out(" lda $varname | bmi $jumpIfFalseLabel")
"<=" -> out("""
lda $varname
beq +
bpl $jumpIfFalseLabel
+ """)
else -> throw AssemblyError("invalid operator")
}
DataType.UWORD -> when(operator) {
"==" -> out(" lda $varname | ora $varname+1 | bne $jumpIfFalseLabel")
"!=" -> out(" lda $varname | ora $varname+1 | beq $jumpIfFalseLabel")
">" -> out(" lda $varname | ora $varname+1 | beq $jumpIfFalseLabel")
"<" -> out(" bra $jumpIfFalseLabel")
">=" -> {}
"<=" -> out(" lda $varname | ora $varname+1 | bne $jumpIfFalseLabel")
else -> throw AssemblyError("invalid operator")
}
DataType.WORD -> when (operator) {
"==" -> out(" lda $varname | bne $jumpIfFalseLabel | lda $varname+1 | bne $jumpIfFalseLabel")
"!=" -> out(" lda $varname | ora $varname+1 | beq $jumpIfFalseLabel")
">" -> out("""
lda $varname+1
bmi $jumpIfFalseLabel
bne +
lda $varname
beq $jumpIfFalseLabel
+ """)
"<" -> out(" lda $varname+1 | bpl $jumpIfFalseLabel")
">=" -> out(" lda $varname+1 | bmi $jumpIfFalseLabel")
"<=" -> out("""
lda $varname+1
bmi +
bne $jumpIfFalseLabel
lda $varname
bne $jumpIfFalseLabel
+ """)
else -> throw AssemblyError("invalid comparison operator $operator")
}
else -> throw AssemblyError("invalid dt")
}
}
private fun testNonzeroComparisonAndJump(
left: Expression,
operator: String,

View File

@ -3,11 +3,13 @@ TODO
For next compiler release (7.7)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- optimize (u)word comparison against 0 to use MSB only if possible
- perhaps also optimize testNonzeroComparisonAndJump() ?
- copying floats around: do it with a subroutine rather than 5 lda/sta pairs .
is slower but floats are very slow already anyway and this should take a lot less program size.
-> assignVariableFloat() + assignConstantFloat()
- don't remove dead variable assignment if it contains a function call
- optimize codegen of pipe operator to avoid needless assigns to temp var
- why is this using stack evaluation: bb = ww>0 (if ww>0 is not using stack!)
Need help with
^^^^^^^^^^^^^^

View File

@ -9,28 +9,49 @@ main {
word ww = 0
float fl = 0
if fl< 0 {
txt.print("wrong fl\n")
ubyte @shared ub
if ww==0 {
ub++
}
fl=-1.111
if 0>fl or fl==2 {
txt.print("good fl\n")
if ww!=0 {
ub++
}
if ww>0 {
ub++
}
if ww<0 {
ub++
}
if ww<=0 {
ub++
}
if ww>=0 {
ub++
}
if ww< 0 {
txt.print("wrong ww\n")
}
if bb<0 {
txt.print("wrong bb\n")
}
bb = -1
ww = -1111
if 0>ww or ww==2 {
txt.print("good ww\n")
}
if 0>bb or bb==2 {
txt.print("good bb\n")
}
; if fl< 0 {
; txt.print("wrong fl\n")
; }
; fl=-1.111
; if 0>fl or fl==2 {
; txt.print("good fl\n")
; }
;
; if ww< 0 {
; txt.print("wrong ww\n")
; }
; if bb<0 {
; txt.print("wrong bb\n")
; }
; bb = -1
; ww = -1111
; if 0>ww or ww==2 {
; txt.print("good ww\n")
; }
; if 0>bb or bb==2 {
; txt.print("good bb\n")
; }
; float @shared f1
;
; f1 = 1.234 |> addfloat1 |> addfloat2 |> addfloat3 ; TODO fix that the value is actually returned