re-use global returnvalue temp var instead of duplicating it in every subroutine that needs it

This commit is contained in:
Irmen de Jong 2021-11-07 14:19:21 +01:00
parent 793596614e
commit f4c4ee78d9
4 changed files with 18 additions and 32 deletions

View File

@ -15,8 +15,6 @@ import prog8.compilerinterface.IErrorReporter
import prog8.compilerinterface.size
import kotlin.math.floor
internal const val retvarName = "prog8_retval"
class StatementOptimizer(private val program: Program,
private val errors: IErrorReporter,
@ -24,23 +22,6 @@ class StatementOptimizer(private val program: Program,
private val compTarget: ICompilationTarget
) : AstWalker() {
private val subsThatNeedReturnVariable = mutableSetOf<Triple<IStatementContainer, DataType, Position>>()
override fun after(subroutine: Subroutine, parent: Node): Iterable<IAstModification> {
for(returnvar in subsThatNeedReturnVariable) {
val decl = VarDecl(VarDeclType.VAR, returnvar.second, ZeropageWish.DONTCARE, null, retvarName, null,
isArray = false,
autogeneratedDontRemove = true,
sharedWithAsm = false,
position = returnvar.third
)
returnvar.first.statements.add(0, decl)
}
subsThatNeedReturnVariable.clear()
return noModifications
}
override fun before(functionCall: FunctionCall, parent: Node): Iterable<IAstModification> {
// if the first instruction in the called subroutine is a return statement with a simple value,
// remove the jump altogeter and inline the returnvalue directly.
@ -439,12 +420,17 @@ class StatementOptimizer(private val program: Program,
val returnDt = subr.returntypes.single()
if (returnDt in IntegerDatatypes) {
// first assign to intermediary variable, then return that
subsThatNeedReturnVariable.add(Triple(subr, returnDt, returnStmt.position))
val returnValueIntermediary1 = IdentifierReference(listOf(retvarName), returnStmt.position)
val returnValueIntermediary2 = IdentifierReference(listOf(retvarName), returnStmt.position)
val tgt = AssignTarget(returnValueIntermediary1, null, null, returnStmt.position)
val returnVarName = "retval_interm_" + when(returnDt) {
DataType.UBYTE -> "ub"
DataType.BYTE -> "b"
DataType.UWORD -> "uw"
DataType.WORD -> "w"
else -> "<undefined>"
}
val returnValueIntermediary = IdentifierReference(listOf("prog8_lib", returnVarName), returnStmt.position)
val tgt = AssignTarget(returnValueIntermediary, null, null, returnStmt.position)
val assign = Assignment(tgt, value, returnStmt.position)
val returnReplacement = Return(returnValueIntermediary2, returnStmt.position)
val returnReplacement = Return(returnValueIntermediary.copy(), returnStmt.position)
return listOf(
IAstModification.InsertBefore(returnStmt, assign, parent as IStatementContainer),
IAstModification.ReplaceNode(returnStmt, returnReplacement, parent)

View File

@ -6,12 +6,13 @@ prog8_lib {
%asminclude "library:prog8_lib.asm"
%asminclude "library:prog8_funcs.asm"
; TODO these retval variables are no longer used???
uword @zp retval_interm_uw ; to store intermediary expression results for return values (hopefully allocated on ZP to reduce code size)
word @zp retval_interm_w ; to store intermediary expression results for return values (hopefully allocated on ZP to reduce code size)
ubyte @zp retval_interm_ub ; to store intermediary expression results for return values (hopefully allocated on ZP to reduce code size)
byte @zp retval_interm_b ; to store intermediary expression results for return values (hopefully allocated on ZP to reduce code size)
; NOTE: these variables are checked in the StatementReorderer (in fun after(decl: VarDecl)), for these exact names!
; to store intermediary expression results for return values (hopefully allocated on ZP to reduce code size):
; NOTE: these variables are used in the StatementReorderer and StatementOptimizer
uword @zp retval_interm_uw
word @zp retval_interm_w
ubyte @zp retval_interm_ub
byte @zp retval_interm_b
asmsub pattern_match(str string @AY, str pattern @R0) clobbers(Y) -> ubyte @A {
%asm {{

View File

@ -1 +1 @@
7.2
7.3-dev

View File

@ -53,7 +53,6 @@ internal class StatementReorderer(val program: Program, val errors: IErrorReport
decl.value = null
if(decl.name.startsWith("retval_interm_") && decl.definingScope.name=="prog8_lib") {
// no need to zero out the special internal returnvalue intermediates.
// TODO these variables are no longer used???
return noModifications
}
val nextStmt = decl.nextSibling()