optimize boolean to ubyte assignment (skip type cast)

This commit is contained in:
Irmen de Jong 2024-02-20 22:12:33 +01:00
parent 7868e672e0
commit 006713fe13
4 changed files with 24 additions and 11 deletions

View File

@ -1562,7 +1562,21 @@ internal class AssignmentAsmGen(private val program: PtProgram,
return assignTypeCastedIdentifier(target.asmVarname, targetDt, asmgen.asmVariableName(value), valueDt)
when (valueDt) {
in ByteDatatypesWithBoolean -> {
DataType.BOOL -> {
if(targetDt in ByteDatatypes) {
// optimization to assign boolean expression to byte target (just assign the 0 or 1 directly, no cast needed)
val assignDirect = AsmAssignment(
AsmAssignSource.fromAstSource(value, program, asmgen),
target,
program.memsizer,
target.position
)
assignExpression(assignDirect, target.scope)
} else {
throw AssemblyError("expected bool or byte target type")
}
}
in ByteDatatypes -> {
assignExpressionToRegister(value, RegisterOrPair.A, valueDt==DataType.BYTE)
assignTypeCastedRegisters(target.asmVarname, targetDt, RegisterOrPair.A, valueDt)
}

View File

@ -1035,12 +1035,12 @@ internal class AstChecker(private val program: Program,
} else {
if(expr.left is TypecastExpression && expr.right is NumericLiteral && !expr.right.inferType(program).istype(DataType.FLOAT)) {
val origLeftDt = (expr.left as TypecastExpression).expression.inferType(program).getOr(DataType.UNDEFINED)
if(rightDt.largerThan(origLeftDt) && !(expr.right as NumericLiteral).cast(origLeftDt).isValid)
if(rightDt.largerThan(origLeftDt) && !(expr.right as NumericLiteral).cast(origLeftDt, true).isValid)
errors.err("operands are not the same type", expr.right.position)
}
if(expr.right is TypecastExpression && expr.left is NumericLiteral && !expr.left.inferType(program).istype(DataType.FLOAT)) {
val origRightDt = (expr.right as TypecastExpression).expression.inferType(program).getOr(DataType.UNDEFINED)
if(leftDt.largerThan(origRightDt) && !(expr.left as NumericLiteral).cast(origRightDt).isValid)
if(leftDt.largerThan(origRightDt) && !(expr.left as NumericLiteral).cast(origRightDt, true).isValid)
errors.err("operands are not the same type", expr.right.position)
}
}

View File

@ -1,8 +1,6 @@
TODO
====
efficient code for assignment float comparisons against a value (it now copies the floats around too many times) 10.1 created efficient code.
examples/maze is larger than on 10.1
rockrunner is a lot bigger still than on 10.1
paint is bigger than on 10.1
@ -50,7 +48,7 @@ ok ok efficient code for assignment word comparisons against 0 (== and !=
ok ok efficient code for assignment float comparisons against 0 (== and !=)
ok ok efficient code for assignment byte comparisons against a value
ok ok efficient code for assignment word comparisons against a value
ok FAIL efficient code for assignment float comparisons against a value
ok ok efficient code for assignment float comparisons against a value
ok ok efficient code for if_cc conditional expressions
ok ok while boolean should produce identical code as while integer!=0 and code should be efficient
ok ok while not boolvar -> can we get rid of the cmp? (6502 only?)

View File

@ -14,11 +14,12 @@ main {
sub start() {
while not staticbool2
cx16.r0L++
while cx16.r0L==0
cx16.r0L++
; cx16.r0L = fl==fl2 as ubyte
; cx16.r1L = fl!=fl2 as ubyte
cx16.r0L = cx16.r0 == cx16.r1 as ubyte
cx16.r1L = cx16.r0 != cx16.r1 as ubyte
cx16.r0L = cx16.r0L == cx16.r1L as ubyte
cx16.r1L = cx16.r0L != cx16.r1L as ubyte
; TODO all this for uwords