140 lines · python
1#!/usr/bin/env python32 3"""Updates FileCheck checks in GlobalISel Known Bits tests.4 5This script is a utility to update MIR based tests with new FileCheck6patterns for GlobalISel Known Bits.7 8The checks added by this script are similar to update_mir_test_checks, using9the output of KnownBits and SignBits from -passes=print<gisel-value-tracking>.10"""11 12from __future__ import print_function13 14from sys import stderr15from traceback import print_exc16import argparse17import os18import re19import sys20 21from UpdateTestChecks import common22from UpdateTestChecks import mir23 24VT_FUNCTION_RE = re.compile(25 r"\s*name:\s*@(?P<func>[A-Za-z0-9_-]+)"26 r"(?P<body>(\s*%[0-9a-zA-Z_]+:[A-Za-z0-9_-]+\s*KnownBits:[01?]+\sSignBits:[0-9]+$)+)",27 flags=(re.X | re.M),28)29 30 31def update_test(ti: common.TestInfo):32 run_list = []33 for l in ti.run_lines:34 if "|" not in l:35 common.warn("Skipping unparsable RUN line: " + l)36 continue37 38 (llc_cmd, filecheck_cmd) = tuple([cmd.strip() for cmd in l.split("|", 1)])39 common.verify_filecheck_prefixes(filecheck_cmd)40 41 if not llc_cmd.startswith("llc "):42 common.warn("Skipping non-llc RUN line: " + l)43 continue44 45 if not filecheck_cmd.startswith("FileCheck "):46 common.warn("Skipping non-FileChecked RUN line: " + l)47 continue48 49 llc_cmd_args = llc_cmd[4:].strip()50 llc_cmd_args = llc_cmd_args.replace("< %s", "").replace("%s", "").strip()51 check_prefixes = common.get_check_prefixes(filecheck_cmd)52 53 run_list.append((check_prefixes, llc_cmd_args))54 55 ginfo = common.make_analyze_generalizer(version=1)56 builder = common.FunctionTestBuilder(57 run_list=run_list,58 flags=type(59 "",60 (object,),61 {62 "verbose": ti.args.verbose,63 "filters": ti.args.filters,64 "function_signature": False,65 "check_attributes": False,66 "replace_value_regex": [],67 },68 ),69 scrubber_args=[],70 path=ti.path,71 ginfo=ginfo,72 )73 74 for prefixes, llc_args in run_list:75 common.debug("Extracted llc cmd:", "llc", llc_args)76 common.debug("Extracted FileCheck prefixes:", str(prefixes))77 78 if ti.path.endswith(".mir"):79 llc_args += " -x mir"80 raw_tool_output = common.invoke_tool(81 ti.args.llc_binary or "llc", llc_args, ti.path, verbose=ti.args.verbose82 )83 84 builder.process_run_line(85 VT_FUNCTION_RE,86 common.scrub_body,87 raw_tool_output,88 prefixes,89 )90 91 builder.processed_prefixes(prefixes)92 93 func_dict = builder.finish_and_get_func_dict()94 prefix_set = set([prefix for p in run_list for prefix in p[0]])95 common.debug("Rewriting FileCheck prefixes:", str(prefix_set))96 output_lines = mir.add_mir_checks(97 ti.input_lines,98 prefix_set,99 ti.test_autogenerated_note,100 ti.path,101 run_list,102 func_dict,103 print_fixed_stack=False,104 first_check_is_next=True,105 at_the_function_name=True,106 )107 108 common.debug("Writing %d lines to %s..." % (len(output_lines), ti.path))109 110 with open(ti.path, "wb") as f:111 f.writelines(["{}\n".format(l).encode("utf-8") for l in output_lines])112 113 114def main():115 parser = argparse.ArgumentParser(116 description=__doc__, formatter_class=argparse.RawTextHelpFormatter117 )118 parser.add_argument(119 "--llc-binary",120 default=None,121 help='The "llc" binary to generate the test case with',122 )123 parser.add_argument("tests", nargs="+")124 args = common.parse_commandline_args(parser)125 126 script_name = os.path.basename(__file__)127 returncode = 0128 for ti in common.itertests(args.tests, parser, script_name="utils/" + script_name):129 try:130 update_test(ti)131 except Exception:132 stderr.write(f"Error: Failed to update test {ti.path}\n")133 print_exc()134 returncode = 1135 return returncode136 137 138if __name__ == "__main__":139 sys.exit(main())140