Skip to content
This repository has been archived by the owner on May 21, 2024. It is now read-only.

Commit

Permalink
Merge pull request boriel-basic#608 from boriel/fix/bad_optimization
Browse files Browse the repository at this point in the history
fix: fix optimization for FOR loop
  • Loading branch information
boriel committed Feb 13, 2022
2 parents 86a32df + 66abcf2 commit 6629acb
Show file tree
Hide file tree
Showing 5 changed files with 205 additions and 10 deletions.
21 changes: 11 additions & 10 deletions src/api/optimize.py
Original file line number Diff line number Diff line change
Expand Up @@ -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_):
Expand All @@ -420,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:
Expand All @@ -433,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
Expand All @@ -445,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

Expand Down
85 changes: 85 additions & 0 deletions tests/functional/zx48k/opt2_for_funcall.asm
Original file line number Diff line number Diff line change
@@ -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
12 changes: 12 additions & 0 deletions tests/functional/zx48k/opt2_for_funcall.bas
Original file line number Diff line number Diff line change
@@ -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
83 changes: 83 additions & 0 deletions tests/functional/zx48k/opt2_while_funcall.asm
Original file line number Diff line number Diff line change
@@ -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
14 changes: 14 additions & 0 deletions tests/functional/zx48k/opt2_while_funcall.bas
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 6629acb

Please sign in to comment.