mirror of
https://github.com/irmen/prog8.git
synced 2025-01-11 13:29:45 +00:00
re-use global returnvalue temp var instead of duplicating it in every subroutine that needs it
This commit is contained in:
parent
793596614e
commit
f4c4ee78d9
@ -15,8 +15,6 @@ import prog8.compilerinterface.IErrorReporter
|
|||||||
import prog8.compilerinterface.size
|
import prog8.compilerinterface.size
|
||||||
import kotlin.math.floor
|
import kotlin.math.floor
|
||||||
|
|
||||||
internal const val retvarName = "prog8_retval"
|
|
||||||
|
|
||||||
|
|
||||||
class StatementOptimizer(private val program: Program,
|
class StatementOptimizer(private val program: Program,
|
||||||
private val errors: IErrorReporter,
|
private val errors: IErrorReporter,
|
||||||
@ -24,23 +22,6 @@ class StatementOptimizer(private val program: Program,
|
|||||||
private val compTarget: ICompilationTarget
|
private val compTarget: ICompilationTarget
|
||||||
) : AstWalker() {
|
) : 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> {
|
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,
|
// 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.
|
// remove the jump altogeter and inline the returnvalue directly.
|
||||||
@ -439,12 +420,17 @@ class StatementOptimizer(private val program: Program,
|
|||||||
val returnDt = subr.returntypes.single()
|
val returnDt = subr.returntypes.single()
|
||||||
if (returnDt in IntegerDatatypes) {
|
if (returnDt in IntegerDatatypes) {
|
||||||
// first assign to intermediary variable, then return that
|
// first assign to intermediary variable, then return that
|
||||||
subsThatNeedReturnVariable.add(Triple(subr, returnDt, returnStmt.position))
|
val returnVarName = "retval_interm_" + when(returnDt) {
|
||||||
val returnValueIntermediary1 = IdentifierReference(listOf(retvarName), returnStmt.position)
|
DataType.UBYTE -> "ub"
|
||||||
val returnValueIntermediary2 = IdentifierReference(listOf(retvarName), returnStmt.position)
|
DataType.BYTE -> "b"
|
||||||
val tgt = AssignTarget(returnValueIntermediary1, null, null, returnStmt.position)
|
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 assign = Assignment(tgt, value, returnStmt.position)
|
||||||
val returnReplacement = Return(returnValueIntermediary2, returnStmt.position)
|
val returnReplacement = Return(returnValueIntermediary.copy(), returnStmt.position)
|
||||||
return listOf(
|
return listOf(
|
||||||
IAstModification.InsertBefore(returnStmt, assign, parent as IStatementContainer),
|
IAstModification.InsertBefore(returnStmt, assign, parent as IStatementContainer),
|
||||||
IAstModification.ReplaceNode(returnStmt, returnReplacement, parent)
|
IAstModification.ReplaceNode(returnStmt, returnReplacement, parent)
|
||||||
|
@ -6,12 +6,13 @@ prog8_lib {
|
|||||||
%asminclude "library:prog8_lib.asm"
|
%asminclude "library:prog8_lib.asm"
|
||||||
%asminclude "library:prog8_funcs.asm"
|
%asminclude "library:prog8_funcs.asm"
|
||||||
|
|
||||||
; TODO these retval variables are no longer used???
|
; to store intermediary expression results for return values (hopefully allocated on ZP to reduce code size):
|
||||||
uword @zp retval_interm_uw ; 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
|
||||||
word @zp retval_interm_w ; to store intermediary expression results for return values (hopefully allocated on ZP to reduce code size)
|
uword @zp retval_interm_uw
|
||||||
ubyte @zp retval_interm_ub ; to store intermediary expression results for return values (hopefully allocated on ZP to reduce code size)
|
word @zp retval_interm_w
|
||||||
byte @zp retval_interm_b ; to store intermediary expression results for return values (hopefully allocated on ZP to reduce code size)
|
ubyte @zp retval_interm_ub
|
||||||
; NOTE: these variables are checked in the StatementReorderer (in fun after(decl: VarDecl)), for these exact names!
|
byte @zp retval_interm_b
|
||||||
|
|
||||||
|
|
||||||
asmsub pattern_match(str string @AY, str pattern @R0) clobbers(Y) -> ubyte @A {
|
asmsub pattern_match(str string @AY, str pattern @R0) clobbers(Y) -> ubyte @A {
|
||||||
%asm {{
|
%asm {{
|
||||||
|
@ -1 +1 @@
|
|||||||
7.2
|
7.3-dev
|
||||||
|
@ -53,7 +53,6 @@ internal class StatementReorderer(val program: Program, val errors: IErrorReport
|
|||||||
decl.value = null
|
decl.value = null
|
||||||
if(decl.name.startsWith("retval_interm_") && decl.definingScope.name=="prog8_lib") {
|
if(decl.name.startsWith("retval_interm_") && decl.definingScope.name=="prog8_lib") {
|
||||||
// no need to zero out the special internal returnvalue intermediates.
|
// no need to zero out the special internal returnvalue intermediates.
|
||||||
// TODO these variables are no longer used???
|
|
||||||
return noModifications
|
return noModifications
|
||||||
}
|
}
|
||||||
val nextStmt = decl.nextSibling()
|
val nextStmt = decl.nextSibling()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user