#!/usr/bin/env python3

"""A script to generate FileCheck statements for 'opt' analysis tests.

This script is a utility to update LLVM opt analysis test cases with new
FileCheck patterns. It can either update all of the tests in the file or
a single test function.

Example usage:
$ update_analyze_test_checks.py --opt=../bin/opt test/foo.ll

Workflow:
1. Make a compiler patch that requires updating some number of FileCheck lines
   in regression test files.
2. Save the patch and revert it from your local work area.
3. Update the RUN-lines in the affected regression tests to look canonical.
   Example: "; RUN: opt < %s -passes='print<cost-model>' -disable-output 2>&1 | FileCheck %s"
4. Refresh the FileCheck lines for either the entire file or select functions by
   running this script.
5. Commit the fresh baseline of checks.
6. Apply your patch from step 1 and rebuild your local binaries.
7. Re-run this script on affected regression tests.
8. Check the diffs to ensure the script has done something reasonable.
9. Submit a patch including the regression test diffs for review.

A common pattern is to have the script insert complete checking of every
instruction. Then, edit it down to only check the relevant instructions.
The script is designed to make adding checks to a test case fast, it is *not*
designed to be authoratitive about what constitutes a good test!
"""

from __future__ import print_function

from sys import stderr
from traceback import print_exc
import argparse
import os  # Used to advertise this file's name ("autogenerated_note").
import sys
import re

from UpdateTestChecks import common


def update_test(opt_basename: str, ti: common.TestInfo):
    triple_in_ir = None
    for l in ti.input_lines:
        m = common.TRIPLE_IR_RE.match(l)
        if m:
            triple_in_ir = m.groups()[0]
            break

    prefix_list = []
    for l in ti.run_lines:
        if "|" not in l:
            common.warn("Skipping unparsable RUN line: " + l)
            continue

        (tool_cmd, filecheck_cmd) = tuple([cmd.strip() for cmd in l.split("|", 1)])
        common.verify_filecheck_prefixes(filecheck_cmd)

        if not tool_cmd.startswith(opt_basename + " "):
            common.warn("WSkipping non-%s RUN line: %s" % (opt_basename, l))
            continue

        if not filecheck_cmd.startswith("FileCheck "):
            common.warn("Skipping non-FileChecked RUN line: " + l)
            continue

        tool_cmd_args = tool_cmd[len(opt_basename) :].strip()
        tool_cmd_args = tool_cmd_args.replace("< %s", "").replace("%s", "").strip()
        check_prefixes = common.get_check_prefixes(filecheck_cmd)

        # FIXME: We should use multiple check prefixes to common check lines. For
        # now, we just ignore all but the last.
        prefix_list.append((check_prefixes, tool_cmd_args))

    ginfo = common.make_analyze_generalizer(version=1)
    builder = common.FunctionTestBuilder(
        run_list=prefix_list,
        flags=type(
            "",
            (object,),
            {
                "verbose": ti.args.verbose,
                "filters": ti.args.filters,
                "function_signature": False,
                "check_attributes": False,
                "replace_value_regex": [],
            },
        ),
        scrubber_args=[],
        path=ti.path,
        ginfo=ginfo,
    )

    for prefixes, opt_args in prefix_list:
        common.debug("Extracted opt cmd:", opt_basename, opt_args, file=sys.stderr)
        common.debug("Extracted FileCheck prefixes:", str(prefixes), file=sys.stderr)

        raw_tool_outputs = common.invoke_tool(ti.args.opt_binary, opt_args, ti.path)

        if re.search(r"Printing analysis ", raw_tool_outputs) is not None:
            # Split analysis outputs by "Printing analysis " declarations.
            for raw_tool_output in re.split(r"Printing analysis ", raw_tool_outputs):
                builder.process_run_line(
                    common.ANALYZE_FUNCTION_RE,
                    common.scrub_body,
                    raw_tool_output,
                    prefixes,
                )
        elif (
            re.search(r"(LV|LDist): Checking a loop in ", raw_tool_outputs) is not None
        ):
            for raw_tool_output in re.split(
                r"(LV|LDist): Checking a loop in ", raw_tool_outputs
            ):
                builder.process_run_line(
                    common.LOOP_PASS_DEBUG_RE,
                    common.scrub_body,
                    raw_tool_output,
                    prefixes,
                )
        else:
            common.warn("Don't know how to deal with this output")
            continue

        builder.processed_prefixes(prefixes)

    func_dict = builder.finish_and_get_func_dict()
    is_in_function = False
    is_in_function_start = False
    prefix_set = set([prefix for prefixes, _ in prefix_list for prefix in prefixes])
    common.debug("Rewriting FileCheck prefixes:", str(prefix_set), file=sys.stderr)
    output_lines = []

    generated_prefixes = []
    for input_info in ti.iterlines(output_lines):
        input_line = input_info.line
        args = input_info.args
        if is_in_function_start:
            if input_line == "":
                continue
            if input_line.lstrip().startswith(";"):
                m = common.CHECK_RE.match(input_line)
                if not m or m.group(1) not in prefix_set:
                    output_lines.append(input_line)
                    continue

            # Print out the various check lines here.
            generated_prefixes.extend(
                common.add_analyze_checks(
                    output_lines,
                    ";",
                    prefix_list,
                    func_dict,
                    func_name,
                    ginfo,
                    is_filtered=builder.is_filtered(),
                )
            )
            is_in_function_start = False

        if is_in_function:
            if common.should_add_line_to_output(input_line, prefix_set):
                # This input line of the function body will go as-is into the output.
                output_lines.append(input_line)
            else:
                continue
            if input_line.strip() == "}":
                is_in_function = False
            continue

        # If it's outside a function, it just gets copied to the output.
        output_lines.append(input_line)

        m = common.IR_FUNCTION_RE.match(input_line)
        if not m:
            continue
        func_name = m.group(1)
        if ti.args.function is not None and func_name != ti.args.function:
            # When filtering on a specific function, skip all others.
            continue
        is_in_function = is_in_function_start = True

    if ti.args.gen_unused_prefix_body:
        output_lines.extend(
            ti.get_checks_for_unused_prefixes(prefix_list, generated_prefixes)
        )

    common.debug("Writing %d lines to %s..." % (len(output_lines), ti.path))

    with open(ti.path, "wb") as f:
        f.writelines(["{}\n".format(l).encode("utf-8") for l in output_lines])


def main():
    from argparse import RawTextHelpFormatter

    parser = argparse.ArgumentParser(
        description=__doc__, formatter_class=RawTextHelpFormatter
    )
    parser.add_argument(
        "--opt-binary",
        default="opt",
        help="The opt binary used to generate the test case",
    )
    parser.add_argument("--function", help="The function in the test file to update")
    parser.add_argument("tests", nargs="+")
    initial_args = common.parse_commandline_args(parser)

    script_name = os.path.basename(__file__)

    opt_basename = os.path.basename(initial_args.opt_binary)
    if opt_basename != "opt":
        common.error("Unexpected opt name: " + opt_basename)
        sys.exit(1)

    returncode = 0
    for ti in common.itertests(
        initial_args.tests, parser, script_name="utils/" + script_name
    ):
        try:
            update_test(opt_basename, ti)
        except Exception:
            stderr.write(f"Error: Failed to update test {ti.path}\n")
            print_exc()
            returncode = 1
    return returncode


if __name__ == "__main__":
    sys.exit(main())
