From eae951415e1a3051666cc812838e3be2394340a0 Mon Sep 17 00:00:00 2001 From: Diego Novillo Date: Thu, 9 Jul 2015 17:21:52 +0000 Subject: Add support for generating profiles in a given directory. When the file is initialized, this patch checks whether the path specifies a directory. If so, it creates the directory tree before truncating the file. Use default.profdata instead of pgo-data for default indexed profile name. llvm-svn: 241824 --- compiler-rt/lib/profile/CMakeLists.txt | 3 +- compiler-rt/lib/profile/GCDAProfiling.c | 28 ++--------------- compiler-rt/lib/profile/InstrProfiling.h | 2 +- compiler-rt/lib/profile/InstrProfilingFile.c | 8 +++++ compiler-rt/lib/profile/InstrProfilingUtil.c | 35 ++++++++++++++++++++++ compiler-rt/lib/profile/InstrProfilingUtil.h | 16 ++++++++++ .../test/profile/Inputs/gcc-flag-compatibility.c | 8 +++++ .../test/profile/gcc-flag-compatibility.test | 17 +++++++++++ compiler-rt/test/profile/lit.cfg | 2 ++ 9 files changed, 92 insertions(+), 27 deletions(-) create mode 100644 compiler-rt/lib/profile/InstrProfilingUtil.c create mode 100644 compiler-rt/lib/profile/InstrProfilingUtil.h create mode 100644 compiler-rt/test/profile/Inputs/gcc-flag-compatibility.c create mode 100644 compiler-rt/test/profile/gcc-flag-compatibility.test (limited to 'compiler-rt') diff --git a/compiler-rt/lib/profile/CMakeLists.txt b/compiler-rt/lib/profile/CMakeLists.txt index d0714e0..d03409f 100644 --- a/compiler-rt/lib/profile/CMakeLists.txt +++ b/compiler-rt/lib/profile/CMakeLists.txt @@ -7,7 +7,8 @@ set(PROFILE_SOURCES InstrProfilingFile.c InstrProfilingPlatformDarwin.c InstrProfilingPlatformOther.c - InstrProfilingRuntime.cc) + InstrProfilingRuntime.cc + InstrProfilingUtil.c) if(APPLE) add_compiler_rt_osx_static_runtime(clang_rt.profile_osx diff --git a/compiler-rt/lib/profile/GCDAProfiling.c b/compiler-rt/lib/profile/GCDAProfiling.c index e32e97f..aec2328 100644 --- a/compiler-rt/lib/profile/GCDAProfiling.c +++ b/compiler-rt/lib/profile/GCDAProfiling.c @@ -20,6 +20,8 @@ |* \*===----------------------------------------------------------------------===*/ +#include "InstrProfilingUtil.h" + #include #include #include @@ -27,17 +29,9 @@ #include #include #include -#ifdef _WIN32 -#include -#endif #define I386_FREEBSD (defined(__FreeBSD__) && defined(__i386__)) -#if !I386_FREEBSD -#include -#include -#endif - #if !defined(_MSC_VER) && !I386_FREEBSD #include #endif @@ -52,7 +46,6 @@ typedef unsigned long long uint64_t; typedef unsigned char uint8_t; typedef unsigned int uint32_t; typedef unsigned long long uint64_t; -int mkdir(const char*, unsigned short); #endif /* #define DEBUG_GCDAPROFILING */ @@ -209,21 +202,6 @@ static char *mangle_filename(const char *orig_filename) { return new_filename; } -static void recursive_mkdir(char *path) { - int i; - - for (i = 1; path[i] != '\0'; ++i) { - if (path[i] != '/') continue; - path[i] = '\0'; -#ifdef _WIN32 - _mkdir(path); -#else - mkdir(path, 0755); /* Some of these will fail, ignore it. */ -#endif - path[i] = '/'; - } -} - static int map_file() { fseek(output_file, 0L, SEEK_END); file_size = ftell(output_file); @@ -283,7 +261,7 @@ void llvm_gcda_start_file(const char *orig_filename, const char version[4], fd = open(filename, O_RDWR | O_CREAT, 0644); if (fd == -1) { /* Try creating the directories first then opening the file. */ - recursive_mkdir(filename); + __llvm_profile_recursive_mkdir(filename); fd = open(filename, O_RDWR | O_CREAT, 0644); if (fd == -1) { /* Bah! It's hopeless. */ diff --git a/compiler-rt/lib/profile/InstrProfiling.h b/compiler-rt/lib/profile/InstrProfiling.h index 84b673c..3778a88 100644 --- a/compiler-rt/lib/profile/InstrProfiling.h +++ b/compiler-rt/lib/profile/InstrProfiling.h @@ -64,7 +64,7 @@ uint64_t *__llvm_profile_end_counters(void); * or if it hasn't been called, the \c LLVM_PROFILE_FILE environment variable, * or if that's not set, the last name given to * \a __llvm_profile_override_default_filename(), or if that's not set, - * \c "default.profdata". + * \c "default.profraw". */ int __llvm_profile_write_file(void); diff --git a/compiler-rt/lib/profile/InstrProfilingFile.c b/compiler-rt/lib/profile/InstrProfilingFile.c index 0102a25..9402238 100644 --- a/compiler-rt/lib/profile/InstrProfilingFile.c +++ b/compiler-rt/lib/profile/InstrProfilingFile.c @@ -8,6 +8,7 @@ \*===----------------------------------------------------------------------===*/ #include "InstrProfiling.h" +#include "InstrProfilingUtil.h" #include #include #include @@ -84,6 +85,13 @@ static void truncateCurrentFile(void) { if (!Filename || !Filename[0]) return; + /* Create the directory holding the file, if needed. */ + if (strchr(Filename, '/')) { + char *Copy = malloc(strlen(Filename) + 1); + strcpy(Copy, Filename); + __llvm_profile_recursive_mkdir(Copy); + } + /* Truncate the file. Later we'll reopen and append. */ File = fopen(Filename, "w"); if (!File) diff --git a/compiler-rt/lib/profile/InstrProfilingUtil.c b/compiler-rt/lib/profile/InstrProfilingUtil.c new file mode 100644 index 0000000..e146dfc --- /dev/null +++ b/compiler-rt/lib/profile/InstrProfilingUtil.c @@ -0,0 +1,35 @@ +/*===- InstrProfilingUtil.c - Support library for PGO instrumentation -----===*\ +|* +|* The LLVM Compiler Infrastructure +|* +|* This file is distributed under the University of Illinois Open Source +|* License. See LICENSE.TXT for details. +|* +\*===----------------------------------------------------------------------===*/ + +#include "InstrProfilingUtil.h" + +#ifdef _WIN32 +#include +#elif I386_FREEBSD +int mkdir(const char*, unsigned short); +#else +#include +#include +#endif + +__attribute__((visibility("hidden"))) +void __llvm_profile_recursive_mkdir(char *path) { + int i; + + for (i = 1; path[i] != '\0'; ++i) { + if (path[i] != '/') continue; + path[i] = '\0'; +#ifdef _WIN32 + _mkdir(path); +#else + mkdir(path, 0755); /* Some of these will fail, ignore it. */ +#endif + path[i] = '/'; + } +} diff --git a/compiler-rt/lib/profile/InstrProfilingUtil.h b/compiler-rt/lib/profile/InstrProfilingUtil.h new file mode 100644 index 0000000..756b18e --- /dev/null +++ b/compiler-rt/lib/profile/InstrProfilingUtil.h @@ -0,0 +1,16 @@ +/*===- InstrProfilingUtil.h - Support library for PGO instrumentation -----===*\ +|* +|* The LLVM Compiler Infrastructure +|* +|* This file is distributed under the University of Illinois Open Source +|* License. See LICENSE.TXT for details. +|* +\*===----------------------------------------------------------------------===*/ + +#ifndef PROFILE_INSTRPROFILINGUTIL_H +#define PROFILE_INSTRPROFILINGUTIL_H + +/*! \brief Create a directory tree. */ +void __llvm_profile_recursive_mkdir(char *Pathname); + +#endif /* PROFILE_INSTRPROFILINGUTIL_H */ diff --git a/compiler-rt/test/profile/Inputs/gcc-flag-compatibility.c b/compiler-rt/test/profile/Inputs/gcc-flag-compatibility.c new file mode 100644 index 0000000..1c07bb1 --- /dev/null +++ b/compiler-rt/test/profile/Inputs/gcc-flag-compatibility.c @@ -0,0 +1,8 @@ +int X = 0; + +int main() { + int i; + for (i = 0; i < 100; i++) + X += i; + return 0; +} diff --git a/compiler-rt/test/profile/gcc-flag-compatibility.test b/compiler-rt/test/profile/gcc-flag-compatibility.test new file mode 100644 index 0000000..8e8b55d --- /dev/null +++ b/compiler-rt/test/profile/gcc-flag-compatibility.test @@ -0,0 +1,17 @@ +RUN: mkdir -p %t.d +RUN: %clang_profgen_gcc=%t.d/d1/d2 -o %t.d/code %S/Inputs/gcc-flag-compatibility.c + +# Test that the instrumented code writes to %t.d/d1/d2/default.profraw +RUN: %run %t.d/code +RUN: llvm-profdata merge -o %t.profdata %t.d/d1/d2/default.profraw + +# Test that we can override the directory and file name with LLVM_PROFILE_FILE. +RUN: env LLVM_PROFILE_FILE=%t.d/x1/prof.raw %run %t.d/code +RUN: llvm-profdata merge -o %t.profdata %t.d/x1/prof.raw + +# Test that we can specify a directory with -fprofile-use. +RUN: llvm-profdata merge -o %t.d/default.profdata %t.d/x1/prof.raw +RUN: %clang_profuse_gcc=%t.d -o %t.d/code %S/Inputs/gcc-flag-compatibility.c + +# Test that we can specify a file with -fprofile-use. +RUN: %clang_profuse_gcc=%t.profdata -o %t.d/code %S/Inputs/gcc-flag-compatibility.c diff --git a/compiler-rt/test/profile/lit.cfg b/compiler-rt/test/profile/lit.cfg index e4910ab..b1b44a1 100644 --- a/compiler-rt/test/profile/lit.cfg +++ b/compiler-rt/test/profile/lit.cfg @@ -45,6 +45,8 @@ def build_invocation(compile_flags): config.substitutions.append( ("%clang ", build_invocation(clang_cflags)) ) config.substitutions.append( ("%clang_profgen ", build_invocation(clang_cflags) + " -fprofile-instr-generate ") ) config.substitutions.append( ("%clang_profuse=", build_invocation(clang_cflags) + " -fprofile-instr-use=") ) +config.substitutions.append( ("%clang_profgen_gcc=", build_invocation(clang_cflags) + " -fprofile-generate=") ) +config.substitutions.append( ("%clang_profuse_gcc=", build_invocation(clang_cflags) + " -fprofile-use=") ) if config.host_os not in ['Darwin', 'FreeBSD', 'Linux']: config.unsupported = True -- cgit v1.1