def _pd_construct(self):

        # Step 1

        _normalized_cfg, vertices, parent = self._pd_normalize_graph()
        # vertices is a list of ContainerNode(CFGNode) instances
        # parent is a dict storing the mapping from ContainerNode(CFGNode) to ContainerNode(CFGNode)
        # Each node in normalized_cfg is a ContainerNode(CFGNode) instance

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

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

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

            predecessors = _normalized_cfg.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 xrange(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._post_dom = networkx.DiGraph() # The post-dom tree described in a directional graph
        for i in xrange(1, len(vertices)):
            if dom[i] is not None and vertices[i] is not None:
                self._post_dom.add_edge(dom[i].obj, vertices[i].obj)

        self._pd_post_process()

        # Create the normalized_cfg without the annoying ContainerNodes
        self._normalized_cfg = networkx.DiGraph()
        for src, dst in _normalized_cfg.edges_iter():
            self._normalized_cfg.add_edge(src.obj, dst.obj)
QuerySet.distinct('field', ...) works
dataset/ETHPy150Open angr/angr/angr/analyses/cdg.py/CDG._pd_construct--crossover with--dataset/ETHPy150Open AppScale/appscale/AppServer/lib/django-1.5/tests/modeltests/distinct_on_fields/tests.py/DistinctOnTests.test_basic_distinct_on