def test_insert_phi_function_pruned_given_2_df(self): """ Note: '|' with no arrows means pointing down GIVEN: block B has 2 DF nodes, C and D. Definition in B will force phi function in C and D A --- / \ | B | | / \ | | | C | \ | D --- """ blocks, ast_string = th.build_blocks_arb(block_links={ 'A': ['B', 'C', 'D'], 'B': ['C', 'D'], 'C': [], 'D': [] }, code={ 'A': ms("""\ temp = 1 phi_var = 1 """), 'B': ms("""\ phi_var= 2 """), 'C': ms("""\ x = phi_var """), 'D': ms("""\ y = phi_var """) }) as_tree = ast.parse(ast_string) cfg_real = Cfg() cfg_real.block_list = blocks cfg_real.as_tree = as_tree cfg_real.root = cfg_real.block_list[0] cfg_real.fill_df() cfg_real.gather_initial_info() cfg_real.compute_live_out() cfg_real.ins_phi_function_pruned() expected_phi_list = { 'A': set(), 'B': set(), 'C': {'phi_var'}, 'D': {'phi_var'} } self.assertPhiListEqual(cfg_real.block_list, expected_phi_list)
def test_compute_liveout_given_5_blocks(self): blocks, ast_string = th.build_blocks_arb(block_links={ 'A': ['B'], 'B': ['C', 'D'], 'C': ['D'], 'D': ['E', 'B'], 'E': [] }, code={ 'A': ms("""\ i = 1 """), 'B': ms("""\ if i < 0: pass """), 'C': ms("""\ s = 0 """), 'D': ms("""\ s = s + i i = i + 1 if i < 0: pass """), 'E': ms("""\ if s < 3: pass """) }) as_tree = ast.parse(ast_string) cfg_real = Cfg() cfg_real.block_list = blocks cfg_real.as_tree = as_tree cfg_real.root = cfg_real.block_list[0] cfg_real.gather_initial_info() cfg_real.compute_live_out() expected_live_out = { 'A': {'s', 'i'}, 'B': {'s', 'i'}, 'C': {'s', 'i'}, 'D': {'s', 'i'}, 'E': set() } self.assertLiveOutEqual(cfg_real.block_list, expected_live_out)
def test_initial_info_given_3_simple_stmt_given_if(self): as_tree = ast.parse( ms("""\ a = 3 if c < 3: y = a + b x, y = a, b """)) cfg_real = Cfg(as_tree) cfg_real.gather_initial_info() expected_ue_var = ({'c'}, {'a', 'b'}) expected_var_kill = ({'a'}, {'y', 'x'}) self.assertUeVarKill(cfg_real.block_list, expected_ue_var, expected_var_kill) expected_globals_var = {'b', 'a', 'c'} self.assertSetEqual(cfg_real.globals_var, expected_globals_var) expected_block_set = { 'x': [cfg_real.block_list[1]], 'a': [cfg_real.block_list[0]], 'y': [cfg_real.block_list[1]] } self.assertDictEqual(cfg_real.block_set, expected_block_set)
def test_initial_info_given_3_simple_stmt_expect_ue_a_vk_a_y_x(self): as_tree = ast.parse( ms("""\ a = 3 y = a + b x, y = a, b """)) cfg_real = Cfg(as_tree) cfg_real.gather_initial_info() expected_ue_var = {'b'} expected_var_kill = {'a', 'y', 'x'} self.assertSetEqual(cfg_real.block_list[0].ue_var, expected_ue_var) self.assertSetEqual(cfg_real.block_list[0].var_kill, expected_var_kill) expected_globals_var = {'b'} self.assertSetEqual(cfg_real.globals_var, expected_globals_var) expected_block_set = { 'x': [cfg_real.block_list[0]], 'a': [cfg_real.block_list[0]], 'y': [cfg_real.block_list[0]] } self.assertDictEqual(cfg_real.block_set, expected_block_set)
def test_VarAst_given_simple_assign(self): as_tree = ast.parse( ms("""\ y = a + b """)) var_ast = VarAst(as_tree.body[0]) self.assertListEqual(var_ast.targets_var, ['y']) self.assertListEqual(var_ast.values_var, ['a', 'b']) self.assertEqual(var_ast.target_op, "Assign") self.assertEqual(var_ast.body_op, "Add")
def test_VarAst_given_while_stmt(self): as_tree = ast.parse( ms("""\ while a > c: useless_var = 3 """)) var_ast = VarAst(as_tree.body[0]) self.assertListEqual(var_ast.targets_var, []) self.assertListEqual(var_ast.values_var, ['a', 'c']) self.assertEqual(var_ast.target_op, "While") self.assertEqual(var_ast.body_op, "Gt")
def test_VarAst_given_if_stmt(self): as_tree = ast.parse( ms("""\ if a < b: pass """)) var_ast = VarAst(as_tree.body[0]) self.assertListEqual(var_ast.targets_var, []) self.assertListEqual(var_ast.values_var, ['a', 'b']) self.assertEqual(var_ast.target_op, "If") self.assertEqual(var_ast.body_op, "Lt")
def test_insert_phi_function_pruned_4_blocks(self): blocks, ast_string = th.build_blocks_arb(block_links={ 'A': ['B', 'C'], 'B': ['D'], 'C': ['D'], 'D': [] }, code={ 'A': ms("""\ pass """), 'B': ms("""\ var = 3 """), 'C': ms("""\ pass """), 'D': ms("""\ if var < 3: pass """) }) as_tree = ast.parse(ast_string) cfg_real = Cfg() cfg_real.block_list = blocks cfg_real.as_tree = as_tree cfg_real.root = cfg_real.block_list[0] cfg_real.fill_df() cfg_real.gather_initial_info() cfg_real.compute_live_out() cfg_real.ins_phi_function_pruned() expected_phi_list = {'A': set(), 'B': set(), 'C': set(), 'D': {'var'}} self.assertPhiListEqual(cfg_real.block_list, expected_phi_list)
def test_VarAst_given_3(self): as_tree = ast.parse( ms("""\ z = 33 """)) var_ast = VarAst(as_tree.body[0]) self.assertListEqual(var_ast.targets_var, ['z']) self.assertListEqual(var_ast.values_var, []) self.assertEqual(var_ast.target_op, "Assign") self.assertEqual(var_ast.body_op, None) self.assertEqual(var_ast.left_operand, 33) self.assertEqual(var_ast.right_operand, None)
def test_VarAst_given_b_const_3(self): as_tree = ast.parse( ms("""\ z = b + 3 """)) var_ast = VarAst(as_tree.body[0]) self.assertListEqual(var_ast.targets_var, ['z']) self.assertListEqual(var_ast.values_var, ['b']) self.assertEqual(var_ast.target_op, "Assign") self.assertEqual(var_ast.body_op, "Add") self.assertEqual(var_ast.left_operand, 'b') self.assertEqual(var_ast.right_operand, 3)
def test_get_ast_stmt_from_block_given_if(self): as_tree = ast.parse( ms("""\ a = 3 if a < 3: x, y = a, b """)) block_1 = RawBasicBlock(1, 3) cfg_holder = Cfg() cfg_holder.as_tree = as_tree tuples_list_real = [(x, y) for x, y in cfg_holder.get_var_ast(block_1)] tuples_list_expected = [(['a'], []), ([], ['a']), (['x', 'y'], ['a', 'b'])] self.assertListEqual(tuples_list_expected, tuples_list_real)
def test_insert_phi_function(self): as_tree = ast.parse( ms("""\ a = 3 # 1st if a > 3: # | a = 3 # 2nd b = 3 else: # 3rd z = 4 # | # expected phi func for 'a' here y = a # 4th """)) cfg_real = Cfg(as_tree) cfg_real.fill_df() cfg_real.gather_initial_info() cfg_real.ins_phi_function_semi_pruned() expected_phi_list_for_block_3 = {'a'} self.assertSetEqual(cfg_real.block_list[-1].phi, expected_phi_list_for_block_3)
def test_insert_phi_function_semi_pruned(self): """ Note: '|' with no arrows means pointing down A | B <------| / \ | C F | | / \ | | G I | | \ / | | H | \ / | D-----------| | E """ blocks, ast_string = th.build_blocks_arb(block_links={ 'A': ['B'], 'B': ['C', 'F'], 'C': ['D'], 'D': ['E', 'B'], 'E': [], 'F': ['G', 'I'], 'G': ['H'], 'H': ['D'], 'I': ['H'] }, code={ 'A': ms("""\ i = 1 """), 'B': ms("""\ a = temp_0 c = temp_1 """), 'C': ms("""\ b = temp_2 c = temp_3 d = temp_4 """), 'D': ms("""\ y = a + b z = c + d i = i + 1 if i < 100: pass """), 'E': "return\n", 'F': ms("""\ a = temp_5 d = temp_6 if a < d: pass """), 'G': ms("""\ d = temp """), 'H': ms("""\ b = temp """), 'I': ms("""\ c = temp """) }) as_tree = ast.parse(ast_string) cfg_real = Cfg() cfg_real.block_list = blocks cfg_real.as_tree = as_tree cfg_real.root = cfg_real.block_list[0] cfg_real.fill_df() cfg_real.gather_initial_info() cfg_real.ins_phi_function_semi_pruned() expected_phi_list = { 'A': set(), 'B': {'a', 'b', 'c', 'd', 'i'}, 'C': set(), 'D': {'a', 'b', 'c', 'd'}, 'E': set(), 'F': set(), 'G': set(), 'H': {'c', 'd'}, 'I': set() } self.assertPhiListEqual(cfg_real.block_list, expected_phi_list)