Index: utils/UpdateTestChecks/common.py =================================================================== --- utils/UpdateTestChecks/common.py +++ utils/UpdateTestChecks/common.py @@ -72,6 +72,11 @@ SCRUB_LOOP_COMMENT_RE = re.compile( r'# =>This Inner Loop Header:.*|# in Loop:.*', flags=re.M) +def warn(msg, test_file=None): + if test_file: + msg = '{}: {}'.format(test_file, msg) + print('WARNING: {}'.format(msg), file=sys.stderr) + def scrub_body(body): # Scrub runs of whitespace out of the assembly, but leave the leading # whitespace in place. @@ -108,7 +113,7 @@ if 'analysis' in m.groupdict(): analysis = m.group('analysis') if analysis.lower() != 'cost model analysis': - print('WARNING: Unsupported analysis mode: %r!' % (analysis,), file=sys.stderr) + 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:]) @@ -123,8 +128,7 @@ continue else: if prefix == prefixes[-1]: - print('WARNING: Found conflicting asm under the ' - 'same prefix: %r!' % (prefix,), file=sys.stderr) + warn('Found conflicting asm under the same prefix: %r!' % (prefix,)) else: func_dict[prefix][func] = None continue @@ -272,8 +276,8 @@ hint = "" if ',' in prefix: hint = " Did you mean '--check-prefixes=" + prefix + "'?" - print(("WARNING: Supplied prefix '%s' is invalid. Prefix must contain only alphanumeric characters, hyphens and underscores." + hint) % - (prefix), file=sys.stderr) + warn(("Supplied prefix '%s' is invalid. Prefix must contain only alphanumeric characters, hyphens and underscores." + hint) % + (prefix)) def verify_filecheck_prefixes(fc_cmd): @@ -287,5 +291,8 @@ for prefix in prefixes: check_prefix(prefix) if prefixes.count(prefix) > 1: - print("WARNING: Supplied prefix '%s' is not unique in the prefix list." % - (prefix,), file=sys.stderr) + warn("Supplied prefix '%s' is not unique in the prefix list." % + (prefix,)) + +def is_autogenerated_test_file(input_lines): + return len(input_lines) > 0 and 'autogenerated' in input_lines[0] Index: utils/update_analyze_test_checks.py =================================================================== --- utils/update_analyze_test_checks.py +++ utils/update_analyze_test_checks.py @@ -56,6 +56,8 @@ help='Show verbose output') parser.add_argument('--opt-binary', default='opt', help='The opt binary used to generate the test case') + parser.add_argument('-u', '--update-only', action='store_true', + help='Only update test if it was already autogened') parser.add_argument( '--function', help='The function in the test file to update') parser.add_argument('tests', nargs='+') @@ -75,6 +77,11 @@ with open(test) as f: input_lines = [l.rstrip() for l in f] + if args.update_only: + if not common.is_autogenerated_test_file(input_lines): + common.warn('Skipping test which isn\'t autogenerated: %s' % (test)) + continue + raw_lines = [m.group(1) for m in [common.RUN_LINE_RE.match(l) for l in input_lines] if m] run_lines = [raw_lines[0]] if len(raw_lines) > 0 else [] @@ -91,15 +98,19 @@ prefix_list = [] for l in run_lines: + if '|' not in l: + common.warn('Skipping unparseable RUN line: %s' % (l,)) + continue + (tool_cmd, filecheck_cmd) = tuple([cmd.strip() for cmd in l.split('|', 1)]) common.verify_filecheck_prefixes(filecheck_cmd) if not tool_cmd.startswith(opt_basename + ' '): - print('WARNING: Skipping non-%s RUN line: %s' % (opt_basename, l), file=sys.stderr) + common.warn('Skipping non-%s RUN line: %s' % (opt_basename, l)) continue if not filecheck_cmd.startswith('FileCheck '): - print('WARNING: Skipping non-FileChecked RUN line: ' + l, file=sys.stderr) + common.warn('Skipping non-FileChecked RUN line: ' + l) continue tool_cmd_args = tool_cmd[len(opt_basename):].strip() Index: utils/update_cc_test_checks.py =================================================================== --- utils/update_cc_test_checks.py +++ utils/update_cc_test_checks.py @@ -86,6 +86,8 @@ parser.add_argument( '--x86_extra_scrub', action='store_true', help='Use more regex for x86 matching to reduce diffs between various subtargets') + parser.add_argument('-u', '--update-only', action='store_true', + help='Only update test if it was already autogened') parser.add_argument('tests', nargs='+') args = parser.parse_args() args.clang_args = shlex.split(args.clang_args or '') @@ -131,6 +133,11 @@ for filename in args.tests: with open(filename) as f: input_lines = [l.rstrip() for l in f] + + if args.update_only: + if not common.is_autogenerated_test_file(input_lines): + common.warn('Skipping test which isn\'t autogenerated: %s' % (filename)) + continue # Extract RUN lines. raw_lines = [m.group(1) @@ -151,6 +158,10 @@ run_list = [] line2spell_and_mangled_list = collections.defaultdict(list) for l in run_lines: + if '|' not in l: + common.warn('Skipping unparseable RUN line: %s' % (l,)) + continue + commands = [cmd.strip() for cmd in l.split('|', 1)] triple_in_cmd = None @@ -161,7 +172,7 @@ # Apply %clang substitution rule, replace %s by `filename`, and append args.clang_args clang_args = shlex.split(commands[0]) if clang_args[0] not in SUBST: - print('WARNING: Skipping non-clang RUN line: ' + l, file=sys.stderr) + common.warn('Skipping non-clang RUN line: ' + l) continue clang_args[0:1] = SUBST[clang_args[0]] clang_args = [filename if i == '%s' else i for i in clang_args] + args.clang_args @@ -170,7 +181,7 @@ filecheck_cmd = commands[-1] common.verify_filecheck_prefixes(filecheck_cmd) if not filecheck_cmd.startswith('FileCheck '): - print('WARNING: Skipping non-FileChecked RUN line: ' + l, file=sys.stderr) + common.warn('Skipping non-FileChecked RUN line: ' + l) continue check_prefixes = [item for m in common.CHECK_PREFIX_RE.finditer(filecheck_cmd) for item in m.group(1).split(',')] Index: utils/update_llc_test_checks.py =================================================================== --- utils/update_llc_test_checks.py +++ utils/update_llc_test_checks.py @@ -38,6 +38,8 @@ help='Use more regex for x86 matching to reduce diffs between various subtargets') parser.add_argument( '--no_x86_scrub_rip', action='store_false', dest='x86_scrub_rip') + parser.add_argument('-u', '--update-only', action='store_true', + help='Only update test if it was already autogened') parser.add_argument('tests', nargs='+') args = parser.parse_args() @@ -50,6 +52,11 @@ with open(test) as f: input_lines = [l.rstrip() for l in f] + if args.update_only: + if not common.is_autogenerated_test_file(input_lines): + common.warn('Skipping test which isn\'t autogenerated: %s' % (test)) + continue + triple_in_ir = None for l in input_lines: m = common.TRIPLE_IR_RE.match(l) @@ -73,6 +80,10 @@ run_list = [] for l in run_lines: + if '|' not in l: + common.warn('Skipping unparseable RUN line: %s' % (l,)) + continue + commands = [cmd.strip() for cmd in l.split('|', 1)] llc_cmd = commands[0] @@ -91,11 +102,11 @@ filecheck_cmd = commands[1] common.verify_filecheck_prefixes(filecheck_cmd) if not llc_cmd.startswith('llc '): - print('WARNING: Skipping non-llc RUN line: ' + l, file=sys.stderr) + common.warn('Skipping non-llc RUN line: ' + l) continue if not filecheck_cmd.startswith('FileCheck '): - print('WARNING: Skipping non-FileChecked RUN line: ' + l, file=sys.stderr) + common.warn('Skipping non-FileChecked RUN line: ' + l) continue llc_cmd_args = llc_cmd[len('llc'):].strip() Index: utils/update_mir_test_checks.py =================================================================== --- utils/update_mir_test_checks.py +++ utils/update_mir_test_checks.py @@ -85,12 +85,6 @@ print(msg, file=sys.stderr) -def warn(msg, test_file=None): - if test_file: - msg = '{}: {}'.format(test_file, msg) - print('WARNING: {}'.format(msg), file=sys.stderr) - - def find_triple_in_ir(lines, verbose=False): for l in lines: m = common.TRIPLE_IR_RE.match(l) @@ -119,16 +113,20 @@ run_list = [] all_prefixes = [] for l in run_lines: + if '|' not in l: + common.warn('Skipping unparseable RUN line: %s' % (l,)) + continue + commands = [cmd.strip() for cmd in l.split('|', 1)] llc_cmd = commands[0] filecheck_cmd = commands[1] if len(commands) > 1 else '' common.verify_filecheck_prefixes(filecheck_cmd) if not llc_cmd.startswith('llc '): - warn('Skipping non-llc RUN line: {}'.format(l), test_file=test) + common.warn('Skipping non-llc RUN line: {}'.format(l), test_file=test) continue if not filecheck_cmd.startswith('FileCheck '): - warn('Skipping non-FileChecked RUN line: {}'.format(l), + common.warn('Skipping non-FileChecked RUN line: {}'.format(l), test_file=test) continue @@ -193,7 +191,7 @@ log(' {}'.format(l)) for prefix in prefixes: if func in func_dict[prefix] and func_dict[prefix][func] != body: - warn('Found conflicting asm for prefix: {}'.format(prefix), + common.warn('Found conflicting asm for prefix: {}'.format(prefix), test_file=test) func_dict[prefix][func] = body @@ -225,7 +223,7 @@ func_body.pop(0) if not func_body: - warn('Function has no instructions to check: {}'.format(func_name), + common.warn('Function has no instructions to check: {}'.format(func_name), test_file=test) return @@ -294,11 +292,16 @@ return True -def update_test_file(llc, test, remove_common_prefixes=False, verbose=False): +def update_test_file(args, test, verbose=False): log('Scanning for RUN lines in test file: {}'.format(test), verbose) with open(test) as fd: input_lines = [l.rstrip() for l in fd] + if args.update_only: + if not common.is_autogenerated_test_file(input_lines): + common.warn('Skipping test which isn\'t autogenerated: %s' % (test)) + return + triple_in_ir = find_triple_in_ir(input_lines, verbose) run_lines = find_run_lines(test, input_lines, verbose) run_list, common_prefixes = build_run_list(test, run_lines, verbose) @@ -313,9 +316,9 @@ log('Extracted LLC cmd: llc {}'.format(llc_args), verbose) log('Extracted FileCheck prefixes: {}'.format(prefixes), verbose) - raw_tool_output = llc(llc_args, test) + raw_tool_output = args.llc(llc_args, test) if not triple_in_cmd and not triple_in_ir: - warn('No triple found: skipping file', test_file=test) + common.warn('No triple found: skipping file', test_file=test) return build_function_body_dictionary(test, raw_tool_output, @@ -327,10 +330,10 @@ prefix_set = set([prefix for run in run_list for prefix in run.prefixes]) log('Rewriting FileCheck prefixes: {}'.format(prefix_set), verbose) - if remove_common_prefixes: + if args.remove_common_prefixes: prefix_set.update(common_prefixes) elif common_prefixes: - warn('Ignoring common prefixes: {}'.format(common_prefixes), + common.warn('Ignoring common prefixes: {}'.format(common_prefixes), test_file=test) comment_char = '#' if test.endswith('.mir') else ';' @@ -425,16 +428,17 @@ parser.add_argument('--remove-common-prefixes', action='store_true', help='Remove existing check lines whose prefixes are ' 'shared between multiple commands') + parser.add_argument('--update-only', action='store_true', + help='Only update test if it was already autogened') parser.add_argument('tests', nargs='+') args = parser.parse_args() test_paths = [test for pattern in args.tests for test in glob.glob(pattern)] for test in test_paths: try: - update_test_file(args.llc, test, args.remove_common_prefixes, - verbose=args.verbose) + update_test_file(update_test_file, test, verbose=args.verbose) except Exception: - warn('Error processing file', test_file=test) + common.warn('Error processing file', test_file=test) raise Index: utils/update_test_checks.py =================================================================== --- utils/update_test_checks.py +++ utils/update_test_checks.py @@ -62,7 +62,7 @@ help='The opt binary used to generate the test case') parser.add_argument( '--function', help='The function in the test file to update') - parser.add_argument('--update-only', action='store_true', + parser.add_argument('-u', '--update-only', action='store_true', help='Only update test if it was already autogened') parser.add_argument('tests', nargs='+') args = parser.parse_args() @@ -78,7 +78,7 @@ test_paths = [] for test in args.tests: if not glob.glob(test): - print('WARNING: Test file \'%s\' was not found. Ignoring it.' % (test,), file=sys.stderr) + common.warn('Test file \'%s\' was not found. Ignoring it.' % (test,)) continue test_paths.append(test) @@ -89,9 +89,9 @@ input_lines = [l.rstrip() for l in f] if args.update_only: - if len(input_lines) == 0 or 'autogenerated' not in input_lines[0]: - print('Skipping test which isn\'t autogenerated: %s' % (test), file=sys.stderr) - continue; + if not common.is_autogenerated_test_file(input_lines): + common.warn('Skipping test which isn\'t autogenerated: %s' % (test)) + continue raw_lines = [m.group(1) for m in [common.RUN_LINE_RE.match(l) for l in input_lines] if m] @@ -110,17 +110,17 @@ prefix_list = [] for l in run_lines: if '|' not in l: - print('WARNING: Skipping unparseable RUN line: %s' % (l,), file=sys.stderr) + common.warn('Skipping unparseable RUN line: %s' % (l,)) continue (tool_cmd, filecheck_cmd) = tuple([cmd.strip() for cmd in l.split('|', 1)]) common.verify_filecheck_prefixes(filecheck_cmd) if not tool_cmd.startswith(opt_basename + ' '): - print('WARNING: Skipping non-%s RUN line: %s' % (opt_basename, l), file=sys.stderr) + common.warn('Skipping non-%s RUN line: %s' % (opt_basename, l)) continue if not filecheck_cmd.startswith('FileCheck '): - print('WARNING: Skipping non-FileChecked RUN line: ' + l, file=sys.stderr) + common.warn('Skipping non-FileChecked RUN line: ' + l) continue tool_cmd_args = tool_cmd[len(opt_basename):].strip()