diff options
author | Chris Bieneman <beanz@apple.com> | 2016-03-21 22:37:14 +0000 |
---|---|---|
committer | Chris Bieneman <beanz@apple.com> | 2016-03-21 22:37:14 +0000 |
commit | 12fd02db6b3e094562d68eeae20c007c0baa3650 (patch) | |
tree | 78ff49bc7dbffe09b1e8a1d7303d0c849f41c0b8 | |
parent | e9b02d68f48030a6306c0bf6b37c17ee2f375ab1 (diff) | |
download | bcm5719-llvm-12fd02db6b3e094562d68eeae20c007c0baa3650.tar.gz bcm5719-llvm-12fd02db6b3e094562d68eeae20c007c0baa3650.zip |
[Perf-training] Adding support for tests to skip the clang driver
This patch adds a new set of substitutions to the lit run lines for order files and PGO generation which run the clang driver to get the cc1 command, then execute the cc1 command directly. This allows the scripts to bypass profiling the clang driver over and over again.
The approach in this patch was discussed via IRC with Sean Silvas.
Special thanks to Daniel Dunbar whose out-of-tree code I liberally plagiarized.
llvm-svn: 263997
-rw-r--r-- | clang/utils/perf-training/cxx/hello_world.cpp | 1 | ||||
-rw-r--r-- | clang/utils/perf-training/lit.cfg | 5 | ||||
-rw-r--r-- | clang/utils/perf-training/lit.site.cfg.in | 1 | ||||
-rw-r--r-- | clang/utils/perf-training/order-files.lit.cfg | 4 | ||||
-rw-r--r-- | clang/utils/perf-training/perf-helper.py | 60 |
5 files changed, 69 insertions, 2 deletions
diff --git a/clang/utils/perf-training/cxx/hello_world.cpp b/clang/utils/perf-training/cxx/hello_world.cpp index 66e00d00d26..fc9f6892eb7 100644 --- a/clang/utils/perf-training/cxx/hello_world.cpp +++ b/clang/utils/perf-training/cxx/hello_world.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cpp -c %s +// RUN: %clang_cpp_skip_driver -Wall -pedantic -c %s #include <iostream> int main(int, char**) { diff --git a/clang/utils/perf-training/lit.cfg b/clang/utils/perf-training/lit.cfg index af4b43b78b0..85d35514341 100644 --- a/clang/utils/perf-training/lit.cfg +++ b/clang/utils/perf-training/lit.cfg @@ -26,10 +26,13 @@ config.clang = lit.util.which('clang', config.clang_tools_dir).replace('\\', '/' config.name = 'Clang Perf Training' config.suffixes = ['.c', '.cpp', '.m', '.mm', '.cu', '.ll', '.cl', '.s', '.S', '.modulemap'] +cc1_wrapper = '%s %s/perf-helper.py cc1' % (config.python_exe, config.test_source_root) + use_lit_shell = os.environ.get("LIT_USE_INTERNAL_SHELL") config.test_format = lit.formats.ShTest(use_lit_shell == "0") +config.substitutions.append( ('%clang_cpp_skip_driver', ' %s %s %s ' % (cc1_wrapper, config.clang, sysroot_flags))) config.substitutions.append( ('%clang_cpp', ' %s --driver-mode=cpp %s ' % (config.clang, sysroot_flags))) -config.substitutions.append( ('%clang_cc1', ' %s -cc1 %s ' % (config.clang, sysroot_flags))) +config.substitutions.append( ('%clang_skip_driver', ' %s %s %s ' % (cc1_wrapper, config.clang, sysroot_flags))) config.substitutions.append( ('%clang', ' %s %s ' % (config.clang, sysroot_flags) ) ) config.substitutions.append( ('%test_root', config.test_exec_root ) ) diff --git a/clang/utils/perf-training/lit.site.cfg.in b/clang/utils/perf-training/lit.site.cfg.in index 9dc380242e5..52c5465dc34 100644 --- a/clang/utils/perf-training/lit.site.cfg.in +++ b/clang/utils/perf-training/lit.site.cfg.in @@ -6,6 +6,7 @@ config.clang_tools_dir = "@CLANG_TOOLS_DIR@" config.test_exec_root = "@CMAKE_CURRENT_BINARY_DIR@" config.test_source_root = "@CMAKE_CURRENT_SOURCE_DIR@" config.target_triple = "@TARGET_TRIPLE@" +config.python_exe = "@PYTHON_EXECUTABLE@" # Support substitution of the tools and libs dirs with user parameters. This is # used when we can't determine the tool dir at configuration time. diff --git a/clang/utils/perf-training/order-files.lit.cfg b/clang/utils/perf-training/order-files.lit.cfg index 0e151bf1fa8..75501f8c629 100644 --- a/clang/utils/perf-training/order-files.lit.cfg +++ b/clang/utils/perf-training/order-files.lit.cfg @@ -28,11 +28,13 @@ config.name = 'Clang Perf Training' config.suffixes = ['.c', '.cpp', '.m', '.mm', '.cu', '.ll', '.cl', '.s', '.S', '.modulemap'] dtrace_wrapper = '%s %s/perf-helper.py dtrace' % (config.python_exe, config.test_source_root) +dtrace_wrapper_cc1 = '%s %s/perf-helper.py dtrace --cc1' % (config.python_exe, config.test_source_root) use_lit_shell = os.environ.get("LIT_USE_INTERNAL_SHELL") config.test_format = lit.formats.ShTest(use_lit_shell == "0") +config.substitutions.append( ('%clang_cpp_skip_driver', ' %s %s --driver-mode=cpp %s ' % (dtrace_wrapper_cc1, config.clang, sysroot_flags))) config.substitutions.append( ('%clang_cpp', ' %s %s --driver-mode=cpp %s ' % (dtrace_wrapper, config.clang, sysroot_flags))) -config.substitutions.append( ('%clang_cc1', ' %s %s -cc1 %s ' % (dtrace_wrapper, config.clang, sysroot_flags))) +config.substitutions.append( ('%clang_skip_driver', ' %s %s %s ' % (dtrace_wrapper_cc1, config.clang, sysroot_flags))) config.substitutions.append( ('%clang', ' %s %s %s ' % (dtrace_wrapper, config.clang, sysroot_flags) ) ) config.substitutions.append( ('%test_root', config.test_exec_root ) ) diff --git a/clang/utils/perf-training/perf-helper.py b/clang/utils/perf-training/perf-helper.py index a4ae68c849a..19f3819b301 100644 --- a/clang/utils/perf-training/perf-helper.py +++ b/clang/utils/perf-training/perf-helper.py @@ -15,6 +15,9 @@ import subprocess import argparse import time import bisect +import shlex + +test_env = { 'PATH' : os.environ['PATH'] } def findFilesWithExtension(path, extension): filenames = [] @@ -52,6 +55,8 @@ def dtrace(args): help='Use dtrace\'s oneshot probes') parser.add_argument('--use-ustack', required=False, action='store_true', help='Use dtrace\'s ustack to print function names') + parser.add_argument('--cc1', required=False, action='store_true', + help='Execute cc1 directly (don\'t profile the driver)') parser.add_argument('cmd', nargs='*', help='') # Use python's arg parser to handle all leading option arguments, but pass @@ -62,6 +67,9 @@ def dtrace(args): opts = parser.parse_args(args[:last_arg_idx]) cmd = args[last_arg_idx:] + if opts.cc1: + cmd = get_cc1_command_for_args(cmd, test_env) + if opts.use_oneshot: target = "oneshot$target:::entry" else: @@ -98,6 +106,57 @@ def dtrace(args): return 0 +def get_cc1_command_for_args(cmd, env): + # Find the cc1 command used by the compiler. To do this we execute the + # compiler with '-###' to figure out what it wants to do. + cmd = cmd + ['-###'] + cc_output = check_output(cmd, stderr=subprocess.STDOUT, env=env).strip() + cc_commands = [] + for ln in cc_output.split('\n'): + # Filter out known garbage. + if (ln == 'Using built-in specs.' or + ln.startswith('Configured with:') or + ln.startswith('Target:') or + ln.startswith('Thread model:') or + ln.startswith('InstalledDir:') or + ' version ' in ln): + continue + cc_commands.append(ln) + + if len(cc_commands) != 1: + print('Fatal error: unable to determine cc1 command: %r' % cc_output) + exit(1) + + cc1_cmd = shlex.split(cc_commands[0]) + if not cc1_cmd: + print('Fatal error: unable to determine cc1 command: %r' % cc_output) + exit(1) + + return cc1_cmd + +def cc1(args): + parser = argparse.ArgumentParser(prog='perf-helper cc1', + description='cc1 wrapper for order file generation') + parser.add_argument('cmd', nargs='*', help='') + + # Use python's arg parser to handle all leading option arguments, but pass + # everything else through to dtrace + first_cmd = next(arg for arg in args if not arg.startswith("--")) + last_arg_idx = args.index(first_cmd) + + opts = parser.parse_args(args[:last_arg_idx]) + cmd = args[last_arg_idx:] + + # clear the profile file env, so that we don't generate profdata + # when capturing the cc1 command + cc1_env = test_env + cc1_env["LLVM_PROFILE_FILE"] = "driver.prfraw" + cc1_cmd = get_cc1_command_for_args(cmd, cc1_env) + os.remove("driver.prfraw") + + subprocess.check_call(cc1_cmd) + return 0; + def parse_dtrace_symbol_file(path, all_symbols, all_symbols_set, missing_symbols, opts): def fix_mangling(symbol): @@ -341,6 +400,7 @@ def genOrderFile(args): commands = {'clean' : clean, 'merge' : merge, 'dtrace' : dtrace, + 'cc1' : cc1, 'gen-order-file' : genOrderFile} def main(): |