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_dominator_tree_given_13_blocks(self): """ |---------> R | / | \ | A <-- B C | | / \ | \ | D <-- E <- | ---- G | | | | F / \ | L | | | | J | \ | | \ | | | ----> H --| I <----| | \ / ----------------------> K ---/ """ blocks = self.build_blocks_arb( block_links={ 'A': ['B', 'C', 'H'], 'B': ['D'], 'C': ['B', 'D', 'F'], 'D': ['E'], 'E': ['G'], 'F': ['G'], 'G': ['F', 'M'], 'H': ['I', 'J'], 'I': ['L'], 'J': ['K', 'L'], 'K': ['L'], 'L': ['M'], 'M': ['A', 'L'] }) cfg_real = Cfg() cfg_real.block_list = blocks cfg_real.root = blocks[0] dom_tree = DominatorTree(cfg_real) dom_tree.fill_dominates() dom_tree.build_tree() expected_blocks = self.build_blocks_arb( block_links={ 'A': ['B', 'C', 'D', 'F', 'G', 'H', 'L', 'M'], 'B': [], 'C': [], 'D': ['E'], 'E': [], 'F': [], 'G': [], 'H': ['I', 'J'], 'I': [], 'J': ['K'], 'K': [], 'L': [], 'M': [] }) self.assertBasicBlockListEqual(dom_tree.dominator_nodes, expected_blocks)
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_dominator_tree_given_complex_block(self): """ A | B <------| / \ | C F | | / \ | | G I | | \ / | | H | \ / | D-----------| | E """ blocks = self.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'] }) cfg_real = Cfg() cfg_real.block_list = blocks cfg_real.root = blocks[0] dom_tree = DominatorTree(cfg_real) dom_tree.fill_dominates() dom_tree.build_tree() expected_blocks = self.build_blocks_arb( block_links={ 'A': ['B'], 'B': ['C', 'D', 'F'], 'C': [], 'D': ['E'], 'E': [], 'F': ['G', 'H', 'I'], 'G': [], 'H': [], 'I': [] }) self.assertBasicBlockListEqual(dom_tree.dominator_nodes, expected_blocks)
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_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)