test_optimize.py 8.1 KB

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