-
Notifications
You must be signed in to change notification settings - Fork 3
/
szdiff.py
executable file
·82 lines (74 loc) · 3.23 KB
/
szdiff.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#!/usr/bin/env python2
import argparse
import itertools
import re
if __name__ == '__main__':
"""Compares a LLVM file with a subzero file for differences.
Before comparing, the LLVM file is massaged to remove comments,
blank lines, global variable definitions, external function
declarations, and possibly other patterns that llvm2ice does not
handle.
The subzero file and the massaged LLVM file are compared line by
line for differences. However, there is a regex defined such that
if the regex matches a line in the LLVM file, that line and the
corresponding line in the subzero 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' (subzero) and one
starting with 'LL' (LLVM).
"""
desc = 'Compare LLVM and subzero bitcode files.'
argparser = argparse.ArgumentParser(description=desc)
argparser.add_argument(
'llfile', nargs=1,
type=argparse.FileType('r'), metavar='LLVM_FILE',
help='LLVM bitcode file')
argparser.add_argument(
'szfile', nargs='?', default='-',
type=argparse.FileType('r'), metavar='SUBZERO_FILE',
help='Subzero bitcode file [default stdin]')
args = argparser.parse_args()
bitcode = args.llfile[0].readlines()
sz_out = [ line.rstrip() for line in args.szfile.readlines()]
# Filter certain lines and patterns from the input, and collect
# the remainder into llc_out.
llc_out = []
tail_call = re.compile(' tail call ');
trailing_comment = re.compile(';.*')
ignore_pattern = re.compile('^ *$|^declare|^@')
for line in bitcode:
# Convert tail call into regular (non-tail) call.
line = tail_call.sub(' call ', line)
# 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
' (float|double) %\w+, [-0-9]',
' inttoptr ', # inttoptr pointer types
' ptrtoint ', # ptrtoint pointer types
' bitcast .*\* .* to .*\*' # bitcast 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)