import argparse
import bisect
import collections
import copy
import glob
import os
import re
import subprocess
import sys
import shlex

from typing import List, Mapping, Set

##### Common utilities for update_*test_checks.py


_verbose = False
_prefix_filecheck_ir_name = ""

"""
Version changelog:

1: Initial version, used by tests that don't specify --version explicitly.
2: --function-signature is now enabled by default and also checks return
   type/attributes.
3: Opening parenthesis of function args is kept on the first LABEL line
   in case arguments are split to a separate SAME line.
4: --check-globals now has a third option ('smart'). The others are now called
   'none' and 'all'. 'smart' is the default.
5: Basic block labels are matched by FileCheck expressions
"""
DEFAULT_VERSION = 5


SUPPORTED_ANALYSES = {
    "Branch Probability Analysis",
    "Cost Model Analysis",
    "Dependence Analysis",
    "Loop Access Analysis",
    "Scalar Evolution Analysis",
}


class Regex(object):
    """Wrap a compiled regular expression object to allow deep copy of a regexp.
    This is required for the deep copy done in do_scrub.

    """

    def __init__(self, regex):
        self.regex = regex

    def __deepcopy__(self, memo):
        result = copy.copy(self)
        result.regex = self.regex
        return result

    def search(self, line):
        return self.regex.search(line)

    def sub(self, repl, line):
        return self.regex.sub(repl, line)

    def pattern(self):
        return self.regex.pattern

    def flags(self):
        return self.regex.flags


class Filter(Regex):
    """Augment a Regex object with a flag indicating whether a match should be
    added (!is_filter_out) or removed (is_filter_out) from the generated checks.

    """

    def __init__(self, regex, is_filter_out):
        super(Filter, self).__init__(regex)
        self.is_filter_out = is_filter_out

    def __deepcopy__(self, memo):
        result = copy.deepcopy(super(Filter, self), memo)
        result.is_filter_out = copy.deepcopy(self.is_filter_out, memo)
        return result


def parse_commandline_args(parser):
    class RegexAction(argparse.Action):
        """Add a regular expression option value to a list of regular expressions.
        This compiles the expression, wraps it in a Regex and adds it to the option
        value list."""

        def __init__(self, option_strings, dest, nargs=None, **kwargs):
            if nargs is not None:
                raise ValueError("nargs not allowed")
            super(RegexAction, self).__init__(option_strings, dest, **kwargs)

        def do_call(self, namespace, values, flags):
            value_list = getattr(namespace, self.dest)
            if value_list is None:
                value_list = []

            try:
                value_list.append(Regex(re.compile(values, flags)))
            except re.error as error:
                raise ValueError(
                    "{}: Invalid regular expression '{}' ({})".format(
                        option_string, error.pattern, error.msg
                    )
                )

            setattr(namespace, self.dest, value_list)

        def __call__(self, parser, namespace, values, option_string=None):
            self.do_call(namespace, values, 0)

    class FilterAction(RegexAction):
        """Add a filter to a list of filter option values."""

        def __init__(self, option_strings, dest, nargs=None, **kwargs):
            super(FilterAction, self).__init__(option_strings, dest, nargs, **kwargs)

        def __call__(self, parser, namespace, values, option_string=None):
            super(FilterAction, self).__call__(parser, namespace, values, option_string)

            value_list = getattr(namespace, self.dest)

            is_filter_out = option_string == "--filter-out"

            value_list[-1] = Filter(value_list[-1].regex, is_filter_out)

            setattr(namespace, self.dest, value_list)

    filter_group = parser.add_argument_group(
        "filtering",
        """Filters are applied to each output line according to the order given. The
    first matching filter terminates filter processing for that current line.""",
    )

    filter_group.add_argument(
        "--filter",
        action=FilterAction,
        dest="filters",
        metavar="REGEX",
        help="Only include lines matching REGEX (may be specified multiple times)",
    )
    filter_group.add_argument(
        "--filter-out",
        action=FilterAction,
        dest="filters",
        metavar="REGEX",
        help="Exclude lines matching REGEX",
    )

    parser.add_argument(
        "--include-generated-funcs",
        action="store_true",
        help="Output checks for functions not in source",
    )
    parser.add_argument(
        "-v", "--verbose", action="store_true", help="Show verbose output"
    )
    parser.add_argument(
        "-u",
        "--update-only",
        action="store_true",
        help="Only update test if it was already autogened",
    )
    parser.add_argument(
        "--force-update",
        action="store_true",
        help="Update test even if it was autogened by a different script",
    )
    parser.add_argument(
        "--enable",
        action="store_true",
        dest="enabled",
        default=True,
        help="Activate CHECK line generation from this point forward",
    )
    parser.add_argument(
        "--disable",
        action="store_false",
        dest="enabled",
        help="Deactivate CHECK line generation from this point forward",
    )
    parser.add_argument(
        "--replace-value-regex",
        nargs="+",
        default=[],
        help="List of regular expressions to replace matching value names",
    )
    parser.add_argument(
        "--prefix-filecheck-ir-name",
        default="",
        help="Add a prefix to FileCheck IR value names to avoid conflicts with scripted names",
    )
    parser.add_argument(
        "--global-value-regex",
        nargs="+",
        default=[],
        help="List of regular expressions that a global value declaration must match to generate a check (has no effect if checking globals is not enabled)",
    )
    parser.add_argument(
        "--global-hex-value-regex",
        nargs="+",
        default=[],
        help="List of regular expressions such that, for matching global value declarations, literal integer values should be encoded in hex in the associated FileCheck directives",
    )
    # FIXME: in 3.9, we can use argparse.BooleanOptionalAction. At that point,
    # we need to rename the flag to just -generate-body-for-unused-prefixes.
    parser.add_argument(
        "--no-generate-body-for-unused-prefixes",
        action="store_false",
        dest="gen_unused_prefix_body",
        default=True,
        help="Generate a function body that always matches for unused prefixes. This is useful when unused prefixes are desired, and it avoids needing to annotate each FileCheck as allowing them.",
    )
    # This is the default when regenerating existing tests. The default when
    # generating new tests is determined by DEFAULT_VERSION.
    parser.add_argument(
        "--version", type=int, default=1, help="The version of output format"
    )
    args = parser.parse_args()
    # TODO: This should not be handled differently from the other options
    global _verbose, _global_value_regex, _global_hex_value_regex
    _verbose = args.verbose
    _global_value_regex = args.global_value_regex
    _global_hex_value_regex = args.global_hex_value_regex
    return args


def parse_args(parser, argv):
    args = parser.parse_args(argv)
    if args.version >= 2:
        args.function_signature = True
    # TODO: This should not be handled differently from the other options
    global _verbose, _global_value_regex, _global_hex_value_regex
    _verbose = args.verbose
    _global_value_regex = args.global_value_regex
    _global_hex_value_regex = args.global_hex_value_regex
    if "check_globals" in args and args.check_globals == "default":
        args.check_globals = "none" if args.version < 4 else "smart"
    return args


class InputLineInfo(object):
    def __init__(self, line, line_number, args, argv):
        self.line = line
        self.line_number = line_number
        self.args = args
        self.argv = argv


class TestInfo(object):
    def __init__(
        self,
        test,
        parser,
        script_name,
        input_lines,
        args,
        argv,
        comment_prefix,
        argparse_callback,
    ):
        self.parser = parser
        self.argparse_callback = argparse_callback
        self.path = test
        self.args = args
        if args.prefix_filecheck_ir_name:
            global _prefix_filecheck_ir_name
            _prefix_filecheck_ir_name = args.prefix_filecheck_ir_name
        self.argv = argv
        self.input_lines = input_lines
        self.run_lines = find_run_lines(test, self.input_lines)
        self.comment_prefix = comment_prefix
        if self.comment_prefix is None:
            if self.path.endswith(".mir") or self.path.endswith(".txt"):
                self.comment_prefix = "#"
            elif self.path.endswith(".s"):
                self.comment_prefix = "//"
            else:
                self.comment_prefix = ";"
        self.autogenerated_note_prefix = self.comment_prefix + " " + UTC_ADVERT
        self.test_autogenerated_note = self.autogenerated_note_prefix + script_name
        self.test_autogenerated_note += get_autogennote_suffix(parser, self.args)
        self.test_unused_note = (
            self.comment_prefix + self.comment_prefix + " " + UNUSED_NOTE
        )

    def ro_iterlines(self):
        for line_num, input_line in enumerate(self.input_lines):
            args, argv = check_for_command(
                input_line, self.parser, self.args, self.argv, self.argparse_callback
            )
            yield InputLineInfo(input_line, line_num, args, argv)

    def iterlines(self, output_lines):
        output_lines.append(self.test_autogenerated_note)
        for line_info in self.ro_iterlines():
            input_line = line_info.line
            # Discard any previous script advertising.
            if input_line.startswith(self.autogenerated_note_prefix):
                continue
            self.args = line_info.args
            self.argv = line_info.argv
            if not self.args.enabled:
                output_lines.append(input_line)
                continue
            yield line_info

    def get_checks_for_unused_prefixes(
        self, run_list, used_prefixes: List[str]
    ) -> List[str]:
        run_list = [element for element in run_list if element[0] is not None]
        unused_prefixes = set(
            [prefix for sublist in run_list for prefix in sublist[0]]
        ).difference(set(used_prefixes))

        ret = []
        if not unused_prefixes:
            return ret
        ret.append(self.test_unused_note)
        for unused in sorted(unused_prefixes):
            ret.append(
                "{comment} {prefix}: {match_everything}".format(
                    comment=self.comment_prefix,
                    prefix=unused,
                    match_everything=r"""{{.*}}""",
                )
            )
        return ret


def itertests(
    test_patterns, parser, script_name, comment_prefix=None, argparse_callback=None
):
    for pattern in test_patterns:
        # On Windows we must expand the patterns ourselves.
        tests_list = glob.glob(pattern)
        if not tests_list:
            warn("Test file pattern '%s' was not found. Ignoring it." % (pattern,))
            continue
        for test in tests_list:
            with open(test) as f:
                input_lines = [l.rstrip() for l in f]
            first_line = input_lines[0] if input_lines else ""
            if UTC_AVOID in first_line:
                warn("Skipping test that must not be autogenerated: " + test)
                continue
            is_regenerate = UTC_ADVERT in first_line

            # If we're generating a new test, set the default version to the latest.
            argv = sys.argv[:]
            if not is_regenerate:
                argv.insert(1, "--version=" + str(DEFAULT_VERSION))

            args = parse_args(parser, argv[1:])
            if argparse_callback is not None:
                argparse_callback(args)
            if is_regenerate:
                if script_name not in first_line and not args.force_update:
                    warn(
                        "Skipping test which wasn't autogenerated by " + script_name,
                        test,
                    )
                    continue
                args, argv = check_for_command(
                    first_line, parser, args, argv, argparse_callback
                )
            elif args.update_only:
                assert UTC_ADVERT not in first_line
                warn("Skipping test which isn't autogenerated: " + test)
                continue
            final_input_lines = []
            for l in input_lines:
                if UNUSED_NOTE in l:
                    break
                final_input_lines.append(l)
            yield TestInfo(
                test,
                parser,
                script_name,
                final_input_lines,
                args,
                argv,
                comment_prefix,
                argparse_callback,
            )


def should_add_line_to_output(
    input_line,
    prefix_set,
    *,
    skip_global_checks=False,
    skip_same_checks=False,
    comment_marker=";",
):
    # Skip any blank comment lines in the IR.
    if not skip_global_checks and input_line.strip() == comment_marker:
        return False
    # Skip a special double comment line we use as a separator.
    if input_line.strip() == comment_marker + SEPARATOR:
        return False
    # Skip any blank lines in the IR.
    # if input_line.strip() == '':
    #  return False
    # And skip any CHECK lines. We're building our own.
    m = CHECK_RE.match(input_line)
    if m and m.group(1) in prefix_set:
        if skip_same_checks and CHECK_SAME_RE.match(input_line):
            # The previous CHECK line was removed, so don't leave this dangling
            return False
        if skip_global_checks:
            # Skip checks only if they are of global value definitions
            global_ir_value_re = re.compile(r"(\[\[|@)", flags=(re.M))
            is_global = global_ir_value_re.search(input_line)
            return not is_global
        return False

    return True


def collect_original_check_lines(ti: TestInfo, prefix_set: set):
    """
    Collect pre-existing check lines into a dictionary `result` which is
    returned.

    result[func_name][prefix] is filled with a list of right-hand-sides of check
    lines.
    """
    result = collections.defaultdict(lambda: {})

    current_prefix = None
    current_function = None
    for input_line_info in ti.ro_iterlines():
        input_line = input_line_info.line
        if input_line.lstrip().startswith(";"):
            m = CHECK_RE.match(input_line)
            if m is not None:
                prefix = m.group(1)
                check_kind = m.group(2)
                line = input_line[m.end() :].strip()

                if prefix != current_prefix:
                    current_function = None
                    current_prefix = None

                if check_kind not in ["LABEL", "SAME"]:
                    if current_function is not None:
                        current_function.append(line)
                    continue

                if check_kind == "SAME":
                    continue

                if check_kind == "LABEL":
                    m = IR_FUNCTION_LABEL_RE.match(line)
                    if m is not None:
                        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

                        current_prefix = prefix
                        current_function = result[func_name][prefix] = []
                        continue

        current_function = None

    return result


# Perform lit-like substitutions
def getSubstitutions(sourcepath):
    sourcedir = os.path.dirname(sourcepath)
    return [
        ("%s", sourcepath),
        ("%S", sourcedir),
        ("%p", sourcedir),
        ("%{pathsep}", os.pathsep),
    ]


def applySubstitutions(s, substitutions):
    for a, b in substitutions:
        s = s.replace(a, b)
    return s


# Invoke the tool that is being tested.
def invoke_tool(exe, cmd_args, ir, preprocess_cmd=None, verbose=False):
    with open(ir) as ir_file:
        substitutions = getSubstitutions(ir)

        # TODO Remove the str form which is used by update_test_checks.py and
        # update_llc_test_checks.py
        # The safer list form is used by update_cc_test_checks.py
        if preprocess_cmd:
            # Allow pre-processing the IR file (e.g. using sed):
            assert isinstance(
                preprocess_cmd, str
            )  # TODO: use a list instead of using shell
            preprocess_cmd = applySubstitutions(preprocess_cmd, substitutions).strip()
            if verbose:
                print(
                    "Pre-processing input file: ",
                    ir,
                    " with command '",
                    preprocess_cmd,
                    "'",
                    sep="",
                    file=sys.stderr,
                )
            pp = subprocess.Popen(
                preprocess_cmd,
                shell=True,
                stdin=subprocess.DEVNULL,
                stdout=subprocess.PIPE,
            )
            ir_file = pp.stdout

        if isinstance(cmd_args, list):
            args = [applySubstitutions(a, substitutions) for a in cmd_args]
            stdout = subprocess.check_output([exe] + args, stdin=ir_file)
        else:
            stdout = subprocess.check_output(
                exe + " " + applySubstitutions(cmd_args, substitutions),
                shell=True,
                stdin=ir_file,
            )
        if sys.version_info[0] > 2:
            # FYI, if you crashed here with a decode error, your run line probably
            # results in bitcode or other binary format being written to the pipe.
            # For an opt test, you probably want to add -S or -disable-output.
            stdout = stdout.decode()
    # Fix line endings to unix CR style.
    return stdout.replace("\r\n", "\n")


##### LLVM IR parser
RUN_LINE_RE = re.compile(r"^\s*(?://|[;#])\s*RUN:\s*(.*)$")
CHECK_PREFIX_RE = re.compile(r"--?check-prefix(?:es)?[= ](\S+)")
PREFIX_RE = re.compile("^[a-zA-Z0-9_-]+$")
CHECK_RE = re.compile(
    r"^\s*(?://|[;#])\s*([^:]+?)(?:-(NEXT|NOT|DAG|LABEL|SAME|EMPTY))?:"
)
CHECK_SAME_RE = re.compile(r"^\s*(?://|[;#])\s*([^:]+?)(?:-SAME)?:")

UTC_ARGS_KEY = "UTC_ARGS:"
UTC_ARGS_CMD = re.compile(r".*" + UTC_ARGS_KEY + r"\s*(?P<cmd>.*)\s*$")
UTC_ADVERT = "NOTE: Assertions have been autogenerated by "
UTC_AVOID = "NOTE: Do not autogenerate"
UNUSED_NOTE = "NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:"

DATA_LAYOUT_RE = re.compile(
    r"target\s+datalayout\s+=\s+\"(?P<layout>.+)\"$", flags=(re.M | re.S)
)

OPT_FUNCTION_RE = re.compile(
    r"^(\s*;\s*Function\sAttrs:\s(?P<attrs>[\w\s():,]+?))?\s*define\s+(?P<funcdef_attrs_and_ret>[^@]*)@(?P<func>[\w.$-]+?)\s*"
    r"(?P<args_and_sig>\((\)|(.*?[\w.-]+?)\))[^{]*\{)\n(?P<body>.*?)^\}$",
    flags=(re.M | re.S),
)

ANALYZE_FUNCTION_RE = re.compile(
    r"^\s*\'(?P<analysis>[\w\s-]+?)\'\s+for\s+function\s+\'(?P<func>[\w.$-]+?)\':"
    r"\s*\n(?P<body>.*)$",
    flags=(re.X | re.S),
)

LOOP_PASS_DEBUG_RE = re.compile(
    r"^\s*\'(?P<func>[\w.$-]+?)\'[^\n]*" r"\s*\n(?P<body>.*)$", flags=(re.X | re.S)
)

IR_FUNCTION_RE = re.compile(r'^\s*define\s+(?:internal\s+)?[^@]*@"?([\w.$-]+)"?\s*\(')
IR_FUNCTION_LABEL_RE = re.compile(
    r'^\s*(?:define\s+(?:internal\s+)?[^@]*)?@"?([\w.$-]+)"?\s*\('
)
TRIPLE_IR_RE = re.compile(r'^\s*target\s+triple\s*=\s*"([^"]+)"$')
TRIPLE_ARG_RE = re.compile(r"-m?triple[= ]([^ ]+)")
MARCH_ARG_RE = re.compile(r"-march[= ]([^ ]+)")
DEBUG_ONLY_ARG_RE = re.compile(r"-debug-only[= ]([^ ]+)")

SCRUB_LEADING_WHITESPACE_RE = re.compile(r"^(\s+)")
SCRUB_WHITESPACE_RE = re.compile(r"(?!^(|  \w))[ \t]+", flags=re.M)
SCRUB_PRESERVE_LEADING_WHITESPACE_RE = re.compile(r"((?!^)[ \t]*(\S))[ \t]+")
SCRUB_TRAILING_WHITESPACE_RE = re.compile(r"[ \t]+$", flags=re.M)
SCRUB_TRAILING_WHITESPACE_TEST_RE = SCRUB_TRAILING_WHITESPACE_RE
SCRUB_TRAILING_WHITESPACE_AND_ATTRIBUTES_RE = re.compile(
    r"([ \t]|(#[0-9]+))+$", flags=re.M
)
SCRUB_KILL_COMMENT_RE = re.compile(r"^ *#+ +kill:.*\n")
SCRUB_LOOP_COMMENT_RE = re.compile(
    r"# =>This Inner Loop Header:.*|# in Loop:.*", flags=re.M
)
SCRUB_TAILING_COMMENT_TOKEN_RE = re.compile(r"(?<=\S)+[ \t]*#$", flags=re.M)

SEPARATOR = "."


def error(msg, test_file=None):
    if test_file:
        msg = "{}: {}".format(msg, test_file)
    print("ERROR: {}".format(msg), file=sys.stderr)


def warn(msg, test_file=None):
    if test_file:
        msg = "{}: {}".format(msg, test_file)
    print("WARNING: {}".format(msg), file=sys.stderr)


def debug(*args, **kwargs):
    # Python2 does not allow def debug(*args, file=sys.stderr, **kwargs):
    if "file" not in kwargs:
        kwargs["file"] = sys.stderr
    if _verbose:
        print(*args, **kwargs)


def find_run_lines(test, lines):
    debug("Scanning for RUN lines in test file:", test)
    raw_lines = [m.group(1) for m in [RUN_LINE_RE.match(l) for l in lines] if m]
    run_lines = [raw_lines[0]] if len(raw_lines) > 0 else []
    for l in raw_lines[1:]:
        if run_lines[-1].endswith("\\"):
            run_lines[-1] = run_lines[-1].rstrip("\\") + " " + l
        else:
            run_lines.append(l)
    debug("Found {} RUN lines in {}:".format(len(run_lines), test))
    for l in run_lines:
        debug("  RUN: {}".format(l))
    return run_lines


def get_triple_from_march(march):
    triples = {
        "amdgcn": "amdgcn",
        "r600": "r600",
        "mips": "mips",
        "nvptx64": "nvptx64",
        "sparc": "sparc",
        "hexagon": "hexagon",
        "ve": "ve",
    }
    for prefix, triple in triples.items():
        if march.startswith(prefix):
            return triple
    print("Cannot find a triple. Assume 'x86'", file=sys.stderr)
    return "x86"


def get_globals_name_prefix(raw_tool_output):
    m = DATA_LAYOUT_RE.search(raw_tool_output)
    if not m:
        return None
    data_layout = m.group("layout")
    idx = data_layout.find("m:")
    if idx < 0:
        return None
    ch = data_layout[idx + 2]
    return "_" if ch == "o" or ch == "x" else None


def apply_filters(line, filters):
    has_filter = False
    for f in filters:
        if not f.is_filter_out:
            has_filter = True
        if f.search(line):
            return False if f.is_filter_out else True
    # If we only used filter-out, keep the line, otherwise discard it since no
    # filter matched.
    return False if has_filter else True


def do_filter(body, filters):
    return (
        body
        if not filters
        else "\n".join(
            filter(lambda line: apply_filters(line, filters), body.splitlines())
        )
    )


def scrub_body(body):
    # Scrub runs of whitespace out of the assembly, but leave the leading
    # whitespace in place.
    body = SCRUB_PRESERVE_LEADING_WHITESPACE_RE.sub(lambda m: m.group(2) + " ", body)

    # Expand the tabs used for indentation.
    body = str.expandtabs(body, 2)
    # Strip trailing whitespace.
    body = SCRUB_TRAILING_WHITESPACE_TEST_RE.sub(r"", body)
    return body


def do_scrub(body, scrubber, scrubber_args, extra):
    if scrubber_args:
        local_args = copy.deepcopy(scrubber_args)
        local_args[0].extra_scrub = extra
        return scrubber(body, *local_args)
    return scrubber(body, *scrubber_args)


# Build up a dictionary of all the function bodies.
class function_body(object):
    def __init__(
        self,
        string,
        extra,
        funcdef_attrs_and_ret,
        args_and_sig,
        attrs,
        func_name_separator,
        ginfo,
    ):
        self.scrub = string
        self.extrascrub = extra
        self.funcdef_attrs_and_ret = funcdef_attrs_and_ret
        self.args_and_sig = args_and_sig
        self.attrs = attrs
        self.func_name_separator = func_name_separator
        self._ginfo = ginfo

    def is_same_except_arg_names(
        self, extrascrub, funcdef_attrs_and_ret, args_and_sig, attrs
    ):
        arg_names = set()

        def drop_arg_names(match):
            nameless_value = self._ginfo.get_nameless_value_from_match(match)
            if nameless_value.check_key == "%":
                arg_names.add(self._ginfo.get_name_from_match(match))
                substitute = ""
            else:
                substitute = match.group(2)
            return match.group(1) + substitute + match.group(match.lastindex)

        def repl_arg_names(match):
            nameless_value = self._ginfo.get_nameless_value_from_match(match)
            if (
                nameless_value.check_key == "%"
                and self._ginfo.get_name_from_match(match) in arg_names
            ):
                return match.group(1) + match.group(match.lastindex)
            return match.group(1) + match.group(2) + match.group(match.lastindex)

        if self.funcdef_attrs_and_ret != funcdef_attrs_and_ret:
            return False
        if self.attrs != attrs:
            return False

        regexp = self._ginfo.get_regexp()
        ans0 = regexp.sub(drop_arg_names, self.args_and_sig)
        ans1 = regexp.sub(drop_arg_names, args_and_sig)
        if ans0 != ans1:
            return False
        if self._ginfo.is_asm():
            # Check without replacements, the replacements are not applied to the
            # body for backend checks.
            return self.extrascrub == extrascrub

        es0 = regexp.sub(repl_arg_names, self.extrascrub)
        es1 = regexp.sub(repl_arg_names, extrascrub)
        es0 = SCRUB_IR_COMMENT_RE.sub(r"", es0)
        es1 = SCRUB_IR_COMMENT_RE.sub(r"", es1)
        return es0 == es1

    def __str__(self):
        return self.scrub


class FunctionTestBuilder:
    def __init__(self, run_list, flags, scrubber_args, path, ginfo):
        self._verbose = flags.verbose
        self._record_args = flags.function_signature
        self._check_attributes = flags.check_attributes
        # Strip double-quotes if input was read by UTC_ARGS
        self._filters = (
            list(
                map(
                    lambda f: Filter(
                        re.compile(f.pattern().strip('"'), f.flags()), f.is_filter_out
                    ),
                    flags.filters,
                )
            )
            if flags.filters
            else []
        )
        self._scrubber_args = scrubber_args
        self._path = path
        self._ginfo = ginfo
        # Strip double-quotes if input was read by UTC_ARGS
        self._replace_value_regex = list(
            map(lambda x: x.strip('"'), flags.replace_value_regex)
        )
        self._func_dict = {}
        self._func_order = {}
        self._global_var_dict = {}
        self._processed_prefixes = set()
        for tuple in run_list:
            for prefix in tuple[0]:
                self._func_dict.update({prefix: dict()})
                self._func_order.update({prefix: []})
                self._global_var_dict.update({prefix: dict()})

    def finish_and_get_func_dict(self):
        for prefix in self.get_failed_prefixes():
            warn(
                "Prefix %s had conflicting output from different RUN lines for all functions in test %s"
                % (
                    prefix,
                    self._path,
                )
            )
        return self._func_dict

    def func_order(self):
        return self._func_order

    def global_var_dict(self):
        return self._global_var_dict

    def is_filtered(self):
        return bool(self._filters)

    def process_run_line(self, function_re, scrubber, raw_tool_output, prefixes):
        build_global_values_dictionary(
            self._global_var_dict, raw_tool_output, prefixes, self._ginfo
        )
        for m in function_re.finditer(raw_tool_output):
            if not m:
                continue
            func = m.group("func")
            body = m.group("body")
            # func_name_separator is the string that is placed right after function name at the
            # beginning of assembly function definition. In most assemblies, that is just a
            # colon: `foo:`. But, for example, in nvptx it is a brace: `foo(`. If is_backend is
            # False, just assume that separator is an empty string.
            if self._ginfo.is_asm():
                # Use ':' as default separator.
                func_name_separator = (
                    m.group("func_name_separator")
                    if "func_name_separator" in m.groupdict()
                    else ":"
                )
            else:
                func_name_separator = ""
            attrs = m.group("attrs") if self._check_attributes else ""
            funcdef_attrs_and_ret = (
                m.group("funcdef_attrs_and_ret") if self._record_args else ""
            )
            # Determine if we print arguments, the opening brace, or nothing after the
            # function name
            if self._record_args and "args_and_sig" in m.groupdict():
                args_and_sig = scrub_body(m.group("args_and_sig").strip())
            elif "args_and_sig" in m.groupdict():
                args_and_sig = "("
            else:
                args_and_sig = ""
            filtered_body = do_filter(body, self._filters)
            scrubbed_body = do_scrub(
                filtered_body, scrubber, self._scrubber_args, extra=False
            )
            scrubbed_extra = do_scrub(
                filtered_body, scrubber, self._scrubber_args, extra=True
            )
            if "analysis" in m.groupdict():
                analysis = m.group("analysis")
                if analysis not in SUPPORTED_ANALYSES:
                    warn("Unsupported analysis mode: %r!" % (analysis,))
            if func.startswith("stress"):
                # We only use the last line of the function body for stress tests.
                scrubbed_body = "\n".join(scrubbed_body.splitlines()[-1:])
            if self._verbose:
                print("Processing function: " + func, file=sys.stderr)
                for l in scrubbed_body.splitlines():
                    print("  " + l, file=sys.stderr)
            for prefix in prefixes:
                # Replace function names matching the regex.
                for regex in self._replace_value_regex:
                    # Pattern that matches capture groups in the regex in leftmost order.
                    group_regex = re.compile(r"\(.*?\)")
                    # Replace function name with regex.
                    match = re.match(regex, func)
                    if match:
                        func_repl = regex
                        # Replace any capture groups with their matched strings.
                        for g in match.groups():
                            func_repl = group_regex.sub(
                                re.escape(g), func_repl, count=1
                            )
                        func = re.sub(func_repl, "{{" + func_repl + "}}", func)

                    # Replace all calls to regex matching functions.
                    matches = re.finditer(regex, scrubbed_body)
                    for match in matches:
                        func_repl = regex
                        # Replace any capture groups with their matched strings.
                        for g in match.groups():
                            func_repl = group_regex.sub(
                                re.escape(g), func_repl, count=1
                            )
                        # Substitute function call names that match the regex with the same
                        # capture groups set.
                        scrubbed_body = re.sub(
                            func_repl, "{{" + func_repl + "}}", scrubbed_body
                        )

                if func in self._func_dict[prefix]:
                    if self._func_dict[prefix][func] is not None and (
                        str(self._func_dict[prefix][func]) != scrubbed_body
                        or self._func_dict[prefix][func].args_and_sig != args_and_sig
                        or self._func_dict[prefix][func].attrs != attrs
                        or self._func_dict[prefix][func].funcdef_attrs_and_ret
                        != funcdef_attrs_and_ret
                    ):
                        if self._func_dict[prefix][func].is_same_except_arg_names(
                            scrubbed_extra,
                            funcdef_attrs_and_ret,
                            args_and_sig,
                            attrs,
                        ):
                            self._func_dict[prefix][func].scrub = scrubbed_extra
                            self._func_dict[prefix][func].args_and_sig = args_and_sig
                        else:
                            # This means a previous RUN line produced a body for this function
                            # that is different from the one produced by this current RUN line,
                            # so the body can't be common across RUN lines. We use None to
                            # indicate that.
                            self._func_dict[prefix][func] = None
                else:
                    if prefix not in self._processed_prefixes:
                        self._func_dict[prefix][func] = function_body(
                            scrubbed_body,
                            scrubbed_extra,
                            funcdef_attrs_and_ret,
                            args_and_sig,
                            attrs,
                            func_name_separator,
                            self._ginfo,
                        )
                        self._func_order[prefix].append(func)
                    else:
                        # An earlier RUN line used this check prefixes but didn't produce
                        # a body for this function. This happens in Clang tests that use
                        # preprocesser directives to exclude individual functions from some
                        # RUN lines.
                        self._func_dict[prefix][func] = None

    def processed_prefixes(self, prefixes):
        """
        Mark a set of prefixes as having had at least one applicable RUN line fully
        processed. This is used to filter out function bodies that don't have
        outputs for all RUN lines.
        """
        self._processed_prefixes.update(prefixes)

    def get_failed_prefixes(self):
        # This returns the list of those prefixes that failed to match any function,
        # because there were conflicting bodies produced by different RUN lines, in
        # all instances of the prefix.
        for prefix in self._func_dict:
            if self._func_dict[prefix] and (
                not [
                    fct
                    for fct in self._func_dict[prefix]
                    if self._func_dict[prefix][fct] is not None
                ]
            ):
                yield prefix


##### Generator of LLVM IR CHECK lines

SCRUB_IR_COMMENT_RE = re.compile(r"\s*;.*")
SCRUB_IR_FUNC_META_RE = re.compile(r"((?:\!(?!dbg\b)[a-zA-Z_]\w*(?:\s+![0-9]+)?)\s*)+")

# TODO: We should also derive check lines for global, debug, loop declarations, etc..


class NamelessValue:
    """
    A NamelessValue object represents a type of value in the IR whose "name" we
    generalize in the generated check lines; where the "name" could be an actual
    name (as in e.g. `@some_global` or `%x`) or just a number (as in e.g. `%12`
    or `!4`).
    """

    def __init__(
        self,
        check_prefix,
        check_key,
        ir_prefix,
        ir_regexp,
        global_ir_rhs_regexp,
        *,
        is_before_functions=False,
        is_number=False,
        replace_number_with_counter=False,
        match_literally=False,
        interlaced_with_previous=False,
        ir_suffix=r"",
    ):
        self.check_prefix = check_prefix
        self.check_key = check_key
        self.ir_prefix = ir_prefix
        self.ir_regexp = ir_regexp
        self.ir_suffix = ir_suffix
        self.global_ir_rhs_regexp = global_ir_rhs_regexp
        self.is_before_functions = is_before_functions
        self.is_number = is_number
        # Some variable numbers (e.g. MCINST1234) will change based on unrelated
        # modifications to LLVM, replace those with an incrementing counter.
        self.replace_number_with_counter = replace_number_with_counter
        self.match_literally = match_literally
        self.interlaced_with_previous = interlaced_with_previous
        self.variable_mapping = {}

    # Return true if this kind of IR value is defined "locally" to functions,
    # which we assume is only the case precisely for LLVM IR local values.
    def is_local_def_ir_value(self):
        return self.check_key == "%"

    # Return the IR regexp we use for this kind or IR value, e.g., [\w.-]+? for locals
    def get_ir_regex(self):
        # for backwards compatibility we check locals with '.*'
        if self.is_local_def_ir_value():
            return ".*"
        return self.ir_regexp

    # Create a FileCheck variable name based on an IR name.
    def get_value_name(self, var: str, check_prefix: str):
        var = var.replace("!", "")
        if self.replace_number_with_counter:
            assert var
            replacement = self.variable_mapping.get(var, None)
            if replacement is None:
                # Replace variable with an incrementing counter
                replacement = str(len(self.variable_mapping) + 1)
                self.variable_mapping[var] = replacement
            var = replacement
        # This is a nameless value, prepend check_prefix.
        if var.isdigit():
            var = check_prefix + var
        else:
            # This is a named value that clashes with the check_prefix, prepend with
            # _prefix_filecheck_ir_name, if it has been defined.
            if (
                may_clash_with_default_check_prefix_name(check_prefix, var)
                and _prefix_filecheck_ir_name
            ):
                var = _prefix_filecheck_ir_name + var
        var = var.replace(".", "_")
        var = var.replace("-", "_")
        return var.upper()

    def get_affixes_from_match(self, match):
        prefix = re.match(self.ir_prefix, match.group(2)).group(0)
        suffix = re.search(self.ir_suffix + "$", match.group(2)).group(0)
        return prefix, suffix


class GeneralizerInfo:
    """
    A GeneralizerInfo object holds information about how check lines should be generalized
    (e.g., variable names replaced by FileCheck meta variables) as well as per-test-file
    state (e.g. information about IR global variables).
    """

    MODE_IR = 0
    MODE_ASM = 1
    MODE_ANALYZE = 2

    def __init__(
        self,
        version,
        mode,
        nameless_values: List[NamelessValue],
        regexp_prefix,
        regexp_suffix,
        no_meta_details=False,
    ):
        self._version = version
        self._mode = mode
        self._nameless_values = nameless_values

        self._regexp_prefix = regexp_prefix
        self._regexp_suffix = regexp_suffix
        self._no_meta_details = no_meta_details

        self._regexp, _ = self._build_regexp(False, False)
        (
            self._unstable_globals_regexp,
            self._unstable_globals_values,
        ) = self._build_regexp(True, True)

    def _build_regexp(self, globals_only, unstable_only):
        matches = []
        values = []
        for nameless_value in self._nameless_values:
            is_global = nameless_value.global_ir_rhs_regexp is not None
            if globals_only and not is_global:
                continue
            if unstable_only and nameless_value.match_literally:
                continue

            match = f"(?:{nameless_value.ir_prefix}({nameless_value.ir_regexp}){nameless_value.ir_suffix})"
            if self.is_ir() and not globals_only and is_global:
                match = "^" + match
            matches.append(match)
            values.append(nameless_value)

        regexp_string = r"|".join(matches)

        return (
            re.compile(
                self._regexp_prefix + r"(" + regexp_string + r")" + self._regexp_suffix
            ),
            values,
        )

    def get_version(self):
        return self._version

    def is_ir(self):
        return self._mode == GeneralizerInfo.MODE_IR

    def is_asm(self):
        return self._mode == GeneralizerInfo.MODE_ASM

    def is_analyze(self):
        return self._mode == GeneralizerInfo.MODE_ANALYZE

    def get_nameless_values(self):
        return self._nameless_values

    def get_regexp(self):
        return self._regexp

    def get_unstable_globals_regexp(self):
        return self._unstable_globals_regexp

    def no_meta_details(self):
        return self._no_meta_details

    # The entire match is group 0, the prefix has one group (=1), the entire
    # IR_VALUE_REGEXP_STRING is one group (=2), and then the nameless values start.
    FIRST_NAMELESS_GROUP_IN_MATCH = 3

    def get_match_info(self, match):
        """
        Returns (name, nameless_value) for the given match object
        """
        if match.re == self._regexp:
            values = self._nameless_values
        else:
            match.re == self._unstable_globals_regexp
            values = self._unstable_globals_values
        for i in range(len(values)):
            g = match.group(i + GeneralizerInfo.FIRST_NAMELESS_GROUP_IN_MATCH)
            if g is not None:
                return g, values[i]
        error("Unable to identify the kind of IR value from the match!")
        return None, None

    # See get_idx_from_match
    def get_name_from_match(self, match):
        return self.get_match_info(match)[0]

    def get_nameless_value_from_match(self, match) -> NamelessValue:
        return self.get_match_info(match)[1]


def make_ir_generalizer(version, no_meta_details):
    values = []

    if version >= 5:
        values += [
            NamelessValue(r"BB", "%", r"label %", r"[\w$.-]+?", None),
            NamelessValue(r"BB", "%", r"^", r"[\w$.-]+?", None, ir_suffix=r":"),
        ]

    values += [
        #            check_prefix   check_key  ir_prefix           ir_regexp                global_ir_rhs_regexp
        NamelessValue(r"TMP", "%", r"%", r"[\w$.-]+?", None),
        NamelessValue(r"ATTR", "#", r"#", r"[0-9]+", None),
        NamelessValue(r"ATTR", "#", r"attributes #", r"[0-9]+", r"{[^}]*}"),
        NamelessValue(r"GLOB", "@", r"@", r"[0-9]+", None),
        NamelessValue(r"GLOB", "@", r"@", r"[0-9]+", r".+", is_before_functions=True),
        NamelessValue(
            r"GLOBNAMED",
            "@",
            r"@",
            r"[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*",
            r".+",
            is_before_functions=True,
            match_literally=True,
            interlaced_with_previous=True,
        ),
        NamelessValue(r"DBG", "!", r"!dbg ", r"![0-9]+", None),
        NamelessValue(r"DIASSIGNID", "!", r"!DIAssignID ", r"![0-9]+", None),
        NamelessValue(r"PROF", "!", r"!prof ", r"![0-9]+", None),
        NamelessValue(r"TBAA", "!", r"!tbaa ", r"![0-9]+", None),
        NamelessValue(r"TBAA_STRUCT", "!", r"!tbaa.struct ", r"![0-9]+", None),
        NamelessValue(r"RNG", "!", r"!range ", r"![0-9]+", None),
        NamelessValue(r"LOOP", "!", r"!llvm.loop ", r"![0-9]+", None),
        NamelessValue(r"META", "!", r"", r"![0-9]+", r"(?:distinct |)!.*"),
        NamelessValue(r"ACC_GRP", "!", r"!llvm.access.group ", r"![0-9]+", None),
        NamelessValue(r"META", "!", r"![a-z.]+ ", r"![0-9]+", None),
        NamelessValue(r"META", "!", r"[, (]", r"![0-9]+", None),
    ]

    prefix = r"(\s*)"
    suffix = r"([,\s\(\)\}]|\Z)"

    # values = [
    #     nameless_value
    #     for nameless_value in IR_NAMELESS_VALUES
    #     if not (globals_only and nameless_value.global_ir_rhs_regexp is None) and
    #        not (unstable_ids_only and nameless_value.match_literally)
    # ]

    return GeneralizerInfo(
        version, GeneralizerInfo.MODE_IR, values, prefix, suffix, no_meta_details
    )


def make_asm_generalizer(version):
    values = [
        NamelessValue(
            r"MCINST",
            "Inst#",
            "<MCInst #",
            r"\d+",
            r".+",
            is_number=True,
            replace_number_with_counter=True,
        ),
        NamelessValue(
            r"MCREG",
            "Reg:",
            "<MCOperand Reg:",
            r"\d+",
            r".+",
            is_number=True,
            replace_number_with_counter=True,
        ),
    ]

    prefix = r"((?:#|//)\s*)"
    suffix = r"([>\s]|\Z)"

    return GeneralizerInfo(version, GeneralizerInfo.MODE_ASM, values, prefix, suffix)


def make_analyze_generalizer(version):
    values = [
        NamelessValue(
            r"GRP",
            "#",
            r"",
            r"0x[0-9a-f]+",
            None,
            replace_number_with_counter=True,
        ),
    ]

    prefix = r"(\s*)"
    suffix = r"(\)?:)"

    return GeneralizerInfo(
        version, GeneralizerInfo.MODE_ANALYZE, values, prefix, suffix
    )


# Return true if var clashes with the scripted FileCheck check_prefix.
def may_clash_with_default_check_prefix_name(check_prefix, var):
    return check_prefix and re.match(
        r"^" + check_prefix + r"[0-9]+?$", var, re.IGNORECASE
    )


def find_diff_matching(lhs: List[str], rhs: List[str]) -> List[tuple]:
    """
    Find a large ordered matching between strings in lhs and rhs.

    Think of this as finding the *unchanged* lines in a diff, where the entries
    of lhs and rhs are lines of the files being diffed.

    Returns a list of matched (lhs_idx, rhs_idx) pairs.
    """

    if not lhs or not rhs:
        return []

    # Collect matches in reverse order.
    matches = []

    # First, collect a set of candidate matching edges. We limit this to a
    # constant multiple of the input size to avoid quadratic runtime.
    patterns = collections.defaultdict(lambda: ([], []))

    for idx in range(len(lhs)):
        patterns[lhs[idx]][0].append(idx)
    for idx in range(len(rhs)):
        patterns[rhs[idx]][1].append(idx)

    multiple_patterns = []

    candidates = []
    for pattern in patterns.values():
        if not pattern[0] or not pattern[1]:
            continue

        if len(pattern[0]) == len(pattern[1]) == 1:
            candidates.append((pattern[0][0], pattern[1][0]))
        else:
            multiple_patterns.append(pattern)

    multiple_patterns.sort(key=lambda pattern: len(pattern[0]) * len(pattern[1]))

    for pattern in multiple_patterns:
        if len(candidates) + len(pattern[0]) * len(pattern[1]) > 2 * (
            len(lhs) + len(rhs)
        ):
            break
        for lhs_idx in pattern[0]:
            for rhs_idx in pattern[1]:
                candidates.append((lhs_idx, rhs_idx))

    if not candidates:
        # The LHS and RHS either share nothing in common, or lines are just too
        # identical. In that case, let's give up and not match anything.
        return []

    # Compute a maximal crossing-free matching via an algorithm that is
    # inspired by a mixture of dynamic programming and line-sweeping in
    # discrete geometry.
    #
    # I would be surprised if this algorithm didn't exist somewhere in the
    # literature, but I found it without consciously recalling any
    # references, so you'll have to make do with the explanation below.
    # Sorry.
    #
    # The underlying graph is bipartite:
    #  - nodes on the LHS represent lines in the original check
    #  - nodes on the RHS represent lines in the new (updated) check
    #
    # Nodes are implicitly sorted by the corresponding line number.
    # Edges (unique_matches) are sorted by the line number on the LHS.
    #
    # Here's the geometric intuition for the algorithm.
    #
    #  * Plot the edges as points in the plane, with the original line
    #    number on the X axis and the updated line number on the Y axis.
    #  * The goal is to find a longest "chain" of points where each point
    #    is strictly above and to the right of the previous point.
    #  * The algorithm proceeds by sweeping a vertical line from left to
    #    right.
    #  * The algorithm maintains a table where `table[N]` answers the
    #    question "What is currently the 'best' way to build a chain of N+1
    #    points to the left of the vertical line". Here, 'best' means
    #    that the last point of the chain is a as low as possible (minimal
    #    Y coordinate).
    #   * `table[N]` is `(y, point_idx)` where `point_idx` is the index of
    #     the last point in the chain and `y` is its Y coordinate
    #   * A key invariant is that the Y values in the table are
    #     monotonically increasing
    #  * Thanks to these properties, the table can be used to answer the
    #    question "What is the longest chain that can be built to the left
    #    of the vertical line using only points below a certain Y value",
    #    using a binary search over the table.
    #  * The algorithm also builds a backlink structure in which every point
    #    links back to the previous point on a best (longest) chain ending
    #    at that point
    #
    # The core loop of the algorithm sweeps the line and updates the table
    # and backlink structure for every point that we cross during the sweep.
    # Therefore, the algorithm is trivially O(M log M) in the number of
    # points.
    candidates.sort(key=lambda candidate: (candidate[0], -candidate[1]))

    backlinks = []
    table_rhs_idx = []
    table_candidate_idx = []
    for _, rhs_idx in candidates:
        candidate_idx = len(backlinks)
        ti = bisect.bisect_left(table_rhs_idx, rhs_idx)

        # Update the table to record a best chain ending in the current point.
        # There always is one, and if any of the previously visited points had
        # a higher Y coordinate, then there is always a previously recorded best
        # chain that can be improved upon by using the current point.
        #
        # There is only one case where there is some ambiguity. If the
        # pre-existing entry table[ti] has the same Y coordinate / rhs_idx as
        # the current point (this can only happen if the same line appeared
        # multiple times on the LHS), then we could choose to keep the
        # previously recorded best chain instead. That would bias the algorithm
        # differently but should have no systematic impact on the quality of the
        # result.
        if ti < len(table_rhs_idx):
            table_rhs_idx[ti] = rhs_idx
            table_candidate_idx[ti] = candidate_idx
        else:
            table_rhs_idx.append(rhs_idx)
            table_candidate_idx.append(candidate_idx)
        if ti > 0:
            backlinks.append(table_candidate_idx[ti - 1])
        else:
            backlinks.append(None)

    # Commit to names in the matching by walking the backlinks. Recursively
    # attempt to fill in more matches in-between.
    match_idx = table_candidate_idx[-1]
    while match_idx is not None:
        current = candidates[match_idx]
        matches.append(current)
        match_idx = backlinks[match_idx]

    matches.reverse()
    return matches


VARIABLE_TAG = "[[@@]]"
METAVAR_RE = re.compile(r"\[\[([A-Z0-9_]+)(?::[^]]+)?\]\]")
NUMERIC_SUFFIX_RE = re.compile(r"[0-9]*$")


class TestVar:
    def __init__(self, nameless_value: NamelessValue, prefix: str, suffix: str):
        self._nameless_value = nameless_value

        self._prefix = prefix
        self._suffix = suffix

    def seen(self, nameless_value: NamelessValue, prefix: str, suffix: str):
        if prefix != self._prefix:
            self._prefix = ""
        if suffix != self._suffix:
            self._suffix = ""

    def get_variable_name(self, text):
        return self._nameless_value.get_value_name(
            text, self._nameless_value.check_prefix
        )

    def get_def(self, name, prefix, suffix):
        if self._nameless_value.is_number:
            return f"{prefix}[[#{name}:]]{suffix}"
        if self._prefix:
            assert self._prefix == prefix
            prefix = ""
        if self._suffix:
            assert self._suffix == suffix
            suffix = ""
        return f"{prefix}[[{name}:{self._prefix}{self._nameless_value.get_ir_regex()}{self._suffix}]]{suffix}"

    def get_use(self, name, prefix, suffix):
        if self._nameless_value.is_number:
            return f"{prefix}[[#{name}]]{suffix}"
        if self._prefix:
            assert self._prefix == prefix
            prefix = ""
        if self._suffix:
            assert self._suffix == suffix
            suffix = ""
        return f"{prefix}[[{name}]]{suffix}"


class CheckValueInfo:
    def __init__(
        self,
        key,
        text,
        name: str,
        prefix: str,
        suffix: str,
    ):
        # Key for the value, e.g. '%'
        self.key = key

        # Text to be matched by the FileCheck variable (without any prefix or suffix)
        self.text = text

        # Name of the FileCheck variable
        self.name = name

        # Prefix and suffix that were captured by the NamelessValue regular expression
        self.prefix = prefix
        self.suffix = suffix


# Represent a check line in a way that allows us to compare check lines while
# ignoring some or all of the FileCheck variable names.
class CheckLineInfo:
    def __init__(self, line, values):
        # Line with all FileCheck variable name occurrences replaced by VARIABLE_TAG
        self.line: str = line

        # Information on each FileCheck variable name occurrences in the line
        self.values: List[CheckValueInfo] = values

    def __repr__(self):
        return f"CheckLineInfo(line={self.line}, self.values={self.values})"


def remap_metavar_names(
    old_line_infos: List[CheckLineInfo],
    new_line_infos: List[CheckLineInfo],
    committed_names: Set[str],
) -> Mapping[str, str]:
    """
    Map all FileCheck variable names that appear in new_line_infos to new
    FileCheck variable names in an attempt to reduce the diff from old_line_infos
    to new_line_infos.

    This is done by:
    * Matching old check lines and new check lines using a diffing algorithm
      applied after replacing names with wildcards.
    * Committing to variable names such that the matched lines become equal
      (without wildcards) if possible
    * This is done recursively to handle cases where many lines are equal
      after wildcard replacement
    """
    # Initialize uncommitted identity mappings
    new_mapping = {}
    for line in new_line_infos:
        for value in line.values:
            new_mapping[value.name] = value.name

    # Recursively commit to the identity mapping or find a better one
    def recurse(old_begin, old_end, new_begin, new_end):
        if old_begin == old_end or new_begin == new_end:
            return

        # Find a matching of lines where uncommitted names are replaced
        # with a placeholder.
        def diffify_line(line, mapper):
            values = []
            for value in line.values:
                mapped = mapper(value.name)
                values.append(mapped if mapped in committed_names else "?")
            return line.line.strip() + " @@@ " + " @ ".join(values)

        lhs_lines = [
            diffify_line(line, lambda x: x)
            for line in old_line_infos[old_begin:old_end]
        ]
        rhs_lines = [
            diffify_line(line, lambda x: new_mapping[x])
            for line in new_line_infos[new_begin:new_end]
        ]

        candidate_matches = find_diff_matching(lhs_lines, rhs_lines)

        candidate_matches = [
            (old_begin + lhs_idx, new_begin + rhs_idx)
            for lhs_idx, rhs_idx in candidate_matches
        ]

        # Candidate matches may conflict if they require conflicting mappings of
        # names. We want to determine a large set of compatible candidates,
        # because that leads to a small diff.
        #
        # We think of the candidates as vertices in a conflict graph. The
        # conflict graph has edges between incompatible candidates. We want to
        # find a large independent set in this graph.
        #
        # Greedily selecting candidates and removing incompatible ones has the
        # disadvantage that making few bad decisions early on can have huge
        # consequences.
        #
        # Instead, we implicitly compute multiple independent sets by greedily
        # assigning a *coloring* to the conflict graph. Then, we select the
        # largest color class (which is the largest independent set we found),
        # commit to all candidates in it, and recurse.
        #
        # Note that we don't actually materialize the conflict graph. Instead,
        # each color class tracks the information needed to decide implicitly
        # whether a vertex conflicts (has an edge to) any of the vertices added
        # to the color class so far.
        class Color:
            def __init__(self):
                # (lhs_idx, rhs_idx) of matches in this color
                self.matches = []

                # rhs_name -> lhs_name mappings required by this color
                self.mapping = {}

                # lhs_names committed for this color
                self.committed = set()

        colors = []

        for lhs_idx, rhs_idx in candidate_matches:
            lhs_line = old_line_infos[lhs_idx]
            rhs_line = new_line_infos[rhs_idx]

            # We scan through the uncommitted names in the candidate line and
            # filter out the color classes to which the candidate could be
            # assigned.
            #
            # Simultaneously, we prepare a new color class in case the candidate
            # conflicts with all colors that have been established so far.
            compatible_colors = colors[:]
            new_color = Color()
            new_color.matches.append((lhs_idx, rhs_idx))

            for lhs_value, rhs_value in zip(lhs_line.values, rhs_line.values):
                if new_mapping[rhs_value.name] in committed_names:
                    # The new value has already been committed. If it was mapped
                    # to the same name as the original value, we can consider
                    # committing other values from this line. Otherwise, we
                    # should ignore this line.
                    if new_mapping[rhs_value.name] == lhs_value.name:
                        continue
                    else:
                        break

                if rhs_value.name in new_color.mapping:
                    # Same, but for a possible commit happening on the same line
                    if new_color.mapping[rhs_value.name] == lhs_value.name:
                        continue
                    else:
                        break

                if (
                    lhs_value.name in committed_names
                    or lhs_value.name in new_color.committed
                ):
                    # We can't map this value because the name we would map it
                    # to has already been committed for something else. Give up
                    # on this line.
                    break

                new_color.mapping[rhs_value.name] = lhs_value.name
                new_color.committed.add(lhs_value.name)

                color_idx = 0
                while color_idx < len(compatible_colors):
                    color = compatible_colors[color_idx]
                    compatible = True
                    if rhs_value.name in color.mapping:
                        compatible = color.mapping[rhs_value.name] == lhs_value.name
                    else:
                        compatible = lhs_value.name not in color.committed
                    if compatible:
                        color_idx += 1
                    else:
                        del compatible_colors[color_idx]
            else:
                # We never broke out of the loop, which means that at a minimum,
                # this line is viable standalone
                if compatible_colors:
                    color = max(compatible_colors, key=lambda color: len(color.matches))
                    color.mapping.update(new_color.mapping)
                    color.committed.update(new_color.committed)
                    color.matches.append((lhs_idx, rhs_idx))
                else:
                    colors.append(new_color)

        if colors:
            # Pick the largest color class. This gives us a large independent
            # (non-conflicting) set of candidate matches. Assign all names
            # required by the independent set and recurse.
            max_color = max(colors, key=lambda color: len(color.matches))

            for rhs_var, lhs_var in max_color.mapping.items():
                new_mapping[rhs_var] = lhs_var
                committed_names.add(lhs_var)

                if (
                    lhs_var != rhs_var
                    and lhs_var in new_mapping
                    and new_mapping[lhs_var] == lhs_var
                ):
                    new_mapping[lhs_var] = "conflict_" + lhs_var

            matches = (
                [(old_begin - 1, new_begin - 1)]
                + max_color.matches
                + [(old_end, new_end)]
            )

            for (lhs_prev, rhs_prev), (lhs_next, rhs_next) in zip(matches, matches[1:]):
                recurse(lhs_prev + 1, lhs_next, rhs_prev + 1, rhs_next)

    recurse(0, len(old_line_infos), 0, len(new_line_infos))

    # Commit to remaining names and resolve conflicts
    for new_name, mapped_name in new_mapping.items():
        if mapped_name in committed_names:
            continue
        if not mapped_name.startswith("conflict_"):
            assert mapped_name == new_name
            committed_names.add(mapped_name)

    for new_name, mapped_name in new_mapping.items():
        if mapped_name in committed_names:
            continue
        assert mapped_name.startswith("conflict_")

        m = NUMERIC_SUFFIX_RE.search(new_name)
        base_name = new_name[: m.start()]
        suffix = int(new_name[m.start() :]) if m.start() != m.end() else 1
        while True:
            candidate = f"{base_name}{suffix}"
            if candidate not in committed_names:
                new_mapping[new_name] = candidate
                committed_names.add(candidate)
                break
            suffix += 1

    return new_mapping


def generalize_check_lines(
    lines,
    ginfo: GeneralizerInfo,
    vars_seen,
    global_vars_seen,
    preserve_names=False,
    original_check_lines=None,
    *,
    unstable_globals_only=False,
    no_meta_details=False,
):
    if unstable_globals_only:
        regexp = ginfo.get_unstable_globals_regexp()
    else:
        regexp = ginfo.get_regexp()

    multiple_braces_re = re.compile(r"({{+)|(}}+)")

    def escape_braces(match_obj):
        return "{{" + re.escape(match_obj.group(0)) + "}}"

    if ginfo.is_ir():
        for i, line in enumerate(lines):
            # An IR variable named '%.' matches the FileCheck regex string.
            line = line.replace("%.", "%dot")
            for regex in _global_hex_value_regex:
                if re.match("^@" + regex + " = ", line):
                    line = re.sub(
                        r"\bi([0-9]+) ([0-9]+)",
                        lambda m: "i"
                        + m.group(1)
                        + " [[#"
                        + hex(int(m.group(2)))
                        + "]]",
                        line,
                    )
                    break
            # Ignore any comments, since the check lines will too.
            scrubbed_line = SCRUB_IR_COMMENT_RE.sub(r"", line)
            # Ignore the metadata details if check global is none
            if no_meta_details:
                scrubbed_line = SCRUB_IR_FUNC_META_RE.sub(r"{{.*}}", scrubbed_line)
            lines[i] = scrubbed_line

    if not preserve_names:
        committed_names = set(
            test_var.get_variable_name(name)
            for (name, _), test_var in vars_seen.items()
        )
        defs = set()

        # Collect information about new check lines, and generalize global reference
        new_line_infos = []
        for line in lines:
            filtered_line = ""
            values = []
            while True:
                m = regexp.search(line)
                if m is None:
                    filtered_line += line
                    break

                name = ginfo.get_name_from_match(m)
                nameless_value = ginfo.get_nameless_value_from_match(m)
                prefix, suffix = nameless_value.get_affixes_from_match(m)
                if may_clash_with_default_check_prefix_name(
                    nameless_value.check_prefix, name
                ):
                    warn(
                        "Change IR value name '%s' or use --prefix-filecheck-ir-name to prevent possible conflict"
                        " with scripted FileCheck name." % (name,)
                    )

                # Record the variable as seen and (for locals) accumulate
                # prefixes/suffixes
                is_local_def = nameless_value.is_local_def_ir_value()
                if is_local_def:
                    vars_dict = vars_seen
                else:
                    vars_dict = global_vars_seen

                key = (name, nameless_value.check_key)

                if is_local_def:
                    test_prefix = prefix
                    test_suffix = suffix
                else:
                    test_prefix = ""
                    test_suffix = ""

                if key in vars_dict:
                    vars_dict[key].seen(nameless_value, test_prefix, test_suffix)
                else:
                    vars_dict[key] = TestVar(nameless_value, test_prefix, test_suffix)
                    defs.add(key)

                var = vars_dict[key].get_variable_name(name)

                # Replace with a [[@@]] tag, but be sure to keep the spaces and commas.
                filtered_line += (
                    line[: m.start()] + m.group(1) + VARIABLE_TAG + m.group(m.lastindex)
                )
                line = line[m.end() :]

                values.append(
                    CheckValueInfo(
                        key=nameless_value.check_key,
                        text=name,
                        name=var,
                        prefix=prefix,
                        suffix=suffix,
                    )
                )

            new_line_infos.append(CheckLineInfo(filtered_line, values))

        committed_names.update(
            test_var.get_variable_name(name)
            for (name, _), test_var in global_vars_seen.items()
        )

        # Collect information about original check lines, if any.
        orig_line_infos = []
        for line in original_check_lines or []:
            filtered_line = ""
            values = []
            while True:
                m = METAVAR_RE.search(line)
                if m is None:
                    filtered_line += line
                    break

                # Replace with a [[@@]] tag, but be sure to keep the spaces and commas.
                filtered_line += line[: m.start()] + VARIABLE_TAG
                line = line[m.end() :]
                values.append(
                    CheckValueInfo(
                        key=None,
                        text=None,
                        name=m.group(1),
                        prefix="",
                        suffix="",
                    )
                )
            orig_line_infos.append(CheckLineInfo(filtered_line, values))

        # Compute the variable name mapping
        mapping = remap_metavar_names(orig_line_infos, new_line_infos, committed_names)

        # Apply the variable name mapping
        for i, line_info in enumerate(new_line_infos):
            line_template = line_info.line
            line = ""

            for value in line_info.values:
                idx = line_template.find(VARIABLE_TAG)
                line += line_template[:idx]
                line_template = line_template[idx + len(VARIABLE_TAG) :]

                key = (value.text, value.key)
                if value.key == "%":
                    vars_dict = vars_seen
                else:
                    vars_dict = global_vars_seen

                if key in defs:
                    line += vars_dict[key].get_def(
                        mapping[value.name], value.prefix, value.suffix
                    )
                    defs.remove(key)
                else:
                    line += vars_dict[key].get_use(
                        mapping[value.name], value.prefix, value.suffix
                    )

            line += line_template

            lines[i] = line

    if ginfo.is_analyze():
        for i, _ in enumerate(lines):
            # Escape multiple {{ or }} as {{}} denotes a FileCheck regex.
            scrubbed_line = multiple_braces_re.sub(escape_braces, lines[i])
            lines[i] = scrubbed_line

    return lines


def add_checks(
    output_lines,
    comment_marker,
    prefix_list,
    func_dict,
    func_name,
    check_label_format,
    ginfo,
    global_vars_seen_dict,
    is_filtered,
    preserve_names=False,
    original_check_lines: Mapping[str, List[str]] = {},
):
    # prefix_exclusions are prefixes we cannot use to print the function because it doesn't exist in run lines that use these prefixes as well.
    prefix_exclusions = set()
    printed_prefixes = []
    for p in prefix_list:
        checkprefixes = p[0]
        # If not all checkprefixes of this run line produced the function we cannot check for it as it does not
        # exist for this run line. A subset of the check prefixes might know about the function but only because
        # other run lines created it.
        if any(
            map(
                lambda checkprefix: func_name not in func_dict[checkprefix],
                checkprefixes,
            )
        ):
            prefix_exclusions |= set(checkprefixes)
            continue

    # prefix_exclusions is constructed, we can now emit the output
    for p in prefix_list:
        global_vars_seen = {}
        checkprefixes = p[0]
        for checkprefix in checkprefixes:
            if checkprefix in global_vars_seen_dict:
                global_vars_seen.update(global_vars_seen_dict[checkprefix])
            else:
                global_vars_seen_dict[checkprefix] = {}
            if checkprefix in printed_prefixes:
                break

            # Check if the prefix is excluded.
            if checkprefix in prefix_exclusions:
                continue

            # If we do not have output for this prefix we skip it.
            if not func_dict[checkprefix][func_name]:
                continue

            # Add some space between different check prefixes, but not after the last
            # check line (before the test code).
            if ginfo.is_asm():
                if len(printed_prefixes) != 0:
                    output_lines.append(comment_marker)

            if checkprefix not in global_vars_seen_dict:
                global_vars_seen_dict[checkprefix] = {}

            global_vars_seen_before = [key for key in global_vars_seen.keys()]

            vars_seen = {}
            printed_prefixes.append(checkprefix)
            attrs = str(func_dict[checkprefix][func_name].attrs)
            attrs = "" if attrs == "None" else attrs
            if ginfo.get_version() > 1:
                funcdef_attrs_and_ret = func_dict[checkprefix][
                    func_name
                ].funcdef_attrs_and_ret
            else:
                funcdef_attrs_and_ret = ""

            if attrs:
                output_lines.append(
                    "%s %s: Function Attrs: %s" % (comment_marker, checkprefix, attrs)
                )
            args_and_sig = str(func_dict[checkprefix][func_name].args_and_sig)
            if args_and_sig:
                args_and_sig = generalize_check_lines(
                    [args_and_sig],
                    ginfo,
                    vars_seen,
                    global_vars_seen,
                    preserve_names,
                    original_check_lines=[],
                    no_meta_details=ginfo.no_meta_details(),
                )[0]
            func_name_separator = func_dict[checkprefix][func_name].func_name_separator
            if "[[" in args_and_sig:
                # Captures in label lines are not supported, thus split into a -LABEL
                # and a separate -SAME line that contains the arguments with captures.
                args_and_sig_prefix = ""
                if ginfo.get_version() >= 3 and args_and_sig.startswith("("):
                    # Ensure the "(" separating function name and arguments is in the
                    # label line. This is required in case of function names that are
                    # prefixes of each other. Otherwise, the label line for "foo" might
                    # incorrectly match on "foo.specialized".
                    args_and_sig_prefix = args_and_sig[0]
                    args_and_sig = args_and_sig[1:]

                # Removing args_and_sig from the label match line requires
                # func_name_separator to be empty. Otherwise, the match will not work.
                assert func_name_separator == ""
                output_lines.append(
                    check_label_format
                    % (
                        checkprefix,
                        funcdef_attrs_and_ret,
                        func_name,
                        args_and_sig_prefix,
                        func_name_separator,
                    )
                )
                output_lines.append(
                    "%s %s-SAME: %s" % (comment_marker, checkprefix, args_and_sig)
                )
            else:
                output_lines.append(
                    check_label_format
                    % (
                        checkprefix,
                        funcdef_attrs_and_ret,
                        func_name,
                        args_and_sig,
                        func_name_separator,
                    )
                )
            func_body = str(func_dict[checkprefix][func_name]).splitlines()
            if not func_body:
                # We have filtered everything.
                continue

            # For ASM output, just emit the check lines.
            if ginfo.is_asm():
                body_start = 1
                if is_filtered:
                    # For filtered output we don't add "-NEXT" so don't add extra spaces
                    # before the first line.
                    body_start = 0
                else:
                    output_lines.append(
                        "%s %s:       %s" % (comment_marker, checkprefix, func_body[0])
                    )
                func_lines = generalize_check_lines(
                    func_body[body_start:], ginfo, vars_seen, global_vars_seen
                )
                for func_line in func_lines:
                    if func_line.strip() == "":
                        output_lines.append(
                            "%s %s-EMPTY:" % (comment_marker, checkprefix)
                        )
                    else:
                        check_suffix = "-NEXT" if not is_filtered else ""
                        output_lines.append(
                            "%s %s%s:  %s"
                            % (comment_marker, checkprefix, check_suffix, func_line)
                        )
                # Remember new global variables we have not seen before
                for key in global_vars_seen:
                    if key not in global_vars_seen_before:
                        global_vars_seen_dict[checkprefix][key] = global_vars_seen[key]
                break
            # For analyze output, generalize the output, and emit CHECK-EMPTY lines as well.
            elif ginfo.is_analyze():
                func_body = generalize_check_lines(
                    func_body, ginfo, vars_seen, global_vars_seen
                )
                for func_line in func_body:
                    if func_line.strip() == "":
                        output_lines.append(
                            "{} {}-EMPTY:".format(comment_marker, checkprefix)
                        )
                    else:
                        check_suffix = "-NEXT" if not is_filtered else ""
                        output_lines.append(
                            "{} {}{}:  {}".format(
                                comment_marker, checkprefix, check_suffix, func_line
                            )
                        )

                # Add space between different check prefixes and also before the first
                # line of code in the test function.
                output_lines.append(comment_marker)

                # Remember new global variables we have not seen before
                for key in global_vars_seen:
                    if key not in global_vars_seen_before:
                        global_vars_seen_dict[checkprefix][key] = global_vars_seen[key]
                break
            # For IR output, change all defs to FileCheck variables, so we're immune
            # to variable naming fashions.
            else:
                func_body = generalize_check_lines(
                    func_body,
                    ginfo,
                    vars_seen,
                    global_vars_seen,
                    preserve_names,
                    original_check_lines=original_check_lines.get(checkprefix),
                )

                # This could be selectively enabled with an optional invocation argument.
                # Disabled for now: better to check everything. Be safe rather than sorry.

                # Handle the first line of the function body as a special case because
                # it's often just noise (a useless asm comment or entry label).
                # if func_body[0].startswith("#") or func_body[0].startswith("entry:"):
                #  is_blank_line = True
                # else:
                #  output_lines.append('%s %s:       %s' % (comment_marker, checkprefix, func_body[0]))
                #  is_blank_line = False

                is_blank_line = False

                for func_line in func_body:
                    if func_line.strip() == "":
                        is_blank_line = True
                        continue
                    # Do not waste time checking IR comments.
                    func_line = SCRUB_IR_COMMENT_RE.sub(r"", func_line)

                    # Skip blank lines instead of checking them.
                    if is_blank_line:
                        output_lines.append(
                            "{} {}:       {}".format(
                                comment_marker, checkprefix, func_line
                            )
                        )
                    else:
                        check_suffix = "-NEXT" if not is_filtered else ""
                        output_lines.append(
                            "{} {}{}:  {}".format(
                                comment_marker, checkprefix, check_suffix, func_line
                            )
                        )
                    is_blank_line = False

                # Add space between different check prefixes and also before the first
                # line of code in the test function.
                output_lines.append(comment_marker)

                # Remember new global variables we have not seen before
                for key in global_vars_seen:
                    if key not in global_vars_seen_before:
                        global_vars_seen_dict[checkprefix][key] = global_vars_seen[key]
                break
    return printed_prefixes


def add_ir_checks(
    output_lines,
    comment_marker,
    prefix_list,
    func_dict,
    func_name,
    preserve_names,
    function_sig,
    ginfo: GeneralizerInfo,
    global_vars_seen_dict,
    is_filtered,
    original_check_lines={},
):
    assert ginfo.is_ir()
    # Label format is based on IR string.
    if function_sig and ginfo.get_version() > 1:
        function_def_regex = "define %s"
    elif function_sig:
        function_def_regex = "define {{[^@]+}}%s"
    else:
        function_def_regex = "%s"
    check_label_format = "{} %s-LABEL: {}@%s%s%s".format(
        comment_marker, function_def_regex
    )
    return add_checks(
        output_lines,
        comment_marker,
        prefix_list,
        func_dict,
        func_name,
        check_label_format,
        ginfo,
        global_vars_seen_dict,
        is_filtered,
        preserve_names,
        original_check_lines=original_check_lines,
    )


def add_analyze_checks(
    output_lines,
    comment_marker,
    prefix_list,
    func_dict,
    func_name,
    ginfo: GeneralizerInfo,
    is_filtered,
):
    assert ginfo.is_analyze()
    check_label_format = "{} %s-LABEL: '%s%s%s%s'".format(comment_marker)
    global_vars_seen_dict = {}
    return add_checks(
        output_lines,
        comment_marker,
        prefix_list,
        func_dict,
        func_name,
        check_label_format,
        ginfo,
        global_vars_seen_dict,
        is_filtered,
    )


def build_global_values_dictionary(glob_val_dict, raw_tool_output, prefixes, ginfo):
    for nameless_value in ginfo.get_nameless_values():
        if nameless_value.global_ir_rhs_regexp is None:
            continue

        lhs_re_str = nameless_value.ir_prefix + nameless_value.ir_regexp
        rhs_re_str = nameless_value.global_ir_rhs_regexp

        global_ir_value_re_str = r"^" + lhs_re_str + r"\s=\s" + rhs_re_str + r"$"
        global_ir_value_re = re.compile(global_ir_value_re_str, flags=(re.M))
        lines = []
        for m in global_ir_value_re.finditer(raw_tool_output):
            # Attach the substring's start index so that CHECK lines
            # can be sorted properly even if they are matched by different nameless values.
            # This is relevant for GLOB and GLOBNAMED since they may appear interlaced.
            lines.append((m.start(), m.group(0)))

        for prefix in prefixes:
            if glob_val_dict[prefix] is None:
                continue
            if nameless_value.check_prefix in glob_val_dict[prefix]:
                if lines == glob_val_dict[prefix][nameless_value.check_prefix]:
                    continue
                if prefix == prefixes[-1]:
                    warn("Found conflicting asm under the same prefix: %r!" % (prefix,))
                else:
                    glob_val_dict[prefix][nameless_value.check_prefix] = None
                    continue
            glob_val_dict[prefix][nameless_value.check_prefix] = lines


def filter_globals_according_to_preference(
    global_val_lines_w_index, global_vars_seen, nameless_value, global_check_setting
):
    if global_check_setting == "none":
        return []
    if global_check_setting == "all":
        return global_val_lines_w_index
    assert global_check_setting == "smart"

    if nameless_value.check_key == "#":
        # attribute sets are usually better checked by --check-attributes
        return []

    def extract(line, nv):
        p = (
            "^"
            + nv.ir_prefix
            + "("
            + nv.ir_regexp
            + ") = ("
            + nv.global_ir_rhs_regexp
            + ")"
        )
        match = re.match(p, line)
        return (match.group(1), re.findall(nv.ir_regexp, match.group(2)))

    transitively_visible = set()
    contains_refs_to = {}

    def add(var):
        nonlocal transitively_visible
        nonlocal contains_refs_to
        if var in transitively_visible:
            return
        transitively_visible.add(var)
        if not var in contains_refs_to:
            return
        for x in contains_refs_to[var]:
            add(x)

    for i, line in global_val_lines_w_index:
        (var, refs) = extract(line, nameless_value)
        contains_refs_to[var] = refs
    for var, check_key in global_vars_seen:
        if check_key != nameless_value.check_key:
            continue
        add(var)
    return [
        (i, line)
        for i, line in global_val_lines_w_index
        if extract(line, nameless_value)[0] in transitively_visible
    ]


METADATA_FILTERS = [
    (
        r"(?<=\")(.+ )?(\w+ version )[\d.]+(?:[^\" ]*)(?: \([^)]+\))?",
        r"{{.*}}\2{{.*}}",
    ),  # preface with glob also, to capture optional CLANG_VENDOR
    (r'(!DIFile\(filename: ".+", directory: )".+"', r"\1{{.*}}"),
]
METADATA_FILTERS_RE = [(re.compile(f), r) for (f, r) in METADATA_FILTERS]


def filter_unstable_metadata(line):
    for f, replacement in METADATA_FILTERS_RE:
        line = f.sub(replacement, line)
    return line


def flush_current_checks(output_lines, new_lines_w_index, comment_marker):
    if not new_lines_w_index:
        return
    output_lines.append(comment_marker + SEPARATOR)
    new_lines_w_index.sort()
    for _, line in new_lines_w_index:
        output_lines.append(line)
    new_lines_w_index.clear()


def add_global_checks(
    glob_val_dict,
    comment_marker,
    prefix_list,
    output_lines,
    ginfo: GeneralizerInfo,
    global_vars_seen_dict,
    preserve_names,
    is_before_functions,
    global_check_setting,
):
    printed_prefixes = set()
    output_lines_loc = {}  # Allows GLOB and GLOBNAMED to be sorted correctly
    for nameless_value in ginfo.get_nameless_values():
        if nameless_value.global_ir_rhs_regexp is None:
            continue
        if nameless_value.is_before_functions != is_before_functions:
            continue
        for p in prefix_list:
            global_vars_seen = {}
            checkprefixes = p[0]
            if checkprefixes is None:
                continue
            for checkprefix in checkprefixes:
                if checkprefix in global_vars_seen_dict:
                    global_vars_seen.update(global_vars_seen_dict[checkprefix])
                else:
                    global_vars_seen_dict[checkprefix] = {}
                if (checkprefix, nameless_value.check_prefix) in printed_prefixes:
                    break
                if not glob_val_dict[checkprefix]:
                    continue
                if nameless_value.check_prefix not in glob_val_dict[checkprefix]:
                    continue
                if not glob_val_dict[checkprefix][nameless_value.check_prefix]:
                    continue

                check_lines = []
                global_vars_seen_before = [key for key in global_vars_seen.keys()]
                lines_w_index = glob_val_dict[checkprefix][nameless_value.check_prefix]
                lines_w_index = filter_globals_according_to_preference(
                    lines_w_index,
                    global_vars_seen_before,
                    nameless_value,
                    global_check_setting,
                )
                for i, line in lines_w_index:
                    if _global_value_regex:
                        matched = False
                        for regex in _global_value_regex:
                            if re.match("^@" + regex + " = ", line) or re.match(
                                "^!" + regex + " = ", line
                            ):
                                matched = True
                                break
                        if not matched:
                            continue
                    [new_line] = generalize_check_lines(
                        [line],
                        ginfo,
                        {},
                        global_vars_seen,
                        preserve_names,
                        unstable_globals_only=True,
                    )
                    new_line = filter_unstable_metadata(new_line)
                    check_line = "%s %s: %s" % (comment_marker, checkprefix, new_line)
                    check_lines.append((i, check_line))
                if not check_lines:
                    continue

                if not checkprefix in output_lines_loc:
                    output_lines_loc[checkprefix] = []
                if not nameless_value.interlaced_with_previous:
                    flush_current_checks(
                        output_lines, output_lines_loc[checkprefix], comment_marker
                    )
                for check_line in check_lines:
                    output_lines_loc[checkprefix].append(check_line)

                printed_prefixes.add((checkprefix, nameless_value.check_prefix))

                # Remembe new global variables we have not seen before
                for key in global_vars_seen:
                    if key not in global_vars_seen_before:
                        global_vars_seen_dict[checkprefix][key] = global_vars_seen[key]
                break

    if printed_prefixes:
        for p in prefix_list:
            if p[0] is None:
                continue
            for checkprefix in p[0]:
                if checkprefix not in output_lines_loc:
                    continue
                flush_current_checks(
                    output_lines, output_lines_loc[checkprefix], comment_marker
                )
                break
        output_lines.append(comment_marker + SEPARATOR)
    return printed_prefixes


def check_prefix(prefix):
    if not PREFIX_RE.match(prefix):
        hint = ""
        if "," in prefix:
            hint = " Did you mean '--check-prefixes=" + prefix + "'?"
        warn(
            (
                "Supplied prefix '%s' is invalid. Prefix must contain only alphanumeric characters, hyphens and underscores."
                + hint
            )
            % (prefix)
        )


def get_check_prefixes(filecheck_cmd):
    check_prefixes = [
        item
        for m in CHECK_PREFIX_RE.finditer(filecheck_cmd)
        for item in m.group(1).split(",")
    ]
    if not check_prefixes:
        check_prefixes = ["CHECK"]
    return check_prefixes


def verify_filecheck_prefixes(fc_cmd):
    fc_cmd_parts = fc_cmd.split()
    for part in fc_cmd_parts:
        if "check-prefix=" in part:
            prefix = part.split("=", 1)[1]
            check_prefix(prefix)
        elif "check-prefixes=" in part:
            prefixes = part.split("=", 1)[1].split(",")
            for prefix in prefixes:
                check_prefix(prefix)
                if prefixes.count(prefix) > 1:
                    warn(
                        "Supplied prefix '%s' is not unique in the prefix list."
                        % (prefix,)
                    )


def get_autogennote_suffix(parser, args):
    autogenerated_note_args = ""
    for action in parser._actions:
        if not hasattr(args, action.dest):
            continue  # Ignore options such as --help that aren't included in args
        # Ignore parameters such as paths to the binary or the list of tests
        if action.dest in (
            "tests",
            "update_only",
            "tool_binary",
            "opt_binary",
            "llc_binary",
            "clang",
            "opt",
            "llvm_bin",
            "verbose",
            "force_update",
            "reset_variable_names",
            "llvm_mc_binary",
        ):
            continue
        value = getattr(args, action.dest)
        if action.dest == "check_globals":
            default_value = "none" if args.version < 4 else "smart"
            if value == default_value:
                continue
            autogenerated_note_args += action.option_strings[0] + " "
            if args.version < 4 and value == "all":
                continue
            autogenerated_note_args += "%s " % value
            continue
        if action.const is not None:  # action stores a constant (usually True/False)
            # Skip actions with different constant values (this happens with boolean
            # --foo/--no-foo options)
            if value != action.const:
                continue
        if parser.get_default(action.dest) == value:
            continue  # Don't add default values
        if action.dest == "function_signature" and args.version >= 2:
            continue  # Enabled by default in version 2
        if action.dest == "filters":
            # Create a separate option for each filter element.  The value is a list
            # of Filter objects.
            for elem in value:
                opt_name = "filter-out" if elem.is_filter_out else "filter"
                opt_value = elem.pattern()
                new_arg = '--%s "%s" ' % (opt_name, opt_value.strip('"'))
                if new_arg not in autogenerated_note_args:
                    autogenerated_note_args += new_arg
        else:
            autogenerated_note_args += action.option_strings[0] + " "
            if action.const is None:  # action takes a parameter
                if action.nargs == "+":
                    value = " ".join(map(lambda v: '"' + v.strip('"') + '"', value))
                autogenerated_note_args += "%s " % value
    if autogenerated_note_args:
        autogenerated_note_args = " %s %s" % (
            UTC_ARGS_KEY,
            autogenerated_note_args[:-1],
        )
    return autogenerated_note_args


def check_for_command(line, parser, args, argv, argparse_callback):
    cmd_m = UTC_ARGS_CMD.match(line)
    if cmd_m:
        for option in shlex.split(cmd_m.group("cmd").strip()):
            if option:
                argv.append(option)
        args = parse_args(parser, filter(lambda arg: arg not in args.tests, argv))
        if argparse_callback is not None:
            argparse_callback(args)
    return args, argv


def find_arg_in_test(test_info, get_arg_to_check, arg_string, is_global):
    result = get_arg_to_check(test_info.args)
    if not result and is_global:
        # See if this has been specified via UTC_ARGS.  This is a "global" option
        # that affects the entire generation of test checks.  If it exists anywhere
        # in the test, apply it to everything.
        saw_line = False
        for line_info in test_info.ro_iterlines():
            line = line_info.line
            if not line.startswith(";") and line.strip() != "":
                saw_line = True
            result = get_arg_to_check(line_info.args)
            if result:
                if warn and saw_line:
                    # We saw the option after already reading some test input lines.
                    # Warn about it.
                    print(
                        "WARNING: Found {} in line following test start: ".format(
                            arg_string
                        )
                        + line,
                        file=sys.stderr,
                    )
                    print(
                        "WARNING: Consider moving {} to top of file".format(arg_string),
                        file=sys.stderr,
                    )
                break
    return result


def dump_input_lines(output_lines, test_info, prefix_set, comment_string):
    for input_line_info in test_info.iterlines(output_lines):
        line = input_line_info.line
        args = input_line_info.args
        if line.strip() == comment_string:
            continue
        if line.strip() == comment_string + SEPARATOR:
            continue
        if line.lstrip().startswith(comment_string):
            m = CHECK_RE.match(line)
            if m and m.group(1) in prefix_set:
                continue
        output_lines.append(line.rstrip("\n"))


def add_checks_at_end(
    output_lines, prefix_list, func_order, comment_string, check_generator
):
    added = set()
    generated_prefixes = set()
    for prefix in prefix_list:
        prefixes = prefix[0]
        tool_args = prefix[1]
        for prefix in prefixes:
            for func in func_order[prefix]:
                # The func order can contain the same functions multiple times.
                # If we see one again we are done.
                if (func, prefix) in added:
                    continue
                if added:
                    output_lines.append(comment_string)

                # The add_*_checks routines expect a run list whose items are
                # tuples that have a list of prefixes as their first element and
                # tool command args string as their second element.  They output
                # checks for each prefix in the list of prefixes.  By doing so, it
                # implicitly assumes that for each function every run line will
                # generate something for that function.  That is not the case for
                # generated functions as some run lines might not generate them
                # (e.g. -fopenmp vs. no -fopenmp).
                #
                # Therefore, pass just the prefix we're interested in.  This has
                # the effect of generating all of the checks for functions of a
                # single prefix before moving on to the next prefix.  So checks
                # are ordered by prefix instead of by function as in "normal"
                # mode.
                for generated_prefix in check_generator(
                    output_lines, [([prefix], tool_args)], func
                ):
                    added.add((func, generated_prefix))
                    generated_prefixes.add(generated_prefix)
    return generated_prefixes
