r263997 - [Perf-training] Adding support for tests to skip the clang driver

Chris Bieneman via cfe-commits cfe-commits at lists.llvm.org
Mon Mar 21 15:37:15 PDT 2016


Author: cbieneman
Date: Mon Mar 21 17:37:14 2016
New Revision: 263997

URL: http://llvm.org/viewvc/llvm-project?rev=263997&view=rev
Log:
[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.

Modified:
    cfe/trunk/utils/perf-training/cxx/hello_world.cpp
    cfe/trunk/utils/perf-training/lit.cfg
    cfe/trunk/utils/perf-training/lit.site.cfg.in
    cfe/trunk/utils/perf-training/order-files.lit.cfg
    cfe/trunk/utils/perf-training/perf-helper.py

Modified: cfe/trunk/utils/perf-training/cxx/hello_world.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/perf-training/cxx/hello_world.cpp?rev=263997&r1=263996&r2=263997&view=diff
==============================================================================
--- cfe/trunk/utils/perf-training/cxx/hello_world.cpp (original)
+++ cfe/trunk/utils/perf-training/cxx/hello_world.cpp Mon Mar 21 17:37:14 2016
@@ -1,4 +1,5 @@
 // RUN: %clang_cpp -c %s
+// RUN: %clang_cpp_skip_driver -Wall -pedantic -c %s
 #include <iostream>
 
 int main(int, char**) {

Modified: cfe/trunk/utils/perf-training/lit.cfg
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/perf-training/lit.cfg?rev=263997&r1=263996&r2=263997&view=diff
==============================================================================
--- cfe/trunk/utils/perf-training/lit.cfg (original)
+++ cfe/trunk/utils/perf-training/lit.cfg Mon Mar 21 17:37:14 2016
@@ -26,10 +26,13 @@ config.clang = lit.util.which('clang', c
 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 ) )
 

Modified: cfe/trunk/utils/perf-training/lit.site.cfg.in
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/perf-training/lit.site.cfg.in?rev=263997&r1=263996&r2=263997&view=diff
==============================================================================
--- cfe/trunk/utils/perf-training/lit.site.cfg.in (original)
+++ cfe/trunk/utils/perf-training/lit.site.cfg.in Mon Mar 21 17:37:14 2016
@@ -6,6 +6,7 @@ config.clang_tools_dir = "@CLANG_TOOLS_D
 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.

Modified: cfe/trunk/utils/perf-training/order-files.lit.cfg
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/perf-training/order-files.lit.cfg?rev=263997&r1=263996&r2=263997&view=diff
==============================================================================
--- cfe/trunk/utils/perf-training/order-files.lit.cfg (original)
+++ cfe/trunk/utils/perf-training/order-files.lit.cfg Mon Mar 21 17:37:14 2016
@@ -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 ) )
 

Modified: cfe/trunk/utils/perf-training/perf-helper.py
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/perf-training/perf-helper.py?rev=263997&r1=263996&r2=263997&view=diff
==============================================================================
--- cfe/trunk/utils/perf-training/perf-helper.py (original)
+++ cfe/trunk/utils/perf-training/perf-helper.py Mon Mar 21 17:37:14 2016
@@ -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():




More information about the cfe-commits mailing list