]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
feat: Support caching of distributed ThinLTO for Clang (#1683)
authorzcfh <1412805291@qq.com>
Wed, 11 Feb 2026 20:05:44 +0000 (04:05 +0800)
committerGitHub <noreply@github.com>
Wed, 11 Feb 2026 20:05:44 +0000 (21:05 +0100)
src/ccache/argprocessing.cpp
src/ccache/argsinfo.hpp
src/ccache/ccache.cpp
test/CMakeLists.txt
test/suites/distributed_thinlto_clang.bash [new file with mode: 0644]

index ab16295d5d16f90ee727735690134e8332545ff7..c07dd1f876a35bb74f335a7c5c965d55759431cd 100644 (file)
@@ -735,6 +735,16 @@ process_option_arg(const Context& ctx,
     return Statistic::none;
   }
 
+  if (arg.starts_with("-fthinlto-index=")) {
+    std::string thinlto_index = arg.substr(arg.find('=') + 1);
+    args_info.thinlto_index_path = thinlto_index;
+    // Thinlto backend phase, the extension of input file is .o but the file is
+    // IR. So treat it as assembler file.
+    args_info.actual_language = "assembler";
+    state.add_common_arg(args[i]);
+    return Statistic::none;
+  }
+
   if (arg.starts_with("-fdebug-compilation-dir")
       || arg.starts_with("-ffile-compilation-dir")) {
     std::string compilation_dir;
index f591449a0f5c9d3a930de56d0b004536accd9970..7bae8b62937cf21151227df16a4873236b38eeb4 100644 (file)
@@ -174,4 +174,7 @@ struct ArgsInfo
 
   // Build session file as passed in -fbuild-session-file.
   std::filesystem::path build_session_file;
+
+  // Thinlto index from -fthinlto-index=
+  std::filesystem::path thinlto_index_path;
 };
index 1debc0ac9c0638ae629761539f1c2c62ef0d349f..13f42274cabccb3a4a64a607df0f0a881243a400 100644 (file)
@@ -2376,6 +2376,9 @@ hash_profiling_related_data(const Context& ctx, Hash& hash)
   // For profile usage (-fprofile(-instr|-sample)-use, -fbranch-probabilities):
   // - hash profile data
   //
+  // For distributed thinlto (-fthinlto-index):
+  // - hash thinlto index data
+  //
   // -fbranch-probabilities and -fvpt usage is covered by
   // -fprofile-generate/-fprofile-use.
   //
@@ -2409,6 +2412,16 @@ hash_profiling_related_data(const Context& ctx, Hash& hash)
     return tl::unexpected(Statistic::no_input_file);
   }
 
+  if (!ctx.args_info.thinlto_index_path.empty()) {
+    LOG("Adding thinlto index '{}' to our hash",
+        ctx.args_info.thinlto_index_path);
+    hash.hash_delimiter("-fthinlto-index");
+    if (!hash_binary_file(ctx, hash, ctx.args_info.thinlto_index_path)) {
+      LOG_RAW("No thinlto index file found");
+      return tl::unexpected(Statistic::no_input_file);
+    }
+  }
+
   return {};
 }
 
index 4bfc39ee749492ffd0dd8fa63d0a8c99e90e6022..d624a97b11ed83d64f578d605adef81c9636a295 100644 (file)
@@ -36,6 +36,7 @@ addtest(debug_compilation_dir)
 addtest(debug_prefix_map)
 addtest(depend)
 addtest(direct)
+addtest(distributed_thinlto_clang)
 addtest(fileclone)
 addtest(hardlink)
 addtest(inode_cache)
diff --git a/test/suites/distributed_thinlto_clang.bash b/test/suites/distributed_thinlto_clang.bash
new file mode 100644 (file)
index 0000000..1d63958
--- /dev/null
@@ -0,0 +1,73 @@
+SUITE_distributed_thinlto_clang_PROBE() {
+    echo 'int main() { return 0; }' >test.c
+    if ! $COMPILER_TYPE_CLANG; then
+        echo "compiler is not Clang"
+    elif ! $COMPILER -fuse-ld=lld test.c 2>/dev/null; then
+        echo "compiler does not support lld"
+    elif ! $COMPILER --help | grep -q -- -fthinlto-index 2>/dev/null; then
+        echo "compiler does not support thinlto-index"
+    fi
+}
+
+SUITE_distributed_thinlto_clang_SETUP() {
+    cat <<EOF >test.c
+#include <stdio.h>
+
+// define in lib1.c
+int lib1();
+// define in lib2.c
+int lib2();
+int main(void) { printf("result: %d\\n", lib1() + lib2()); return 0;}
+EOF
+    cat <<EOF >lib1.c
+int lib1() { return 1; }
+EOF
+    cat <<EOF >lib2.c
+int lib2() { return 2; }
+EOF
+    $COMPILER -flto=thin -O2 -c -o test.o test.c
+    $COMPILER -flto=thin -O2 -c -o lib1.o lib1.c
+    $COMPILER -flto=thin -O2 -c -o lib2.o lib2.c
+    # Use compiler to generate thinlto.index.bc.
+    $COMPILER -fuse-ld=lld -Wl,--thinlto-index-only=test.rst test.o lib1.o lib2.o
+    backdate *.c *.o *.bc
+    unset CCACHE_NODIRECT
+}
+
+SUITE_distributed_thinlto_clang() {
+    # -------------------------------------------------------------------------
+    TEST "-fthinlto-index=test.o.thinlto.bc"
+
+    $CCACHE_COMPILE -c -fthinlto-index=lib1.o.thinlto.bc lib1.o -o lib1.native.o
+    expect_stat direct_cache_hit 0
+    expect_stat cache_miss 1
+
+    $CCACHE_COMPILE -c -fthinlto-index=lib1.o.thinlto.bc lib1.o -o lib1.native.o
+    expect_stat direct_cache_hit 1
+    expect_stat cache_miss 1
+
+    $CCACHE_COMPILE -c -fthinlto-index=test.o.thinlto.bc test.o -o test.native.o
+    expect_stat direct_cache_hit 1
+    expect_stat cache_miss 2
+
+    $CCACHE_COMPILE -c -fthinlto-index=test.o.thinlto.bc test.o -o test.native.o
+    expect_stat direct_cache_hit 2
+    expect_stat cache_miss 2
+
+    # Modify lib2.c, only affect test.o.thinlto.bc, but not affect lib1.o.thinlto.bc.
+    echo 'int tmp_x;' >>lib2.c
+
+    $COMPILER -O2 -flto=thin -c -o lib2.o lib2.c
+    $COMPILER -fuse-ld=lld -Wl,--thinlto-index-only=test.rst test.o lib1.o lib2.o
+    backdate *.c *.o *.bc
+
+    $CCACHE_COMPILE -c -fthinlto-index=lib1.o.thinlto.bc lib1.o -o lib1.native.o
+    expect_stat direct_cache_hit 3
+    expect_stat cache_miss 2
+
+    $CCACHE_COMPILE -c -fthinlto-index=test.o.thinlto.bc test.o -o test.native.o
+    expect_stat direct_cache_hit 3
+    expect_stat cache_miss 3
+
+    # -------------------------------------------------------------------------
+}