]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
Include $PWD in hash for -fprofile-generate with relative directory
authorJoel Rosdahl <joel@rosdahl.net>
Sun, 27 Jun 2021 18:34:06 +0000 (20:34 +0200)
committerJoel Rosdahl <joel@rosdahl.net>
Sun, 27 Jun 2021 19:24:46 +0000 (21:24 +0200)
For a relative profile directory D, GCC stores $PWD/D as part of the
profile filename in an object file generated with -fprofile-generate, so
we need to include the same information in the hash.

Fixes #872.

src/ccache.cpp
test/suites/profiling.bash

index 4f81c63b040397655dab839bb596716afa3044f0..0b3d23f76542927afbb849af04c6573d7efd30b5 100644 (file)
@@ -1648,9 +1648,17 @@ calculate_result_and_manifest_key(Context& ctx,
 
   if (ctx.args_info.profile_generate) {
     ASSERT(!ctx.args_info.profile_path.empty());
-    LOG("Adding profile directory {} to our hash", ctx.args_info.profile_path);
+
+    // For a relative profile directory D the compiler stores $PWD/D as part of
+    // the profile filename so we need to include the same information in the
+    // hash.
+    const std::string profile_path =
+      Util::is_absolute_path(ctx.args_info.profile_path)
+        ? ctx.args_info.profile_path
+        : FMT("{}/{}", ctx.apparent_cwd, ctx.args_info.profile_path);
+    LOG("Adding profile directory {} to our hash", profile_path);
     hash.hash_delimiter("-fprofile-dir");
-    hash.hash(ctx.args_info.profile_path);
+    hash.hash(profile_path);
   }
 
   if (ctx.args_info.profile_use && !hash_profile_data_file(ctx, hash)) {
index dbe36d41f9211bedf600950be5bae854393c92f4..f9e0cba3bc48bb4f1725150244bad834aa22aca5 100644 (file)
@@ -97,6 +97,57 @@ SUITE_profiling() {
     expect_stat 'cache hit (direct)' 1
     expect_stat 'cache miss' 3
 
+    # -------------------------------------------------------------------------
+    TEST "-fprofile-generate=dir in different directories"
+
+    mkdir -p dir1/data dir2/data
+
+    cd dir1
+
+    $CCACHE_COMPILE -Werror -fprofile-generate=data -c ../test.c \
+        || test_failed "compilation error"
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache miss' 1
+
+    $CCACHE_COMPILE -Werror -fprofile-generate=data -c ../test.c \
+        || test_failed "compilation error"
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache miss' 1
+
+    $COMPILER -Werror -fprofile-generate test.o -o test \
+        || test_failed "compilation error"
+
+    ./test || test_failed "execution error"
+    merge_profiling_data data
+
+    $CCACHE_COMPILE -Werror -fprofile-use=data -c ../test.c \
+        || test_failed "compilation error"
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache miss' 2
+
+    cd ../dir2
+
+    $CCACHE_COMPILE -Werror -fprofile-generate=data -c ../test.c \
+        || test_failed "compilation error"
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache miss' 3
+
+    $CCACHE_COMPILE -Werror -fprofile-generate=data -c ../test.c \
+        || test_failed "compilation error"
+    expect_stat 'cache hit (direct)' 2
+    expect_stat 'cache miss' 3
+
+    $COMPILER -Werror -fprofile-generate test.o -o test \
+        || test_failed "compilation error"
+
+    ./test || test_failed "execution error"
+    merge_profiling_data data
+
+    $CCACHE_COMPILE -Werror -fprofile-use=data -c ../test.c \
+        || test_failed "compilation error"
+    # Note: No expect_stat here since GCC and Clang behave differently – just
+    # check that the compiler doesn't warn about not finding the profile data.
+
     # -------------------------------------------------------------------------
     TEST "-ftest-coverage with -fprofile-dir"