diff options
-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(): |