예제 #1
0
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")
예제 #2
0
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
예제 #3
0
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)
예제 #4
0
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)
예제 #5
0
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)])
예제 #6
0
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')