def _insert_dummy_exit_node(cfg: CFG) -> CFG: dummy_exit_node = pg.ProgramGraphNode(index=sys.maxsize, is_artificial=True) exit_nodes = cfg.exit_nodes if not exit_nodes and len(cfg.nodes) == 1: exit_nodes = cfg.nodes cfg.add_node(dummy_exit_node) for exit_node in exit_nodes: cfg.add_edge(exit_node, dummy_exit_node) return cfg
def _insert_dummy_entry_node(cfg: CFG) -> CFG: dummy_entry_node = pg.ProgramGraphNode(index=-1, is_artificial=True) entry_node = cfg.entry_node if not entry_node and len(cfg.nodes) == 1: entry_node = cfg.nodes.pop() # There is only one candidate to pop elif not entry_node: entry_node = [n for n in cfg.nodes if n.index == 0][0] cfg.add_node(dummy_entry_node) cfg.add_edge(dummy_entry_node, entry_node) return cfg
def _create_augmented_graph(graph: cfg.CFG) -> cfg.CFG: entry_node = graph.entry_node assert entry_node, "Cannot work with CFG without entry node" exit_nodes = graph.exit_nodes augmented_graph = graph.copy() start_node = pg.ProgramGraphNode(index=-sys.maxsize, is_artificial=True) augmented_graph.add_node(start_node) augmented_graph.add_edge(start_node, entry_node) for exit_node in exit_nodes: augmented_graph.add_edge(start_node, exit_node) return augmented_graph
def _create_nodes( blocks: ControlFlowGraph, ) -> Tuple[Dict[int, List[int]], Dict[int, pg.ProgramGraphNode]]: nodes: Dict[int, pg.ProgramGraphNode] = {} edges: Dict[int, List[int]] = {} for node_index, block in enumerate(blocks): node = pg.ProgramGraphNode(index=node_index, basic_block=block) nodes[node_index] = node if node_index not in edges: edges[node_index] = [] next_block = block.next_block if next_block: next_index = blocks.get_block_index(next_block) edges[node_index].append(next_index) if target_block := block.get_jump(): next_index = blocks.get_block_index(target_block) edges[node_index].append(next_index)