mirror of
https://github.com/irmen/prog8.git
synced 2024-11-18 19:12:44 +00:00
until-loop condition now also simplified to avoid stack-eval
This commit is contained in:
parent
53e1729e2f
commit
c80df4140b
@ -235,6 +235,10 @@ internal class BeforeAsmGenerationAstChanger(val program: Program, private val o
|
||||
)
|
||||
|
||||
private fun simplifyConditionalExpression(expr: BinaryExpression): CondExprSimplificationResult {
|
||||
|
||||
// TODO: somehow figure out if the expr will result in stack-evaluation STILL after being split off,
|
||||
// in that case: do *not* split it off but just keep it as it is (otherwise code size increases)
|
||||
|
||||
var leftAssignment: Assignment? = null
|
||||
var leftOperandReplacement: Expression? = null
|
||||
var rightAssignment: Assignment? = null
|
||||
@ -302,9 +306,21 @@ internal class BeforeAsmGenerationAstChanger(val program: Program, private val o
|
||||
(binExpr.right as? NumericLiteralValue)?.number!=0)
|
||||
throw FatalAstException("0==X should have been swapped to if X==0")
|
||||
|
||||
// TODO simplify conditional expression like in if-statement
|
||||
// simplify the conditional expression, introduce simple assignments if required.
|
||||
// NOTE: sometimes this increases code size because additional stores/loads are generated for the
|
||||
// intermediate variables. We assume these are optimized away from the resulting assembly code later.
|
||||
val simplify = simplifyConditionalExpression(binExpr)
|
||||
val modifications = mutableListOf<IAstModification>()
|
||||
if(simplify.rightVarAssignment!=null) {
|
||||
modifications += IAstModification.ReplaceNode(binExpr.right, simplify.rightOperandReplacement!!, binExpr)
|
||||
modifications += IAstModification.InsertLast(simplify.rightVarAssignment, untilLoop.body)
|
||||
}
|
||||
if(simplify.leftVarAssignment!=null) {
|
||||
modifications += IAstModification.ReplaceNode(binExpr.left, simplify.leftOperandReplacement!!, binExpr)
|
||||
modifications += IAstModification.InsertLast(simplify.leftVarAssignment, untilLoop.body)
|
||||
}
|
||||
|
||||
return noModifications
|
||||
return modifications
|
||||
}
|
||||
|
||||
@Suppress("DuplicatedCode")
|
||||
@ -327,8 +343,13 @@ internal class BeforeAsmGenerationAstChanger(val program: Program, private val o
|
||||
(binExpr.right as? NumericLiteralValue)?.number!=0)
|
||||
throw FatalAstException("0==X should have been swapped to if X==0")
|
||||
|
||||
// TODO simplify conditional expression like in if-statement
|
||||
|
||||
// TODO simplify the conditional expression, introduce simple assignments if required.
|
||||
// NOTE: sometimes this increases code size because additional stores/loads are generated for the
|
||||
// intermediate variables. We assume these are optimized away from the resulting assembly code later.
|
||||
// NOTE: this is nasty for a while-statement as the condition occurs at the top of the loop
|
||||
// so the expression needs to be evaluated also before the loop is entered...
|
||||
// but I don't want to duplicate the expression.
|
||||
// val simplify = simplifyConditionalExpression(binExpr)
|
||||
return noModifications
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,7 @@ TODO
|
||||
|
||||
For next compiler release (7.3)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
- add expression simplification to while and until loops as well.
|
||||
...
|
||||
|
||||
|
||||
Blocked by an official Commander-x16 v39 release
|
||||
@ -14,6 +14,11 @@ Blocked by an official Commander-x16 v39 release
|
||||
|
||||
Future
|
||||
^^^^^^
|
||||
- simplifyConditionalExpression() should not split expression if it still results in stack-based evaluation
|
||||
- remove special code generation for while and util expression
|
||||
by rewriting while and until expressions into if+jump (consider them syntactic sugar)
|
||||
but the result should not produce larger code ofcourse!
|
||||
- while-expression should now also get the simplifyConditionalExpression() treatment
|
||||
- fix the asm-labels problem (github issue #62)
|
||||
- find a way to optimize asm-subroutine param passing where it now sometimes uses the evalstack?
|
||||
- document the various compiler command line options in more detail. See "Compiling program code" in the docs
|
||||
|
@ -1,16 +1,33 @@
|
||||
%import textio
|
||||
|
||||
main {
|
||||
|
||||
sub start() {
|
||||
byte xx=1
|
||||
ubyte xx=10
|
||||
|
||||
if xx+2 {
|
||||
xx++
|
||||
txt.print("if\n")
|
||||
if xx-2 {
|
||||
txt.print("in if\n")
|
||||
}
|
||||
|
||||
sub test() -> ubyte {
|
||||
txt.print("\nwhile\n")
|
||||
xx=6
|
||||
while xx-2 {
|
||||
xx--
|
||||
txt.print_ub(xx)
|
||||
txt.spc()
|
||||
}
|
||||
|
||||
txt.print("\nuntil\n")
|
||||
xx=2
|
||||
do {
|
||||
xx++
|
||||
return xx
|
||||
txt.print_ub(xx)
|
||||
txt.spc()
|
||||
} until xx+2==10
|
||||
txt.print("\ndone")
|
||||
|
||||
repeat {
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user