| Index: szdiff.py
|
| diff --git a/szdiff.py b/szdiff.py
|
| new file mode 100755
|
| index 0000000000000000000000000000000000000000..0df3a8b150bf85f787784c0690418ca9288dbd2c
|
| --- /dev/null
|
| +++ b/szdiff.py
|
| @@ -0,0 +1,82 @@
|
| +#!/usr/bin/env python2
|
| +
|
| +import argparse
|
| +import itertools
|
| +import subprocess
|
| +import re
|
| +
|
| +if __name__ == '__main__':
|
| + """Runs llvm2ice on an input .ll file, and compares the output
|
| + against the input.
|
| +
|
| + Before comparing, the input file is massaged to remove comments,
|
| + blank lines, global variable definitions, external function
|
| + declarations, and possibly other patterns that llvm2ice does not
|
| + handle.
|
| +
|
| + The output file and the massaged input file are compared line by
|
| + line for differences. However, there is a regex defined such that
|
| + if the regex matches a line in the input file, that line and the
|
| + corresponding line in the output file are ignored. This lets us
|
| + ignore minor differences such as inttoptr and ptrtoint, and
|
| + printing of floating-point constants.
|
| +
|
| + On success, no output is produced. On failure, each mismatch is
|
| + printed as two lines, one starting with 'SZ' and one starting with
|
| + 'LL'.
|
| + """
|
| + desc = 'Compare llvm2ice output against bitcode input.'
|
| + argparser = argparse.ArgumentParser(description=desc)
|
| + argparser.add_argument(
|
| + 'llfile', nargs='?', default='-',
|
| + type=argparse.FileType('r'), metavar='FILE',
|
| + help='Textual bitcode file [default stdin]')
|
| + argparser.add_argument(
|
| + '--llvm2ice', required=False, default='./llvm2ice', metavar='LLVM2ICE',
|
| + help='Path to llvm2ice driver program [default ./llvm2ice]')
|
| + args = argparser.parse_args()
|
| + bitcode = args.llfile.readlines()
|
| +
|
| + # Run llvm2ice and collect its output lines into sz_out.
|
| + command = [args.llvm2ice, '-verbose', 'inst', '-notranslate', '-']
|
| + p = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
|
| + sz_out = p.communicate(input=''.join(bitcode))[0].splitlines()
|
| +
|
| + # Filter certain lines and patterns from the input, and collect
|
| + # the remainder into llc_out.
|
| + llc_out = []
|
| + trailing_comment = re.compile(';.*')
|
| + ignore_pattern = re.compile('^ *$|^declare|^@')
|
| + for line in bitcode:
|
| + # Remove trailing comments and spaces.
|
| + line = trailing_comment.sub('', line).rstrip()
|
| + # Ignore blanks lines, forward declarations, and variable definitions.
|
| + if not ignore_pattern.search(line):
|
| + llc_out.append(line)
|
| +
|
| + # Compare sz_out and llc_out line by line, but ignore pairs of
|
| + # lines where the llc line matches a certain pattern.
|
| + return_code = 0
|
| + lines_total = 0
|
| + lines_diff = 0
|
| + ignore_pattern = re.compile(
|
| + '|'.join([' -[0-9]', # negative constants
|
| + ' (float|double) [-0-9]', # FP constants
|
| + ' inttoptr ', # inttoptr pointer types
|
| + ' ptrtoint ' # ptrtoint pointer types
|
| + ]))
|
| + for (sz_line, llc_line) in itertools.izip_longest(sz_out, llc_out):
|
| + lines_total += 1
|
| + if sz_line == llc_line:
|
| + continue
|
| + if llc_line and ignore_pattern.search(llc_line):
|
| + lines_diff += 1
|
| + continue
|
| + if sz_line: print 'SZ>' + sz_line
|
| + if llc_line: print 'LL>' + llc_line
|
| + return_code = 1
|
| +
|
| + if return_code == 0:
|
| + message = 'Success (ignored %d diffs out of %d lines)'
|
| + print message % (lines_diff, lines_total)
|
| + exit(return_code)
|
|
|