def get_bound_super_ctxt_inner(split, call_ctxt, no_splitting=(False, None)): first_f = trace_refute.identify_function([], (call_ctxt + [split])[:1]) call_sites = all_call_sites(first_f) if function_limit(first_f) == 0: return (0, "FunctionLimit") safe_call_sites = [cs for cs in call_sites if ctxt_within_function_limits([cs] + call_ctxt)] if call_sites and not safe_call_sites: return (0, "FunctionLimit") if len(call_ctxt) < 3 and len(safe_call_sites) == 1: call_ctxt2 = list(safe_call_sites) + call_ctxt if call_ctxt_computable(split, call_ctxt2): return get_bound_super_ctxt(split, call_ctxt2) fname = trace_refute.identify_function(call_ctxt, [split]) bound = function_limit_bound(fname, split) if bound: return bound bound = get_bound_ctxt(split, call_ctxt) if bound: return bound if no_splitting[0]: assert no_splitting[1], no_splitting no_splitting[1][0] = True return None # try to split over potential call sites if len(call_ctxt) >= 3: return None if len(call_sites) == 0: # either entry point or nonsense return None if [call_site for call_site in safe_call_sites if not call_ctxt_computable(split, [call_site] + call_ctxt)]: return None anc_bounds = [ get_bound_super_ctxt(split, [call_site] + call_ctxt, no_splitting=True) for call_site in safe_call_sites ] if None in anc_bounds: return None (bound, kind) = max(anc_bounds) return (bound, "MergedBound")
def call_ctxt_computable(split, call_ctxt): fs = [ trace_refute.identify_function([], [call_site]) for call_site in call_ctxt ] non_computable = [f for f in fs if trace_refute.has_complex_loop(f)] if non_computable: trace('avoiding functions with complex loops: %s' % non_computable) return not non_computable
def get_call_ctxt_problem(split, call_ctxt, timing=True): # time this for diagnostic reasons start = time.time() from trace_refute import identify_function, build_compound_problem_with_links f = identify_function(call_ctxt, [split]) for (ctxt2, p, hyps, addr_map) in call_ctxt_problems: if ctxt2 == (call_ctxt, f): return (p, hyps, addr_map) (p, hyps, addr_map) = build_compound_problem_with_links(call_ctxt, f) if avoid_C_information[0]: hyps = [h for h in hyps if not has_C_information(p, h)] call_ctxt_problems.append(((call_ctxt, f), p, hyps, addr_map)) del call_ctxt_problems[:-20] end = time.time() if timing: save_extra_timing('GetProblem', call_ctxt + [split], end - start) return (p, hyps, addr_map)
def get_call_ctxt_problem (split, call_ctxt, timing = True): # time this for diagnostic reasons start = time.time () from trace_refute import identify_function, build_compound_problem_with_links f = identify_function (call_ctxt, [split]) for (ctxt2, p, hyps, addr_map) in call_ctxt_problems: if ctxt2 == (call_ctxt, f): return (p, hyps, addr_map) (p, hyps, addr_map) = build_compound_problem_with_links (call_ctxt, f) if avoid_C_information[0]: hyps = [h for h in hyps if not has_C_information (p, h)] call_ctxt_problems.append(((call_ctxt, f), p, hyps, addr_map)) del call_ctxt_problems[: -20] end = time.time () if timing: save_extra_timing ('GetProblem', call_ctxt + [split], end - start) return (p, hyps, addr_map)
def call_ctxt_computable(split, call_ctxt): fs = [trace_refute.identify_function([], [call_site]) for call_site in call_ctxt] return not ([f for f in fs if trace_refute.has_complex_loop(f)])
def get_bound_super_ctxt_inner(split, call_ctxt, no_splitting=(False, None)): first_f = trace_refute.identify_function([], (call_ctxt + [split])[:1]) call_sites = all_call_sites(first_f) if function_limit(first_f) == 0: return (0, 'FunctionLimit') safe_call_sites = [ cs for cs in call_sites if ctxt_within_function_limits([cs] + call_ctxt) ] if call_sites and not safe_call_sites: return (0, 'FunctionLimit') if len(call_ctxt) < 3 and len(safe_call_sites) == 1: call_ctxt2 = list(safe_call_sites) + call_ctxt if call_ctxt_computable(split, call_ctxt2): trace('using unique calling context %s' % str((split, call_ctxt2))) return get_bound_super_ctxt(split, call_ctxt2) fname = trace_refute.identify_function(call_ctxt, [split]) bound = function_limit_bound(fname, split) if bound: return bound bound = get_bound_ctxt(split, call_ctxt) if bound: return bound trace('no bound found immediately.') if no_splitting[0]: assert no_splitting[1], no_splitting no_splitting[1][0] = True trace('cannot split by context (recursion).') return None # try to split over potential call sites if len(call_ctxt) >= 3: trace('cannot split by context (context depth).') return None if len(call_sites) == 0: # either entry point or nonsense trace('cannot split by context (reached top level).') return None problem_sites = [ call_site for call_site in safe_call_sites if not call_ctxt_computable(split, [call_site] + call_ctxt) ] if problem_sites: trace('cannot split by context (issues in %s).' % problem_sites) return None anc_bounds = [ get_bound_super_ctxt(split, [call_site] + call_ctxt, no_splitting=True) for call_site in safe_call_sites ] if None in anc_bounds: return None (bound, kind) = max(anc_bounds) return (bound, 'MergedBound')