def firstRoundExp(cargo_root,
                  old_fname,
                  new_fname,
                  all_line_nums,
                  arg=None,
                  test_times=5):
    genAllFirstRoundExp(cargo_root, old_fname, new_fname, all_line_nums)

    time_list = []
    for idx, line_num in enumerate(all_line_nums):
        dir_name = os.path.join(cargo_root, "explore-src-r1",
                                "exp-" + str(idx))
        exp_name = os.path.join(dir_name, "exp.exe")
        os.chdir(dir_name)
        time_exp, _, _ = runExpWithName(exp_name, arg, test_time=test_times)
        if time_exp is None:
            exit()

        print("Exp", idx, ",line: ", line_num, ":", time_exp)
        time_list.append(time_exp)

    impact_tuple = list(zip(all_line_nums, time_list))

    # ordered it in descending order
    impact_tuple.sort(key=lambda x: x[1], reverse=True)

    return impact_tuple
def secondRoundExp(cargo_root,
                   old_fname,
                   new_fname,
                   sorted_line_nums,
                   arg=None,
                   test_times=5):
    genAllSecondRoundExp(cargo_root, old_fname, new_fname, sorted_line_nums)

    cur_lines = []
    lines_list = []
    time_list = []
    top_error_list = []  # longer
    bottom_error_list = []  # shorter

    for idx, line_num in enumerate(sorted_line_nums):
        dir_name = os.path.join(cargo_root, "explore-src-r2",
                                "exp-" + str(idx))
        exp_name = os.path.join(dir_name, "exp.exe")
        os.chdir(dir_name)
        time_exp, shortest_run, longest_run = runExpWithName(
            exp_name, arg, test_time=test_times)
        if time_exp is None:
            exit()

        print("Exp", idx, ":", time_exp)
        cur_lines.append(line_num)
        time_list.append(time_exp)
        top_error_list.append(longest_run - time_exp)
        bottom_error_list.append(time_exp - shortest_run)
        lines_list.append(cur_lines.copy())

    final_tuple = list(
        zip(lines_list, time_list, top_error_list, bottom_error_list))

    return final_tuple
def quickTestExpWithName(idx, test_times=5, option=0):
    cargo_root = "/scratch/ziyangx/BoundsCheckExplorer/brotli-expand"
    arg = "/u/ziyangx/bounds-check/BoundsCheckExplorer/brotli-exp/silesia-5.brotli"
    dir_name = os.path.join(cargo_root, "explore-src-quick-test",
                            "exp-" + str(idx))
    exp_name = os.path.join(dir_name, "exp.exe")
    os.chdir(dir_name)
    time_exp = runExpWithName(exp_name, arg, test_time=test_times)
    # time_exp, shortest_run, longest_run = runExpWithName(exp_name, arg, test_time=test_times)
    # option 0, median, option 1, shortest, option 2 longest
    return time_exp[option]
def quickTest(
        unsafe_lines,
        arg="/u/ziyangx/bounds-check/BoundsCheckExplorer/brotli-exp/silesia-5.brotli",
        test_times=5):
    old_fname = "src/lib-unsafe.rs"
    new_fname = "src/lib.rs"
    cargo_root = "/scratch/ziyangx/BoundsCheckExplorer/brotli-expand"

    genSourceExp("explore", "quick-test", unsafe_lines)
    print("binary generated")
    exp_name = os.path.join(cargo_root, "baseline", "exp-quick-test/exp.exe")

    quick_result = runExpWithName(exp_name, arg, test_time=test_times)
    return quick_result
    transform("original-o3.bc", "bcrm-o3.bc")

    p = genExpNoLLVMPass("bcrm-o3.bc")
    p.wait()


if __name__ == '__main__':
    cargo_root, arg = argParse()

    # safe baseline
    genO3Bc(cargo_root)
    p = genExp("original.bc")
    p.wait()
    exp_name = os.path.join(cargo_root, "baseline", "exp-safe/exp.exe")
    # warm up
    runExpWithName(exp_name, arg, test_time=5)

    safe_time = runExpWithName(exp_name, arg, test_time=5)
    print("Safe baseline (O3 from O0):", safe_time)

    p = genExp("original-o3.bc")
    p.wait()
    exp_name = os.path.join(cargo_root, "baseline", "exp-safe/exp.exe")
    # warm up
    runExpWithName(exp_name, arg, test_time=5)

    safe_time = runExpWithName(exp_name, arg, test_time=5)
    print("Safe baseline (O3 from O3):", safe_time)

    p = genExpNoLLVMPass("original-o3.bc")
    p.wait()
    if p2_src is not None:
        with open(p2_src, 'rb') as fd:
            impact_obj = pickle.load(fd)

    # get all lines with unsafe
    os.chdir(cargo_root)
    line_nums = getUnsafeLines(old_fname)

    print("Running Corvair on ", len(line_nums), " bounds checks")

    # all safe baseline
    p = genSourceExpNB(cargo_root, "baseline", old_fname, new_fname, "safe",
                       [])
    p.wait()
    exp_name = os.path.join(cargo_root, "baseline", "exp-safe/exp.exe")
    safe_time = runExpWithName(exp_name, arg, test_time=test_times)
    print("Safe baseline:", safe_time)

    # all unsafe baseline
    p = genSourceExpNB(cargo_root, "baseline", old_fname, new_fname, "unsafe",
                       line_nums)
    p.wait()
    exp_name = os.path.join(cargo_root, "baseline", "exp-unsafe/exp.exe")
    unsafe_time = runExpWithName(exp_name, arg, test_time=test_times)
    print("Unsafe baseline:", unsafe_time)

    # remove cold baseline
    hot_lines = line_nums.copy()
    from ParseCallgrind import getColdLines
    rs_fname = "src/lib.rs"
    cold_lines = getColdLines(hot_lines, calout_fname, 1, single_file=rs_fname)