Skip to content

Commit 26c9b98

Browse files
committed
Add O4 optimization level!
Finally the O4 level, which allows: - Propagation of register values from one block to others - Also computes propagation of values written in memory in 109 and 110 opts - Precompute templating filter for faster computation
1 parent 37984e4 commit 26c9b98

10 files changed

Lines changed: 543 additions & 7 deletions

File tree

arch/zx48k/optimizer/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# -*- coding: utf-8 -*-
22

33
from api.utils import flatten_list
4+
from arch.zx48k.peephole import engine
45

56
from .patterns import RE_PRAGMA, RE_LABEL
67
from .common import LABELS, JUMP_LABELS, MEMORY
@@ -232,8 +233,9 @@ def optimize(initial_memory):
232233
for x in basic_blocks:
233234
x.compute_cpu_state()
234235

236+
filtered_patterns_list = [p for p in engine.PATTERNS if OPTIONS.optimization.value >= p.level >= 3]
235237
for x in basic_blocks:
236-
x.optimize()
238+
x.optimize(filtered_patterns_list)
237239

238240
for x in basic_blocks:
239241
if x.comes_from == [] and len([y for y in JUMP_LABELS if x is LABELS[y].basic_block]):

arch/zx48k/optimizer/basicblock.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import arch
44
import api.utils
5+
import api.config
56

67
from api.debug import __DEBUG__
78
from api.identityset import IdentitySet
@@ -11,7 +12,6 @@
1112
from .common import LABELS, JUMP_LABELS
1213
from .errors import OptimizerInvalidBasicBlockError, OptimizerError
1314
from .cpustate import CPUState
14-
from ..peephole import engine
1515
from ..peephole import evaluator
1616

1717
from . import helpers
@@ -527,26 +527,29 @@ def compute_cpu_state(self):
527527
for asm_line in self.code:
528528
self.cpu.execute(asm_line)
529529

530-
def optimize(self):
530+
def optimize(self, patterns_list):
531531
""" Tries to detect peep-hole patterns in this basic block
532532
and remove them.
533533
"""
534534
if self.optimized:
535535
return
536536

537-
filtered_patterns_list = [p for p in engine.PATTERNS if p.level >= 3]
538537
changed = True
539538
code = self.code
540539
old_unary = dict(evaluator.Evaluator.UNARY)
541540
evaluator.Evaluator.UNARY['GVAL'] = lambda x: self.cpu.get(x)
542-
regs, mems = self.guesses_initial_state_from_origin_blocks()
541+
542+
if api.config.OPTIONS.optimization.value > 3:
543+
regs, mems = self.guesses_initial_state_from_origin_blocks()
544+
else:
545+
regs, mems = {}, {}
543546

544547
while changed:
545548
changed = False
546549
self.cpu.reset(regs=regs, mems=mems)
547550

548551
for i, asm_line in enumerate(code):
549-
for p in filtered_patterns_list:
552+
for p in patterns_list:
550553
match = p.patt.match(code[i:])
551554
if match is None: # HINT: {} is also a valid match
552555
continue
@@ -651,7 +654,7 @@ def get_basic_blocks(block):
651654
block = new_block
652655
new_block = None
653656

654-
for i, mem in enumerate(block[:-1]):
657+
for i, mem in enumerate(block):
655658
if i and mem.code == EDP: # END_PROGRAM label always starts a basic block
656659
block, new_block = block_partition(block, i - 1)
657660
LABELS[END_PROGRAM_LABEL].basic_block = new_block
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
;; Removes useless LD's
2+
;; Tries to guess the value of the 1st and 2nd operands.
3+
;; If they're the same, this LD is useless
4+
5+
OLEVEL: 4
6+
OFLAG: 109
7+
8+
REPLACE {{
9+
$1 $2, $3
10+
}}
11+
12+
IF {{
13+
($2 <> sp) && ($2 <> ix) && !IS_REQUIRED($2) &&
14+
($1 == ld || (!IS_REQUIRED(f) && ($1 == add || $1 == adc || $1 == sbc)))
15+
}}
16+
17+
WITH {{
18+
}}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
;; Removes useless LD's
2+
;; Tries to guess the value of the 1st and 2nd operands.
3+
;; If they're the same, this LD is useless
4+
5+
OLEVEL: 4
6+
OFLAG: 110
7+
8+
REPLACE {{
9+
$1 $2
10+
}}
11+
12+
IF {{
13+
((($1 == inc || $1 == dec) && !IS_REQUIRED($2))
14+
|| ($1 == sub && !IS_REQUIRED(a))
15+
) && ($2 <> sp) && !IS_REQUIRED(f)
16+
}}
17+
18+
WITH {{
19+
}}

tests/functional/opt4_atohl_a.asm

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
org 32768
2+
__START_PROGRAM:
3+
di
4+
push ix
5+
push iy
6+
exx
7+
push hl
8+
exx
9+
ld hl, 0
10+
add hl, sp
11+
ld (__CALL_BACK__), hl
12+
ei
13+
ld a, (_g)
14+
push af
15+
ld a, (_i)
16+
push af
17+
call _putTile10x8Box
18+
ld bc, 0
19+
__END_PROGRAM:
20+
di
21+
ld hl, (__CALL_BACK__)
22+
ld sp, hl
23+
exx
24+
pop hl
25+
pop iy
26+
pop ix
27+
exx
28+
ei
29+
ret
30+
__CALL_BACK__:
31+
DEFW 0
32+
_putTile10x8Box:
33+
_putTile10x8Box__leave:
34+
ret
35+
36+
ZXBASIC_USER_DATA:
37+
_dw1:
38+
DEFB 00, 00
39+
_i:
40+
DEFB 00, 00
41+
_g:
42+
DEFB 00, 00
43+
; Defines DATA END --> HEAP size is 0
44+
ZXBASIC_USER_DATA_END EQU ZXBASIC_MEM_HEAP
45+
; Defines USER DATA Length in bytes
46+
ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA
47+
END

tests/functional/opt4_atohl_a.bas

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
2+
sub FASTCALL putTile10x8Box (dir1 as Uinteger,d1 as ubyte ,d2 as ubyte)
3+
end sub
4+
5+
DIM dw1, i, g as Uinteger
6+
putTile10x8Box(dw1, i, g)
7+

tests/functional/opt4_inca.asm

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
org 32768
2+
__START_PROGRAM:
3+
di
4+
push ix
5+
push iy
6+
exx
7+
push hl
8+
exx
9+
ld hl, 0
10+
add hl, sp
11+
ld (__CALL_BACK__), hl
12+
ei
13+
ld a, 31
14+
add a, 4
15+
ld (_d1), a
16+
ld bc, 0
17+
__END_PROGRAM:
18+
di
19+
ld hl, (__CALL_BACK__)
20+
ld sp, hl
21+
exx
22+
pop hl
23+
pop iy
24+
pop ix
25+
exx
26+
ei
27+
ret
28+
__CALL_BACK__:
29+
DEFW 0
30+
31+
ZXBASIC_USER_DATA:
32+
_d1:
33+
DEFB 00
34+
; Defines DATA END --> HEAP size is 0
35+
ZXBASIC_USER_DATA_END EQU ZXBASIC_MEM_HEAP
36+
; Defines USER DATA Length in bytes
37+
ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA
38+
END

tests/functional/opt4_inca.bas

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
DIM d1 as UByte
2+
3+
d1 = 32
4+
d1 = d1 + 1
5+
6+
d1 = 30
7+
d1 = d1 + 4
8+
d1 = d1 + 5
9+
10+
d1 = 31
11+
d1 = d1 + 4
12+

0 commit comments

Comments
 (0)