Skip to content

Conversation

jansvoboda11
Copy link
Contributor

This PR propagates the correctly-configured VFS from Clang through the LTO infrastructure into the PGOOptions constructor in LTOBackend.cpp. This works towards unifying the way the compiler interacts with the FS.

@llvmbot llvmbot added clang Clang issues not falling into any other category clang:codegen IR generation bugs: mangling, exceptions, etc. LTO Link time optimization (regular/full LTO or ThinLTO) labels Sep 18, 2025
@llvmbot
Copy link
Member

llvmbot commented Sep 18, 2025

@llvm/pr-subscribers-lto
@llvm/pr-subscribers-clang-codegen

@llvm/pr-subscribers-clang

Author: Jan Svoboda (jansvoboda11)

Changes

This PR propagates the correctly-configured VFS from Clang through the LTO infrastructure into the PGOOptions constructor in LTOBackend.cpp. This works towards unifying the way the compiler interacts with the FS.


Patch is 20.42 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/159671.diff

6 Files Affected:

  • (modified) clang/lib/CodeGen/BackendUtil.cpp (+5-5)
  • (modified) llvm/include/llvm/LTO/LTO.h (+5-2)
  • (modified) llvm/include/llvm/LTO/LTOBackend.h (+10-10)
  • (modified) llvm/lib/LTO/LTO.cpp (+33-24)
  • (modified) llvm/lib/LTO/LTOBackend.cpp (+15-11)
  • (modified) llvm/lib/LTO/LTOCodeGenerator.cpp (+3-1)
diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index 77bf0c8251fc2..9b6d0650f3895 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -1384,11 +1384,11 @@ runThinLTOBackend(CompilerInstance &CI, ModuleSummaryIndex *CombinedIndex,
     Conf.CGFileType = getCodeGenFileType(Action);
     break;
   }
-  if (Error E =
-          thinBackend(Conf, -1, AddStream, *M, *CombinedIndex, ImportList,
-                      ModuleToDefinedGVSummaries[M->getModuleIdentifier()],
-                      /*ModuleMap=*/nullptr, Conf.CodeGenOnly,
-                      /*IRAddStream=*/nullptr, CGOpts.CmdArgs)) {
+  if (Error E = thinBackend(
+          Conf, &CI.getVirtualFileSystem(), -1, AddStream, *M, *CombinedIndex,
+          ImportList, ModuleToDefinedGVSummaries[M->getModuleIdentifier()],
+          /*ModuleMap=*/nullptr, Conf.CodeGenOnly,
+          /*IRAddStream=*/nullptr, CGOpts.CmdArgs)) {
     handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) {
       errs() << "Error running ThinLTO backend: " << EIB.message() << '\n';
     });
diff --git a/llvm/include/llvm/LTO/LTO.h b/llvm/include/llvm/LTO/LTO.h
index 323c478691a92..50dc37748cc07 100644
--- a/llvm/include/llvm/LTO/LTO.h
+++ b/llvm/include/llvm/LTO/LTO.h
@@ -28,6 +28,7 @@
 #include "llvm/Support/Error.h"
 #include "llvm/Support/StringSaver.h"
 #include "llvm/Support/ThreadPool.h"
+#include "llvm/Support/VirtualFileSystem.h"
 #include "llvm/Support/thread.h"
 #include "llvm/Transforms/IPO/FunctionAttrs.h"
 #include "llvm/Transforms/IPO/FunctionImport.h"
@@ -209,6 +210,7 @@ using ImportsFilesContainer = llvm::SmallVector<std::string>;
 class ThinBackendProc {
 protected:
   const Config &Conf;
+  IntrusiveRefCntPtr<vfs::FileSystem> FS;
   ModuleSummaryIndex &CombinedIndex;
   const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries;
   IndexWriteCallback OnWrite;
@@ -219,11 +221,12 @@ class ThinBackendProc {
 
 public:
   ThinBackendProc(
-      const Config &Conf, ModuleSummaryIndex &CombinedIndex,
+      const Config &Conf, IntrusiveRefCntPtr<vfs::FileSystem> FS,
+      ModuleSummaryIndex &CombinedIndex,
       const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,
       lto::IndexWriteCallback OnWrite, bool ShouldEmitImportsFiles,
       ThreadPoolStrategy ThinLTOParallelism)
-      : Conf(Conf), CombinedIndex(CombinedIndex),
+      : Conf(Conf), FS(std::move(FS)), CombinedIndex(CombinedIndex),
         ModuleToDefinedGVSummaries(ModuleToDefinedGVSummaries),
         OnWrite(OnWrite), ShouldEmitImportsFiles(ShouldEmitImportsFiles),
         BackendThreadPool(ThinLTOParallelism) {}
diff --git a/llvm/include/llvm/LTO/LTOBackend.h b/llvm/include/llvm/LTO/LTOBackend.h
index 86b488c764e06..edcad76a66b53 100644
--- a/llvm/include/llvm/LTO/LTOBackend.h
+++ b/llvm/include/llvm/LTO/LTOBackend.h
@@ -35,8 +35,8 @@ class Target;
 namespace lto {
 
 /// Runs middle-end LTO optimizations on \p Mod.
-LLVM_ABI bool opt(const Config &Conf, TargetMachine *TM, unsigned Task,
-                  Module &Mod, bool IsThinLTO,
+LLVM_ABI bool opt(const Config &Conf, IntrusiveRefCntPtr<vfs::FileSystem> FS,
+                  TargetMachine *TM, unsigned Task, Module &Mod, bool IsThinLTO,
                   ModuleSummaryIndex *ExportSummary,
                   const ModuleSummaryIndex *ImportSummary,
                   const std::vector<uint8_t> &CmdArgs);
@@ -56,14 +56,14 @@ LLVM_ABI Error backend(const Config &C, AddStreamFn AddStream,
 /// the backend will skip optimization and only perform code generation. If
 /// \p IRAddStream is not nullptr, it will be called just before code generation
 /// to serialize the optimized IR.
-LLVM_ABI Error
-thinBackend(const Config &C, unsigned Task, AddStreamFn AddStream, Module &M,
-            const ModuleSummaryIndex &CombinedIndex,
-            const FunctionImporter::ImportMapTy &ImportList,
-            const GVSummaryMapTy &DefinedGlobals,
-            MapVector<StringRef, BitcodeModule> *ModuleMap, bool CodeGenOnly,
-            AddStreamFn IRAddStream = nullptr,
-            const std::vector<uint8_t> &CmdArgs = std::vector<uint8_t>());
+LLVM_ABI Error thinBackend(
+    const Config &C, IntrusiveRefCntPtr<vfs::FileSystem> FS, unsigned Task,
+    AddStreamFn AddStream, Module &M, const ModuleSummaryIndex &CombinedIndex,
+    const FunctionImporter::ImportMapTy &ImportList,
+    const GVSummaryMapTy &DefinedGlobals,
+    MapVector<StringRef, BitcodeModule> *ModuleMap, bool CodeGenOnly,
+    AddStreamFn IRAddStream = nullptr,
+    const std::vector<uint8_t> &CmdArgs = std::vector<uint8_t>());
 
 LLVM_ABI Error
 finalizeOptimizationRemarks(std::unique_ptr<ToolOutputFile> DiagOutputFile);
diff --git a/llvm/lib/LTO/LTO.cpp b/llvm/lib/LTO/LTO.cpp
index ce9ecc35e1922..fe4daecc3209c 100644
--- a/llvm/lib/LTO/LTO.cpp
+++ b/llvm/lib/LTO/LTO.cpp
@@ -54,6 +54,7 @@
 #include "llvm/Support/TimeProfiler.h"
 #include "llvm/Support/ToolOutputFile.h"
 #include "llvm/Support/VCSRevision.h"
+#include "llvm/Support/VirtualFileSystem.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Target/TargetOptions.h"
 #include "llvm/Transforms/IPO.h"
@@ -1494,13 +1495,15 @@ class CGThinBackend : public ThinBackendProc {
 
 public:
   CGThinBackend(
-      const Config &Conf, ModuleSummaryIndex &CombinedIndex,
+      const Config &Conf, IntrusiveRefCntPtr<vfs::FileSystem> FS,
+      ModuleSummaryIndex &CombinedIndex,
       const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,
       AddStreamFn AddStream, lto::IndexWriteCallback OnWrite,
       bool ShouldEmitIndexFiles, bool ShouldEmitImportsFiles,
       ThreadPoolStrategy ThinLTOParallelism)
-      : ThinBackendProc(Conf, CombinedIndex, ModuleToDefinedGVSummaries,
-                        OnWrite, ShouldEmitImportsFiles, ThinLTOParallelism),
+      : ThinBackendProc(Conf, std::move(FS), CombinedIndex,
+                        ModuleToDefinedGVSummaries, OnWrite,
+                        ShouldEmitImportsFiles, ThinLTOParallelism),
         AddStream(std::move(AddStream)),
         ShouldEmitIndexFiles(ShouldEmitIndexFiles) {
     auto &Defs = CombinedIndex.cfiFunctionDefs();
@@ -1518,14 +1521,15 @@ class InProcessThinBackend : public CGThinBackend {
 
 public:
   InProcessThinBackend(
-      const Config &Conf, ModuleSummaryIndex &CombinedIndex,
-      ThreadPoolStrategy ThinLTOParallelism,
+      const Config &Conf, IntrusiveRefCntPtr<vfs::FileSystem> FS,
+      ModuleSummaryIndex &CombinedIndex, ThreadPoolStrategy ThinLTOParallelism,
       const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,
       AddStreamFn AddStream, FileCache Cache, lto::IndexWriteCallback OnWrite,
       bool ShouldEmitIndexFiles, bool ShouldEmitImportsFiles)
-      : CGThinBackend(Conf, CombinedIndex, ModuleToDefinedGVSummaries,
-                      AddStream, OnWrite, ShouldEmitIndexFiles,
-                      ShouldEmitImportsFiles, ThinLTOParallelism),
+      : CGThinBackend(Conf, std::move(FS), CombinedIndex,
+                      ModuleToDefinedGVSummaries, AddStream, OnWrite,
+                      ShouldEmitIndexFiles, ShouldEmitImportsFiles,
+                      ThinLTOParallelism),
         Cache(std::move(Cache)) {}
 
   virtual Error runThinLTOBackendThread(
@@ -1545,7 +1549,7 @@ class InProcessThinBackend : public CGThinBackend {
       if (!MOrErr)
         return MOrErr.takeError();
 
-      return thinBackend(Conf, Task, AddStream, **MOrErr, CombinedIndex,
+      return thinBackend(Conf, FS, Task, AddStream, **MOrErr, CombinedIndex,
                          ImportList, DefinedGlobals, &ModuleMap,
                          Conf.CodeGenOnly);
     };
@@ -1629,12 +1633,12 @@ class FirstRoundThinBackend : public InProcessThinBackend {
 
 public:
   FirstRoundThinBackend(
-      const Config &Conf, ModuleSummaryIndex &CombinedIndex,
+      const Config &Conf, IntrusiveRefCntPtr<vfs::FileSystem> FS, ModuleSummaryIndex &CombinedIndex,
       ThreadPoolStrategy ThinLTOParallelism,
       const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,
       AddStreamFn CGAddStream, FileCache CGCache, AddStreamFn IRAddStream,
       FileCache IRCache)
-      : InProcessThinBackend(Conf, CombinedIndex, ThinLTOParallelism,
+      : InProcessThinBackend(Conf, std::move(FS), CombinedIndex, ThinLTOParallelism,
                              ModuleToDefinedGVSummaries, std::move(CGAddStream),
                              std::move(CGCache), /*OnWrite=*/nullptr,
                              /*ShouldEmitIndexFiles=*/false,
@@ -1659,7 +1663,7 @@ class FirstRoundThinBackend : public InProcessThinBackend {
       if (!MOrErr)
         return MOrErr.takeError();
 
-      return thinBackend(Conf, Task, CGAddStream, **MOrErr, CombinedIndex,
+      return thinBackend(Conf, FS, Task, CGAddStream, **MOrErr, CombinedIndex,
                          ImportList, DefinedGlobals, &ModuleMap,
                          Conf.CodeGenOnly, IRAddStream);
     };
@@ -1724,13 +1728,13 @@ class SecondRoundThinBackend : public InProcessThinBackend {
 
 public:
   SecondRoundThinBackend(
-      const Config &Conf, ModuleSummaryIndex &CombinedIndex,
+      const Config &Conf, IntrusiveRefCntPtr<vfs::FileSystem> FS, ModuleSummaryIndex &CombinedIndex,
       ThreadPoolStrategy ThinLTOParallelism,
       const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,
       AddStreamFn AddStream, FileCache Cache,
       std::unique_ptr<SmallVector<StringRef>> IRFiles,
       stable_hash CombinedCGDataHash)
-      : InProcessThinBackend(Conf, CombinedIndex, ThinLTOParallelism,
+      : InProcessThinBackend(Conf, std::move(FS), CombinedIndex, ThinLTOParallelism,
                              ModuleToDefinedGVSummaries, std::move(AddStream),
                              std::move(Cache),
                              /*OnWrite=*/nullptr,
@@ -1754,7 +1758,7 @@ class SecondRoundThinBackend : public InProcessThinBackend {
       std::unique_ptr<Module> LoadedModule =
           cgdata::loadModuleForTwoRounds(BM, Task, BackendContext, *IRFiles);
 
-      return thinBackend(Conf, Task, AddStream, *LoadedModule, CombinedIndex,
+      return thinBackend(Conf, FS, Task, AddStream, *LoadedModule, CombinedIndex,
                          ImportList, DefinedGlobals, &ModuleMap,
                          /*CodeGenOnly=*/true);
     };
@@ -1796,8 +1800,9 @@ ThinBackend lto::createInProcessThinBackend(ThreadPoolStrategy Parallelism,
       [=](const Config &Conf, ModuleSummaryIndex &CombinedIndex,
           const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,
           AddStreamFn AddStream, FileCache Cache) {
+        auto FS = vfs::getRealFileSystem();
         return std::make_unique<InProcessThinBackend>(
-            Conf, CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
+            Conf, FS, CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
             AddStream, Cache, OnWrite, ShouldEmitIndexFiles,
             ShouldEmitImportsFiles);
       };
@@ -1845,13 +1850,13 @@ class WriteIndexesThinBackend : public ThinBackendProc {
 
 public:
   WriteIndexesThinBackend(
-      const Config &Conf, ModuleSummaryIndex &CombinedIndex,
+      const Config &Conf, IntrusiveRefCntPtr<vfs::FileSystem> FS, ModuleSummaryIndex &CombinedIndex,
       ThreadPoolStrategy ThinLTOParallelism,
       const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,
       std::string OldPrefix, std::string NewPrefix,
       std::string NativeObjectPrefix, bool ShouldEmitImportsFiles,
       raw_fd_ostream *LinkedObjectsFile, lto::IndexWriteCallback OnWrite)
-      : ThinBackendProc(Conf, CombinedIndex, ModuleToDefinedGVSummaries,
+      : ThinBackendProc(Conf, std::move(FS), CombinedIndex, ModuleToDefinedGVSummaries,
                         OnWrite, ShouldEmitImportsFiles, ThinLTOParallelism),
         OldPrefix(OldPrefix), NewPrefix(NewPrefix),
         NativeObjectPrefix(NativeObjectPrefix),
@@ -1917,8 +1922,9 @@ ThinBackend lto::createWriteIndexesThinBackend(
       [=](const Config &Conf, ModuleSummaryIndex &CombinedIndex,
           const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,
           AddStreamFn AddStream, FileCache Cache) {
+        auto FS = vfs::getRealFileSystem();
         return std::make_unique<WriteIndexesThinBackend>(
-            Conf, CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
+            Conf, FS, CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
             OldPrefix, NewPrefix, NativeObjectPrefix, ShouldEmitImportsFiles,
             LinkedObjectsFile, OnWrite);
       };
@@ -2151,12 +2157,14 @@ Error LTO::runThinLTO(AddStreamFn AddStream, FileCache Cache,
   // objects and optimized IRs, using the same cache directory as the original.
   cgdata::StreamCacheData CG(MaxTasks, Cache, "CG"), IR(MaxTasks, Cache, "IR");
 
+  auto FS = vfs::getRealFileSystem();
+
   // First round: Execute optimization and code generation, outputting to
   // temporary scratch objects. Serialize the optimized IRs before initiating
   // code generation.
   LLVM_DEBUG(dbgs() << "[TwoRounds] Running the first round of codegen\n");
   auto FirstRoundLTO = std::make_unique<FirstRoundThinBackend>(
-      Conf, ThinLTO.CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
+      Conf, FS, ThinLTO.CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
       CG.AddStream, CG.Cache, IR.AddStream, IR.Cache);
   if (Error E = RunBackends(FirstRoundLTO.get()))
     return E;
@@ -2172,7 +2180,7 @@ Error LTO::runThinLTO(AddStreamFn AddStream, FileCache Cache,
   // merged data.
   LLVM_DEBUG(dbgs() << "[TwoRounds] Running the second round of codegen\n");
   auto SecondRoundLTO = std::make_unique<SecondRoundThinBackend>(
-      Conf, ThinLTO.CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
+      Conf, FS, ThinLTO.CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
       AddStream, Cache, IR.getResult(), CombinedHash);
   return RunBackends(SecondRoundLTO.get());
 }
@@ -2280,7 +2288,7 @@ class OutOfProcessThinBackend : public CGThinBackend {
 
 public:
   OutOfProcessThinBackend(
-      const Config &Conf, ModuleSummaryIndex &CombinedIndex,
+      const Config &Conf, IntrusiveRefCntPtr<vfs::FileSystem> FS, ModuleSummaryIndex &CombinedIndex,
       ThreadPoolStrategy ThinLTOParallelism,
       const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,
       AddStreamFn AddStream, lto::IndexWriteCallback OnWrite,
@@ -2288,7 +2296,7 @@ class OutOfProcessThinBackend : public CGThinBackend {
       StringRef LinkerOutputFile, StringRef Distributor,
       ArrayRef<StringRef> DistributorArgs, StringRef RemoteCompiler,
       ArrayRef<StringRef> RemoteCompilerArgs, bool SaveTemps)
-      : CGThinBackend(Conf, CombinedIndex, ModuleToDefinedGVSummaries,
+      : CGThinBackend(Conf, std::move(FS), CombinedIndex, ModuleToDefinedGVSummaries,
                       AddStream, OnWrite, ShouldEmitIndexFiles,
                       ShouldEmitImportsFiles, ThinLTOParallelism),
         LinkerOutputFile(LinkerOutputFile), DistributorPath(Distributor),
@@ -2549,8 +2557,9 @@ ThinBackend lto::createOutOfProcessThinBackend(
       [=](const Config &Conf, ModuleSummaryIndex &CombinedIndex,
           const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,
           AddStreamFn AddStream, FileCache /*Cache*/) {
+        auto FS = vfs::getRealFileSystem();
         return std::make_unique<OutOfProcessThinBackend>(
-            Conf, CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
+            Conf, FS, CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
             AddStream, OnWrite, ShouldEmitIndexFiles, ShouldEmitImportsFiles,
             LinkerOutputFile, Distributor, DistributorArgs, RemoteCompiler,
             RemoteCompilerArgs, SaveTemps);
diff --git a/llvm/lib/LTO/LTOBackend.cpp b/llvm/lib/LTO/LTOBackend.cpp
index ce42fc526beac..9152740e850e1 100644
--- a/llvm/lib/LTO/LTOBackend.cpp
+++ b/llvm/lib/LTO/LTOBackend.cpp
@@ -236,11 +236,11 @@ createTargetMachine(const Config &Conf, const Target *TheTarget, Module &M) {
   return TM;
 }
 
-static void runNewPMPasses(const Config &Conf, Module &Mod, TargetMachine *TM,
-                           unsigned OptLevel, bool IsThinLTO,
+static void runNewPMPasses(const Config &Conf,
+                           IntrusiveRefCntPtr<vfs::FileSystem> FS, Module &Mod,
+                           TargetMachine *TM, unsigned OptLevel, bool IsThinLTO,
                            ModuleSummaryIndex *ExportSummary,
                            const ModuleSummaryIndex *ImportSummary) {
-  auto FS = vfs::getRealFileSystem();
   std::optional<PGOOptions> PGOOpt;
   if (!Conf.SampleProfile.empty())
     PGOOpt = PGOOptions(Conf.SampleProfile, "", Conf.ProfileRemapping,
@@ -362,8 +362,9 @@ static bool isEmptyModule(const Module &Mod) {
          Mod.getModuleInlineAsm().empty();
 }
 
-bool lto::opt(const Config &Conf, TargetMachine *TM, unsigned Task, Module &Mod,
-              bool IsThinLTO, ModuleSummaryIndex *ExportSummary,
+bool lto::opt(const Config &Conf, IntrusiveRefCntPtr<vfs::FileSystem> FS,
+              TargetMachine *TM, unsigned Task, Module &Mod, bool IsThinLTO,
+              ModuleSummaryIndex *ExportSummary,
               const ModuleSummaryIndex *ImportSummary,
               const std::vector<uint8_t> &CmdArgs) {
   llvm::TimeTraceScope timeScope("opt");
@@ -391,8 +392,8 @@ bool lto::opt(const Config &Conf, TargetMachine *TM, unsigned Task, Module &Mod,
   // regular LTO combined module, with a large combined index from ThinLTO.
   if (!isEmptyModule(Mod)) {
     // FIXME: Plumb the combined index into the new pass manager.
-    runNewPMPasses(Conf, Mod, TM, Conf.OptLevel, IsThinLTO, ExportSummary,
-                   ImportSummary);
+    runNewPMPasses(Conf, std::move(FS), Mod, TM, Conf.OptLevel, IsThinLTO,
+                   ExportSummary, ImportSummary);
   }
   return !Conf.PostOptModuleHook || Conf.PostOptModuleHook(Task, Mod);
 }
@@ -563,7 +564,8 @@ Error lto::backend(const Config &C, AddStreamFn AddStream,
 
   LLVM_DEBUG(dbgs() << "Running regular LTO\n");
   if (!C.CodeGenOnly) {
-    if (!opt(C, TM.get(), 0, Mod, /*IsThinLTO=*/false,
+    auto FS = vfs::getRealFileSystem();
+    if (!opt(C, FS, TM.get(), 0, Mod, /*IsThinLTO=*/false,
              /*ExportSummary=*/&CombinedIndex, /*ImportSummary=*/nullptr,
              /*CmdArgs*/ std::vector<uint8_t>()))
       return Error::success();
@@ -600,8 +602,10 @@ static void dropDeadSymbols(Module &Mod, const GVSummaryMapTy &DefinedGlobals,
   }
 }
 
-Error lto::thinBackend(const Config &Conf, unsigned Task, AddStreamFn AddStream,
-                       Module &Mod, const ModuleSummaryIndex &CombinedIndex,
+Error lto::thinBackend(const Config &Conf,
+                       IntrusiveRefCntPtr<vfs::FileSystem> FS, unsigned Task,
+                       AddStreamFn AddStream, Module &Mod,
+                       const ModuleSummaryIndex &CombinedIndex,
                        const FunctionImporter::ImportMapTy &ImportList,
                        const GVSummaryMapTy &DefinedGlobals,
                        MapVector<StringRef, BitcodeModule> *ModuleMap,
@@ -642,7 +646,7 @@ Error lto::thinBackend(const Config &Conf, unsigned Task, AddStreamFn AddStream,
       [&](Module &Mod, TargetMachine *TM,
           std::unique_ptr<ToolOutputFile> DiagnosticOutputFile) {
         // Perform optimization and code generation for ThinLTO.
-        if (!opt(Conf, TM, Task, Mod, /*IsThinLTO=*/true,
+        if (!opt(Conf, FS, TM, Task, Mod, /*IsThinLTO=*/true,
                  /*ExportSummary=*/nullptr, /*ImportSummary=*/&CombinedIndex,
                  CmdArgs))
           return finalizeOptimizationRemarks(std::move(DiagnosticOutputFile));
diff --git a/llvm/lib/LTO/LTOCodeGenerator.cpp b/llvm/lib/LTO/LTOCodeGenerator.cpp
index d8a96f73110fd..14c11abafd12f 100644
--- a/llvm/lib/LTO/LTOCodeGenerator.cpp
+++ b/llvm/lib/LTO/LTOCodeGenerator.cpp
@@ -46,6 +46,7 @@
 #include "llvm/Support/Process.h"
 #include "llvm/Support/Signals.h"
 #include "llvm/Support/ToolOutputFile.h"
+#include "llvm/Support/VirtualFileSystem.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Target/TargetOptions.h"
 #include "llvm/TargetParser/Host.h"
@@ -611,7 +612,8 @@ bool LTOCodeGenerator::optimize() {
 
   ModuleSummaryIndex Combine...
[truncated]

Copy link

github-actions bot commented Sep 18, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

Copy link
Collaborator

@cachemeifyoucan cachemeifyoucan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any way for user to pass in a different VFS to ThinLTO backend? I think this PR just lift the VFS creation one lever higher but I don't see any benefits of doing that?

@jansvoboda11
Copy link
Contributor Author

Yes, clang/lib/CodeGen/BackendUtil.cpp does pass the CompilerInstance's VFS into thinBackend(), so that runNewPMPasses() in llvm/lib/LTO/LTOBackend.cpp doesn't need to call vfs::getRealFileSystem()

@cachemeifyoucan
Copy link
Collaborator

Ah, I think it only applies to clang -fthinlto-index= invocation, not LTO/PGOOptions. Can you adjust the commit message and also add a test for it?

@jansvoboda11
Copy link
Contributor Author

Yes, this only kicks in when Clang gets invoked with the -fthinlto-index= argument, but it doesn't affect how that particular file gets loaded. It only affects the files passed via PGOOptions, like -fprofile-instrument-use-path= and -fprofile-sample-use=. So I think spelling out -fthinlto-index= in the message might be a bit misleading, since that file still goes straight to the real FS.

Also, I'm not sure how necessary it is to test this specifically. The idea is that once all such uses of the real FS are abstracted away, we turn on sandboxing in asserts builds (that verifies the one true VFS is being used everywhere), and we get test coverage that way.

@cachemeifyoucan
Copy link
Collaborator

It is important that gets mentioned because this doesn't affect LTO builds that triggered by linker. The -fthinlto-index is only used by distributed builds like Bazel for distributed thinLTO so it is important to mention what changed.

You can totally construct a test case that -fthinlto-index also passed with a vfs overlay to the clang. That should not go to real FS

@jansvoboda11
Copy link
Contributor Author

(FWIW I think this #160188 might be a better solution.)

@cachemeifyoucan
Copy link
Collaborator

Yes, I think that is what I preferred too.

@jansvoboda11 jansvoboda11 deleted the lto-use-vfs branch September 29, 2025 17:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang:codegen IR generation bugs: mangling, exceptions, etc. clang Clang issues not falling into any other category LTO Link time optimization (regular/full LTO or ThinLTO)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants