From 124befe9d6ab9fe008e1aeba6c773fedc0a77637 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Sun, 9 Jan 2022 18:49:44 +0100 Subject: [PATCH] slightly optimized code for assigning boolean expressions such as ``b = xx>99`` --- .../codegen/assignment/AssignmentAsmGen.kt | 47 ++++++++++++++++--- docs/source/todo.rst | 3 +- examples/test.p8 | 17 ++++--- 3 files changed, 51 insertions(+), 16 deletions(-) diff --git a/codeGeneration/src/prog8/codegen/target/cpu6502/codegen/assignment/AssignmentAsmGen.kt b/codeGeneration/src/prog8/codegen/target/cpu6502/codegen/assignment/AssignmentAsmGen.kt index 12928bcc7..d14766454 100644 --- a/codeGeneration/src/prog8/codegen/target/cpu6502/codegen/assignment/AssignmentAsmGen.kt +++ b/codeGeneration/src/prog8/codegen/target/cpu6502/codegen/assignment/AssignmentAsmGen.kt @@ -285,16 +285,42 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen else throw AssemblyError("invalid dt") asmgen.assignRegister(register, assign.target) } + is BinaryExpression -> { + if(value.operator in ComparisonOperators) { + // TODO real optimized code for comparison expressions + // for now generate code for this: assign-false; if expr { assign-true } + translateNormalAssignment( + AsmAssignment( + AsmAssignSource(SourceStorageKind.LITERALNUMBER, program, asmgen, DataType.UBYTE, number=NumericLiteralValue.fromBoolean(false, assign.position)), + assign.target, false, program.memsizer, assign.position + ) + ) + val origTarget = assign.target.origAstTarget + if(origTarget!=null) { + val assignTrue = AnonymousScope(mutableListOf( + Assignment(origTarget, NumericLiteralValue.fromBoolean(true, assign.position), assign.position) + ), assign.position) + val assignFalse = AnonymousScope(mutableListOf(), assign.position) + val ifelse = IfElse(value.copy(), assignTrue, assignFalse, assign.position) + ifelse.linkParents(value) + asmgen.translate(ifelse) + } + else { + // no orig ast assign target, can't use the workaround, so fallback to stack eval + fallbackToStackEval(value, assign) + } + } else { + // Everything else just evaluate via the stack. + // (we can't use the assignment helper functions (assignExpressionTo...) to do it via registers here, + // because the code here is the implementation of exactly that...) + fallbackToStackEval(value, assign) + } + } else -> { // Everything else just evaluate via the stack. // (we can't use the assignment helper functions (assignExpressionTo...) to do it via registers here, // because the code here is the implementation of exactly that...) - // TODO DON'T STACK-EVAL THIS... by using a temp var? so that it becomes augmentable assignment expression? - asmgen.translateExpression(value) - if (assign.target.datatype in WordDatatypes && assign.source.datatype in ByteDatatypes) - asmgen.signExtendStackLsb(assign.source.datatype) - if(assign.target.kind!=TargetStorageKind.STACK || assign.target.datatype != assign.source.datatype) - assignStackValue(assign.target) + fallbackToStackEval(value, assign) } } } @@ -308,6 +334,15 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen } } + private fun fallbackToStackEval(value: Expression, assign: AsmAssignment) { + // TODO DON'T STACK-EVAL THIS... by using a temp var? so that it becomes augmentable assignment expression? + asmgen.translateExpression(value) + if (assign.target.datatype in WordDatatypes && assign.source.datatype in ByteDatatypes) + asmgen.signExtendStackLsb(assign.source.datatype) + if (assign.target.kind != TargetStorageKind.STACK || assign.target.datatype != assign.source.datatype) + assignStackValue(assign.target) + } + private fun containmentCheckIntoA(containment: ContainmentCheck) { val elementDt = containment.element.inferType(program) val range = containment.iterable as? RangeExpression diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 54977a130..589e38b49 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -4,7 +4,7 @@ TODO For next compiler release (7.7) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - 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 ^^^^^^^^^^^^^^ @@ -53,6 +53,7 @@ Future Things and Ideas More optimization ideas ^^^^^^^^^^^^^^^^^^^^^^^ +- translateNormalAssignment() -> better code gen for assigning boolean comparison expressions - if a for loop's loopvariable isn't referenced in the body, replace by a repeatloop - automatically convert if statements that test for multiple values (if X==1 or X==2..) to if X in [1,2,..] statements, instead of just a warning - byte typed expressions should be evaluated in the accumulator where possible, without (temp)var diff --git a/examples/test.p8 b/examples/test.p8 index d5ac1894c..f78e38146 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -5,15 +5,14 @@ main { sub start() { - ubyte dead - dead = 1 - dead = func() - dead = 2 - dead = func() - dead = 3 - dead = func() - dead = 4 - dead = func() + uword ww + ubyte bb + + bb = ww==0 + bb++ + if ww==0 { + bb++ + } ; fl = 1.234 |> addfloat1 |> addfloat2 |> addfloat3 ; floats.print_f(fl)