(self, graph, entry_node)
Find post-dominators for each node in the graph.

        This implementation is based on paper A Fast Algorithm for Finding Dominators in a Flow Graph by Thomas
        Lengauer and Robert E. Tarjan from Stanford University, ACM Transactions on Programming Languages and Systems,
        Vol. 1, No. 1, July 1979
Find post-dominators for each node in the graph.
Find post - dominators for each node in the graph .
def _construct(self, graph, entry_node):
        """
        Find post-dominators for each node in the graph.

        This implementation is based on paper A Fast Algorithm for Finding Dominators in a Flow Graph by Thomas
        Lengauer and Robert E. Tarjan from Stanford University, ACM Transactions on Programming Languages and Systems,
        Vol. 1, No. 1, July 1979
        """

        # Step 1

        _prepared_graph, vertices, parent = self._prepare_graph(graph, entry_node)
        # vertices is a list of ContainerNode instances
        # parent is a dict storing the mapping from ContainerNode to ContainerNode
        # Each node in prepared_graph is a ContainerNode instance

        bucket = defaultdict(set)
        dom = [None] * (len(vertices))
        self._ancestor = [None] * (len(vertices) + 1)

        for i in range(len(vertices) - 1, 0, -1):
            w = vertices[i]

            # Step 2
            if w not in parent:
                # It's one of the start nodes
                continue

            predecessors = _prepared_graph.predecessors(w)
            for v in predecessors:
                u = self._pd_eval(v)
                if self._semi[u.index].index < self._semi[w.index].index:
                    self._semi[w.index] = self._semi[u.index]

            bucket[vertices[self._semi[w.index].index].index].add(w)

            self._pd_link(parent[w], w)

            # Step 3
            for v in bucket[parent[w].index]:
                u = self._pd_eval(v)
                if self._semi[u.index].index < self._semi[v.index].index:
                    dom[v.index] = u
                else:
                    dom[v.index] = parent[w]

            bucket[parent[w].index].clear()

        for i in range(1, len(vertices)):
            w = vertices[i]
            if w not in parent:
                continue
            if dom[w.index].index != vertices[self._semi[w.index].index].index:
                dom[w.index] = dom[dom[w.index].index]

        self.dom = networkx.DiGraph()  # The post-dom tree described in a directional graph
        for i in range(1, len(vertices)):
            if dom[i] is not None and vertices[i] is not None:
                self.dom.add_edge(dom[i].obj, vertices[i].obj)

        # Output
        self.prepared_graph = _prepared_graph
def _construct ( self , graph , entry_node ) : # Step 1 _prepared_graph , vertices , parent = self . _prepare_graph ( graph , entry_node ) # vertices is a list of ContainerNode instances # parent is a dict storing the mapping from ContainerNode to ContainerNode # Each node in prepared_graph is a ContainerNode instance bucket = defaultdict ( set ) dom = [ None ] * ( len ( vertices ) ) self . _ancestor = [ None ] * ( len ( vertices ) + 1 ) for i in range ( len ( vertices ) - 1 , 0 , - 1 ) : w = vertices [ i ] # Step 2 if w not in parent : # It's one of the start nodes continue predecessors = _prepared_graph . predecessors ( w ) for v in predecessors : u = self . _pd_eval ( v ) if self . _semi [ u . index ] . index < self . _semi [ w . index ] . index : self . _semi [ w . index ] = self . _semi [ u . index ] bucket [ vertices [ self . _semi [ w . index ] . index ] . index ] . add ( w ) self . _pd_link ( parent [ w ] , w ) # Step 3 for v in bucket [ parent [ w ] . index ] : u = self . _pd_eval ( v ) if self . _semi [ u . index ] . index < self . _semi [ v . index ] . index : dom [ v . index ] = u else : dom [ v . index ] = parent [ w ] bucket [ parent [ w ] . index ] . clear ( ) for i in range ( 1 , len ( vertices ) ) : w = vertices [ i ] if w not in parent : continue if dom [ w . index ] . index != vertices [ self . _semi [ w . index ] . index ] . index : dom [ w . index ] = dom [ dom [ w . index ] . index ] self . dom = networkx . DiGraph ( ) # The post-dom tree described in a directional graph for i in range ( 1 , len ( vertices ) ) : if dom [ i ] is not None and vertices [ i ] is not None : self . dom . add_edge ( dom [ i ] . obj , vertices [ i ] . obj ) # Output self . prepared_graph = _prepared_graph