def fun_loops_info(fname): if fname in loops_info_cache: return loops_info_cache[fname] p = functions[fname].as_problem(problem.Problem) p.do_analysis() info = {} for l_id in p.loop_heads(): ext_reachable = [ n for n in p.loop_body(l_id) if [n2 for n2 in p.preds[n] if p.loop_id(n2) != l_id] ] if ext_reachable != [l_id]: trace("Loop in %s non-uniform, additional entries %s." % (fname, ext_reachable)) uniform = False elif problem.has_inner_loop(p, l_id): trace("Loop in %s non-uniform, inner loop." % fname) uniform = False else: assert is_addr(l_id), (fname, l_id) uniform = True for n in p.loop_body(l_id): info[n] = (l_id, uniform) loops_info_cache[fname] = info return info
def has_complex_loop(fname): if fname in has_complex_loop_cache: return has_complex_loop_cache[fname] p = functions[fname].as_problem(problem.Problem) p.do_analysis() result = bool([h for h in p.loop_heads() if problem.has_inner_loop(p, h)]) has_complex_loop_cache[fname] = result return result
def add_fun_to_loop_data_cache(fname): p = functions[fname].as_problem(problem.Problem) p.do_loop_analysis() for h in p.loop_heads(): addrs = [n for n in p.loop_body(h) if trace_refute.is_addr(n)] min_addr = min(addrs) for addr in addrs: addr_to_loop_id_cache[addr] = min_addr complex_loop_id_cache[min_addr] = problem.has_inner_loop(p, h) return min_addr
def get_loop_heads(fun): if not fun.entry: return [] p = fun.as_problem(problem.Problem) p.do_loop_analysis() loops = set() for h in p.loop_heads(): # any address in the loop will do. pick the smallest one addr = min([n for n in p.loop_body(h) if trace_refute.is_addr(n)]) loops.add((addr, fun.name, problem.has_inner_loop(p, h))) return list(loops)