Add GCC-compatible flags -fprofile-generate and -fprofile-use
Justin Bogner
mail at justinbogner.com
Tue Jul 7 17:55:40 PDT 2015
Diego Novillo <dnovillo at google.com> writes:
> I've updated the frontend and runtime patches based on the discussions
> we had in this thread and IRC.
>
> Thanks. Diego.
>
>
> commit b0ac1b3d8529318bed75c89b44d0b0a03c0d3497
> Author: Diego Novillo <dnovillo at google.com>
> Date: Thu Jun 25 18:50:33 2015 -0400
>
> 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.
>
> diff --git a/lib/profile/GCDAProfiling.c b/lib/profile/GCDAProfiling.c
> index e32e97f..e245cf0 100644
> --- a/lib/profile/GCDAProfiling.c
> +++ b/lib/profile/GCDAProfiling.c
> @@ -20,6 +20,8 @@
> |*
> \*===----------------------------------------------------------------------===*/
>
> +#include "InstrProfiling.h"
> +
> #include <errno.h>
> #include <fcntl.h>
> #include <stdio.h>
> @@ -209,7 +211,8 @@ static char *mangle_filename(const char *orig_filename) {
> return new_filename;
> }
>
> -static void recursive_mkdir(char *path) {
> +__attribute__((visibility("hidden")))
> +void __llvm_profile_recursive_mkdir(char *path) {
Better break this out of GCDAProfiling.c into a separate file - we don't
want to force InstrProfiling to pull in GCDAProfiling symbols, and it's
a layering violation for GCDAProfiling to be #including
InstrProfiling.h.
> int i;
>
> for (i = 1; path[i] != '\0'; ++i) {
> @@ -283,7 +286,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 84b673c..123e384 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);
>
> @@ -104,4 +104,7 @@ uint64_t __llvm_profile_get_magic(void);
> /*! \brief Get the version of the file format. */
> uint64_t __llvm_profile_get_version(void);
>
> +/*! \brief Create a directory tree. */
> +void __llvm_profile_recursive_mkdir(char *Pathname);
> +
> #endif /* PROFILE_INSTRPROFILING_H_ */
> diff --git a/lib/profile/InstrProfilingFile.c b/lib/profile/InstrProfilingFile.c
> index 0102a25..3006bf9 100644
> --- a/lib/profile/InstrProfilingFile.c
> +++ b/lib/profile/InstrProfilingFile.c
> @@ -84,6 +84,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/test/profile/Inputs/gcc-flag-compatibility.c b/test/profile/Inputs/gcc-flag-compatibility.c
> new file mode 100644
> index 0000000..1c07bb1
> --- /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 0000000..8e8b55d
> --- /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 e4910ab..b1b44a1 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
More information about the cfe-commits
mailing list