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