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