On 9 March 2016 at 11:12, Sanjay Patel <spa...@rotateright.com> wrote:
> Nothing to do with the patch itself (although it looks great and thanks!) - 
> is the CHECK line generator script available somewhere? I'd love to be able 
> to use that.

It's horribly hacky and fragile, but what I've got should be attached
here. Particular issues are:

  * Spotting where to put CHECK lines in the C file is bad and relies
on '{' being on the same line as the definition.
  * If a function argument name is an extension of a definition, the
2-pass substitution will go wrong. It really should actually look for
%-based tokens rather than just text.
  * No handling of basic blocks as values.

But, it mostly did the trick so it's not useless.

Cheers.

Tim.
import re, sys

C_FUNC_DEF = re.compile(r'([_a-zA-Z][_a-zA-Z0-9]*)\(.*{')
LL_FUNC_DEF = re.compile(r'define.*@(.*)\(')
VALUE_DEF = re.compile(r'\s+%(.*) =')

def get_value_name(var):
    if var.isdigit():
        var = 'TMP' + var
    var = var.replace('.', '_')
    return var.upper()

def get_value_definition(var):
    return '[[' + get_value_name(var) + ':%.*]]'

def get_value_use(var):
    return '[[' + get_value_name(var) + ']]'

def genericize_function(lines):
    lines_with_def = []
    vars_seen = []
    for line in lines:
        if line == 'entry:':
            # Can't branch to %entry or really do anything useful with it, so
            # skip the clutter.
            continue

        m = VALUE_DEF.match(line)
        if m:
            vars_seen.append(m.group(1))
            line = line.replace('%' + m.group(1), get_value_definition(m.group(1)))

        lines_with_def.append(line)

    output_lines = []
    vars_seen.sort(key=len, reverse=True)
    for line in lines_with_def:
        if not LL_FUNC_DEF.match(line):
            for var in vars_seen:
                line = line.replace('%' + var, get_value_use(var))
        output_lines.append(line)

    return output_lines

def add_checks(lines):
    check_lines = ['// CHECK-LABEL: ' + lines[0]]
    check_lines.extend('// CHECK: ' + line for line in lines[1:])
    return check_lines

def create_test_dictionary(ll_file):
    tests = {}
    func_lines = []
    in_func = ''
    for line in ll_file:
        if line == '}':
            tests[in_func] = add_checks(genericize_function(func_lines))
            continue

        m = LL_FUNC_DEF.match(line)
        if m:
            func_lines = []
            in_func = m.group(1)

        func_lines.append(line)

    return tests

def apply_test_dictionary(c_file, tests):
    output_lines = []

    for line in c_file:
        m = C_FUNC_DEF.search(line)
        if m and m.group(1) in tests:
            for test_line in tests[m.group(1)]:
                output_lines.append(test_line)
        output_lines.append(line)
    return output_lines

def main():
    c_name = sys.argv[1]
    ll_name = sys.argv[2]
    out_name = sys.argv[3]

    with open(sys.argv[2], 'r') as f:
        ll_lines = f.read().split('\n')

    tests = create_test_dictionary(ll_lines)

    with open(sys.argv[1], 'r') as f:
        c_lines = f.read().split('\n')

    output_lines = apply_test_dictionary(c_lines, tests)

    with open(sys.argv[3], 'w') as f:
        f.write('\n'.join(output_lines))


if __name__ == '__main__':
    main()

Attachment: make_test.sh
Description: Bourne shell script

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to