def test_optimize_code_with_different_operator(self): as_tree = ast.parse( ms("""\ c = d + e d = d + e f = g | h i = s ^ 3 k = g | h p = s ^ 3 q = 3 < x l = 3 < x""")) lvn_test = Lvn() ssa_code = SsaCode(as_tree) ssa_code = lvn_test.optimize(ssa_code) self.assertEqual( str(ssa_code), ms("""\ c_0 = d_0 + e_0 d_1 = c_0 f_0 = g_0 | h_0 i_0 = s_0 ^ 3 k_0 = f_0 p_0 = i_0 q_0 = 3 < x_0 l_0 = q_0 """))
def test_enumerate_given_multiple_time(self): as_tree = ast.parse( ms("""\ a = 3 # a = 0 a = 4 # a = 1 a = b # b = 2, a = 3 a = c # c = 4, a = 5 a = d # d = 6, a = 7 """)) ssa_code = SsaCode(as_tree) lvn_dict = LvnDict() for ssa in ssa_code: lvn_dict.variable_dict.enumerate(ssa) expected_value_dict = { 'a_0': 1, 'a_1': 3, 'a_2': 5, 'b_0': 4, 'c_0': 6, 'a_3': 7, 'd_0': 8, 'a_4': 9, '3': 0, '4': 2 } self.assertDictEqual(lvn_dict.variable_dict, expected_value_dict)
def test_enumerate_given_a_update(self): as_tree = ast.parse( ms("""\ a = x + y b = x + y a = 2 c = x + y d = 3 + x f = y + 4""")) ssa_code = SsaCode(as_tree) lvn_dict = LvnDict() for ssa in ssa_code: lvn_dict.variable_dict.enumerate(ssa) expected_value_dict = { 'a_0': 2, 'x_0': 0, 'y_0': 1, 'b_0': 3, '2': 4, 'a_1': 5, 'c_0': 6, '3': 7, 'd_0': 8, '4': 9, 'f_0': 10 } self.assertDictEqual(lvn_dict.variable_dict, expected_value_dict)
def test_optimize_code_with_variable_redefinition_expect_not_update(self): """ x gets redefined at 3rd statement, result in the 4th statement not optimized :return: """ as_tree = ast.parse( ms("""\ c = d + e e = 5 d = d + e d = d + e c = d + e c = d + e""")) lvn_test = Lvn() ssa_code = SsaCode(as_tree) ssa_code = lvn_test.optimize(ssa_code) self.assertEqual( str(ssa_code), ms("""\ c_0 = d_0 + e_0 e_1 = 5 d_1 = d_0 + 5 d_2 = 5 + d_1 c_1 = 5 + d_2 """))
def test_ssa_all_valid_expressions(self): as_tree = ast.parse( ms("""\ a = b + c d = 2 * e f = g / 3 h = - 4 i = + j k = 1 < 3 l = k | m n = o ^ 2""")) ssa_code = SsaCode(as_tree) self.assertEqual( str(ssa_code), ms("""\ a_0 = b_0 Add c_0 d_0 = 2 Mult e_0 f_0 = g_0 Div 3 h_0 = USub 4 i_0 = UAdd j_0 k_0 = 1 Lt 3 l_0 = k_0 BitOr m_0 n_0 = o_0 BitXor 2 """))
def test_get_lvn_stmt_all_possibilities(self): as_tree = ast.parse( ms("""\ a = b + 4 # 2 = 0 + 1 c = 33 + d # 5 = 3 + 4 e = f + g # 8 = 6 + 7 h = 24 # ... i = j k = - 38 l = - m """)) ssa_code = SsaCode(as_tree) lvn_dict = LvnDict() lvn_stmt_list = [] for ssa in ssa_code: lvn_dict.variable_dict.enumerate(ssa) lvn_stmt = lvn_dict.get_lvn_stmt(ssa) lvn_stmt_list.append(lvn_stmt) expected_lvn_stmt_list = [(2, 0, 'Add', 1), (5, 3, 'Add', 4), (8, 6, 'Add', 7), (10, 9, None, None), (12, 11, None, None), (14, None, 'USub', 13), (16, None, 'USub', 15)] self.assert_lvn_stmt_list(lvn_stmt_list, *expected_lvn_stmt_list)
def test_ssa_generation_number(self): as_tree = ast.parse(ms("""\ z = 4""")) ssa_code = SsaCode(as_tree) expected_ssa_dict = {'z': 0, 4: 0} self.assertEqual(str(ssa_code), "z_0 = 4\n") self.assertDictEqual(ssa_code.var_version_list, expected_ssa_dict)
def test_ssa_generation_1_stmt(self): as_tree = ast.parse(ms("""\ z = a + y""")) ssa_code = SsaCode(as_tree) expected_ssa_dict = {'z': 0, 'a': 0, 'y': 0} self.assertEqual(str(ssa_code), "z_0 = a_0 Add y_0\n") self.assertDictEqual(ssa_code.var_version_list, expected_ssa_dict)
def test_optimize_redundant_stmt_1_stmt_d_d(self): as_tree = ast.parse(ms("""\ d = d""")) lvn_test = Lvn() ssa_code = SsaCode(as_tree) ssa_code = lvn_test.optimize(ssa_code) self.assertEqual(str(ssa_code), ms("""\ """))
def test_ssa_generation_2_stmt_expect_update_target(self): as_tree = ast.parse(ms("""\ z = a + y z = a""")) ssa_code = SsaCode(as_tree) expected_ssa_dict = {'z': [0, 1], 'a': [0], 'y': [0]} self.assertEqual(str(ssa_code), "z_0 = a_0 Add y_0\nz_1 = a_0\n") self.assertVariableVersionStack(ssa_code.var_version_list, expected_ssa_dict)
def test_optimize_redundant_stmt_2_stmt_a_a(self): as_tree = ast.parse(ms("""\ a = b a = a""")) lvn_test = Lvn() ssa_code = SsaCode(as_tree) ssa_code = lvn_test.optimize(ssa_code) self.assertEqual(str(ssa_code), ms("""\ a_0 = b_0 """))
def test_optimize_redundant_stmt_substituted(self): as_tree = ast.parse(ms("""\ d = a a = d""")) lvn_test = Lvn() ssa_code = SsaCode(as_tree) ssa_code = lvn_test.optimize(ssa_code) self.assertEqual(str(ssa_code), ms("""\ d_0 = a_0 """))
def test_optimize_simple_assignment_expect_substitute_single_var(self): as_tree = ast.parse(ms("""\ a = b c = a""")) lvn_test = Lvn() ssa_code = SsaCode(as_tree) ssa_code = lvn_test.optimize(ssa_code) self.assertEqual( str(ssa_code), ms("""\ a_0 = b_0 c_0 = b_0 """))
def test_optimize_reordering_operands_Sub_op_expect_no_subs(self): as_tree = ast.parse( ms("""\ a = b - c d = c - b""")) lvn_test = Lvn() ssa_code = SsaCode(as_tree) ssa_code = lvn_test.optimize(ssa_code) self.assertEqual( str(ssa_code), ms("""\ a_0 = b_0 - c_0 d_0 = c_0 - b_0 """))
def test_optimize_code_with_bin_op(self): as_tree = ast.parse( ms("""\ f = g | h k = g | j""")) lvn_test = Lvn() ssa_code = SsaCode(as_tree) ssa_code = lvn_test.optimize(ssa_code) self.assertEqual( str(ssa_code), ms("""\ f_0 = g_0 | h_0 k_0 = g_0 | j_0 """))
def test_optimize_code_with_xor(self): as_tree = ast.parse( ms("""\ f = g ^ 33 k = g ^ h""")) lvn_test = Lvn() ssa_code = SsaCode(as_tree) ssa_code = lvn_test.optimize(ssa_code) self.assertEqual( str(ssa_code), ms("""\ f_0 = g_0 ^ 33 k_0 = g_0 ^ h_0 """))
def test_optimize_code_with_2_lvn_stmt_same_expect_not_updated(self): as_tree = ast.parse( ms("""\ f = g + j # 0 + 1 k = g + 1 """)) lvn_test = Lvn() ssa_code = SsaCode(as_tree) ssa_code = lvn_test.optimize(ssa_code) self.assertEqual( str(ssa_code), ms("""\ f_0 = g_0 + j_0 k_0 = g_0 + 1 """))
def test_optimize_reordering_operands_BitOr_op(self): as_tree = ast.parse( ms("""\ a = b | c d = c | b""")) lvn_test = Lvn() ssa_code = SsaCode(as_tree) ssa_code = lvn_test.optimize(ssa_code) self.assertEqual( str(ssa_code), ms("""\ a_0 = b_0 | c_0 d_0 = a_0 """))
def test_ssa_generation_2_stmt(self): as_tree = ast.parse( ms("""\ z = a + y x = b + c""")) ssa_code = SsaCode(as_tree) expected_ssa_dict = {'z': 0, 'a': 0, 'y': 0, 'x': 0, 'b': 0, 'c': 0} self.assertEqual( str(ssa_code), ms("""\ z_0 = a_0 Add y_0 x_0 = b_0 Add c_0 """)) self.assertDictEqual(ssa_code.var_version_list, expected_ssa_dict)
def test_optimize_simple_assignment_given_3_stmt_same(self): as_tree = ast.parse( ms("""\ a=3 b=a c=b""")) lvn_test = Lvn() ssa_code = SsaCode(as_tree) ssa_code = lvn_test.optimize(ssa_code) self.assertEqual( str(ssa_code), ms("""\ a_0 = 3 b_0 = 3 c_0 = 3 """))
def test_get_lvn_stmt_given_const(self): as_tree = ast.parse( ms("""\ c = 33 # 1 = 0 a = c + d # 3 = 1 + 2 """)) ssa_code = SsaCode(as_tree) lvn_dict = LvnDict() lvn_stmt_list = [] for ssa in ssa_code: lvn_dict.variable_dict.enumerate(ssa) lvn_stmt = lvn_dict.get_lvn_stmt(ssa) lvn_stmt_list.append((lvn_stmt)) expected_lvn_stmt_list = [(1, 0, None, None), (3, 1, 'Add', 2)] self.assert_lvn_stmt_list(lvn_stmt_list, *expected_lvn_stmt_list)
def test_optimize_simple_assignment_expect_substituted(self): as_tree = ast.parse( ms("""\ z = a + y b = a c = b d = c + y""")) lvn_test = Lvn() ssa_code = SsaCode(as_tree) ssa_code = lvn_test.optimize(ssa_code) self.assertEqual( str(ssa_code), ms("""\ z_0 = a_0 + y_0 b_0 = a_0 c_0 = a_0 d_0 = z_0 """))
def test_optimize_simple_assignment_given_constant(self): as_tree = ast.parse( ms("""\ a = 33 + y b = 33 c = b d = c + y""")) lvn_test = Lvn() ssa_code = SsaCode(as_tree) ssa_code = lvn_test.optimize(ssa_code) self.assertEqual( str(ssa_code), ms("""\ a_0 = 33 + y_0 b_0 = 33 c_0 = 33 d_0 = a_0 """))
def test_optimize_simple_assignment_expect_constant_folding(self): as_tree = ast.parse( ms("""\ a = 5 b = a c = b + 9 d = b * c""")) lvn_test = Lvn() ssa_code = SsaCode(as_tree) ssa_code = lvn_test.optimize(ssa_code) self.assertEqual( str(ssa_code), ms("""\ a_0 = 5 b_0 = 5 c_0 = 14 d_0 = 70 """))
def lvn_code_to_ssa_code(self): ssa_code = SsaCode() for lvn_code_tuple in self.lvn_dict.lvn_code_tuples_list: target, left, op, right = None, None, None, None target = self.lvn_dict.variable_dict.val_num_var_list[ lvn_code_tuple[0]] # left is constant left = self.lvn_dict.variable_dict.val_num_var_list[ lvn_code_tuple[1]] if lvn_code_tuple[2] is not None and lvn_code_tuple[3] is not None: op = self.get_real_operator(lvn_code_tuple[2]) right = self.lvn_dict.variable_dict.val_num_var_list[ lvn_code_tuple[3]] ssa = Ssa(target, left, op, right) ssa_code.code_list.append(ssa) return ssa_code
def test_optimize_redundant_stmt_2_stmt(self): as_tree = ast.parse( ms("""\ d = b + 0 e = b f = b - 0 g = c * 0""")) lvn_test = Lvn() ssa_code = SsaCode(as_tree) ssa_code = lvn_test.optimize(ssa_code) self.assertEqual( str(ssa_code), ms("""\ d_0 = b_0 e_0 = b_0 f_0 = b_0 g_0 = 0 """))
def test_ssa_generation_2_stmt_expect_update_target_multiple_time(self): as_tree = ast.parse( ms("""\ z = a + y z = a + y z = a a = y""")) ssa_code = SsaCode(as_tree) expected_ssa_dict = {'z': 2, 'a': 1, 'y': 0} self.assertEqual( str(ssa_code), ms("""\ z_0 = a_0 Add y_0 z_1 = a_0 Add y_0 z_2 = a_0 a_1 = y_0 """)) self.assertDictEqual(ssa_code.var_version_list, expected_ssa_dict)
def test_optimize_simple_assignment_expect_constant_fold_and_replaced( self): as_tree = ast.parse( ms("""\ a = 14 + c d = 8 e = d + 6 # is 14 f = e + c""")) lvn_test = Lvn() ssa_code = SsaCode(as_tree) ssa_code = lvn_test.optimize(ssa_code) self.assertEqual( str(ssa_code), ms("""\ a_0 = 14 + c_0 d_0 = 8 e_0 = 14 f_0 = a_0 """))
def test_optimize_simple_assignment_given_all_possible_combination(self): as_tree = ast.parse( ms("""\ z = l a = x + y b = 33 c = y + 11 d = 34 + f""")) lvn_test = Lvn() ssa_code = SsaCode(as_tree) ssa_code = lvn_test.optimize(ssa_code) self.assertEqual( str(ssa_code), ms("""\ z_0 = l_0 a_0 = x_0 + y_0 b_0 = 33 c_0 = y_0 + 11 d_0 = 34 + f_0 """))
def test_ssa_all_valid_expressions(self): as_tree = ast.parse( ms("""\ c = d + e e = 5 d = d + e d = d + e c = d + e c = d + e""")) ssa_code = SsaCode(as_tree) self.assertEqual( str(ssa_code), ms("""\ c_0 = d_0 Add e_0 e_1 = 5 d_1 = d_0 Add e_1 d_2 = d_1 Add e_1 c_1 = d_2 Add e_1 c_2 = d_2 Add e_1 """))