| 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 subprocess | 5 import subprocess |
| 6 import sys | 6 import sys |
| 7 import tempfile | 7 import tempfile |
| 8 | 8 |
| 9 import targets |
| 9 from utils import shellcmd | 10 from utils import shellcmd |
| 10 from utils import FindBaseNaCl | 11 from utils import FindBaseNaCl |
| 11 | 12 |
| 12 def main(): | 13 def main(): |
| 13 """Builds a cross-test binary for comparing Subzero and llc translation. | 14 """Builds a cross-test binary for comparing Subzero and llc translation. |
| 14 | 15 |
| 15 Each --test argument is compiled once by llc and once by Subzero. C/C++ | 16 Each --test argument is compiled once by llc and once by Subzero. C/C++ |
| 16 tests are first compiled down to PNaCl bitcode using pnacl-clang and | 17 tests are first compiled down to PNaCl bitcode using pnacl-clang and |
| 17 pnacl-opt. The --prefix argument ensures that symbol names are different | 18 pnacl-opt. The --prefix argument ensures that symbol names are different |
| 18 between the two object files, to avoid linking errors. | 19 between the two object files, to avoid linking errors. |
| 19 | 20 |
| 20 There is also a --driver argument that specifies the C/C++ file that calls | 21 There is also a --driver argument that specifies the C/C++ file that calls |
| 21 the test functions with a variety of interesting inputs and compares their | 22 the test functions with a variety of interesting inputs and compares their |
| 22 results. | 23 results. |
| 23 | 24 |
| 24 """ | 25 """ |
| 25 # arch_map maps a Subzero target string to an llvm-mc -triple string. | 26 # arch_map maps a Subzero target string to TargetInfo (e.g., triple). |
| 26 arch_map = { 'x8632':'i686', 'x8664':'x86_64', 'arm':'armv7a' } | 27 arch_map = { 'x8632': targets.X8632Target, |
| 28 'x8664': targets.X8664Target, |
| 29 'arm32': targets.ARM32Target } |
| 30 arch_sz_flags = { 'x8632': [], |
| 31 'x8664': [], |
| 32 # TODO(jvoung): remove skip-unimplemented when implemented |
| 33 'arm32': ['--skip-unimplemented'] |
| 34 } |
| 35 arch_llc_flags_extra = { |
| 36 # Use sse2 instructions regardless of input -mattr |
| 37 # argument to avoid differences in (undefined) behavior of |
| 38 # converting NaN to int. |
| 39 'x8632': ['-mattr=sse2'], |
| 40 'x8664': ['-mattr=sse2'], |
| 41 'arm32': [], |
| 42 } |
| 27 desc = 'Build a cross-test that compares Subzero and llc translation.' | 43 desc = 'Build a cross-test that compares Subzero and llc translation.' |
| 28 argparser = argparse.ArgumentParser(description=desc) | 44 argparser = argparse.ArgumentParser(description=desc) |
| 29 argparser.add_argument('--test', required=True, action='append', | 45 argparser.add_argument('--test', required=True, action='append', |
| 30 metavar='TESTFILE_LIST', | 46 metavar='TESTFILE_LIST', |
| 31 help='List of C/C++/.ll files with test functions') | 47 help='List of C/C++/.ll files with test functions') |
| 32 argparser.add_argument('--driver', required=True, | 48 argparser.add_argument('--driver', required=True, |
| 33 metavar='DRIVER', | 49 metavar='DRIVER', |
| 34 help='Driver program') | 50 help='Driver program') |
| 35 argparser.add_argument('--target', required=False, default='x8632', | 51 argparser.add_argument('--target', required=False, default='x8632', |
| 36 choices=arch_map.keys(), | 52 choices=arch_map.keys(), |
| 37 metavar='TARGET', | 53 metavar='TARGET', |
| 38 help='Translation target architecture.' + | 54 help='Translation target architecture.' + |
| 39 ' Default %(default)s.') | 55 ' Default %(default)s.') |
| 40 argparser.add_argument('-O', required=False, default='2', dest='optlevel', | 56 argparser.add_argument('-O', required=False, default='2', dest='optlevel', |
| 41 choices=['m1', '-1', '0', '1', '2'], | 57 choices=['m1', '-1', '0', '1', '2'], |
| 42 metavar='OPTLEVEL', | 58 metavar='OPTLEVEL', |
| 43 help='Optimization level for llc and Subzero ' + | 59 help='Optimization level for llc and Subzero ' + |
| 44 '(m1 and -1 are equivalent).' + | 60 '(m1 and -1 are equivalent).' + |
| 45 ' Default %(default)s.') | 61 ' Default %(default)s.') |
| 46 argparser.add_argument('--clang-opt', required=False, default=True, | 62 argparser.add_argument('--clang-opt', required=False, default=True, |
| 47 dest='clang_opt') | 63 dest='clang_opt') |
| 48 argparser.add_argument('--mattr', required=False, default='sse2', | 64 argparser.add_argument('--mattr', required=False, default='sse2', |
| 49 dest='attr', choices=['sse2', 'sse4.1'], | 65 dest='attr', choices=['sse2', 'sse4.1', |
| 66 'neon', 'hwdiv-arm'], |
| 50 metavar='ATTRIBUTE', | 67 metavar='ATTRIBUTE', |
| 51 help='Target attribute. Default %(default)s.') | 68 help='Target attribute. Default %(default)s.') |
| 52 argparser.add_argument('--sandbox', required=False, default=0, type=int, | 69 argparser.add_argument('--sandbox', required=False, default=0, type=int, |
| 53 dest='sandbox', | 70 dest='sandbox', |
| 54 help='Use sandboxing. Default "%(default)s".') | 71 help='Use sandboxing. Default "%(default)s".') |
| 55 argparser.add_argument('--prefix', required=True, | 72 argparser.add_argument('--prefix', required=True, |
| 56 metavar='SZ_PREFIX', | 73 metavar='SZ_PREFIX', |
| 57 help='String prepended to Subzero symbol names') | 74 help='String prepended to Subzero symbol names') |
| 58 argparser.add_argument('--output', '-o', required=True, | 75 argparser.add_argument('--output', '-o', required=True, |
| 59 metavar='EXECUTABLE', | 76 metavar='EXECUTABLE', |
| 60 help='Executable to produce') | 77 help='Executable to produce') |
| 61 argparser.add_argument('--dir', required=False, default='.', | 78 argparser.add_argument('--dir', required=False, default='.', |
| 62 metavar='OUTPUT_DIR', | 79 metavar='OUTPUT_DIR', |
| 63 help='Output directory for all files.' + | 80 help='Output directory for all files.' + |
| 64 ' Default "%(default)s".') | 81 ' Default "%(default)s".') |
| 65 argparser.add_argument('--crosstest-bitcode', required=False, | 82 argparser.add_argument('--crosstest-bitcode', required=False, |
| 66 default=1, type=int, | 83 default=1, type=int, |
| 67 help='Compile non-subzero crosstest object file ' + | 84 help='Compile non-subzero crosstest object file ' + |
| 68 'from the same bitcode as the subzero object. ' + | 85 'from the same bitcode as the subzero object. ' + |
| 69 'If 0, then compile it straight from source.' + | 86 'If 0, then compile it straight from source.' + |
| 70 ' Default %(default)d.') | 87 ' Default %(default)d.') |
| 71 argparser.add_argument('--filetype', default='obj', dest='filetype', | 88 argparser.add_argument('--filetype', default='obj', dest='filetype', |
| 72 choices=['obj', 'asm', 'iasm'], | 89 choices=['obj', 'asm', 'iasm'], |
| 73 help='Output file type. Default %(default)s.') | 90 help='Output file type. Default %(default)s.') |
| 74 args = argparser.parse_args() | 91 args = argparser.parse_args() |
| 75 | 92 |
| 76 nacl_root = FindBaseNaCl() | 93 nacl_root = FindBaseNaCl() |
| 77 bindir = ('{root}/toolchain/linux_x86/pnacl_newlib_raw/bin' | 94 bindir = ('{root}/toolchain/linux_x86/pnacl_newlib_raw/bin' |
| 78 .format(root=nacl_root)) | 95 .format(root=nacl_root)) |
| 79 triple = arch_map[args.target] + ('-nacl' if args.sandbox else '') | 96 target_info = arch_map[args.target] |
| 97 triple = target_info.triple |
| 98 if args.sandbox: |
| 99 triple = targets.ConvertTripleToNaCl(triple) |
| 100 llc_flags = target_info.llc_flags + arch_llc_flags_extra[args.target] |
| 80 mypath = os.path.abspath(os.path.dirname(sys.argv[0])) | 101 mypath = os.path.abspath(os.path.dirname(sys.argv[0])) |
| 81 | 102 |
| 82 objs = [] | 103 objs = [] |
| 83 for arg in args.test: | 104 for arg in args.test: |
| 84 # Construct a "unique key" for each test so that tests can be run in | 105 # Construct a "unique key" for each test so that tests can be run in |
| 85 # parallel without race conditions on temporary file creation. | 106 # parallel without race conditions on temporary file creation. |
| 86 key = '{target}.{sb}.O{opt}.{attr}'.format( | 107 key = '{target}.{sb}.O{opt}.{attr}'.format( |
| 87 target=args.target, sb='sb' if args.sandbox else 'nat', | 108 target=args.target, sb='sb' if args.sandbox else 'nat', |
| 88 opt=args.optlevel, attr=args.attr) | 109 opt=args.optlevel, attr=args.attr) |
| 89 base, ext = os.path.splitext(arg) | 110 base, ext = os.path.splitext(arg) |
| (...skipping 19 matching lines...) Expand all Loading... |
| 109 shellcmd(['{path}/pnacl-sz'.format(path=os.path.dirname(mypath)), | 130 shellcmd(['{path}/pnacl-sz'.format(path=os.path.dirname(mypath)), |
| 110 '-O' + args.optlevel, | 131 '-O' + args.optlevel, |
| 111 '-mattr=' + args.attr, | 132 '-mattr=' + args.attr, |
| 112 '--target=' + args.target, | 133 '--target=' + args.target, |
| 113 '--sandbox=' + str(args.sandbox), | 134 '--sandbox=' + str(args.sandbox), |
| 114 '--prefix=' + args.prefix, | 135 '--prefix=' + args.prefix, |
| 115 '-allow-uninitialized-globals', | 136 '-allow-uninitialized-globals', |
| 116 '-externalize', | 137 '-externalize', |
| 117 '-filetype=' + args.filetype, | 138 '-filetype=' + args.filetype, |
| 118 '-o=' + (obj_sz if args.filetype == 'obj' else asm_sz), | 139 '-o=' + (obj_sz if args.filetype == 'obj' else asm_sz), |
| 119 bitcode]) | 140 bitcode] + arch_sz_flags[args.target]) |
| 120 if args.filetype != 'obj': | 141 if args.filetype != 'obj': |
| 121 shellcmd(['{bin}/llvm-mc'.format(bin=bindir), | 142 shellcmd(['{bin}/llvm-mc'.format(bin=bindir), |
| 122 '-triple=' + triple, | 143 '-triple=' + triple, |
| 123 '-filetype=obj', | 144 '-filetype=obj', |
| 124 '-o=' + obj_sz, | 145 '-o=' + obj_sz, |
| 125 asm_sz]) | 146 asm_sz]) |
| 126 # Each separately translated Subzero object file contains its own | 147 # Each separately translated Subzero object file contains its own |
| 127 # definition of the __Sz_block_profile_info profiling symbol. Avoid | 148 # definition of the __Sz_block_profile_info profiling symbol. Avoid |
| 128 # linker errors (multiply defined symbol) by making all copies weak. | 149 # linker errors (multiply defined symbol) by making all copies weak. |
| 129 # (This could also be done by Subzero if it supported weak symbol | 150 # (This could also be done by Subzero if it supported weak symbol |
| 130 # definitions.) This approach should be OK because cross tests are | 151 # definitions.) This approach should be OK because cross tests are |
| 131 # currently the only situation where multiple translated files are | 152 # currently the only situation where multiple translated files are |
| 132 # linked into the executable, but when PNaCl supports shared nexe | 153 # linked into the executable, but when PNaCl supports shared nexe |
| 133 # libraries, this would need to change. | 154 # libraries, this would need to change. |
| 134 shellcmd(['{bin}/le32-nacl-objcopy'.format(bin=bindir), | 155 shellcmd(['{bin}/le32-nacl-objcopy'.format(bin=bindir), |
| 135 '--weaken-symbol=__Sz_block_profile_info', obj_sz]) | 156 '--weaken-symbol=__Sz_block_profile_info', obj_sz]) |
| 136 objs.append(obj_sz) | 157 objs.append(obj_sz) |
| 137 if args.crosstest_bitcode: | 158 if args.crosstest_bitcode: |
| 138 shellcmd(['{bin}/pnacl-llc'.format(bin=bindir), | 159 shellcmd(['{bin}/pnacl-llc'.format(bin=bindir), |
| 139 '-mtriple=' + triple, | 160 '-mtriple=' + triple, |
| 140 # Use sse2 instructions regardless of input -mattr | |
| 141 # argument to avoid differences in (undefined) behavior of | |
| 142 # converting NaN to int. | |
| 143 '-mattr=sse2', | |
| 144 '-externalize', | 161 '-externalize', |
| 145 '-filetype=obj', | 162 '-filetype=obj', |
| 146 '-o=' + obj_llc, | 163 '-o=' + obj_llc, |
| 147 bitcode]) | 164 bitcode] + llc_flags) |
| 148 objs.append(obj_llc) | 165 objs.append(obj_llc) |
| 149 else: | 166 else: |
| 150 objs.append(arg) | 167 objs.append(arg) |
| 151 | 168 |
| 152 # Add szrt_sb_x8632.o or szrt_native_x8632.o. | 169 # Add szrt_sb_x8632.o or szrt_native_x8632.o. |
| 153 objs.append(( | 170 objs.append(( |
| 154 '{root}/toolchain_build/src/subzero/build/runtime/' + | 171 '{root}/toolchain_build/src/subzero/build/runtime/' + |
| 155 'szrt_{sb}_' + args.target + '.o' | 172 'szrt_{sb}_' + args.target + '.o' |
| 156 ).format(root=nacl_root, sb='sb' if args.sandbox else 'native')) | 173 ).format(root=nacl_root, sb='sb' if args.sandbox else 'native')) |
| 157 pure_c = os.path.splitext(args.driver)[1] == '.c' | 174 pure_c = os.path.splitext(args.driver)[1] == '.c' |
| 158 # Set compiler to clang, clang++, pnacl-clang, or pnacl-clang++. | 175 # Set compiler to clang, clang++, pnacl-clang, or pnacl-clang++. |
| 159 compiler = '{bin}/{prefix}{cc}'.format( | 176 compiler = '{bin}/{prefix}{cc}'.format( |
| 160 bin=bindir, prefix='pnacl-' if args.sandbox else '', | 177 bin=bindir, prefix='pnacl-' if args.sandbox else '', |
| 161 cc='clang' if pure_c else 'clang++') | 178 cc='clang' if pure_c else 'clang++') |
| 162 sb_native_args = (['-O0', '--pnacl-allow-native', '-arch', 'x8632', | 179 sb_native_args = (['-O0', '--pnacl-allow-native', '-arch', 'x8632', |
| 163 '-Wn,-defsym=__Sz_AbsoluteZero=0'] | 180 '-Wn,-defsym=__Sz_AbsoluteZero=0'] |
| 164 if args.sandbox else | 181 if args.sandbox else |
| 165 ['-g', '-m32', '-lm', '-lpthread', | 182 ['-g', '-target=' + triple, |
| 183 '-lm', '-lpthread', |
| 166 '-Wl,--defsym=__Sz_AbsoluteZero=0']) | 184 '-Wl,--defsym=__Sz_AbsoluteZero=0']) |
| 167 shellcmd([compiler, args.driver] + objs + | 185 shellcmd([compiler, args.driver] + objs + |
| 168 ['-o', os.path.join(args.dir, args.output)] + sb_native_args) | 186 ['-o', os.path.join(args.dir, args.output)] + sb_native_args) |
| 169 | 187 |
| 170 if __name__ == '__main__': | 188 if __name__ == '__main__': |
| 171 main() | 189 main() |
| OLD | NEW |