r255740 - [CMake] Add support for generating profdata for clang from training files

Chris Bieneman via cfe-commits cfe-commits at lists.llvm.org
Tue Dec 15 17:02:46 PST 2015


Author: cbieneman
Date: Tue Dec 15 19:02:44 2015
New Revision: 255740

URL: http://llvm.org/viewvc/llvm-project?rev=255740&view=rev
Log:
[CMake] Add support for generating profdata for clang from training files

Summary:
This patch adds support for using LIT to drive generating PGO profile data for clang.

This first pass implementation should work on Linux and Unix based platforms. If you build clang using CMake with LLVM_BUILD_INSTRUMENTED=On the CMake build generates a generate-profdata target that will use the just-built clang to build any test files (see hello_world.cpp as an example). Each test compile will generate profraw files for each clang process. After all tests have run CMake will merge the profraw files using llvm-profdata.

Future opportunities for extension:
* Support for Build->Profile->Build bootstrapping
* Support for linker order file generation using a similar mechanism and the same training data
* Support for Windows

Reviewers: dexonsmith, friss, bogner, cmatthews, vsk, silvas

Subscribers: cfe-commits

Differential Revision: http://reviews.llvm.org/D15462

Added:
    cfe/trunk/utils/perf-training/
    cfe/trunk/utils/perf-training/CMakeLists.txt
    cfe/trunk/utils/perf-training/README.txt
    cfe/trunk/utils/perf-training/cxx/
    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/perf-helper.py
Modified:
    cfe/trunk/CMakeLists.txt

Modified: cfe/trunk/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/CMakeLists.txt?rev=255740&r1=255739&r2=255740&view=diff
==============================================================================
--- cfe/trunk/CMakeLists.txt (original)
+++ cfe/trunk/CMakeLists.txt Tue Dec 15 19:02:44 2015
@@ -570,6 +570,7 @@ if( CLANG_INCLUDE_TESTS )
       ARGS ${LLVM_LIT_EXTRA_ARGS}
       )
   endif()
+  add_subdirectory(utils/perf-training)
 endif()
 
 option(CLANG_INCLUDE_DOCS "Generate build targets for the Clang docs."

Added: cfe/trunk/utils/perf-training/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/perf-training/CMakeLists.txt?rev=255740&view=auto
==============================================================================
--- cfe/trunk/utils/perf-training/CMakeLists.txt (added)
+++ cfe/trunk/utils/perf-training/CMakeLists.txt Tue Dec 15 19:02:44 2015
@@ -0,0 +1,36 @@
+if(LLVM_BUILD_INSTRUMENTED)
+  if (CMAKE_CFG_INTDIR STREQUAL ".")
+    set(LLVM_BUILD_MODE ".")
+  else ()
+    set(LLVM_BUILD_MODE "%(build_mode)s")
+  endif ()
+
+  string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} CLANG_TOOLS_DIR ${LLVM_RUNTIME_OUTPUT_INTDIR})
+
+  configure_lit_site_cfg(
+    ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in
+    ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg
+    )
+
+  add_lit_testsuite(generate-profraw "Generating clang PGO data"
+    ${CMAKE_CURRENT_BINARY_DIR}
+    DEPENDS clang clear-profraw
+    )
+
+  add_custom_target(clear-profraw
+    COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/perf-helper.py clean ${CMAKE_CURRENT_BINARY_DIR}
+    COMMENT "Clearing old profraw data")
+
+  if(NOT LLVM_PROFDATA)
+    find_program(LLVM_PROFDATA llvm-profdata)
+  endif()
+
+  if(NOT LLVM_PROFDATA)
+    message(FATAL_ERROR "Must set LLVM_PROFDATA to point to llvm-profdata to use for merging PGO data")
+  endif()
+
+  add_custom_target(generate-profdata
+    COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/perf-helper.py merge ${LLVM_PROFDATA} ${CMAKE_CURRENT_BINARY_DIR}/clang.profdata ${CMAKE_CURRENT_BINARY_DIR}
+    COMMENT "Merging profdata"
+    DEPENDS generate-profraw)
+endif()

Added: cfe/trunk/utils/perf-training/README.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/perf-training/README.txt?rev=255740&view=auto
==============================================================================
--- cfe/trunk/utils/perf-training/README.txt (added)
+++ cfe/trunk/utils/perf-training/README.txt Tue Dec 15 19:02:44 2015
@@ -0,0 +1,6 @@
+==========================
+ Performance Training Data
+==========================
+
+This directory contains simple source files for use as training data for
+generating PGO data and linker order files for clang.

Added: 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=255740&view=auto
==============================================================================
--- cfe/trunk/utils/perf-training/cxx/hello_world.cpp (added)
+++ cfe/trunk/utils/perf-training/cxx/hello_world.cpp Tue Dec 15 19:02:44 2015
@@ -0,0 +1,7 @@
+// RUN: %clang_cpp -c %s
+#include <iostream>
+
+int main(int, char**) {
+  std::cout << "Hello, World!";
+  return 0;
+}

Added: cfe/trunk/utils/perf-training/lit.cfg
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/perf-training/lit.cfg?rev=255740&view=auto
==============================================================================
--- cfe/trunk/utils/perf-training/lit.cfg (added)
+++ cfe/trunk/utils/perf-training/lit.cfg Tue Dec 15 19:02:44 2015
@@ -0,0 +1,35 @@
+# -*- Python -*-
+
+from lit import Test
+import lit.formats
+import lit.util
+
+def getSysrootFlagsOnDarwin(config, lit_config):
+    # On Darwin, support relocatable SDKs by providing Clang with a
+    # default system root path.
+    if 'darwin' in config.target_triple:
+        try:
+            out = lit.util.capture(['xcrun', '--show-sdk-path']).strip()
+            res = 0
+        except OSError:
+            res = -1
+        if res == 0 and out:
+            sdk_path = out
+            lit_config.note('using SDKROOT: %r' % sdk_path)
+            return '-isysroot %s' % sdk_path
+    return ''
+
+sysroot_flags = getSysrootFlagsOnDarwin(config, lit_config)
+
+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']
+
+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', ' %s --driver-mode=cpp %s ' % (config.clang, sysroot_flags)))
+config.substitutions.append( ('%clang', ' %s %s ' % (config.clang, sysroot_flags) ) )
+
+config.environment['LLVM_PROFILE_FILE'] = 'perf-training-%p.profraw'
+

Added: 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=255740&view=auto
==============================================================================
--- cfe/trunk/utils/perf-training/lit.site.cfg.in (added)
+++ cfe/trunk/utils/perf-training/lit.site.cfg.in Tue Dec 15 19:02:44 2015
@@ -0,0 +1,20 @@
+import sys
+
+## Autogenerated by LLVM/Clang configuration.
+# Do not edit!
+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@"
+
+# 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.
+try:
+    config.clang_tools_dir = config.clang_tools_dir % lit_config.params
+except KeyError:
+    e = sys.exc_info()[1]
+    key, = e.args
+    lit_config.fatal("unable to find %r parameter, use '--param=%s=VALUE'" % (key,key))
+
+# Let the main config do the real work.
+lit_config.load_config(config, "@CLANG_SOURCE_DIR@/utils/perf-training/lit.cfg")

Added: cfe/trunk/utils/perf-training/perf-helper.py
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/perf-training/perf-helper.py?rev=255740&view=auto
==============================================================================
--- cfe/trunk/utils/perf-training/perf-helper.py (added)
+++ cfe/trunk/utils/perf-training/perf-helper.py Tue Dec 15 19:02:44 2015
@@ -0,0 +1,46 @@
+#===- perf-helper.py - Clang Python Bindings -----------------*- python -*--===#
+#
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+#===------------------------------------------------------------------------===#
+
+import sys
+import os
+import subprocess
+
+def findProfrawFiles(path):
+  profraw_files = []
+  for root, dirs, files in os.walk(path): 
+    for filename in files:
+      if filename.endswith(".profraw"):
+        profraw_files.append(os.path.join(root, filename))
+  return profraw_files
+
+def clean(args):
+  if len(args) != 1:
+    print 'Usage: %s clean <path>\n\tRemoves all *.profraw files from <path>.' % __file__
+    return 1
+  for profraw in findProfrawFiles(args[0]):
+    os.remove(profraw)
+  return 0
+
+def merge(args):
+  if len(args) != 3:
+    print 'Usage: %s clean <llvm-profdata> <output> <path>\n\tMerges all profraw files from path into output.' % __file__
+    return 1
+  cmd = [args[0], 'merge', '-o', args[1]]
+  cmd.extend(findProfrawFiles(args[2]))
+  subprocess.check_call(cmd)
+  return 0
+
+commands = {'clean' : clean, 'merge' : merge}
+
+def main():
+  f = commands[sys.argv[1]]
+  sys.exit(f(sys.argv[2:]))
+
+if __name__ == '__main__':
+  main()




More information about the cfe-commits mailing list