Skip to content

Commit 37984e4

Browse files
committed
Correctly detect memory dependencies
* Removed useless code in goes_requires * Added more debug info for applied templates * Fixed memory dependencies for memory positions When it's a memory access with a register like (hl) or (ix + n), changing the register makes the access required.
1 parent f4b6faa commit 37984e4

2 files changed

Lines changed: 28 additions & 14 deletions

File tree

arch/zx48k/optimizer/basicblock.py

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -360,17 +360,35 @@ def is_used(self, regs, i, top=None):
360360
if self.lock:
361361
return True
362362

363-
regs = api.utils.flatten_list([helpers.single_registers(x) for x in regs]) # make a copy
364363
if top is None:
365364
top = len(self)
366365
else:
367366
top -= 1
368367

369-
for ii in range(i, top):
370-
for r in self.mem[ii].requires:
371-
if r in regs:
368+
if regs and regs[0][0] == '(' and regs[0][-1] == ')': # A memory address
369+
r16 = helpers.single_registers(regs[0][1:-1])\
370+
if helpers.is_16bit_oper_register(regs[0][1:-1]) else []
371+
ix = helpers.single_registers(helpers.idx_args(regs[0][1:-1])[0]) \
372+
if helpers.idx_args(regs[0][1:-1]) else []
373+
374+
rr = set(r16 + ix)
375+
for mem in self[i:top]: # For memory accesses only mark as NOT uses if it's overwritten
376+
if mem.inst == 'ld' and mem.opers[0] == regs[0]:
377+
return False
378+
379+
if mem.opers and mem.opers[-1] == regs[0]:
380+
return True
381+
382+
if rr and any(_ in r16 for _ in mem.destroys): # (hl) :: inc hl / (ix + n) :: inc ix
372383
return True
373384

385+
return True
386+
387+
regs = api.utils.flatten_list([helpers.single_registers(x) for x in regs]) # make a copy
388+
for ii in range(i, top):
389+
if any(r in regs for r in self.mem[ii].requires):
390+
return True
391+
374392
for r in self.mem[ii].destroys:
375393
if r in regs:
376394
regs.remove(r)
@@ -457,15 +475,6 @@ def goes_requires(self, regs):
457475
""" Returns whether any of the goes_to block requires any of
458476
the given registers.
459477
"""
460-
if len(self) and self.mem[-1].inst == 'call' and self.mem[-1].condition_flag is None:
461-
for block in self.calls:
462-
if block.is_used(regs, 0):
463-
return True
464-
465-
d = block.destroys()
466-
if not len([x for x in regs if x not in d]):
467-
return False # If all registers are destroyed then they're not used
468-
469478
for block in self.goes_to:
470479
if block.is_used(regs, 0):
471480
return True
@@ -551,8 +560,10 @@ def optimize(self):
551560

552561
# all patterns applied successfully. Apply this pattern
553562
new_code = list(code)
563+
matched = new_code[i: i + len(p.patt)]
554564
new_code[i: i + len(p.patt)] = p.template.filter(match)
555565
api.errmsg.info('pattern applied [{}:{}]'.format("%03i" % p.flag, p.fname))
566+
api.debug.__DEBUG__('matched: \n {}'.format('\n '.join(matched)), level=1)
556567
changed = new_code != code
557568
if changed:
558569
code = new_code

arch/zx48k/peephole/engine.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,11 @@ def apply_match(asm_list, patterns_list, index=0):
113113
continue
114114

115115
# All patterns have matched successfully. Apply this pattern
116-
asm_list[index: index + len(p.patt)] = p.template.filter(match)
116+
matched = asm_list[index: index + len(p.patt)]
117+
applied = p.template.filter(match)
118+
asm_list[index: index + len(p.patt)] = applied
117119
api.errmsg.info('pattern applied [{}:{}]'.format("%03i" % p.flag, p.fname))
120+
api.debug.__DEBUG__('matched: \n {}'.format('\n '.join(matched)), level=1)
118121
return True
119122

120123
return False

0 commit comments

Comments
 (0)