Fangrui Song | 3823fc4 | 2018-02-02 16:41:07 +0000 | [diff] [blame^] | 1 | from __future__ import print_function |
Fangrui Song | ee4e2e7 | 2018-01-30 00:40:05 +0000 | [diff] [blame] | 2 | import re |
| 3 | import subprocess |
Fangrui Song | 3823fc4 | 2018-02-02 16:41:07 +0000 | [diff] [blame^] | 4 | import sys |
Fangrui Song | ee4e2e7 | 2018-01-30 00:40:05 +0000 | [diff] [blame] | 5 | |
| 6 | RUN_LINE_RE = re.compile('^\s*;\s*RUN:\s*(.*)$') |
| 7 | CHECK_PREFIX_RE = re.compile('--?check-prefix(?:es)?=(\S+)') |
| 8 | CHECK_RE = re.compile(r'^\s*;\s*([^:]+?)(?:-NEXT|-NOT|-DAG|-LABEL)?:') |
| 9 | |
| 10 | IR_FUNCTION_RE = re.compile('^\s*define\s+(?:internal\s+)?[^@]*@(\w+)\s*\(') |
| 11 | TRIPLE_IR_RE = re.compile(r'^target\s+triple\s*=\s*"([^"]+)"$') |
| 12 | TRIPLE_ARG_RE = re.compile(r'-mtriple=([^ ]+)') |
| 13 | |
| 14 | SCRUB_LEADING_WHITESPACE_RE = re.compile(r'^(\s+)') |
| 15 | SCRUB_WHITESPACE_RE = re.compile(r'(?!^(| \w))[ \t]+', flags=re.M) |
| 16 | SCRUB_TRAILING_WHITESPACE_RE = re.compile(r'[ \t]+$', flags=re.M) |
| 17 | SCRUB_KILL_COMMENT_RE = re.compile(r'^ *#+ +kill:.*\n') |
| 18 | SCRUB_LOOP_COMMENT_RE = re.compile( |
| 19 | r'# =>This Inner Loop Header:.*|# in Loop:.*', flags=re.M) |
| 20 | |
| 21 | def should_add_line_to_output(input_line, prefix_set): |
| 22 | # Skip any blank comment lines in the IR. |
| 23 | if input_line.strip() == ';': |
| 24 | return False |
| 25 | # Skip any blank lines in the IR. |
| 26 | #if input_line.strip() == '': |
| 27 | # return False |
| 28 | # And skip any CHECK lines. We're building our own. |
| 29 | m = CHECK_RE.match(input_line) |
| 30 | if m and m.group(1) in prefix_set: |
| 31 | return False |
| 32 | |
| 33 | return True |
| 34 | |
| 35 | # Invoke the tool that is being tested. |
| 36 | def invoke_tool(exe, cmd_args, ir): |
| 37 | with open(ir) as ir_file: |
| 38 | stdout = subprocess.check_output(exe + ' ' + cmd_args, |
| 39 | shell=True, stdin=ir_file) |
Fangrui Song | 3823fc4 | 2018-02-02 16:41:07 +0000 | [diff] [blame^] | 40 | if sys.version_info[0] > 2: |
| 41 | stdout = stdout.decode() |
Fangrui Song | ee4e2e7 | 2018-01-30 00:40:05 +0000 | [diff] [blame] | 42 | # Fix line endings to unix CR style. |
Fangrui Song | 3823fc4 | 2018-02-02 16:41:07 +0000 | [diff] [blame^] | 43 | return stdout.replace('\r\n', '\n') |
Fangrui Song | ee4e2e7 | 2018-01-30 00:40:05 +0000 | [diff] [blame] | 44 | |
| 45 | # Build up a dictionary of all the function bodies. |
| 46 | def build_function_body_dictionary(function_re, scrubber, scrubber_args, raw_tool_output, prefixes, func_dict, verbose): |
| 47 | for m in function_re.finditer(raw_tool_output): |
| 48 | if not m: |
| 49 | continue |
| 50 | func = m.group('func') |
| 51 | scrubbed_body = scrubber(m.group('body'), *scrubber_args) |
| 52 | if func.startswith('stress'): |
| 53 | # We only use the last line of the function body for stress tests. |
| 54 | scrubbed_body = '\n'.join(scrubbed_body.splitlines()[-1:]) |
| 55 | if verbose: |
Fangrui Song | 3823fc4 | 2018-02-02 16:41:07 +0000 | [diff] [blame^] | 56 | print('Processing function: ' + func, file=sys.stderr) |
Fangrui Song | ee4e2e7 | 2018-01-30 00:40:05 +0000 | [diff] [blame] | 57 | for l in scrubbed_body.splitlines(): |
Fangrui Song | 3823fc4 | 2018-02-02 16:41:07 +0000 | [diff] [blame^] | 58 | print(' ' + l, file=sys.stderr) |
Fangrui Song | ee4e2e7 | 2018-01-30 00:40:05 +0000 | [diff] [blame] | 59 | for prefix in prefixes: |
| 60 | if func in func_dict[prefix] and func_dict[prefix][func] != scrubbed_body: |
| 61 | if prefix == prefixes[-1]: |
Fangrui Song | 3823fc4 | 2018-02-02 16:41:07 +0000 | [diff] [blame^] | 62 | print('WARNING: Found conflicting asm under the ' |
| 63 | 'same prefix: %r!' % (prefix,), file=sys.stderr) |
Fangrui Song | ee4e2e7 | 2018-01-30 00:40:05 +0000 | [diff] [blame] | 64 | else: |
| 65 | func_dict[prefix][func] = None |
| 66 | continue |
| 67 | |
| 68 | func_dict[prefix][func] = scrubbed_body |