nontrivial return value evaluation now via intermediary variable to try to avoid slow stack based evaluation

This commit is contained in:
Irmen de Jong 2020-12-31 22:13:24 +01:00
parent 8e3e996f4a
commit 8e927e0b73
5 changed files with 69 additions and 84 deletions

View File

@ -8,6 +8,8 @@ prog8_lib {
%asminclude "library:prog8_lib.asm", ""
%asminclude "library:prog8_funcs.asm", ""
uword @zp retval_interm_w ; to store intermediary expression results for return values (hopefully allocated on ZP to reduce code size)
ubyte @zp retval_interm_b ; to store intermediary expression results for return values (hopefully allocated on ZP to reduce code size)
asmsub pattern_match(str string @AY, str pattern @R0) clobbers(Y) -> ubyte @A {
%asm {{

View File

@ -215,12 +215,12 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
// Everything else just evaluate via the stack.
// (we can't use the assignment helper functions to do it via registers here,
// because the code here is the implementation of exactly that...)
if(value.parent is Return) {
if (value.parent is Return) {
if (this.asmgen.options.slowCodegenWarnings)
println("warning: slow stack evaluation used for return: $value target=${assign.target.kind} at ${value.position}")
}
asmgen.translateExpression(value)
if(assign.target.datatype in WordDatatypes && assign.source.datatype in ByteDatatypes)
exprAsmgen.translateExpression(value)
if (assign.target.datatype in WordDatatypes && assign.source.datatype in ByteDatatypes)
asmgen.signExtendStackLsb(assign.source.datatype)
assignStackValue(assign.target)
}

View File

@ -441,6 +441,44 @@ internal class StatementOptimizer(private val program: Program,
return noModifications
}
override fun after(returnStmt: Return, parent: Node): Iterable<IAstModification> {
fun returnViaIntermediary(value: Expression): Iterable<IAstModification>? {
val returnDt = returnStmt.definingSubroutine()!!.returntypes.single()
if (returnDt in IntegerDatatypes) {
// first assign to intermediary, then return that register
val returnValueIntermediary =
if (returnDt in ByteDatatypes)
IdentifierReference(listOf("prog8_lib", "retval_interm_b"), returnStmt.position)
else
IdentifierReference(listOf("prog8_lib", "retval_interm_w"), returnStmt.position)
val tgt = AssignTarget(returnValueIntermediary, null, null, returnStmt.position)
val assign = Assignment(tgt, value, returnStmt.position)
val returnReplacement = Return(returnValueIntermediary, returnStmt.position)
return listOf(
IAstModification.InsertBefore(returnStmt, assign, parent as INameScope),
IAstModification.ReplaceNode(returnStmt, returnReplacement, parent)
)
}
return null
}
when(returnStmt.value) {
is PrefixExpression -> {
val mod = returnViaIntermediary(returnStmt.value!!)
if(mod!=null)
return mod
}
is BinaryExpression -> {
val mod = returnViaIntermediary(returnStmt.value!!)
if(mod!=null)
return mod
}
else -> {}
}
return super.after(returnStmt, parent)
}
private fun hasBreak(scope: INameScope): Boolean {
class Searcher: IAstVisitor

View File

@ -125,14 +125,17 @@ main {
xx+=4
}
cx16.wait(3*60)
cx16.wait(3*60)
demo2()
gfx2.screen_mode(255)
txt.print("done!\n")
test_stack.test()
}
sub start2 () {
sub demo2 () {
gfx2.text_charset(3)
ubyte[] modes = [1, 0, 128]
@ -143,9 +146,6 @@ main {
cx16.wait(200)
}
gfx2.screen_mode(255)
txt.print("done!\n")
test_stack.test()
}
sub draw() {

View File

@ -1,91 +1,36 @@
%import test_stack
%import textio
%import diskio
%import floats
%zeropage basicsafe
%option no_sysinit
main {
sub start () {
uword uw
ubyte ub
float ff
uword large_buffer_ptr = progend()
ubyte[256] buffer
uword size
if diskio.f_open(8, "rom.asm") {
txt.print("read-exact\n")
c64.SETTIM(0,0,0)
size = 0
while not c64.READST() {
diskio.f_read_exact(&buffer, len(buffer))
size += 256
}
diskio.f_close()
txt.print_uw(size)
txt.chrout('\n')
print_time()
txt.chrout('\n')
} else
txt.print("can't open file!\n")
txt.print(diskio.status(8))
txt.chrout('\n')
if diskio.f_open(8, "rom.asm") {
txt.print("read-all\n")
c64.SETTIM(0,0,0)
size = 0
size = diskio.f_read_all(large_buffer_ptr)
diskio.f_close()
txt.print_uw(size)
txt.chrout('\n')
print_time()
txt.chrout('\n')
} else
txt.print("can't open file!\n")
txt.print(diskio.status(8))
txt.chrout('\n')
; if diskio.f_open(8, "rom.asm") {
; txt.print("read\n")
; c64.SETTIM(0,0,0)
; size = 0
; while not c64.READST() {
; size += diskio.f_read(&buffer, len(buffer))
; }
;
; diskio.f_close()
; txt.print_uw(size)
; txt.chrout('\n')
; print_time()
; txt.chrout('\n')
; }
test_stack.test()
uw = funcuw()
ub = funcub()
ff = funcff()
}
sub funcuw() -> uword {
uword a=1111
uword b=2222
return a+b
}
sub print_time() {
ubyte time_lo
ubyte time_mid
ubyte time_hi
sub funcub() -> ubyte {
ubyte a=11
ubyte b=22
return a+b
}
%asm {{
stx P8ZP_SCRATCH_REG
jsr c64.RDTIM ; A/X/Y
sta time_lo
stx time_mid
sty time_hi
ldx P8ZP_SCRATCH_REG
}}
txt.print_ub(time_hi)
txt.chrout(':')
txt.print_ub(time_mid)
txt.chrout(':')
txt.print_ub(time_lo)
txt.chrout('\n')
sub funcff() -> float {
float a=1111.1
float b=2222.2
return a+b
}
}