'Unroll loops for each function. The resulting CFG may still contain loops due to recursion, function calls, etc.
:param int max_loop_unrolling_times: The maximum iterations of unrolling.
:return: None'

def unroll_loops(self, max_loop_unrolling_times):

    if ((not isinstance(max_loop_unrolling_times, (int, long))) or (max_loop_unrolling_times < 0)):
        raise AngrCFGError(('Max    loop    unrolling    times    must    be    set    to    an    integer    greater    than    or    equal    to    0    if    ' + 'loop    unrolling    is    enabled.'))
    def _unroll(graph, loop):
        '\n                                                The    loop    callback    method    where    loops    are    unrolled.\n\n                                                :param    networkx.DiGraph    graph:    The    control    flow    graph.\n                                                :param    angr.analyses.loopfinder.Loop    loop:    The    loop    instance.\n                                                :return:    None\n                                                '
        for back_edge in loop.continue_edges:
            loop_body_addrs = set([n.addr for n in loop.body_nodes])
            src_blocknode = back_edge[0]
            dst_blocknode = back_edge[1]
            for src in self.get_all_nodes(src_blocknode.addr):
                for dst in graph.successors_iter(src):
                    if (dst.addr != dst_blocknode.addr):
                        continue
                    new_dst = dst.copy()
                    new_dst.looping_times = (dst.looping_times + 1)
                    if ((new_dst not in graph) and (new_dst.looping_times <= max_loop_unrolling_times)):
                        dst_successors = graph.successors(dst)
                        edge_data = graph.get_edge_data(src, dst)
                        graph.add_edge(src, new_dst, **edge_data)
                        for ds in dst_successors:
                            if ((ds.looping_times == 0) and (ds.addr not in loop_body_addrs)):
                                edge_data = graph.get_edge_data(dst, ds)
                                graph.add_edge(new_dst, ds, **edge_data)
                    graph.remove_edge(src, dst)
    self._detect_loops(loop_callback=_unroll)
