Get all immediate dominators of sub graph from given node upwards.

        :param str node: id of the node to navigate forwards from.
        :param networkx.classes.digraph.DiGraph target_graph: graph to analyse, default is self.graph.
        :param bool reverse_graph: Whether the target graph should be reversed before analysation.

        :return: each node of graph as index values, with element as respective node's immediate dominator.
        :rtype: dict

def _immediate_dominators(self, node, target_graph=None, reverse_graph=False):
        """
        Get all immediate dominators of sub graph from given node upwards.

        :param str node: id of the node to navigate forwards from.
        :param networkx.classes.digraph.DiGraph target_graph: graph to analyse, default is self.graph.
        :param bool reverse_graph: Whether the target graph should be reversed before analysation.

        :return: each node of graph as index values, with element as respective node's immediate dominator.
        :rtype: dict
        """
        if target_graph is None:
            target_graph = self.graph

        if node not in target_graph:
            raise AngrCFGError('Target node %s is not in graph.' % node)

        graph = networkx.DiGraph(target_graph)
        if reverse_graph:
            # Reverse the graph without deepcopy
            for n in target_graph.nodes():
                graph.add_node(n)
            for src, dst in target_graph.edges():
                graph.add_edge(dst, src)

        idom = {node: node}

        order = list(networkx.dfs_postorder_nodes(graph, node))
        dfn = {u: i for i, u in enumerate(order)}
        order.pop()
        order.reverse()

        def intersect(u_, v_):
            """
            Finds the highest (in postorder valuing) point of intersection above two node arguments.

            :param str u_: nx node id.
            :param str v_: nx node id.
            :return: intersection of paths.
            :rtype: str
            """
            while u_ != v_:
                while dfn[u_] < dfn[v_]:
                    u_ = idom[u_]
                while dfn[u_] > dfn[v_]:
                    v_ = idom[v_]
            return u_

        changed = True
        while changed:
            changed = False
            for u in order:
                new_idom = reduce(intersect, (v for v in graph.pred[u] if v in idom))
                if u not in idom or idom[u] != new_idom:
                    idom[u] = new_idom
                    changed = True

        return idom