xref: /netbsd-src/external/apache2/llvm/dist/llvm/utils/update_mir_test_checks.py (revision 82d56013d7b633d116a93943de88e08335357a7c)
1*82d56013Sjoerg#!/usr/bin/env python3
27330f729Sjoerg
37330f729Sjoerg"""Updates FileCheck checks in MIR tests.
47330f729Sjoerg
57330f729SjoergThis script is a utility to update MIR based tests with new FileCheck
67330f729Sjoergpatterns.
77330f729Sjoerg
87330f729SjoergThe checks added by this script will cover the entire body of each
97330f729Sjoergfunction it handles. Virtual registers used are given names via
107330f729SjoergFileCheck patterns, so if you do want to check a subset of the body it
117330f729Sjoergshould be straightforward to trim out the irrelevant parts. None of
127330f729Sjoergthe YAML metadata will be checked, other than function names.
137330f729Sjoerg
147330f729SjoergIf there are multiple llc commands in a test, the full set of checks
157330f729Sjoergwill be repeated for each different check pattern. Checks for patterns
167330f729Sjoergthat are common between different commands will be left as-is by
177330f729Sjoergdefault, or removed if the --remove-common-prefixes flag is provided.
187330f729Sjoerg"""
197330f729Sjoerg
207330f729Sjoergfrom __future__ import print_function
217330f729Sjoerg
227330f729Sjoergimport argparse
237330f729Sjoergimport collections
247330f729Sjoergimport glob
257330f729Sjoergimport os
267330f729Sjoergimport re
277330f729Sjoergimport subprocess
287330f729Sjoergimport sys
297330f729Sjoerg
307330f729Sjoergfrom UpdateTestChecks import common
317330f729Sjoerg
327330f729SjoergMIR_FUNC_NAME_RE = re.compile(r' *name: *(?P<func>[A-Za-z0-9_.-]+)')
337330f729SjoergMIR_BODY_BEGIN_RE = re.compile(r' *body: *\|')
347330f729SjoergMIR_BASIC_BLOCK_RE = re.compile(r' *bb\.[0-9]+.*:$')
357330f729SjoergVREG_RE = re.compile(r'(%[0-9]+)(?::[a-z0-9_]+)?(?:\([<>a-z0-9 ]+\))?')
367330f729SjoergMI_FLAGS_STR= (
377330f729Sjoerg    r'(frame-setup |frame-destroy |nnan |ninf |nsz |arcp |contract |afn '
387330f729Sjoerg    r'|reassoc |nuw |nsw |exact |fpexcept )*')
397330f729SjoergVREG_DEF_RE = re.compile(
407330f729Sjoerg    r'^ *(?P<vregs>{0}(?:, {0})*) = '
417330f729Sjoerg    r'{1}(?P<opcode>[A-Zt][A-Za-z0-9_]+)'.format(VREG_RE.pattern, MI_FLAGS_STR))
427330f729SjoergMIR_PREFIX_DATA_RE = re.compile(r'^ *(;|bb.[0-9].*: *$|[a-z]+:( |$)|$)')
437330f729Sjoerg
447330f729SjoergIR_FUNC_NAME_RE = re.compile(
457330f729Sjoerg    r'^\s*define\s+(?:internal\s+)?[^@]*@(?P<func>[A-Za-z0-9_.]+)\s*\(')
467330f729SjoergIR_PREFIX_DATA_RE = re.compile(r'^ *(;|$)')
477330f729Sjoerg
487330f729SjoergMIR_FUNC_RE = re.compile(
497330f729Sjoerg    r'^---$'
507330f729Sjoerg    r'\n'
517330f729Sjoerg    r'^ *name: *(?P<func>[A-Za-z0-9_.-]+)$'
527330f729Sjoerg    r'.*?'
537330f729Sjoerg    r'^ *body: *\|\n'
547330f729Sjoerg    r'(?P<body>.*?)\n'
557330f729Sjoerg    r'^\.\.\.$',
567330f729Sjoerg    flags=(re.M | re.S))
577330f729Sjoerg
587330f729Sjoerg
597330f729Sjoergclass LLC:
607330f729Sjoerg    def __init__(self, bin):
617330f729Sjoerg        self.bin = bin
627330f729Sjoerg
637330f729Sjoerg    def __call__(self, args, ir):
647330f729Sjoerg        if ir.endswith('.mir'):
657330f729Sjoerg            args = '{} -x mir'.format(args)
667330f729Sjoerg        with open(ir) as ir_file:
677330f729Sjoerg            stdout = subprocess.check_output('{} {}'.format(self.bin, args),
687330f729Sjoerg                                             shell=True, stdin=ir_file)
697330f729Sjoerg            if sys.version_info[0] > 2:
707330f729Sjoerg              stdout = stdout.decode()
717330f729Sjoerg            # Fix line endings to unix CR style.
727330f729Sjoerg            stdout = stdout.replace('\r\n', '\n')
737330f729Sjoerg        return stdout
747330f729Sjoerg
757330f729Sjoerg
767330f729Sjoergclass Run:
777330f729Sjoerg    def __init__(self, prefixes, cmd_args, triple):
787330f729Sjoerg        self.prefixes = prefixes
797330f729Sjoerg        self.cmd_args = cmd_args
807330f729Sjoerg        self.triple = triple
817330f729Sjoerg
827330f729Sjoerg    def __getitem__(self, index):
837330f729Sjoerg        return [self.prefixes, self.cmd_args, self.triple][index]
847330f729Sjoerg
857330f729Sjoerg
867330f729Sjoergdef log(msg, verbose=True):
877330f729Sjoerg    if verbose:
887330f729Sjoerg        print(msg, file=sys.stderr)
897330f729Sjoerg
907330f729Sjoerg
917330f729Sjoergdef find_triple_in_ir(lines, verbose=False):
927330f729Sjoerg    for l in lines:
937330f729Sjoerg        m = common.TRIPLE_IR_RE.match(l)
947330f729Sjoerg        if m:
957330f729Sjoerg            return m.group(1)
967330f729Sjoerg    return None
977330f729Sjoerg
987330f729Sjoerg
997330f729Sjoergdef build_run_list(test, run_lines, verbose=False):
1007330f729Sjoerg    run_list = []
1017330f729Sjoerg    all_prefixes = []
1027330f729Sjoerg    for l in run_lines:
1037330f729Sjoerg        if '|' not in l:
1047330f729Sjoerg            common.warn('Skipping unparseable RUN line: ' + l)
1057330f729Sjoerg            continue
1067330f729Sjoerg
1077330f729Sjoerg        commands = [cmd.strip() for cmd in l.split('|', 1)]
1087330f729Sjoerg        llc_cmd = commands[0]
1097330f729Sjoerg        filecheck_cmd = commands[1] if len(commands) > 1 else ''
1107330f729Sjoerg        common.verify_filecheck_prefixes(filecheck_cmd)
1117330f729Sjoerg
1127330f729Sjoerg        if not llc_cmd.startswith('llc '):
1137330f729Sjoerg            common.warn('Skipping non-llc RUN line: {}'.format(l), test_file=test)
1147330f729Sjoerg            continue
1157330f729Sjoerg        if not filecheck_cmd.startswith('FileCheck '):
1167330f729Sjoerg            common.warn('Skipping non-FileChecked RUN line: {}'.format(l),
1177330f729Sjoerg                 test_file=test)
1187330f729Sjoerg            continue
1197330f729Sjoerg
1207330f729Sjoerg        triple = None
1217330f729Sjoerg        m = common.TRIPLE_ARG_RE.search(llc_cmd)
1227330f729Sjoerg        if m:
1237330f729Sjoerg            triple = m.group(1)
1247330f729Sjoerg        # If we find -march but not -mtriple, use that.
1257330f729Sjoerg        m = common.MARCH_ARG_RE.search(llc_cmd)
1267330f729Sjoerg        if m and not triple:
1277330f729Sjoerg            triple = '{}--'.format(m.group(1))
1287330f729Sjoerg
1297330f729Sjoerg        cmd_args = llc_cmd[len('llc'):].strip()
1307330f729Sjoerg        cmd_args = cmd_args.replace('< %s', '').replace('%s', '').strip()
1317330f729Sjoerg
1327330f729Sjoerg        check_prefixes = [
1337330f729Sjoerg            item
1347330f729Sjoerg            for m in common.CHECK_PREFIX_RE.finditer(filecheck_cmd)
1357330f729Sjoerg            for item in m.group(1).split(',')]
1367330f729Sjoerg        if not check_prefixes:
1377330f729Sjoerg            check_prefixes = ['CHECK']
1387330f729Sjoerg        all_prefixes += check_prefixes
1397330f729Sjoerg
1407330f729Sjoerg        run_list.append(Run(check_prefixes, cmd_args, triple))
1417330f729Sjoerg
1427330f729Sjoerg    # Remove any common prefixes. We'll just leave those entirely alone.
1437330f729Sjoerg    common_prefixes = set([prefix for prefix in all_prefixes
1447330f729Sjoerg                           if all_prefixes.count(prefix) > 1])
1457330f729Sjoerg    for run in run_list:
1467330f729Sjoerg        run.prefixes = [p for p in run.prefixes if p not in common_prefixes]
1477330f729Sjoerg
1487330f729Sjoerg    return run_list, common_prefixes
1497330f729Sjoerg
1507330f729Sjoerg
1517330f729Sjoergdef find_functions_with_one_bb(lines, verbose=False):
1527330f729Sjoerg    result = []
1537330f729Sjoerg    cur_func = None
1547330f729Sjoerg    bbs = 0
1557330f729Sjoerg    for line in lines:
1567330f729Sjoerg        m = MIR_FUNC_NAME_RE.match(line)
1577330f729Sjoerg        if m:
1587330f729Sjoerg            if bbs == 1:
1597330f729Sjoerg                result.append(cur_func)
1607330f729Sjoerg            cur_func = m.group('func')
1617330f729Sjoerg            bbs = 0
1627330f729Sjoerg        m = MIR_BASIC_BLOCK_RE.match(line)
1637330f729Sjoerg        if m:
1647330f729Sjoerg            bbs += 1
1657330f729Sjoerg    if bbs == 1:
1667330f729Sjoerg        result.append(cur_func)
1677330f729Sjoerg    return result
1687330f729Sjoerg
1697330f729Sjoerg
1707330f729Sjoergdef build_function_body_dictionary(test, raw_tool_output, triple, prefixes,
1717330f729Sjoerg                                   func_dict, verbose):
1727330f729Sjoerg    for m in MIR_FUNC_RE.finditer(raw_tool_output):
1737330f729Sjoerg        func = m.group('func')
1747330f729Sjoerg        body = m.group('body')
1757330f729Sjoerg        if verbose:
1767330f729Sjoerg            log('Processing function: {}'.format(func))
1777330f729Sjoerg            for l in body.splitlines():
1787330f729Sjoerg                log('  {}'.format(l))
1797330f729Sjoerg        for prefix in prefixes:
1807330f729Sjoerg            if func in func_dict[prefix] and func_dict[prefix][func] != body:
1817330f729Sjoerg                common.warn('Found conflicting asm for prefix: {}'.format(prefix),
1827330f729Sjoerg                     test_file=test)
1837330f729Sjoerg            func_dict[prefix][func] = body
1847330f729Sjoerg
1857330f729Sjoerg
1867330f729Sjoergdef add_checks_for_function(test, output_lines, run_list, func_dict, func_name,
1877330f729Sjoerg                            single_bb, verbose=False):
1887330f729Sjoerg    printed_prefixes = set()
1897330f729Sjoerg    for run in run_list:
1907330f729Sjoerg        for prefix in run.prefixes:
1917330f729Sjoerg            if prefix in printed_prefixes:
1927330f729Sjoerg                continue
1937330f729Sjoerg            if not func_dict[prefix][func_name]:
1947330f729Sjoerg                continue
1957330f729Sjoerg            # if printed_prefixes:
1967330f729Sjoerg            #     # Add some space between different check prefixes.
1977330f729Sjoerg            #     output_lines.append('')
1987330f729Sjoerg            printed_prefixes.add(prefix)
1997330f729Sjoerg            log('Adding {} lines for {}'.format(prefix, func_name), verbose)
2007330f729Sjoerg            add_check_lines(test, output_lines, prefix, func_name, single_bb,
2017330f729Sjoerg                            func_dict[prefix][func_name].splitlines())
2027330f729Sjoerg            break
2037330f729Sjoerg    return output_lines
2047330f729Sjoerg
2057330f729Sjoerg
2067330f729Sjoergdef add_check_lines(test, output_lines, prefix, func_name, single_bb,
2077330f729Sjoerg                    func_body):
2087330f729Sjoerg    if single_bb:
2097330f729Sjoerg        # Don't bother checking the basic block label for a single BB
2107330f729Sjoerg        func_body.pop(0)
2117330f729Sjoerg
2127330f729Sjoerg    if not func_body:
2137330f729Sjoerg        common.warn('Function has no instructions to check: {}'.format(func_name),
2147330f729Sjoerg             test_file=test)
2157330f729Sjoerg        return
2167330f729Sjoerg
2177330f729Sjoerg    first_line = func_body[0]
2187330f729Sjoerg    indent = len(first_line) - len(first_line.lstrip(' '))
2197330f729Sjoerg    # A check comment, indented the appropriate amount
2207330f729Sjoerg    check = '{:>{}}; {}'.format('', indent, prefix)
2217330f729Sjoerg
2227330f729Sjoerg    output_lines.append('{}-LABEL: name: {}'.format(check, func_name))
2237330f729Sjoerg
2247330f729Sjoerg    vreg_map = {}
2257330f729Sjoerg    for func_line in func_body:
2267330f729Sjoerg        if not func_line.strip():
2277330f729Sjoerg            continue
2287330f729Sjoerg        m = VREG_DEF_RE.match(func_line)
2297330f729Sjoerg        if m:
2307330f729Sjoerg            for vreg in VREG_RE.finditer(m.group('vregs')):
2317330f729Sjoerg                name = mangle_vreg(m.group('opcode'), vreg_map.values())
2327330f729Sjoerg                vreg_map[vreg.group(1)] = name
2337330f729Sjoerg                func_line = func_line.replace(
2347330f729Sjoerg                    vreg.group(1), '[[{}:%[0-9]+]]'.format(name), 1)
2357330f729Sjoerg        for number, name in vreg_map.items():
2367330f729Sjoerg            func_line = re.sub(r'{}\b'.format(number), '[[{}]]'.format(name),
2377330f729Sjoerg                               func_line)
2387330f729Sjoerg        check_line = '{}: {}'.format(check, func_line[indent:]).rstrip()
2397330f729Sjoerg        output_lines.append(check_line)
2407330f729Sjoerg
2417330f729Sjoerg
2427330f729Sjoergdef mangle_vreg(opcode, current_names):
2437330f729Sjoerg    base = opcode
2447330f729Sjoerg    # Simplify some common prefixes and suffixes
2457330f729Sjoerg    if opcode.startswith('G_'):
2467330f729Sjoerg        base = base[len('G_'):]
2477330f729Sjoerg    if opcode.endswith('_PSEUDO'):
2487330f729Sjoerg        base = base[:len('_PSEUDO')]
2497330f729Sjoerg    # Shorten some common opcodes with long-ish names
2507330f729Sjoerg    base = dict(IMPLICIT_DEF='DEF',
2517330f729Sjoerg                GLOBAL_VALUE='GV',
2527330f729Sjoerg                CONSTANT='C',
2537330f729Sjoerg                FCONSTANT='C',
2547330f729Sjoerg                MERGE_VALUES='MV',
2557330f729Sjoerg                UNMERGE_VALUES='UV',
2567330f729Sjoerg                INTRINSIC='INT',
2577330f729Sjoerg                INTRINSIC_W_SIDE_EFFECTS='INT',
2587330f729Sjoerg                INSERT_VECTOR_ELT='IVEC',
2597330f729Sjoerg                EXTRACT_VECTOR_ELT='EVEC',
2607330f729Sjoerg                SHUFFLE_VECTOR='SHUF').get(base, base)
2617330f729Sjoerg    # Avoid ambiguity when opcodes end in numbers
2627330f729Sjoerg    if len(base.rstrip('0123456789')) < len(base):
2637330f729Sjoerg        base += '_'
2647330f729Sjoerg
2657330f729Sjoerg    i = 0
2667330f729Sjoerg    for name in current_names:
2677330f729Sjoerg        if name.rstrip('0123456789') == base:
2687330f729Sjoerg            i += 1
2697330f729Sjoerg    if i:
2707330f729Sjoerg        return '{}{}'.format(base, i)
2717330f729Sjoerg    return base
2727330f729Sjoerg
2737330f729Sjoerg
2747330f729Sjoergdef should_add_line_to_output(input_line, prefix_set):
2757330f729Sjoerg    # Skip any check lines that we're handling.
2767330f729Sjoerg    m = common.CHECK_RE.match(input_line)
2777330f729Sjoerg    if m and m.group(1) in prefix_set:
2787330f729Sjoerg        return False
2797330f729Sjoerg    return True
2807330f729Sjoerg
2817330f729Sjoerg
2827330f729Sjoergdef update_test_file(args, test):
2837330f729Sjoerg    with open(test) as fd:
2847330f729Sjoerg        input_lines = [l.rstrip() for l in fd]
2857330f729Sjoerg
2867330f729Sjoerg    script_name = os.path.basename(__file__)
2877330f729Sjoerg    first_line = input_lines[0] if input_lines else ""
2887330f729Sjoerg    if 'autogenerated' in first_line and script_name not in first_line:
2897330f729Sjoerg        common.warn("Skipping test which wasn't autogenerated by " +
2907330f729Sjoerg                    script_name + ": " + test)
2917330f729Sjoerg        return
2927330f729Sjoerg
2937330f729Sjoerg    if args.update_only:
2947330f729Sjoerg      if not first_line or 'autogenerated' not in first_line:
2957330f729Sjoerg        common.warn("Skipping test which isn't autogenerated: " + test)
2967330f729Sjoerg        return
2977330f729Sjoerg
2987330f729Sjoerg    triple_in_ir = find_triple_in_ir(input_lines, args.verbose)
299*82d56013Sjoerg    run_lines = common.find_run_lines(test, input_lines)
3007330f729Sjoerg    run_list, common_prefixes = build_run_list(test, run_lines, args.verbose)
3017330f729Sjoerg
3027330f729Sjoerg    simple_functions = find_functions_with_one_bb(input_lines, args.verbose)
3037330f729Sjoerg
3047330f729Sjoerg    func_dict = {}
3057330f729Sjoerg    for run in run_list:
3067330f729Sjoerg        for prefix in run.prefixes:
3077330f729Sjoerg            func_dict.update({prefix: dict()})
3087330f729Sjoerg    for prefixes, llc_args, triple_in_cmd in run_list:
3097330f729Sjoerg        log('Extracted LLC cmd: llc {}'.format(llc_args), args.verbose)
3107330f729Sjoerg        log('Extracted FileCheck prefixes: {}'.format(prefixes), args.verbose)
3117330f729Sjoerg
3127330f729Sjoerg        raw_tool_output = args.llc(llc_args, test)
3137330f729Sjoerg        if not triple_in_cmd and not triple_in_ir:
3147330f729Sjoerg            common.warn('No triple found: skipping file', test_file=test)
3157330f729Sjoerg            return
3167330f729Sjoerg
3177330f729Sjoerg        build_function_body_dictionary(test, raw_tool_output,
3187330f729Sjoerg                                       triple_in_cmd or triple_in_ir,
3197330f729Sjoerg                                       prefixes, func_dict, args.verbose)
3207330f729Sjoerg
3217330f729Sjoerg    state = 'toplevel'
3227330f729Sjoerg    func_name = None
3237330f729Sjoerg    prefix_set = set([prefix for run in run_list for prefix in run.prefixes])
3247330f729Sjoerg    log('Rewriting FileCheck prefixes: {}'.format(prefix_set), args.verbose)
3257330f729Sjoerg
3267330f729Sjoerg    if args.remove_common_prefixes:
3277330f729Sjoerg        prefix_set.update(common_prefixes)
3287330f729Sjoerg    elif common_prefixes:
3297330f729Sjoerg        common.warn('Ignoring common prefixes: {}'.format(common_prefixes),
3307330f729Sjoerg             test_file=test)
3317330f729Sjoerg
3327330f729Sjoerg    comment_char = '#' if test.endswith('.mir') else ';'
3337330f729Sjoerg    autogenerated_note = ('{} NOTE: Assertions have been autogenerated by '
3347330f729Sjoerg                          'utils/{}'.format(comment_char, script_name))
3357330f729Sjoerg    output_lines = []
3367330f729Sjoerg    output_lines.append(autogenerated_note)
3377330f729Sjoerg
3387330f729Sjoerg    for input_line in input_lines:
3397330f729Sjoerg        if input_line == autogenerated_note:
3407330f729Sjoerg            continue
3417330f729Sjoerg
3427330f729Sjoerg        if state == 'toplevel':
3437330f729Sjoerg            m = IR_FUNC_NAME_RE.match(input_line)
3447330f729Sjoerg            if m:
3457330f729Sjoerg                state = 'ir function prefix'
3467330f729Sjoerg                func_name = m.group('func')
3477330f729Sjoerg            if input_line.rstrip('| \r\n') == '---':
3487330f729Sjoerg                state = 'document'
3497330f729Sjoerg            output_lines.append(input_line)
3507330f729Sjoerg        elif state == 'document':
3517330f729Sjoerg            m = MIR_FUNC_NAME_RE.match(input_line)
3527330f729Sjoerg            if m:
3537330f729Sjoerg                state = 'mir function metadata'
3547330f729Sjoerg                func_name = m.group('func')
3557330f729Sjoerg            if input_line.strip() == '...':
3567330f729Sjoerg                state = 'toplevel'
3577330f729Sjoerg                func_name = None
3587330f729Sjoerg            if should_add_line_to_output(input_line, prefix_set):
3597330f729Sjoerg                output_lines.append(input_line)
3607330f729Sjoerg        elif state == 'mir function metadata':
3617330f729Sjoerg            if should_add_line_to_output(input_line, prefix_set):
3627330f729Sjoerg                output_lines.append(input_line)
3637330f729Sjoerg            m = MIR_BODY_BEGIN_RE.match(input_line)
3647330f729Sjoerg            if m:
3657330f729Sjoerg                if func_name in simple_functions:
3667330f729Sjoerg                    # If there's only one block, put the checks inside it
3677330f729Sjoerg                    state = 'mir function prefix'
3687330f729Sjoerg                    continue
3697330f729Sjoerg                state = 'mir function body'
3707330f729Sjoerg                add_checks_for_function(test, output_lines, run_list,
3717330f729Sjoerg                                        func_dict, func_name, single_bb=False,
3727330f729Sjoerg                                        verbose=args.verbose)
3737330f729Sjoerg        elif state == 'mir function prefix':
3747330f729Sjoerg            m = MIR_PREFIX_DATA_RE.match(input_line)
3757330f729Sjoerg            if not m:
3767330f729Sjoerg                state = 'mir function body'
3777330f729Sjoerg                add_checks_for_function(test, output_lines, run_list,
3787330f729Sjoerg                                        func_dict, func_name, single_bb=True,
3797330f729Sjoerg                                        verbose=args.verbose)
3807330f729Sjoerg
3817330f729Sjoerg            if should_add_line_to_output(input_line, prefix_set):
3827330f729Sjoerg                output_lines.append(input_line)
3837330f729Sjoerg        elif state == 'mir function body':
3847330f729Sjoerg            if input_line.strip() == '...':
3857330f729Sjoerg                state = 'toplevel'
3867330f729Sjoerg                func_name = None
3877330f729Sjoerg            if should_add_line_to_output(input_line, prefix_set):
3887330f729Sjoerg                output_lines.append(input_line)
3897330f729Sjoerg        elif state == 'ir function prefix':
3907330f729Sjoerg            m = IR_PREFIX_DATA_RE.match(input_line)
3917330f729Sjoerg            if not m:
3927330f729Sjoerg                state = 'ir function body'
3937330f729Sjoerg                add_checks_for_function(test, output_lines, run_list,
3947330f729Sjoerg                                        func_dict, func_name, single_bb=False,
3957330f729Sjoerg                                        verbose=args.verbose)
3967330f729Sjoerg
3977330f729Sjoerg            if should_add_line_to_output(input_line, prefix_set):
3987330f729Sjoerg                output_lines.append(input_line)
3997330f729Sjoerg        elif state == 'ir function body':
4007330f729Sjoerg            if input_line.strip() == '}':
4017330f729Sjoerg                state = 'toplevel'
4027330f729Sjoerg                func_name = None
4037330f729Sjoerg            if should_add_line_to_output(input_line, prefix_set):
4047330f729Sjoerg                output_lines.append(input_line)
4057330f729Sjoerg
4067330f729Sjoerg
4077330f729Sjoerg    log('Writing {} lines to {}...'.format(len(output_lines), test), args.verbose)
4087330f729Sjoerg
4097330f729Sjoerg    with open(test, 'wb') as fd:
4107330f729Sjoerg        fd.writelines(['{}\n'.format(l).encode('utf-8') for l in output_lines])
4117330f729Sjoerg
4127330f729Sjoerg
4137330f729Sjoergdef main():
4147330f729Sjoerg    parser = argparse.ArgumentParser(
4157330f729Sjoerg        description=__doc__, formatter_class=argparse.RawTextHelpFormatter)
4167330f729Sjoerg    parser.add_argument('--llc-binary', dest='llc', default='llc', type=LLC,
4177330f729Sjoerg                        help='The "llc" binary to generate the test case with')
4187330f729Sjoerg    parser.add_argument('--remove-common-prefixes', action='store_true',
4197330f729Sjoerg                        help='Remove existing check lines whose prefixes are '
4207330f729Sjoerg                             'shared between multiple commands')
4217330f729Sjoerg    parser.add_argument('tests', nargs='+')
422*82d56013Sjoerg    args = common.parse_commandline_args(parser)
4237330f729Sjoerg
4247330f729Sjoerg    test_paths = [test for pattern in args.tests for test in glob.glob(pattern)]
4257330f729Sjoerg    for test in test_paths:
4267330f729Sjoerg        try:
4277330f729Sjoerg            update_test_file(args, test)
4287330f729Sjoerg        except Exception:
4297330f729Sjoerg            common.warn('Error processing file', test_file=test)
4307330f729Sjoerg            raise
4317330f729Sjoerg
4327330f729Sjoerg
4337330f729Sjoergif __name__ == '__main__':
4347330f729Sjoerg  main()
435