test_optimize.py 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. import unittest
  2. from src.optimize.redundancies import remove_redundancies, remove_redundant_jumps
  3. from src.program import Program
  4. from src.statement import Statement as S, Block as B
  5. def optimize_block(block):
  6. """Optimize a basic block using a Program object."""
  7. # program = Program([])
  8. # program.blocks = [block]
  9. # del program.statements
  10. # program.optimize_blocks()
  11. remove_redundancies(block)
  12. eliminate_common_subexpressions(block)
  13. fold_constants(block)
  14. copy_propagation(block)
  15. return program.blocks
  16. class TestOptimize(unittest.TestCase):
  17. def setUp(self):
  18. self.foo = S('command', 'foo')
  19. self.bar = S('command', 'bar')
  20. def tearDown(self):
  21. del self.foo
  22. del self.bar
  23. def test_optimize_block_movaa(self):
  24. block = B([self.foo,
  25. S('command', 'move', '$regA', '$regA'),
  26. self.bar])
  27. remove_redundancies(block)
  28. self.assertEquals(block.statements, [self.foo, self.bar])
  29. def test_optimize_block_movab(self):
  30. move = S('command', 'move', '$regA', '$regB')
  31. block = B([self.foo,
  32. move,
  33. self.bar])
  34. remove_redundancies(block)
  35. self.assertEquals(block.statements, [self.foo, move, self.bar])
  36. def test_optimize_block_movinst_true(self):
  37. block = B([self.foo,
  38. S('command', 'move', '$regA', '$regB'),
  39. S('command', 'addu', '$regA', '$regA', 2),
  40. self.bar])
  41. remove_redundancies(block)
  42. self.assertEquals(block.statements, [self.foo,
  43. S('command', 'addu', '$regA', '$regB', 2),
  44. self.bar])
  45. def test_optimize_block_movinst_false(self):
  46. statements = [self.foo, \
  47. S('command', 'move', '$regA', '$regB'), \
  48. S('command', 'addu', '$regD', '$regC', 2), \
  49. self.bar]
  50. block = B(statements)
  51. remove_redundancies(block)
  52. self.assertEquals(block.statements, statements)
  53. def test_optimize_block_instr_mov_jal_true(self):
  54. block = B([self.foo,
  55. S('command', 'addu', '$regA', '$regC', 2),
  56. S('command', 'move', '$4', '$regA'),
  57. S('command', 'jal', 'L1'),
  58. self.bar])
  59. remove_redundancies(block)
  60. self.assertEquals(block.statements, [self.foo,
  61. S('command', 'addu', '$4', '$regC', 2),
  62. S('command', 'jal', 'L1'),
  63. self.bar])
  64. def test_optimize_block_instr_mov_jal_false(self):
  65. arguments = [self.foo, \
  66. S('command', 'addu', '$regA', '$regC', 2), \
  67. S('command', 'move', '$3', '$regA'), \
  68. S('command', 'jal', 'L1'), \
  69. self.bar]
  70. block = B(arguments)
  71. remove_redundancies(block)
  72. self.assertEquals(block.statements, arguments)
  73. def test_optimize_block_sw_ld_true(self):
  74. block = B([self.foo,
  75. S('command', 'sw', '$regA', '$regB'),
  76. S('command', 'lw', '$regA', '$regB'),
  77. self.bar])
  78. remove_redundancies(block)
  79. self.assertEquals(block.statements, [self.foo,
  80. S('command', 'sw', '$regA', '$regB'),
  81. self.bar])
  82. def test_optimize_block_sw_ld_false(self):
  83. arguments = [self.foo, \
  84. S('command', 'sw', '$regA', '$regB'), \
  85. S('command', 'lw', '$regD', '$regC'), \
  86. self.bar]
  87. block = B(arguments)
  88. remove_redundancies(block)
  89. self.assertEquals(block.statements, arguments)
  90. def test_optimize_block_shift_true(self):
  91. block = B([self.foo,
  92. S('command', 'sll', '$regA', '$regA', 0),
  93. self.bar])
  94. remove_redundancies(block)
  95. self.assertEquals(block.statements, [self.foo, self.bar])
  96. def test_optimize_block_shift_false(self):
  97. arguments = [self.foo, \
  98. S('command', 'sll', '$regA', '$regB', 0), \
  99. self.bar]
  100. block = B(arguments)
  101. remove_redundancies(block)
  102. self.assertEquals(block.statements, arguments)
  103. arguments2 = [self.foo, \
  104. S('command', 'sll', '$regA', '$regA', 1), \
  105. self.bar]
  106. block2 = B(arguments2)
  107. remove_redundancies(block2)
  108. self.assertEquals(block2.statements, arguments2)
  109. def test_optimize_block_add_lw_true(self):
  110. block = B([self.foo,
  111. S('command', 'addu', '$regA', '$regA', 10),
  112. S('command', 'lw', '$regB', '0($regA)'),
  113. self.bar])
  114. remove_redundancies(block)
  115. self.assertEquals(block.statements, [self.foo,
  116. S('command', 'lw', '$regB', '10($regA)'),
  117. self.bar])
  118. def test_optimize_block_add_lw_false(self):
  119. arguments = [self.foo, \
  120. S('command', 'addu', '$regA', '$regA', 10), \
  121. S('command', 'lw', '$regB', '0($regC)'), \
  122. self.bar]
  123. block = B(arguments)
  124. remove_redundancies(block)
  125. arguments2 = [self.foo, \
  126. S('command', 'addu', '$regA', '$regB', 10), \
  127. S('command', 'lw', '$regB', '0($regA)'), \
  128. self.bar]
  129. block2 = B(arguments2)
  130. arguments3 = [self.foo, \
  131. S('command', 'addu', '$regA', '$regA', 10), \
  132. S('command', 'lw', '$regB', '1($regA)'), \
  133. self.bar]
  134. block3 = B(arguments3)
  135. remove_redundancies(block3)
  136. self.assertEquals(block.statements, arguments)
  137. self.assertEquals(block2.statements, arguments2)
  138. self.assertEquals(block3.statements, arguments3)
  139. def test_remove_redundant_jumps_beq_j_true(self):
  140. block = B([self.foo,
  141. S('command', 'beq', '$regA', '$regB', '$Lx'),
  142. S('command', 'j', '$Ly'),
  143. S('label', '$Lx'),
  144. self.bar])
  145. remove_redundant_jumps(block)
  146. self.assertEquals(block.statements, [self.foo,
  147. S('command', 'bne', '$regA', '$regB', '$Ly'),
  148. S('label', '$Lx'),
  149. self.bar])
  150. def test_remove_redundant_jumps_beq_j_false(self):
  151. arguments = [self.foo, \
  152. S('command', 'beq', '$regA', '$regB', '$Lz'), \
  153. S('command', 'j', '$Ly'), \
  154. S('label', '$Lx'), \
  155. self.bar]
  156. block = B(arguments)
  157. remove_redundant_jumps(block)
  158. self.assertEquals(block.statements, arguments)
  159. def test_remove_redundant_jumps_bne_j_true(self):
  160. block = B([self.foo,
  161. S('command', 'bne', '$regA', '$regB', '$Lx'),
  162. S('command', 'j', '$Ly'),
  163. S('label', '$Lx'),
  164. self.bar])
  165. remove_redundant_jumps(block)
  166. self.assertEquals(block.statements, [self.foo,
  167. S('command', 'beq', '$regA', '$regB', '$Ly'),
  168. S('label', '$Lx'),
  169. self.bar])
  170. def test_remove_redundant_jumps_bne_j_false(self):
  171. arguments = [self.foo, \
  172. S('command', 'bne', '$regA', '$regB', '$Lz'), \
  173. S('command', 'j', '$Ly'), \
  174. S('label', '$Lx'), \
  175. self.bar]
  176. block = B(arguments)
  177. remove_redundant_jumps(block)
  178. self.assertEquals(block.statements, arguments)
  179. def test_optimize_block_move_move_true(self):
  180. block = B([self.foo,
  181. S('command', 'move', '$regA', '$regB'),
  182. S('command', 'move', '$regB', '$regA'),
  183. self.bar])
  184. remove_redundancies(block)
  185. self.assertEquals(block.statements, [self.foo,
  186. S('command', 'move', '$regA', '$regB'),
  187. self.bar])
  188. def test_optimize_block_mov_mov_false(self):
  189. arguments = [self.foo, \
  190. S('command', 'move', '$regA', '$regB'), \
  191. S('command', 'move', '$regB', '$regC'), \
  192. self.bar]
  193. block = B(arguments)
  194. remove_redundancies(block)
  195. self.assertEquals(block.statements, arguments)