Skip to content
Snippets Groups Projects
Commit fc4ae6b6 authored by Taddeus Kroes's avatar Taddeus Kroes
Browse files

Moved some optimization wrapper fucntions.

parent bf493e78
No related branches found
No related tags found
No related merge requests found
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)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment