Index: cfe/trunk/CMakeLists.txt =================================================================== --- cfe/trunk/CMakeLists.txt +++ cfe/trunk/CMakeLists.txt @@ -570,6 +570,7 @@ ARGS ${LLVM_LIT_EXTRA_ARGS} ) endif() + add_subdirectory(utils/perf-training) endif() option(CLANG_INCLUDE_DOCS "Generate build targets for the Clang docs." Index: cfe/trunk/utils/perf-training/CMakeLists.txt =================================================================== --- cfe/trunk/utils/perf-training/CMakeLists.txt +++ cfe/trunk/utils/perf-training/CMakeLists.txt @@ -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() Index: cfe/trunk/utils/perf-training/README.txt =================================================================== --- cfe/trunk/utils/perf-training/README.txt +++ cfe/trunk/utils/perf-training/README.txt @@ -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. Index: cfe/trunk/utils/perf-training/cxx/hello_world.cpp =================================================================== --- cfe/trunk/utils/perf-training/cxx/hello_world.cpp +++ cfe/trunk/utils/perf-training/cxx/hello_world.cpp @@ -0,0 +1,7 @@ +// RUN: %clang_cpp -c %s +#include + +int main(int, char**) { + std::cout << "Hello, World!"; + return 0; +} Index: cfe/trunk/utils/perf-training/lit.cfg =================================================================== --- cfe/trunk/utils/perf-training/lit.cfg +++ cfe/trunk/utils/perf-training/lit.cfg @@ -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' + Index: cfe/trunk/utils/perf-training/lit.site.cfg.in =================================================================== --- cfe/trunk/utils/perf-training/lit.site.cfg.in +++ cfe/trunk/utils/perf-training/lit.site.cfg.in @@ -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") Index: cfe/trunk/utils/perf-training/perf-helper.py =================================================================== --- cfe/trunk/utils/perf-training/perf-helper.py +++ cfe/trunk/utils/perf-training/perf-helper.py @@ -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 \n\tRemoves all *.profraw files from .' % __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 \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()