| OLD | NEW |
| 1 #!/usr/bin/env python2 | 1 #!/usr/bin/env python2 |
| 2 | 2 |
| 3 import argparse | 3 import argparse |
| 4 import os | 4 import os |
| 5 import re | 5 import re |
| 6 import subprocess | 6 import subprocess |
| 7 import sys | 7 import sys |
| 8 import tempfile | 8 import tempfile |
| 9 | 9 |
| 10 sys.path.insert(0, '../pydir') | 10 sys.path.insert(0, '../pydir') |
| 11 from utils import shellcmd | 11 from utils import shellcmd |
| 12 from utils import FindBaseNaCl |
| 12 | 13 |
| 13 if __name__ == '__main__': | 14 if __name__ == '__main__': |
| 14 """Builds a cross-test binary that allows functions translated by | 15 """Builds a cross-test binary that allows functions translated by |
| 15 Subzero and llc to be compared. | 16 Subzero and llc to be compared. |
| 16 | 17 |
| 17 Each --test argument is compiled once by llc and once by Subzero. | 18 Each --test argument is compiled once by llc and once by Subzero. |
| 18 C/C++ tests are first compiled down to PNaCl bitcode by the | 19 C/C++ tests are first compiled down to PNaCl bitcode by the |
| 19 build-pnacl-ir.py script. The --prefix argument ensures that | 20 build-pnacl-ir.py script. The --prefix argument ensures that |
| 20 symbol names are different between the two object files, to avoid | 21 symbol names are different between the two object files, to avoid |
| 21 linking errors. | 22 linking errors. |
| (...skipping 26 matching lines...) Expand all Loading... |
| 48 metavar='ATTRIBUTE', help='Target attribute') | 49 metavar='ATTRIBUTE', help='Target attribute') |
| 49 argparser.add_argument('--prefix', required=True, | 50 argparser.add_argument('--prefix', required=True, |
| 50 metavar='SZ_PREFIX', | 51 metavar='SZ_PREFIX', |
| 51 help='String prepended to Subzero symbol names') | 52 help='String prepended to Subzero symbol names') |
| 52 argparser.add_argument('--output', '-o', required=True, | 53 argparser.add_argument('--output', '-o', required=True, |
| 53 metavar='EXECUTABLE', | 54 metavar='EXECUTABLE', |
| 54 help='Executable to produce') | 55 help='Executable to produce') |
| 55 argparser.add_argument('--dir', required=False, default='.', | 56 argparser.add_argument('--dir', required=False, default='.', |
| 56 metavar='OUTPUT_DIR', | 57 metavar='OUTPUT_DIR', |
| 57 help='Output directory for all files') | 58 help='Output directory for all files') |
| 58 argparser.add_argument('--llvm-bin-path', required=False, | |
| 59 default=os.environ.get('LLVM_BIN_PATH'), | |
| 60 metavar='PATH', | |
| 61 help='Path to LLVM executables like llc ' + | |
| 62 '(defaults to $LLVM_BIN_PATH)') | |
| 63 argparser.add_argument('--crosstest-bitcode', required=False, | 59 argparser.add_argument('--crosstest-bitcode', required=False, |
| 64 default=1, type=int, | 60 default=1, type=int, |
| 65 help='Compile non-subzero crosstest object file ' + | 61 help='Compile non-subzero crosstest object file ' + |
| 66 'from the same bitcode as the subzero object. ' + | 62 'from the same bitcode as the subzero object. ' + |
| 67 'If 0, then compile it straight from source.') | 63 'If 0, then compile it straight from source.') |
| 68 args = argparser.parse_args() | 64 args = argparser.parse_args() |
| 69 | 65 |
| 66 nacl_root = FindBaseNaCl() |
| 67 # Prepend host_x86_32/bin to $PATH. |
| 68 os.environ['PATH'] = nacl_root + \ |
| 69 '/toolchain/linux_x86/pnacl_newlib/host_x86_32/bin' + \ |
| 70 os.pathsep + os.environ['PATH'] |
| 71 |
| 70 objs = [] | 72 objs = [] |
| 71 remove_internal = re.compile('^define internal ') | 73 remove_internal = re.compile('^define internal ') |
| 72 fix_target = re.compile('le32-unknown-nacl') | 74 fix_target = re.compile('le32-unknown-nacl') |
| 73 llvm_bin_path = args.llvm_bin_path | |
| 74 for arg in args.test: | 75 for arg in args.test: |
| 75 base, ext = os.path.splitext(arg) | 76 base, ext = os.path.splitext(arg) |
| 76 if ext == '.ll': | 77 if ext == '.ll': |
| 77 bitcode = arg | 78 bitcode = arg |
| 78 else: | 79 else: |
| 79 bitcode = os.path.join(args.dir, base + '.pnacl.ll') | 80 bitcode = os.path.join(args.dir, base + '.pnacl.ll') |
| 80 shellcmd(['../pydir/build-pnacl-ir.py', '--disable-verify', | 81 shellcmd(['../pydir/build-pnacl-ir.py', '--disable-verify', |
| 81 '--dir', args.dir, arg]) | 82 '--dir', args.dir, arg]) |
| 82 # Read in the bitcode file, fix it up, and rewrite the file. | 83 # Read in the bitcode file, fix it up, and rewrite the file. |
| 83 f = open(bitcode) | 84 f = open(bitcode) |
| (...skipping 10 matching lines...) Expand all Loading... |
| 94 asm_sz = os.path.join(args.dir, base_sz + '.sz.s') | 95 asm_sz = os.path.join(args.dir, base_sz + '.sz.s') |
| 95 obj_sz = os.path.join(args.dir, base_sz + '.sz.o') | 96 obj_sz = os.path.join(args.dir, base_sz + '.sz.o') |
| 96 obj_llc = os.path.join(args.dir, base + '.llc.o') | 97 obj_llc = os.path.join(args.dir, base + '.llc.o') |
| 97 shellcmd(['../llvm2ice', | 98 shellcmd(['../llvm2ice', |
| 98 '-O' + args.optlevel, | 99 '-O' + args.optlevel, |
| 99 '-mattr=' + args.attr, | 100 '-mattr=' + args.attr, |
| 100 '--target=' + args.target, | 101 '--target=' + args.target, |
| 101 '--prefix=' + args.prefix, | 102 '--prefix=' + args.prefix, |
| 102 '-o=' + asm_sz, | 103 '-o=' + asm_sz, |
| 103 bitcode]) | 104 bitcode]) |
| 104 shellcmd([os.path.join(llvm_bin_path, 'llvm-mc'), | 105 shellcmd(['llvm-mc', |
| 105 '-arch=' + arch_map[args.target], | 106 '-arch=' + arch_map[args.target], |
| 106 '-x86-asm-syntax=intel', | 107 '-x86-asm-syntax=intel', |
| 107 '-filetype=obj', | 108 '-filetype=obj', |
| 108 '-o=' + obj_sz, | 109 '-o=' + obj_sz, |
| 109 asm_sz]) | 110 asm_sz]) |
| 110 objs.append(obj_sz) | 111 objs.append(obj_sz) |
| 111 # Each original bitcode file needs to be translated by the | 112 # Each original bitcode file needs to be translated by the |
| 112 # LLVM toolchain and have its object file linked in. There | 113 # LLVM toolchain and have its object file linked in. There |
| 113 # are two ways to do this: explicitly use llc, or include the | 114 # are two ways to do this: explicitly use llc, or include the |
| 114 # .ll file in the link command. It turns out that these two | 115 # .ll file in the link command. It turns out that these two |
| 115 # approaches can produce different semantics on some undefined | 116 # approaches can produce different semantics on some undefined |
| 116 # bitcode behavior. Specifically, LLVM produces different | 117 # bitcode behavior. Specifically, LLVM produces different |
| 117 # results for overflowing fptoui instructions for i32 and i64 | 118 # results for overflowing fptoui instructions for i32 and i64 |
| 118 # on x86-32. As it turns out, Subzero lowering was based on | 119 # on x86-32. As it turns out, Subzero lowering was based on |
| 119 # inspecting the object code produced by the direct llc | 120 # inspecting the object code produced by the direct llc |
| 120 # command, so we need to directly run llc on the bitcode, even | 121 # command, so we need to directly run llc on the bitcode, even |
| 121 # though it makes this script longer, to avoid spurious | 122 # though it makes this script longer, to avoid spurious |
| 122 # failures. This behavior can be inspected by switching | 123 # failures. This behavior can be inspected by switching |
| 123 # use_llc between True and False. | 124 # use_llc between True and False. |
| 124 use_llc = False | 125 use_llc = False |
| 125 if not args.crosstest_bitcode: | 126 if not args.crosstest_bitcode: |
| 126 objs.append(arg) | 127 objs.append(arg) |
| 127 elif use_llc: | 128 elif use_llc: |
| 128 shellcmd([os.path.join(llvm_bin_path, 'llc'), | 129 shellcmd(['llc' |
| 129 '-filetype=obj', | 130 '-filetype=obj', |
| 130 '-o=' + obj_llc, | 131 '-o=' + obj_llc, |
| 131 bitcode]) | 132 bitcode]) |
| 132 objs.append(obj_llc) | 133 objs.append(obj_llc) |
| 133 else: | 134 else: |
| 134 objs.append(bitcode) | 135 objs.append(bitcode) |
| 135 | 136 |
| 136 linker = 'clang' if os.path.splitext(args.driver)[1] == '.c' else 'clang++' | 137 linker = 'clang' if os.path.splitext(args.driver)[1] == '.c' else 'clang++' |
| 137 shellcmd([os.path.join(llvm_bin_path, linker), '-g', '-m32', args.driver] + | 138 shellcmd([linker, '-g', '-m32', args.driver] + |
| 138 objs + | 139 objs + |
| 139 ['-lm', '-lpthread', '-o', os.path.join(args.dir, args.output)]) | 140 ['-lm', '-lpthread', '-o', os.path.join(args.dir, args.output)]) |
| OLD | NEW |