test_dataflow.py 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. import unittest
  2. from src.statement import Statement as S
  3. from src.dataflow import BasicBlock as B, find_leaders, find_basic_blocks, \
  4. generate_flow_graph, Dag, DagNode, DagLeaf, get_defs, \
  5. reaching_definitions
  6. class TestDataflow(unittest.TestCase):
  7. def setUp(self):
  8. add = S('command', 'add', '$1', '$2', '$3')
  9. self.statements = [add, S('command', 'j', 'foo'), add, add, \
  10. S('label', 'foo')]
  11. def tearDown(self):
  12. del self.statements
  13. def test_find_leaders(self):
  14. self.assertEqual(find_leaders(self.statements), [0, 2, 4])
  15. def test_find_basic_blocks(self):
  16. s = self.statements
  17. self.assertEqual(map(lambda b: b.statements, find_basic_blocks(s)), \
  18. [B(s[:2]).statements, B(s[2:4]).statements, \
  19. B(s[4:]).statements])
  20. def test_get_defs(self):
  21. s1 = S('command', 'add', '$3', '$1', '$2')
  22. s2 = S('command', 'move', '$1', '$3')
  23. s3 = S('command', 'move', '$3', '$2')
  24. s4 = S('command', 'li', '$4', '0x00000001')
  25. block = B([s1, s2, s3, s4])
  26. self.assertEqual(get_defs([block]), {
  27. '$3': set([s1.sid, s3.sid]),
  28. '$1': set([s2.sid]),
  29. '$4': set([s4.sid])
  30. })
  31. def test_create_gen_kill_simple(self):
  32. s1 = S('command', 'addu', '$3', '$1', '$2')
  33. s2 = S('command', 'addu', '$1', '$3', 10)
  34. s3 = S('command', 'subu', '$3', '$1', 5)
  35. s4 = S('command', 'li', '$4', '0x00000001')
  36. block = B([s1, s2, s3, s4])
  37. block.create_gen_kill(get_defs([block]))
  38. self.assertEqual(block.gen_set, set([s2.sid, s3.sid, s4.sid]))
  39. self.assertEqual(block.kill_set, set([s1.sid]))
  40. def test_create_gen_kill_between_blocks(self):
  41. s11 = S('command', 'li', 'a', 3)
  42. s12 = S('command', 'li', 'b', 5)
  43. s13 = S('command', 'li', 'd', 4)
  44. s14 = S('command', 'li', 'x', 100)
  45. s15 = S('command', 'blt', 'a', 'b', 'L1')
  46. b1 = B([s11, s12, s13, s14, s15])
  47. s21 = S('command', 'addu', 'c', 'a', 'b')
  48. s22 = S('command', 'li', 'd', 2)
  49. b2 = B([s21, s22])
  50. s31 = S('label', 'L1')
  51. s32 = S('command', 'li', 'c', 4)
  52. s33 = S('command', 'mult', 'b', 'd')
  53. s34 = S('command', 'mflo', 'temp')
  54. s35 = S('command', 'addu', 'return', 'temp', 'c')
  55. b3 = B([s31, s32, s33, s34, s35])
  56. defs = get_defs([b1, b2, b3])
  57. b1.create_gen_kill(defs)
  58. b2.create_gen_kill(defs)
  59. b3.create_gen_kill(defs)
  60. self.assertEqual(b1.gen_set, set([s11.sid, s12.sid, s13.sid, s14.sid]))
  61. self.assertEqual(b1.kill_set, set([s22.sid]))
  62. self.assertEqual(b2.gen_set, set([s21.sid, s22.sid]))
  63. self.assertEqual(b2.kill_set, set([s13.sid, s32.sid]))
  64. self.assertEqual(b3.gen_set, set([s32.sid, s34.sid, s35.sid]))
  65. self.assertEqual(b3.kill_set, set([s21.sid]))
  66. def test_reaching_definitions(self):
  67. s11 = S('command', 'li', 'a', 3)
  68. s12 = S('command', 'li', 'b', 5)
  69. s13 = S('command', 'li', 'd', 4)
  70. s14 = S('command', 'li', 'x', 100)
  71. s15 = S('command', 'blt', 'a', 'b', 'L1')
  72. b1 = B([s11, s12, s13, s14, s15])
  73. s21 = S('command', 'addu', 'c', 'a', 'b')
  74. s22 = S('command', 'li', 'd', 2)
  75. b2 = B([s21, s22])
  76. s31 = S('label', 'L1')
  77. s32 = S('command', 'li', 'c', 4)
  78. s33 = S('command', 'mult', 'b', 'd')
  79. s34 = S('command', 'mflo', 'temp')
  80. s35 = S('command', 'addu', 'return', 'temp', 'c')
  81. b3 = B([s31, s32, s33, s34, s35])
  82. reaching_definitions([b1, b2, b3])
  83. self.assertEqual(b1.in_set, set())
  84. self.assertEqual(b1.out_set, set([s11.sid, s12.sid, s13.sid]))
  85. self.assertEqual(b2.in_set, set([s11.sid, s12.sid]))
  86. self.assertEqual(b2.out_set, set([s12.sid, s22.sid]))
  87. self.assertEqual(b3.in_set, set([s12.sid, s22.sid]))
  88. self.assertEqual(b3.out_set, set())
  89. def test_generate_flow_graph_simple(self):
  90. b1 = B([S('command', 'foo'), S('command', 'j', 'b2')])
  91. b2 = B([S('label', 'b2'), S('command', 'bar')])
  92. generate_flow_graph([b1, b2])
  93. self.assertEqual(b1.edges_to, [b2])
  94. self.assertEqual(b2.edges_from, [b1])
  95. def test_generate_flow_graph_branch(self):
  96. b1 = B([S('command', 'foo'), S('command', 'beq', '$1', '$2', 'b3')])
  97. b2 = B([S('command', 'bar')])
  98. b3 = B([S('label', 'b3'), S('command', 'baz')])
  99. generate_flow_graph([b1, b2, b3])
  100. self.assertIn(b2, b1.edges_to)
  101. self.assertIn(b3, b1.edges_to)
  102. self.assertEqual(b2.edges_from, [b1])
  103. self.assertEqual(b2.edges_to, [b3])
  104. self.assertIn(b1, b3.edges_from)
  105. self.assertIn(b2, b3.edges_from)
  106. def test_dag_unary(self):
  107. dag = Dag(B([S('command', 'neg.d', '$rd', '$rs')]))
  108. expect = Dag([])
  109. expect.nodes = [DagLeaf('$rs'), DagNode('neg.d', '$rd', \
  110. DagLeaf('$rs'))]
  111. self.assertEqualDag(dag, expect)
  112. def test_dag_binary(self):
  113. dag = Dag(B([S('command', 'addu', '$rd', '$r1', '$r2')]))
  114. expect = Dag([])
  115. expect.nodes = [DagLeaf('$r1'),
  116. DagLeaf('$r2'),
  117. DagNode('addu', '$rd', DagLeaf('$r1'), DagLeaf('$r2'))]
  118. self.assertEqualDag(dag, expect)
  119. # def test_dag_combinednode(self):
  120. # dag = Dag(B([S('command', 'mult', '$rd1', '$r1', '$r2'),
  121. # S('command', 'mult', '$rd2', '$r1', '$r2')]))
  122. # expect = Dag([])
  123. # multnode = DagNode('mult',
  124. # DagLeaf('$r1'),
  125. # DagLeaf('$r2'))
  126. # multnode.labels = ['$rd1', '$rd2']
  127. # expect.nodes = [DagLeaf('$r1'),
  128. # DagLeaf('$r2'),
  129. # multnode]
  130. #
  131. # self.assertEqualDag(dag, expect)
  132. def assertEqualDag(self, dag1, dag2):
  133. self.assertEqual(len(dag1.nodes), len(dag2.nodes))
  134. for node1, node2 in zip(dag1.nodes, dag2.nodes):
  135. self.assertEqualNodes(node1, node2)
  136. def assertEqualNodes(self, node1, node2):
  137. if isinstance(node1, DagLeaf):
  138. self.assertIsInstance(node2, DagLeaf)
  139. self.assertEqual(node1.reg, node2.reg)
  140. elif isinstance(node2, DagLeaf):
  141. raise AssertionError
  142. else:
  143. self.assertEqual(node1.op, node2.op)
  144. self.assertEqual(node1.labels, node2.labels)
  145. self.assertEqual(len(node1.nodes), len(node2.nodes))
  146. for child1, child2 in zip(node1.nodes, node2.nodes):
  147. self.assertEqualNodes(child1, child2)