From 8e32fed59522195debe86ae35c314f6bf34aed09 Mon Sep 17 00:00:00 2001 From: Jan Voung Date: Wed, 17 Jun 2015 10:16:23 -0700 Subject: [PATCH] Set up crosstest to run simple loop in Om1 on ARM. We can't run O2 yet because some of the advanced Phi lowering hooks aren't implemented for O2 yet. BUG= https://code.google.com/p/nativeclient/issues/detail?id=4076 R=stichnot@chromium.org Review URL: https://codereview.chromium.org/1160873006. --- Makefile.standalone | 14 +++++++--- pydir/build-runtime.py | 25 +++++------------- pydir/crosstest.py | 40 ++++++++++++++++++++-------- pydir/crosstest_generator.py | 62 ++++++++++++++++++++++++++++++++------------ pydir/targets.py | 27 +++++++++++++++++++ 5 files changed, 118 insertions(+), 50 deletions(-) create mode 100644 pydir/targets.py diff --git a/Makefile.standalone b/Makefile.standalone index 708c91f9c..5f2686ba8 100644 --- a/Makefile.standalone +++ b/Makefile.standalone @@ -22,10 +22,13 @@ SB_LLVM_PATH ?= $(shell readlink -e \ NACL_ROOT ?= $(shell python -c "import sys; sys.path.insert(0, 'pydir'); \ import utils; print utils.FindBaseNaCl()") +# TOOLCHAIN_ROOT is the location of NaCl/PNaCl toolchains and other +# tools like qemu. +TOOLCHAIN_ROOT ?= $(shell readlink -e $(NACL_ROOT)/toolchain/linux_x86) + # PNACL_TOOLCHAIN_ROOT is the location of the PNaCl toolchain. # This is used as the default root for finding binutils, libcxx, etc. -PNACL_TOOLCHAIN_ROOT ?= $(shell readlink -e \ - $(NACL_ROOT)/toolchain/linux_x86/pnacl_newlib_raw) +PNACL_TOOLCHAIN_ROOT ?= $(shell readlink -e $(TOOLCHAIN_ROOT)/pnacl_newlib_raw) # The location of PNaCl tools (e.g., binutils objdump, pnacl-clang++, etc.). PNACL_BIN_PATH ?= $(shell readlink -e $(PNACL_TOOLCHAIN_ROOT)/bin) @@ -105,6 +108,7 @@ $(info -----------------------------------------------) $(info Using LLVM_SRC_PATH = $(LLVM_SRC_PATH)) $(info Using SB_LLVM_PATH = $(SB_LLVM_PATH)) $(info Using NACL_ROOT = $(NACL_ROOT)) +$(info Using TOOLCHAIN_ROOT = $(TOOLCHAIN_ROOT)) $(info Using PNACL_TOOLCHAIN_ROOT = $(PNACL_TOOLCHAIN_ROOT)) $(info Using PNACL_BIN_PATH = $(PNACL_BIN_PATH)) $(info Using CLANG_PATH = $(CLANG_PATH)) @@ -303,8 +307,10 @@ check-xtest: $(OBJDIR)/pnacl-sz make_symlink runtime # Do all native/sse2 tests, but only test_vector_ops for native/sse4.1. # For (slow) sandboxed tests, limit to Om1/sse4.1. ./pydir/crosstest_generator.py -v --lit \ - -i native,sse2 -i native,sse4.1,test_vector_ops \ - -i sandbox,sse4.1,Om1 + --toolchain-root $(TOOLCHAIN_ROOT) \ + -i x8632,native,sse2 -i x8632,native,sse4.1,test_vector_ops \ + -i x8632,sandbox,sse4.1,Om1 \ + -i arm32,native,neon,Om1,simple_loop PNACL_BIN_PATH=$(PNACL_BIN_PATH) \ $(LLVM_SRC_PATH)/utils/lit/lit.py -sv crosstest/Output endif diff --git a/pydir/build-runtime.py b/pydir/build-runtime.py index cc1054ff5..4010b51d7 100755 --- a/pydir/build-runtime.py +++ b/pydir/build-runtime.py @@ -1,13 +1,15 @@ #!/usr/bin/env python2 import argparse -from collections import namedtuple import os import shutil import tempfile + +import targets from utils import shellcmd from utils import FindBaseNaCl + def Translate(ll_files, extra_args, obj, verbose): """Translate a set of input bitcode files into a single object file. @@ -29,6 +31,7 @@ def Translate(ll_files, extra_args, obj, verbose): obj ], echo=verbose) + def PartialLink(obj_files, extra_args, lib, verbose): """Partially links a set of obj files into a final obj library.""" shellcmd(['le32-nacl-ld', @@ -37,10 +40,6 @@ def PartialLink(obj_files, extra_args, lib, verbose): ] + extra_args + obj_files, echo=verbose) -TargetInfo = namedtuple('TargetInfo', - ['target', 'triple', 'llc_flags', 'ld_emu']) - - def MakeRuntimesForTarget(target_info, ll_files, srcdir, tempdir, rtdir, verbose): def TmpFile(template): @@ -72,7 +71,7 @@ def MakeRuntimesForTarget(target_info, ll_files, # The sandboxed library does not get the profiler helper function as the # binaries are linked with -nostdlib. Translate(ll_files, - ['-mtriple=' + target_info.triple.replace('linux', 'nacl')] + + ['-mtriple=' + targets.ConvertTripleToNaCl(target_info.triple)] + target_info.llc_flags, OutFile('{rtdir}/szrt_sb_{target}.o'), verbose) @@ -123,19 +122,9 @@ def main(): ll_files = ['{dir}/szrt.ll'.format(dir=tempdir), '{srcdir}/szrt_ll.ll'.format(srcdir=srcdir)] - x8632_target = TargetInfo(target='x8632', - triple='i686-none-linux', - llc_flags=['-mcpu=pentium4m'], - ld_emu='elf_i386_nacl') - MakeRuntimesForTarget(x8632_target, ll_files, + MakeRuntimesForTarget(targets.X8632Target, ll_files, srcdir, tempdir, rtdir, args.verbose) - arm32_target = TargetInfo(target='arm32', - triple='armv7a-none-linux-gnueabihf', - llc_flags=['-mcpu=cortex-a9', - '-float-abi=hard', - '-mattr=+neon'], - ld_emu='armelf_nacl') - MakeRuntimesForTarget(arm32_target, ll_files, + MakeRuntimesForTarget(targets.ARM32Target, ll_files, srcdir, tempdir, rtdir, args.verbose) finally: diff --git a/pydir/crosstest.py b/pydir/crosstest.py index ca7e242ad..ebc33f8d7 100755 --- a/pydir/crosstest.py +++ b/pydir/crosstest.py @@ -6,6 +6,7 @@ import subprocess import sys import tempfile +import targets from utils import shellcmd from utils import FindBaseNaCl @@ -22,8 +23,23 @@ def main(): results. """ - # arch_map maps a Subzero target string to an llvm-mc -triple string. - arch_map = { 'x8632':'i686', 'x8664':'x86_64', 'arm':'armv7a' } + # arch_map maps a Subzero target string to TargetInfo (e.g., triple). + arch_map = { 'x8632': targets.X8632Target, + 'x8664': targets.X8664Target, + 'arm32': targets.ARM32Target } + arch_sz_flags = { 'x8632': [], + 'x8664': [], + # TODO(jvoung): remove skip-unimplemented when implemented + 'arm32': ['--skip-unimplemented'] + } + arch_llc_flags_extra = { + # Use sse2 instructions regardless of input -mattr + # argument to avoid differences in (undefined) behavior of + # converting NaN to int. + 'x8632': ['-mattr=sse2'], + 'x8664': ['-mattr=sse2'], + 'arm32': [], + } desc = 'Build a cross-test that compares Subzero and llc translation.' argparser = argparse.ArgumentParser(description=desc) argparser.add_argument('--test', required=True, action='append', @@ -46,7 +62,8 @@ def main(): argparser.add_argument('--clang-opt', required=False, default=True, dest='clang_opt') argparser.add_argument('--mattr', required=False, default='sse2', - dest='attr', choices=['sse2', 'sse4.1'], + dest='attr', choices=['sse2', 'sse4.1', + 'neon', 'hwdiv-arm'], metavar='ATTRIBUTE', help='Target attribute. Default %(default)s.') argparser.add_argument('--sandbox', required=False, default=0, type=int, @@ -76,7 +93,11 @@ def main(): nacl_root = FindBaseNaCl() bindir = ('{root}/toolchain/linux_x86/pnacl_newlib_raw/bin' .format(root=nacl_root)) - triple = arch_map[args.target] + ('-nacl' if args.sandbox else '') + target_info = arch_map[args.target] + triple = target_info.triple + if args.sandbox: + triple = targets.ConvertTripleToNaCl(triple) + llc_flags = target_info.llc_flags + arch_llc_flags_extra[args.target] mypath = os.path.abspath(os.path.dirname(sys.argv[0])) objs = [] @@ -116,7 +137,7 @@ def main(): '-externalize', '-filetype=' + args.filetype, '-o=' + (obj_sz if args.filetype == 'obj' else asm_sz), - bitcode]) + bitcode] + arch_sz_flags[args.target]) if args.filetype != 'obj': shellcmd(['{bin}/llvm-mc'.format(bin=bindir), '-triple=' + triple, @@ -137,14 +158,10 @@ def main(): if args.crosstest_bitcode: shellcmd(['{bin}/pnacl-llc'.format(bin=bindir), '-mtriple=' + triple, - # Use sse2 instructions regardless of input -mattr - # argument to avoid differences in (undefined) behavior of - # converting NaN to int. - '-mattr=sse2', '-externalize', '-filetype=obj', '-o=' + obj_llc, - bitcode]) + bitcode] + llc_flags) objs.append(obj_llc) else: objs.append(arg) @@ -162,7 +179,8 @@ def main(): sb_native_args = (['-O0', '--pnacl-allow-native', '-arch', 'x8632', '-Wn,-defsym=__Sz_AbsoluteZero=0'] if args.sandbox else - ['-g', '-m32', '-lm', '-lpthread', + ['-g', '-target=' + triple, + '-lm', '-lpthread', '-Wl,--defsym=__Sz_AbsoluteZero=0']) shellcmd([compiler, args.driver] + objs + ['-o', os.path.join(args.dir, args.output)] + sb_native_args) diff --git a/pydir/crosstest_generator.py b/pydir/crosstest_generator.py index 945ad0086..e79657f65 100755 --- a/pydir/crosstest_generator.py +++ b/pydir/crosstest_generator.py @@ -27,6 +27,22 @@ def Match(desc, includes, excludes, default_match): return True return default_match + +def RunNativePrefix(toolchain_root, target, run_cmd): + """Returns a prefix for running an executable for the target. + + For example, we may be running an ARM or MIPS target executable on an + x86 machine and need to use an emulator. + """ + arch_map = { 'x8632' : '', + 'x8664' : '', + 'arm32' : os.path.join(toolchain_root, 'arm_trusted', + 'run_under_qemu_arm'), + } + prefix = arch_map[target] + return (prefix + ' ' + run_cmd) if prefix else run_cmd + + def main(): """Framework for cross test generation and execution. @@ -39,13 +55,20 @@ def main(): root = FindBaseNaCl() # The rest of the attribute sets. - targets = [ 'x8632' ] + targets = [ 'x8632', 'arm32' ] sandboxing = [ 'native', 'sandbox' ] opt_levels = [ 'Om1', 'O2' ] - arch_attrs = [ 'sse2', 'sse4.1' ] + arch_attrs = { 'x8632': [ 'sse2', 'sse4.1' ], + 'arm32': [ 'neon', 'hwdiv-arm' ] } + flat_attrs = [] + for v in arch_attrs.values(): + flat_attrs += v + arch_flags = { 'x8632': [], + # ARM doesn't have an integrated assembler yet. + 'arm32': ['--filetype=asm'] } # all_keys is only used in the help text. all_keys = '; '.join([' '.join(targets), ' '.join(sandboxing), - ' '.join(opt_levels), ' '.join(arch_attrs)]) + ' '.join(opt_levels), ' '.join(flat_attrs)]) argparser = argparse.ArgumentParser( description=' ' + main.__doc__ + @@ -76,6 +99,8 @@ def main(): help='Output directory') argparser.add_argument('--lit', default=False, action='store_true', help='Generate files for lit testing') + argparser.add_argument('--toolchain-root', dest='toolchain_root', + help='Path to toolchain binaries.') args = argparser.parse_args() # Run from the crosstest directory to make it easy to grab inputs. @@ -113,7 +138,7 @@ def main(): for target in targets: for sb in sandboxing: for opt in opt_levels: - for attr in arch_attrs: + for attr in arch_attrs[target]: desc = [ test, target, sb, opt, attr ] if Match(set(desc), includes, excludes, default_match): exe = '{test}_{target}_{sb}_{opt}_{attr}'.format( @@ -122,24 +147,27 @@ def main(): extra = (tests.get(test, 'flags').split(' ') if tests.has_option(test, 'flags') else []) # Generate the compile command. - cmp_cmd = ['{path}/crosstest.py'.format(path=pypath), - '-{opt}'.format(opt=opt), - '--mattr={attr}'.format(attr=attr), - '--prefix=Subzero_', - '--target={target}'.format(target=target), - '--sandbox={sb}'.format(sb='1' if sb=='sandbox' - else '0'), - '--dir={dir}'.format(dir=args.dir), - '--output={exe}'.format(exe=exe), - '--driver={drv}'.format(drv=tests.get(test, 'driver')), - ] + extra + \ - [ '--test=' + t - for t in tests.get(test, 'test').split(' ') ] + cmp_cmd = ( + ['{path}/crosstest.py'.format(path=pypath), + '-{opt}'.format(opt=opt), + '--mattr={attr}'.format(attr=attr), + '--prefix=Subzero_', + '--target={target}'.format(target=target), + '--sandbox={sb}'.format(sb='1' if sb=='sandbox' else '0'), + '--dir={dir}'.format(dir=args.dir), + '--output={exe}'.format(exe=exe), + '--driver={drv}'.format(drv=tests.get(test, 'driver'))] + + extra + + ['--test=' + t + for t in tests.get(test, 'test').split(' ')] + + arch_flags[target]) run_cmd_base = os.path.join(args.dir, exe) # Generate the run command. run_cmd = run_cmd_base if sb == 'sandbox': run_cmd = '{root}/run.py -q '.format(root=root) + run_cmd + else: + run_cmd = RunNativePrefix(args.toolchain_root, target, run_cmd) if args.lit: # Create a file to drive the lit test. with open(run_cmd_base + '.xtest', 'w') as f: diff --git a/pydir/targets.py b/pydir/targets.py new file mode 100644 index 000000000..0f6433c30 --- /dev/null +++ b/pydir/targets.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python2 + +from collections import namedtuple + +TargetInfo = namedtuple('TargetInfo', + ['target', 'triple', 'llc_flags', 'ld_emu']) + +X8632Target = TargetInfo(target='x8632', + triple='i686-none-linux', + llc_flags=['-mcpu=pentium4m'], + ld_emu='elf_i386_nacl') + +X8664Target = TargetInfo(target='x8664', + triple='x86_64-none-linux', + llc_flags=['-mcpu=x86-64'], + ld_emu='elf_x86_64_nacl') + +ARM32Target = TargetInfo(target='arm32', + triple='armv7a-none-linux-gnueabihf', + llc_flags=['-mcpu=cortex-a9', + '-float-abi=hard', + '-mattr=+neon'], + ld_emu='armelf_nacl') + + +def ConvertTripleToNaCl(nonsfi_triple): + return nonsfi_triple.replace('linux', 'nacl') -- 2.11.0