From 1da9b3000789a7da359aec5f7d24227d167840a7 Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sun, 13 Feb 2022 18:27:28 +0100 Subject: [PATCH 1/2] fix: fix optimization for WHILE loop --- src/api/optimize.py | 5 +- tests/functional/zx48k/opt2_while_funcall.asm | 83 +++++++++++++++++++ tests/functional/zx48k/opt2_while_funcall.bas | 14 ++++ 3 files changed, 100 insertions(+), 2 deletions(-) create mode 100644 tests/functional/zx48k/opt2_while_funcall.asm create mode 100644 tests/functional/zx48k/opt2_while_funcall.bas diff --git a/src/api/optimize.py b/src/api/optimize.py index ce8832f40..14d9c50c6 100644 --- a/src/api/optimize.py +++ b/src/api/optimize.py @@ -407,8 +407,9 @@ def visit_IF(self, node): yield node def visit_WHILE(self, node): - expr_ = yield node.children[0] - body_ = yield node.children[1] + node = yield self.generic_visit(node) + expr_ = node.children[0] + body_ = node.children[1] if self.O_LEVEL >= 1: if chk.is_number(expr_) and not expr_.value and not chk.is_block_accessed(body_): diff --git a/tests/functional/zx48k/opt2_while_funcall.asm b/tests/functional/zx48k/opt2_while_funcall.asm new file mode 100644 index 000000000..73ae6f7db --- /dev/null +++ b/tests/functional/zx48k/opt2_while_funcall.asm @@ -0,0 +1,83 @@ + org 32768 +.core.__START_PROGRAM: + di + push ix + push iy + exx + push hl + exx + ld hl, 0 + add hl, sp + ld (.core.__CALL_BACK__), hl + ei + jp .core.__MAIN_PROGRAM__ +.core.__CALL_BACK__: + DEFW 0 +.core.ZXBASIC_USER_DATA: + ; Defines USER DATA Length in bytes +.core.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_END - .core.ZXBASIC_USER_DATA + .core.__LABEL__.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_LEN + .core.__LABEL__.ZXBASIC_USER_DATA EQU .core.ZXBASIC_USER_DATA +.core.ZXBASIC_USER_DATA_END: +.core.__MAIN_PROGRAM__: + call _main + ld hl, 0 + ld b, h + ld c, l +.core.__END_PROGRAM: + di + ld hl, (.core.__CALL_BACK__) + ld sp, hl + exx + pop hl + pop iy + pop ix + exx + ei + ret +_saludar: + push ix + ld ix, 0 + add ix, sp + ld l, (ix+4) + ld h, (ix+5) + inc hl +_saludar__leave: + ld sp, ix + pop ix + exx + pop hl + ex (sp), hl + exx + ret +_main: + push ix + ld ix, 0 + add ix, sp + ld hl, 0 + push hl + ld (ix-2), 0 + ld (ix-1), 0 +.LABEL.__LABEL0: + ld l, (ix-2) + ld h, (ix-1) + ld de, 2 + or a + sbc hl, de + jp nc, _main__leave + ld l, (ix-2) + ld h, (ix-1) + push hl + call _saludar + ld l, (ix-2) + ld h, (ix-1) + inc hl + ld (ix-2), l + ld (ix-1), h + jp .LABEL.__LABEL0 +_main__leave: + ld sp, ix + pop ix + ret + ;; --- end of user code --- + END diff --git a/tests/functional/zx48k/opt2_while_funcall.bas b/tests/functional/zx48k/opt2_while_funcall.bas new file mode 100644 index 000000000..304178888 --- /dev/null +++ b/tests/functional/zx48k/opt2_while_funcall.bas @@ -0,0 +1,14 @@ +main() + +function saludar(x as Uinteger) as Uinteger + return x + 1 +end function + +sub main() + dim i, result as uinteger + i = 0 + while i < 2 + result = saludar(i) + i = i + 1 + end while +end sub From 66abcf2e179da709ac87fcd9077cea08495808aa Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sun, 13 Feb 2022 18:17:31 +0100 Subject: [PATCH 2/2] fix: fix optimization for FOR loop --- src/api/optimize.py | 16 ++-- tests/functional/zx48k/opt2_for_funcall.asm | 85 +++++++++++++++++++++ tests/functional/zx48k/opt2_for_funcall.bas | 12 +++ 3 files changed, 105 insertions(+), 8 deletions(-) create mode 100644 tests/functional/zx48k/opt2_for_funcall.asm create mode 100644 tests/functional/zx48k/opt2_for_funcall.bas diff --git a/src/api/optimize.py b/src/api/optimize.py index 14d9c50c6..0c21e6ee9 100644 --- a/src/api/optimize.py +++ b/src/api/optimize.py @@ -421,10 +421,12 @@ def visit_WHILE(self, node): yield node def visit_FOR(self, node): - from_ = yield node.children[1] - to_ = yield node.children[2] - step_ = yield node.children[3] - body_ = yield node.children[4] + node = yield self.generic_visit(node) + + from_ = node.children[1] + to_ = node.children[2] + step_ = node.children[3] + body_ = node.children[4] if self.O_LEVEL > 0 and chk.is_number(from_, to_, step_) and not chk.is_block_accessed(body_): if from_ > to_ and step_ > 0: @@ -434,8 +436,6 @@ def visit_FOR(self, node): yield self.NOP return - for i, child in enumerate((from_, to_, step_, body_), start=1): - node.children[i] = child yield node # TODO: ignore unused labels @@ -446,8 +446,8 @@ def _visit_LABEL(self, node): yield node def generic_visit(self, node: symbols.SYMBOL): - for i in range(len(node.children)): - node.children[i] = yield ToVisit(node.children[i]) + for i, child in enumerate(node.children): + node.children[i] = yield ToVisit(child) yield node diff --git a/tests/functional/zx48k/opt2_for_funcall.asm b/tests/functional/zx48k/opt2_for_funcall.asm new file mode 100644 index 000000000..91677e9f4 --- /dev/null +++ b/tests/functional/zx48k/opt2_for_funcall.asm @@ -0,0 +1,85 @@ + org 32768 +.core.__START_PROGRAM: + di + push ix + push iy + exx + push hl + exx + ld hl, 0 + add hl, sp + ld (.core.__CALL_BACK__), hl + ei + jp .core.__MAIN_PROGRAM__ +.core.__CALL_BACK__: + DEFW 0 +.core.ZXBASIC_USER_DATA: + ; Defines USER DATA Length in bytes +.core.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_END - .core.ZXBASIC_USER_DATA + .core.__LABEL__.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_LEN + .core.__LABEL__.ZXBASIC_USER_DATA EQU .core.ZXBASIC_USER_DATA +.core.ZXBASIC_USER_DATA_END: +.core.__MAIN_PROGRAM__: + call _main + ld hl, 0 + ld b, h + ld c, l +.core.__END_PROGRAM: + di + ld hl, (.core.__CALL_BACK__) + ld sp, hl + exx + pop hl + pop iy + pop ix + exx + ei + ret +_saludar: + push ix + ld ix, 0 + add ix, sp + ld l, (ix+4) + ld h, (ix+5) + inc hl +_saludar__leave: + ld sp, ix + pop ix + exx + pop hl + ex (sp), hl + exx + ret +_main: + push ix + ld ix, 0 + add ix, sp + ld hl, 0 + push hl + ld (ix-2), 1 + ld (ix-1), 0 + jp .LABEL.__LABEL0 +.LABEL.__LABEL3: + ld l, (ix-2) + ld h, (ix-1) + push hl + call _saludar + ld l, (ix-2) + ld h, (ix-1) + inc hl + ld (ix-2), l + ld (ix-1), h +.LABEL.__LABEL0: + ld l, (ix-2) + ld h, (ix-1) + ex de, hl + ld hl, 2 + or a + sbc hl, de + jp nc, .LABEL.__LABEL3 +_main__leave: + ld sp, ix + pop ix + ret + ;; --- end of user code --- + END diff --git a/tests/functional/zx48k/opt2_for_funcall.bas b/tests/functional/zx48k/opt2_for_funcall.bas new file mode 100644 index 000000000..ffa5449e0 --- /dev/null +++ b/tests/functional/zx48k/opt2_for_funcall.bas @@ -0,0 +1,12 @@ +main() + +function saludar(x as Uinteger) as Uinteger + return x + 1 +end function + +sub main() + dim i, result as uinteger + for i = 1 to 2 + result = saludar(i) + next +end sub