From c2b4e481a0504cbb50e83098d2634b063be6b5c9 Mon Sep 17 00:00:00 2001 From: Wael Yehia Date: Wed, 19 Nov 2025 10:19:24 -0500 Subject: [PATCH] [libLTO] add thinlto caching flags to libLTO (#168567) On AIX, the linker's release cadence is once per year and it doesn't backport non-critical fixes to previous releases. We would like to get thinLTO caching accessible for current customers, so this PR adds the cache flags as cl::opt options. --- llvm/tools/lto/lto.cpp | 43 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/llvm/tools/lto/lto.cpp b/llvm/tools/lto/lto.cpp index 467a4da27dcd..513d0578af24 100644 --- a/llvm/tools/lto/lto.cpp +++ b/llvm/tools/lto/lto.cpp @@ -24,6 +24,7 @@ #include "llvm/LTO/legacy/LTOCodeGenerator.h" #include "llvm/LTO/legacy/LTOModule.h" #include "llvm/LTO/legacy/ThinLTOCodeGenerator.h" +#include "llvm/Support/FileSystem.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Signals.h" #include "llvm/Support/TargetSelect.h" @@ -44,6 +45,29 @@ static cl::opt EnableFreestanding( "lto-freestanding", cl::init(false), cl::desc("Enable Freestanding (disable builtins / TLI) during LTO")); +static cl::opt ThinLTOCacheDir( + "legacy-thinlto-cache-dir", + cl::desc("Experimental option, enable ThinLTO caching. Note: the cache " + "currently does not take the mcmodel setting into account, so you " + "might get false hits if different mcmodels are used in different " + "builds using the same cache directory.")); + +static cl::opt ThinLTOCachePruningInterval( + "legacy-thinlto-cache-pruning-interval", cl::init(1200), + cl::desc("Set ThinLTO cache pruning interval (seconds).")); + +static cl::opt ThinLTOCacheMaxSizeBytes( + "legacy-thinlto-cache-max-size-bytes", + cl::desc("Set ThinLTO cache pruning directory maximum size in bytes.")); + +static cl::opt ThinLTOCacheMaxSizeFiles( + "legacy-thinlto-cache-max-size-files", cl::init(1000000), + cl::desc("Set ThinLTO cache pruning directory maximum number of files.")); + +static cl::opt ThinLTOCacheEntryExpiration( + "legacy-thinlto-cache-entry-expiration", cl::init(604800) /* 1w */, + cl::desc("Set ThinLTO cache entry expiration time (seconds).")); + #ifdef NDEBUG static bool VerifyByDefault = false; #else @@ -543,6 +567,25 @@ thinlto_code_gen_t thinlto_create_codegen(void) { assert(CGOptLevelOrNone); CodeGen->setCodeGenOptLevel(*CGOptLevelOrNone); } + if (!ThinLTOCacheDir.empty()) { + auto Err = llvm::sys::fs::create_directories(ThinLTOCacheDir); + if (Err) + report_fatal_error(Twine("Unable to create thinLTO cache directory: ") + + Err.message()); + bool result; + Err = llvm::sys::fs::is_directory(ThinLTOCacheDir, result); + if (Err || !result) + report_fatal_error(Twine("Unable to get status of thinLTO cache path or " + "path is not a directory: ") + + Err.message()); + CodeGen->setCacheDir(ThinLTOCacheDir); + + CodeGen->setCachePruningInterval(ThinLTOCachePruningInterval); + CodeGen->setCacheEntryExpiration(ThinLTOCacheEntryExpiration); + CodeGen->setCacheMaxSizeFiles(ThinLTOCacheMaxSizeFiles); + CodeGen->setCacheMaxSizeBytes(ThinLTOCacheMaxSizeBytes); + } + return wrap(CodeGen); }