Commit fc4ae6b6 authored by Taddeus Kroes's avatar Taddeus Kroes

Moved some optimization wrapper fucntions.

parent bf493e78
from src.dataflow import find_basic_blocks from src.dataflow import find_basic_blocks
from standard import redundant_move_1, redundant_move_2, \ from redundancies import remove_redundant_jumps, move_1, move_2, move_3, \
redundant_move_3, redundant_move_4, redundant_load, \ move_4, load, shift, add
redundant_shift, redundant_add
from advanced import eliminate_common_subexpressions, fold_constants, \ from advanced import eliminate_common_subexpressions, fold_constants, \
copy_propagation copy_propagation
def optimize_global(statements): def remove_redundancies(block):
"""Optimize statement sequences on a global level.""" """Execute all functions that remove redundant statements."""
callbacks = [move_1, move_2, move_3, move_4, load, shift, add]
old_len = -1 old_len = -1
changed = False
while old_len != len(statements):
old_len = len(statements)
while not statements.end():
s = statements.read()
# beq/bne ..., $Lx -> bne/beq ..., $Ly
# j $Ly $Lx:
# $Lx:
if s.is_command('beq', 'bne'):
following = statements.peek(2)
if len(following) == 2:
j, label = following
if j.is_command('j') and label.is_label(s[2]):
s.name = 'bne' if s.is_command('beq') else 'beq'
s[2] = j[0]
statements.replace(3, [s, label])
def optimize_block(block):
"""Optimize a basic block."""
standard = [redundant_move_1, redundant_move_2, redundant_move_3, \
redundant_move_4, redundant_load, redundant_shift, \
redundant_add]
old_len = -1
# Standard optimizations
while old_len != len(block): while old_len != len(block):
old_len = len(block) old_len = len(block)
while not block.end(): while not block.end():
s = block.read() s = block.read()
for callback in standard: for callback in callbacks:
if callback(s, block): if callback(s, block):
changed = True
break break
# Advanced optimizations return changed
#changed = True
#while changed: def optimize_block(block):
# changed = eliminate_common_subexpressions(block) \ """Optimize a basic block."""
# or fold_constants(block) while remove_redundancies(block) \
| eliminate_common_subexpressions(block) \
while eliminate_common_subexpressions(block) \
| fold_constants(block) \ | fold_constants(block) \
| copy_propagation(block): | copy_propagation(block):
pass pass
......
import re import re
def redundant_move_1(mov, statements): def move_1(mov, statements):
""" """
mov $regA, $regA -> --- remove it mov $regA, $regA -> --- remove it
""" """
...@@ -11,7 +11,7 @@ def redundant_move_1(mov, statements): ...@@ -11,7 +11,7 @@ def redundant_move_1(mov, statements):
return True return True
def redundant_move_2(mov, statements): def move_2(mov, statements):
""" """
mov $regA, $regB -> instr $regA, $regB, ... mov $regA, $regB -> instr $regA, $regB, ...
instr $regA, $regA, ... instr $regA, $regA, ...
...@@ -26,7 +26,7 @@ def redundant_move_2(mov, statements): ...@@ -26,7 +26,7 @@ def redundant_move_2(mov, statements):
return True return True
def redundant_move_3(ins, statements): def move_3(ins, statements):
""" """
instr $regA, ... -> instr $4, ... instr $regA, ... -> instr $4, ...
mov $4, $regA jal XX mov $4, $regA jal XX
...@@ -47,7 +47,7 @@ def redundant_move_3(ins, statements): ...@@ -47,7 +47,7 @@ def redundant_move_3(ins, statements):
return True return True
def redundant_move_4(mov1, statements): def move_4(mov1, statements):
""" """
mov $RegA, $RegB -> move $RegA, $RegB mov $RegA, $RegB -> move $RegA, $RegB
mov $RegB, $RegA mov $RegB, $RegA
...@@ -62,7 +62,7 @@ def redundant_move_4(mov1, statements): ...@@ -62,7 +62,7 @@ def redundant_move_4(mov1, statements):
return True return True
def redundant_load(sw, statements): def load(sw, statements):
""" """
sw $regA, XX -> sw $regA, XX sw $regA, XX -> sw $regA, XX
ld $regA, XX ld $regA, XX
...@@ -76,7 +76,7 @@ def redundant_load(sw, statements): ...@@ -76,7 +76,7 @@ def redundant_load(sw, statements):
return True return True
def redundant_shift(shift, statements): def shift(shift, statements):
""" """
shift $regA, $regA, 0 -> --- remove it shift $regA, $regA, 0 -> --- remove it
""" """
...@@ -86,7 +86,7 @@ def redundant_shift(shift, statements): ...@@ -86,7 +86,7 @@ def redundant_shift(shift, statements):
return True return True
def redundant_add(add, statements): def add(add, statements):
""" """
add $regA, $regA, X -> lw ..., X($regA) add $regA, $regA, X -> lw ..., X($regA)
lw ..., 0($regA) lw ..., 0($regA)
...@@ -99,3 +99,28 @@ def redundant_add(add, statements): ...@@ -99,3 +99,28 @@ def redundant_add(add, statements):
statements.replace(2, [lw]) statements.replace(2, [lw])
return True return True
def remove_redundant_jumps(statements):
"""Optimize statement sequences on a global level."""
old_len = -1
while old_len != len(statements):
old_len = len(statements)
while not statements.end():
s = statements.read()
# beq/bne ..., $Lx -> bne/beq ..., $Ly
# j $Ly $Lx:
# $Lx:
if s.is_command('beq', 'bne'):
following = statements.peek(2)
if len(following) == 2:
j, label = following
if j.is_command('j') and label.is_label(s[2]):
s.name = 'bne' if s.is_command('beq') else 'beq'
s[2] = j[0]
statements.replace(3, [s, label])
import unittest import unittest
from src.optimize import optimize_global, optimize_block from src.optimize.redundancies import remove_redundant_jumps
from src.optimize import optimize_block
from src.statement import Statement as S, Block as B from src.statement import Statement as S, Block as B
...@@ -155,51 +156,51 @@ class TestOptimize(unittest.TestCase): ...@@ -155,51 +156,51 @@ class TestOptimize(unittest.TestCase):
self.assertEquals(block2.statements, arguments2) self.assertEquals(block2.statements, arguments2)
self.assertEquals(block3.statements, arguments3) self.assertEquals(block3.statements, arguments3)
def test_optimize_global_beq_j_true(self): def test_remove_redundant_jumps_beq_j_true(self):
block = B([self.foo, block = B([self.foo,
S('command', 'beq', '$regA', '$regB', '$Lx'), S('command', 'beq', '$regA', '$regB', '$Lx'),
S('command', 'j', '$Ly'), S('command', 'j', '$Ly'),
S('label', '$Lx'), S('label', '$Lx'),
self.bar]) self.bar])
optimize_global(block) remove_redundant_jumps(block)
self.assertEquals(block.statements, [self.foo, self.assertEquals(block.statements, [self.foo,
S('command', 'bne', '$regA', '$regB', '$Ly'), S('command', 'bne', '$regA', '$regB', '$Ly'),
S('label', '$Lx'), S('label', '$Lx'),
self.bar]) self.bar])
def test_optimize_global_beq_j_false(self): def test_remove_redundant_jumps_beq_j_false(self):
arguments = [self.foo, \ arguments = [self.foo, \
S('command', 'beq', '$regA', '$regB', '$Lz'), \ S('command', 'beq', '$regA', '$regB', '$Lz'), \
S('command', 'j', '$Ly'), \ S('command', 'j', '$Ly'), \
S('label', '$Lx'), \ S('label', '$Lx'), \
self.bar] self.bar]
block = B(arguments) block = B(arguments)
optimize_global(block) remove_redundant_jumps(block)
self.assertEquals(block.statements, arguments) self.assertEquals(block.statements, arguments)
def test_optimize_global_bne_j_true(self): def test_remove_redundant_jumps_bne_j_true(self):
block = B([self.foo, block = B([self.foo,
S('command', 'bne', '$regA', '$regB', '$Lx'), S('command', 'bne', '$regA', '$regB', '$Lx'),
S('command', 'j', '$Ly'), S('command', 'j', '$Ly'),
S('label', '$Lx'), S('label', '$Lx'),
self.bar]) self.bar])
optimize_global(block) remove_redundant_jumps(block)
self.assertEquals(block.statements, [self.foo, self.assertEquals(block.statements, [self.foo,
S('command', 'beq', '$regA', '$regB', '$Ly'), S('command', 'beq', '$regA', '$regB', '$Ly'),
S('label', '$Lx'), S('label', '$Lx'),
self.bar]) self.bar])
def test_optimize_global_bne_j_false(self): def test_remove_redundant_jumps_bne_j_false(self):
arguments = [self.foo, \ arguments = [self.foo, \
S('command', 'bne', '$regA', '$regB', '$Lz'), \ S('command', 'bne', '$regA', '$regB', '$Lz'), \
S('command', 'j', '$Ly'), \ S('command', 'j', '$Ly'), \
S('label', '$Lx'), \ S('label', '$Lx'), \
self.bar] self.bar]
block = B(arguments) block = B(arguments)
optimize_global(block) remove_redundant_jumps(block)
self.assertEquals(block.statements, arguments) self.assertEquals(block.statements, arguments)
......
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