[NFC] factor update test function test builder as a class

This allows us to have shared logic over multiple test runs, e.g. do we
have unused prefixes, or which function bodies have conflicting outputs
for a prefix appearing in different RUN lines.

This patch is just wrapping existing functionality, and replacing its uses.
A subsequent patch would then fold the current functionality into the newly
introduced class.

Differential Revision: https://reviews.llvm.org/D93413
This commit is contained in:
Mircea Trofin 2020-12-16 10:20:12 -08:00
parent 541e476fc0
commit ed1e565aaf
6 changed files with 79 additions and 57 deletions

View File

@ -324,8 +324,7 @@ def get_triple_from_march(march):
print("Cannot find a triple. Assume 'x86'", file=sys.stderr)
return 'x86'
def build_function_body_dictionary_for_triple(args, raw_tool_output, triple,
prefixes, func_dict, func_order):
def get_run_handler(triple):
target_handlers = {
'i686': (scrub_asm_x86, ASM_FUNCTION_X86_RE),
'x86': (scrub_asm_x86, ASM_FUNCTION_X86_RE),
@ -366,10 +365,7 @@ def build_function_body_dictionary_for_triple(args, raw_tool_output, triple,
if handler is None:
raise KeyError('Triple %r is not supported' % (triple))
scrubber, function_re = handler
common.build_function_body_dictionary(
function_re, scrubber, [args], raw_tool_output, prefixes,
func_dict, func_order, args.verbose, False, False)
return handler
##### Generator of assembly CHECK lines

View File

@ -322,7 +322,32 @@ def build_function_body_dictionary(function_re, scrubber, scrubber_args, raw_too
func_dict[prefix][func] = function_body(scrubbed_body, scrubbed_extra, args_and_sig, attrs)
func_order[prefix].append(func)
warn_on_failed_prefixes(func_dict)
class FunctionTestBuilder:
def __init__(self, run_list, flags, scrubber_args):
self._verbose = flags.verbose
self._record_args = flags.function_signature
self._check_attributes = flags.check_attributes
self._scrubber_args = scrubber_args
self._func_dict = {}
self._func_order = {}
for tuple in run_list:
for prefix in tuple[0]:
self._func_dict.update({prefix:dict()})
self._func_order.update({prefix: []})
def finish_and_get_func_dict(self):
warn_on_failed_prefixes(self._func_dict)
return self._func_dict
def func_order(self):
return self._func_order
def process_run_line(self, function_re, scrubber, raw_tool_output, prefixes):
build_function_body_dictionary(function_re, scrubber, self._scrubber_args,
raw_tool_output, prefixes, self._func_dict,
self._func_order, self._verbose,
self._record_args, self._check_attributes)
##### Generator of LLVM IR CHECK lines

View File

@ -108,12 +108,11 @@ def main():
# now, we just ignore all but the last.
prefix_list.append((check_prefixes, tool_cmd_args))
func_dict = {}
func_order = {}
for prefixes, _ in prefix_list:
for prefix in prefixes:
func_dict.update({prefix: dict()})
func_order.update({prefix: []})
builder = common.FunctionTestBuilder(
run_list = prefix_list,
flags = args,
scrubber_args = [])
for prefixes, opt_args in prefix_list:
common.debug('Extracted opt cmd:', opt_basename, opt_args, file=sys.stderr)
common.debug('Extracted FileCheck prefixes:', str(prefixes), file=sys.stderr)
@ -122,10 +121,10 @@ def main():
# Split analysis outputs by "Printing analysis " declarations.
for raw_tool_output in re.split(r'Printing analysis ', raw_tool_outputs):
common.build_function_body_dictionary(
common.ANALYZE_FUNCTION_RE, common.scrub_body, [],
raw_tool_output, prefixes, func_dict, func_order, args.verbose, False, False)
builder.process_run_line(common.ANALYZE_FUNCTION_RE, common.scrub_body,
raw_tool_output, prefixes)
func_dict = builder.finish_and_get_func_dict()
is_in_function = False
is_in_function_start = False
prefix_set = set([prefix for prefixes, _ in prefix_list for prefix in prefixes])

View File

@ -176,8 +176,8 @@ def config():
return args, parser
def get_function_body(args, filename, clang_args, extra_commands, prefixes,
triple_in_cmd, func_dict, func_order):
def get_function_body(builder, args, filename, clang_args, extra_commands,
prefixes):
# TODO Clean up duplication of asm/common build_function_body_dictionary
# Invoke external tool and extract function bodies.
raw_tool_output = common.invoke_tool(args.clang, clang_args, filename)
@ -195,10 +195,9 @@ def get_function_body(args, filename, clang_args, extra_commands, prefixes,
raw_tool_output = common.invoke_tool(extra_args[0],
extra_args[1:], f.name)
if '-emit-llvm' in clang_args:
common.build_function_body_dictionary(
common.OPT_FUNCTION_RE, common.scrub_body, [],
raw_tool_output, prefixes, func_dict, func_order, args.verbose,
args.function_signature, args.check_attributes)
builder.process_run_line(
common.OPT_FUNCTION_RE, common.scrub_body, raw_tool_output,
prefixes)
else:
print('The clang command line should include -emit-llvm as asm tests '
'are discouraged in Clang testsuite.', file=sys.stderr)
@ -248,25 +247,25 @@ def main():
run_list.append((check_prefixes, clang_args, commands[1:-1], triple_in_cmd))
# Execute clang, generate LLVM IR, and extract functions.
func_dict = {}
func_order = {}
for p in run_list:
prefixes = p[0]
for prefix in prefixes:
func_dict.update({prefix: dict()})
func_order.update({prefix: []})
builder = common.FunctionTestBuilder(
run_list=run_list,
flags=ti.args,
scrubber_args=[])
for prefixes, clang_args, extra_commands, triple_in_cmd in run_list:
common.debug('Extracted clang cmd: clang {}'.format(clang_args))
common.debug('Extracted FileCheck prefixes: {}'.format(prefixes))
get_function_body(ti.args, ti.path, clang_args, extra_commands, prefixes,
triple_in_cmd, func_dict, func_order)
get_function_body(builder, ti.args, ti.path, clang_args, extra_commands,
prefixes)
# Invoke clang -Xclang -ast-dump=json to get mapping from start lines to
# mangled names. Forward all clang args for now.
for k, v in get_line2spell_and_mangled(ti.args, clang_args).items():
line2spell_and_mangled_list[k].append(v)
func_dict = builder.finish_and_get_func_dict()
global_vars_seen_dict = {}
prefix_set = set([prefix for p in run_list for prefix in p[0]])
output_lines = []
@ -302,8 +301,8 @@ def main():
prefixes,
func_dict, func)
common.add_checks_at_end(output_lines, run_list, func_order, '//',
lambda my_output_lines, prefixes, func:
common.add_checks_at_end(output_lines, run_list, builder.func_order(),
'//', lambda my_output_lines, prefixes, func:
check_generator(my_output_lines,
prefixes, func))
else:

View File

@ -104,24 +104,28 @@ def main():
else:
check_indent = ''
func_dict = {}
func_order = {}
for p in run_list:
prefixes = p[0]
for prefix in prefixes:
func_dict.update({prefix: dict()})
func_order.update({prefix: []})
builder = common.FunctionTestBuilder(
run_list=run_list,
flags=type('', (object,), {
'verbose': ti.args.verbose,
'function_signature': False,
'check_attributes': False}),
scrubber_args=[ti.args])
for prefixes, llc_args, triple_in_cmd, march_in_cmd in run_list:
common.debug('Extracted LLC cmd:', llc_tool, llc_args)
common.debug('Extracted FileCheck prefixes:', str(prefixes))
raw_tool_output = common.invoke_tool(ti.args.llc_binary or llc_tool, llc_args, ti.path)
raw_tool_output = common.invoke_tool(ti.args.llc_binary or llc_tool,
llc_args, ti.path)
triple = triple_in_cmd or triple_in_ir
if not triple:
triple = asm.get_triple_from_march(march_in_cmd)
asm.build_function_body_dictionary_for_triple(ti.args, raw_tool_output,
triple, prefixes, func_dict, func_order)
scrubber, function_re = asm.get_run_handler(triple)
builder.process_run_line(function_re, scrubber, raw_tool_output, prefixes)
func_dict = builder.finish_and_get_func_dict()
is_in_function = False
is_in_function_start = False
@ -146,7 +150,7 @@ def main():
common.dump_input_lines(output_lines, ti, prefix_set, ';')
# Now generate all the checks.
common.add_checks_at_end(output_lines, run_list, func_order,
common.add_checks_at_end(output_lines, run_list, builder.func_order(),
check_indent + ';',
lambda my_output_lines, prefixes, func:
asm.add_asm_checks(my_output_lines,

View File

@ -102,22 +102,21 @@ def main():
prefix_list.append((check_prefixes, tool_cmd_args))
global_vars_seen_dict = {}
func_dict = {}
func_order = {}
for prefixes, _ in prefix_list:
for prefix in prefixes:
func_dict.update({prefix: dict()})
func_order.update({prefix: []})
builder = common.FunctionTestBuilder(
run_list=prefix_list,
flags=ti.args,
scrubber_args=[])
for prefixes, opt_args in prefix_list:
common.debug('Extracted opt cmd: ' + opt_basename + ' ' + opt_args)
common.debug('Extracted FileCheck prefixes: ' + str(prefixes))
raw_tool_output = common.invoke_tool(ti.args.opt_binary, opt_args, ti.path)
common.build_function_body_dictionary(
common.OPT_FUNCTION_RE, common.scrub_body, [],
raw_tool_output, prefixes, func_dict, func_order, ti.args.verbose,
ti.args.function_signature, ti.args.check_attributes)
raw_tool_output = common.invoke_tool(ti.args.opt_binary, opt_args,
ti.path)
builder.process_run_line(common.OPT_FUNCTION_RE, common.scrub_body,
raw_tool_output, prefixes)
func_dict = builder.finish_and_get_func_dict()
is_in_function = False
is_in_function_start = False
prefix_set = set([prefix for prefixes, _ in prefix_list for prefix in prefixes])
@ -140,8 +139,8 @@ def main():
common.dump_input_lines(output_lines, ti, prefix_set, ';')
# Now generate all the checks.
common.add_checks_at_end(output_lines, prefix_list, func_order, ';',
lambda my_output_lines, prefixes, func:
common.add_checks_at_end(output_lines, prefix_list, builder.func_order(),
';', lambda my_output_lines, prefixes, func:
common.add_ir_checks(my_output_lines, ';',
prefixes,
func_dict, func, False,