diff options
-rw-r--r-- | lib/profile/CMakeLists.txt | 3 | ||||
-rw-r--r-- | lib/profile/GCDAProfiling.c | 28 | ||||
-rw-r--r-- | lib/profile/InstrProfiling.h | 2 | ||||
-rw-r--r-- | lib/profile/InstrProfilingFile.c | 8 | ||||
-rw-r--r-- | lib/profile/InstrProfilingUtil.c | 35 | ||||
-rw-r--r-- | lib/profile/InstrProfilingUtil.h | 16 | ||||
-rw-r--r-- | test/profile/Inputs/gcc-flag-compatibility.c | 8 | ||||
-rw-r--r-- | test/profile/gcc-flag-compatibility.test | 17 | ||||
-rw-r--r-- | test/profile/lit.cfg | 2 |
9 files changed, 92 insertions, 27 deletions
diff --git a/lib/profile/CMakeLists.txt b/lib/profile/CMakeLists.txt index d0714e0d1..d03409fc4 100644 --- a/lib/profile/CMakeLists.txt +++ b/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/lib/profile/GCDAProfiling.c b/lib/profile/GCDAProfiling.c index e32e97fdb..aec232856 100644 --- a/lib/profile/GCDAProfiling.c +++ b/lib/profile/GCDAProfiling.c @@ -20,6 +20,8 @@ |* \*===----------------------------------------------------------------------===*/ +#include "InstrProfilingUtil.h" + #include <errno.h> #include <fcntl.h> #include <stdio.h> @@ -27,17 +29,9 @@ #include <string.h> #include <sys/mman.h> #include <sys/file.h> -#ifdef _WIN32 -#include <direct.h> -#endif #define I386_FREEBSD (defined(__FreeBSD__) && defined(__i386__)) -#if !I386_FREEBSD -#include <sys/stat.h> -#include <sys/types.h> -#endif - #if !defined(_MSC_VER) && !I386_FREEBSD #include <stdint.h> #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/lib/profile/InstrProfiling.h b/lib/profile/InstrProfiling.h index 84b673c69..3778a8889 100644 --- a/lib/profile/InstrProfiling.h +++ b/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/lib/profile/InstrProfilingFile.c b/lib/profile/InstrProfilingFile.c index 0102a2533..940223829 100644 --- a/lib/profile/InstrProfilingFile.c +++ b/lib/profile/InstrProfilingFile.c @@ -8,6 +8,7 @@ \*===----------------------------------------------------------------------===*/ #include "InstrProfiling.h" +#include "InstrProfilingUtil.h" #include <errno.h> #include <stdio.h> #include <stdlib.h> @@ -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/lib/profile/InstrProfilingUtil.c b/lib/profile/InstrProfilingUtil.c new file mode 100644 index 000000000..e146dfca8 --- /dev/null +++ b/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 <direct.h> +#elif I386_FREEBSD +int mkdir(const char*, unsigned short); +#else +#include <sys/stat.h> +#include <sys/types.h> +#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/lib/profile/InstrProfilingUtil.h b/lib/profile/InstrProfilingUtil.h new file mode 100644 index 000000000..756b18e7c --- /dev/null +++ b/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/test/profile/Inputs/gcc-flag-compatibility.c b/test/profile/Inputs/gcc-flag-compatibility.c new file mode 100644 index 000000000..1c07bb1d0 --- /dev/null +++ b/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/test/profile/gcc-flag-compatibility.test b/test/profile/gcc-flag-compatibility.test new file mode 100644 index 000000000..8e8b55daf --- /dev/null +++ b/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/test/profile/lit.cfg b/test/profile/lit.cfg index e4910abbe..b1b44a1a0 100644 --- a/test/profile/lit.cfg +++ b/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 |