(graph, end_node)
return region, region_head
Back track on the graph from `end_node` and find the longest chain of nodes where each node has only one
        predecessor and one successor (the last-but-two node may have two successors to account for the typical
        stack-canary-detection logic).

        :param end_node:    A node in the graph.
        :return:            A graph of nodes where the first node either has no predecessors or at least two
                            predecessors.
Back track on the graph from `end_node` and find the longest chain of nodes where each node has only one
        predecessor and one successor (the last-but-two node may have two successors to account for the typical
        stack-canary-detection logic).
Back track on the graph from end_node and find the longest chain of nodes where each node has only one predecessor and one successor ( the last - but - two node may have two successors to account for the typical stack - canary - detection logic ) .
def _single_entry_region(graph, end_node) -> Tuple[networkx.DiGraph, Any]:
        """
        Back track on the graph from `end_node` and find the longest chain of nodes where each node has only one
        predecessor and one successor (the last-but-two node may have two successors to account for the typical
        stack-canary-detection logic).

        :param end_node:    A node in the graph.
        :return:            A graph of nodes where the first node either has no predecessors or at least two
                            predecessors.
        """

        def _is_fork_node(node_) -> bool:
            """
            Check if the node and its successors form a "fork" region. A "fork" region is a region where:
            - The entry node has two successors,
            - Each successor has only the entry node as its predecessor.
            - Each successor has no successors.
            """

            succs = list(graph.successors(node_))
            if len(succs) != 2:
                return False
            for succ in succs:
                if graph.in_degree[succ] != 1:
                    return False
                if graph.out_degree[succ] != 0:
                    return False
            return True

        region = networkx.DiGraph()
        region.add_node(end_node)

        traversed = { end_node }
        node = end_node
        region_head = end_node
        while True:
            preds = list(graph.predecessors(node))
            if len(preds) != 1:
                break
            last_but_two_node = node is end_node

            pred_node = preds[0]

            if pred_node in traversed:
                break

            if last_but_two_node:
                if _is_fork_node(pred_node):
                    # add the entire "fork" to the region
                    for succ in graph.successors(pred_node):
                        region.add_edge(pred_node, succ)
                else:
                    break
            elif not last_but_two_node and graph.out_degree[pred_node] != 1:
                break

            region.add_edge(pred_node, node)
            traversed.add(pred_node)
            region_head = pred_node

        return region, region_head
def _single_entry_region ( graph , end_node ) -> Tuple [ networkx . DiGraph , Any ] : def _is_fork_node ( node_ ) -> bool : """
            Check if the node and its successors form a "fork" region. A "fork" region is a region where:
            - The entry node has two successors,
            - Each successor has only the entry node as its predecessor.
            - Each successor has no successors.
            """ succs = list ( graph . successors ( node_ ) ) if len ( succs ) != 2 : return False for succ in succs : if graph . in_degree [ succ ] != 1 : return False if graph . out_degree [ succ ] != 0 : return False return True region = networkx . DiGraph ( ) region . add_node ( end_node ) traversed = { end_node } node = end_node region_head = end_node while True : preds = list ( graph . predecessors ( node ) ) if len ( preds ) != 1 : break last_but_two_node = node is end_node pred_node = preds [ 0 ] if pred_node in traversed : break if last_but_two_node : if _is_fork_node ( pred_node ) : # add the entire "fork" to the region for succ in graph . successors ( pred_node ) : region . add_edge ( pred_node , succ ) else : break elif not last_but_two_node and graph . out_degree [ pred_node ] != 1 : break region . add_edge ( pred_node , node ) traversed . add ( pred_node ) region_head = pred_node return region , region_head