diff options
author | David Greene <dag@cray.com> | 2020-01-13 12:16:35 -0600 |
---|---|---|
committer | David Greene <dag@hpe.com> | 2020-09-18 06:34:59 -0500 |
commit | 7c8bb409f31ebbe24ac978e123efcef961a58340 (patch) | |
tree | 6e8574b3731bdff6b5e89055cf2e32420aef33dd /llvm/utils/UpdateTestChecks/common.py | |
parent | 09a3737384ec34c6b216e7c6b9ca768c26ffb1d1 (diff) | |
download | llvm-7c8bb409f31ebbe24ac978e123efcef961a58340.zip llvm-7c8bb409f31ebbe24ac978e123efcef961a58340.tar.gz llvm-7c8bb409f31ebbe24ac978e123efcef961a58340.tar.bz2 |
[UpdateCCTestChecks] Include generated functions if asked
Add the --include-generated-funcs option to update_cc_test_checks.py so that any
functions created by the compiler that don't exist in the source will also be
checked.
We need to maintain the output order of generated function checks so that
CHECK-LABEL works properly. To do so, maintain a list of functions output for
each prefix in the order they are output. Use this list to output checks for
generated functions in the proper order.
Differential Revision: https://reviews.llvm.org/D83004
Diffstat (limited to 'llvm/utils/UpdateTestChecks/common.py')
-rw-r--r-- | llvm/utils/UpdateTestChecks/common.py | 84 |
1 files changed, 78 insertions, 6 deletions
diff --git a/llvm/utils/UpdateTestChecks/common.py b/llvm/utils/UpdateTestChecks/common.py index d49fe50..488425d 100644 --- a/llvm/utils/UpdateTestChecks/common.py +++ b/llvm/utils/UpdateTestChecks/common.py @@ -18,6 +18,8 @@ else: _verbose = False def parse_commandline_args(parser): + 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', @@ -62,19 +64,25 @@ class TestInfo(object): self.test_autogenerated_note = self.autogenerated_note_prefix + script_name self.test_autogenerated_note += get_autogennote_suffix(parser, self.args) + 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_num, input_line in enumerate(self.input_lines): + 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, self.argv = check_for_command(input_line, self.parser, - self.args, self.argv, self.argparse_callback) + self.args = line_info.args + self.argv = line_info.argv if not self.args.enabled: output_lines.append(input_line) continue - yield InputLineInfo(input_line, line_num, self.args, self.argv) - + yield line_info def itertests(test_patterns, parser, script_name, comment_prefix=None, argparse_callback=None): for pattern in test_patterns: @@ -250,7 +258,7 @@ class function_body(object): def __str__(self): return self.scrub -def build_function_body_dictionary(function_re, scrubber, scrubber_args, raw_tool_output, prefixes, func_dict, verbose, record_args, check_attributes): +def build_function_body_dictionary(function_re, scrubber, scrubber_args, raw_tool_output, prefixes, func_dict, func_order, verbose, record_args, check_attributes): for m in function_re.finditer(raw_tool_output): if not m: continue @@ -292,6 +300,7 @@ def build_function_body_dictionary(function_re, scrubber, scrubber_args, raw_too continue func_dict[prefix][func] = function_body(scrubbed_body, scrubbed_extra, args_and_sig, attrs) + func_order[prefix].append(func) ##### Generator of LLVM IR CHECK lines @@ -594,3 +603,66 @@ def check_for_command(line, parser, args, argv, argparse_callback): 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.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() + for prefixes, tool_args, *rest in prefix_list: + for prefix in prefixes: + for func in func_order[prefix]: + if added: + output_lines.append(comment_string) + added.add(func) + + # 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. + check_generator(output_lines, + [([prefix], tool_args)], + func) |