slightly optimized code for assigning boolean expressions such as `b = xx>99`

This commit is contained in:
Irmen de Jong 2022-01-09 18:49:44 +01:00
parent 895534f32b
commit 124befe9d6
3 changed files with 51 additions and 16 deletions

View File

@ -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

View File

@ -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

View File

@ -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)