'Find the loops defined by the graph\'s back edges.'

def _find_loops(self):

    bodies = {}
    for (src, dest) in self._back_edges:
        header = dest
        body = set([header])
        queue = [src]
        while queue:
            n = queue.pop()
            if (n not in body):
                body.add(n)
                queue.extend(self._preds[n])
        if (header in bodies):
            bodies[header].update(body)
        else:
            bodies[header] = body
    loops = {}
    for (header, body) in bodies.items():
        entries = set()
        exits = set()
        for n in body:
            entries.update((self._preds[n] - body))
            exits.update((self._succs[n] - body))
        loop = Loop(header=header, body=body, entries=entries, exits=exits)
        loops[header] = loop
    self._loops = loops
    in_loops = dict(((n, []) for n in self._nodes))
    for loop in sorted(loops.values(), key=(lambda loop: len(loop.body))):
        for n in loop.body:
            in_loops[n].append(loop.header)
    self._in_loops = in_loops
