Commit e3caa5f9 authored by Richard Torenvliet's avatar Richard Torenvliet

Merge branch 'master' of github.com:taddeus/peephole

parents 779efaa1 21ff6f23
...@@ -31,9 +31,9 @@ def optimize_block(block): ...@@ -31,9 +31,9 @@ def optimize_block(block):
while remove_redundancies(block) \ while remove_redundancies(block) \
| eliminate_common_subexpressions(block) \ | eliminate_common_subexpressions(block) \
| fold_constants(block) \ | fold_constants(block) \
| copy_propagation(block)\ | copy_propagation(block) \
| algebraic_transformations(block) \
| eliminate_dead_code(block): | eliminate_dead_code(block):
#| algebraic_transformations(block) \
pass pass
......
...@@ -149,22 +149,44 @@ def fold_constants(block): ...@@ -149,22 +149,44 @@ def fold_constants(block):
register[s[0]] = constants[s[1]] register[s[0]] = constants[s[1]]
elif s.name == 'mflo': elif s.name == 'mflo':
# Move of `Lo' register to another register # Move of `Lo' register to another register
register[s[0]] = register['Lo'] register[s[0]] = register['$lo']
elif s.name == 'mfhi': elif s.name == 'mfhi':
# Move of `Hi' register to another register # Move of `Hi' register to another register
register[s[0]] = register['Hi'] register[s[0]] = register['$hi']
elif s.name in ['mult', 'div'] \ elif s.name in ['mult', 'div'] \
and s[0] in register and s[1] in register: and s[0]in register and s[1] in register:
# Multiplication/division with constants # Multiplication/division with constants
rs, rt = s rs, rt = s
a, b = register[rs], register[rt]
if s.name == 'mult': if s.name == 'mult':
binary = bin(register[rs] * register[rt])[2:] if not a or not b:
binary = '0' * (64 - len(binary)) + binary # Multiplication by 0
register['Hi'] = int(binary[:32], base=2) hi = lo = to_hex(0)
register['Lo'] = int(binary[32:], base=2) elif a == 1:
# Multiplication by 1
hi = to_hex(0)
lo = to_hex(b)
elif b == 1:
# Multiplication by 1
hi = to_hex(0)
lo = to_hex(a)
else:
# Calculate result and fill Hi/Lo registers
binary = bin(a * b)[2:]
binary = '0' * (64 - len(binary)) + binary
hi = int(binary[:32], base=2)
lo = int(binary[32:], base=2)
# Replace the multiplication with two immidiate loads to the
# Hi/Lo registers
block.replace(1, [S('command', 'li', '$hi', hi),
S('command', 'li', '$lo', li)])
elif s.name == 'div': elif s.name == 'div':
register['Lo'], register['Hi'] = divmod(rs, rt) lo, hi = divmod(rs, rt)
register['$lo'], register['$hi'] = lo, hi
changed = True
elif s.name in ['addu', 'subu']: elif s.name in ['addu', 'subu']:
# Addition/subtraction with constants # Addition/subtraction with constants
rd, rs, rt = s rd, rs, rt = s
...@@ -187,7 +209,9 @@ def fold_constants(block): ...@@ -187,7 +209,9 @@ def fold_constants(block):
block.replace(1, [S('command', 'li', rd, result)]) block.replace(1, [S('command', 'li', rd, result)])
register[rd] = result register[rd] = result
changed = True changed = True
elif rt_known: continue
if rt_known:
# a = 10 -> b = c + 10 # a = 10 -> b = c + 10
# b = c + a # b = c + a
s[2] = register[rt] s[2] = register[rt]
...@@ -198,9 +222,15 @@ def fold_constants(block): ...@@ -198,9 +222,15 @@ def fold_constants(block):
s[1] = rt s[1] = rt
s[2] = register[rs] s[2] = register[rs]
changed = True changed = True
elif len(s) and s[0] in register:
# Known register is overwritten, remove its value if s[2] == 0:
del register[s[0]] # Addition/subtraction with 0
block.replace(1, [S('command', 'move', rd, s[1])])
else:
for reg in s.get_def():
if reg in register:
# Known register is overwritten, remove its value
del register[reg]
return changed return changed
......
...@@ -111,8 +111,8 @@ class Statement: ...@@ -111,8 +111,8 @@ class Statement:
"""Check if the statement is a logical operator.""" """Check if the statement is a logical operator."""
return self.is_command() and re.match('^(xor|or|and)i?$', self.name) return self.is_command() and re.match('^(xor|or|and)i?$', self.name)
def is_double_aritmethic(self): def is_double_arithmetic(self):
"""Check if the statement is a aritmethic .d operator.""" """Check if the statement is a arithmetic .d operator."""
return self.is_command() and \ return self.is_command() and \
re.match('^(add|sub|div|mul)\.d$', self.name) re.match('^(add|sub|div|mul)\.d$', self.name)
...@@ -153,7 +153,7 @@ class Statement: ...@@ -153,7 +153,7 @@ class Statement:
instr = ['move', 'addu', 'subu', 'li', 'mtc1', 'dmfc1', 'mov.d'] instr = ['move', 'addu', 'subu', 'li', 'mtc1', 'dmfc1', 'mov.d']
if self.is_load_non_immediate() or self.is_arith() \ if self.is_load_non_immediate() or self.is_arith() \
or self.is_logical() or self.is_double_aritmethic() \ or self.is_logical() or self.is_double_arithmetic() \
or self.is_move_from_spec() or self.is_double_unary() \ or self.is_move_from_spec() or self.is_double_unary() \
or self.is_set_if_less() or self.is_convert() \ or self.is_set_if_less() or self.is_convert() \
or self.is_truncate() or self.is_load() \ or self.is_truncate() or self.is_load() \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment