Author: Wenju He
Date: 2026-09-24T12:24:46+08:00
New Revision: af00034e5ce89ce3fba77b7153f23737662b777a

URL: 
https://github.com/llvm/llvm-project/commit/af00034e5ce89ce3fba77b7153f23737662b777a
DIFF: 
https://github.com/llvm/llvm-project/commit/af00034e5ce89ce3fba77b7153f23737662b777a.diff

LOG: [clang-sycl-linker] AOT-compile split modules concurrently (#224548)

AOT-compile all split modules in a thread pool instead of one at a time,
cutting AOT wall time when there are multiple split modules.

---------

Co-authored-by: Claude Sonnet 5 <[email protected]>

Added: 
    

Modified: 
    clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp

Removed: 
    


################################################################################
diff  --git a/clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp 
b/clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp
index b1dd41ae3434b..60ab7dc4e2a7d 100644
--- a/clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp
+++ b/clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp
@@ -47,6 +47,7 @@
 #include "llvm/Support/FormatVariadic.h"
 #include "llvm/Support/InitLLVM.h"
 #include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Parallel.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/Program.h"
 #include "llvm/Support/Signals.h"
@@ -57,6 +58,8 @@
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Transforms/Utils/SplitModuleByCategory.h"
 
+#include <mutex>
+
 using namespace llvm;
 using namespace llvm::opt;
 using namespace llvm::object;
@@ -169,8 +172,11 @@ static void printCommands(ArrayRef<StringRef> CmdArgs) {
 /// Execute the command \p ExecutablePath with the arguments \p Args.
 static Error executeCommands(StringRef ExecutablePath,
                              ArrayRef<StringRef> Args) {
-  if (Verbose || DryRun)
+  if (Verbose || DryRun) {
+    static std::mutex PrintMutex;
+    std::lock_guard<std::mutex> Lock(PrintMutex);
     printCommands(Args);
+  }
 
   if (DryRun)
     return Error::success();
@@ -912,6 +918,33 @@ static bool canSkipModuleSplit(IRSplitMode Mode, const 
Module &M,
   });
 }
 
+/// AOT-compiles every JIT image in \p SplitModules concurrently and swaps each
+/// module's path to point at the compiled object.
+static Error aotCompileSplitModules(SmallVectorImpl<SplitModule> &SplitModules,
+                                    const ArgList &Args) {
+  // Each worker thread writes only its own index, so this is race-free.
+  SmallVector<std::string, 0> AOTFiles(SplitModules.size());
+  for (size_t I = 0, E = SplitModules.size(); I != E; ++I) {
+    // Reuse the codegen file's unique name so the AOT output can be
+    // correlated with the SPIR-V file it was compiled from.
+    SmallString<128> AOTFile(SplitModules[I].ModuleFilePath);
+    sys::path::replace_extension(AOTFile, "out");
+    TempFiles.push_back(AOTFile);
+    AOTFiles[I] = std::string(TempFiles.back());
+  }
+
+  if (Error Err = parallelForEachError(
+          llvm::seq<size_t>(0, SplitModules.size()), [&](size_t I) -> Error {
+            return runAOTCompile(SplitModules[I].ModuleFilePath, AOTFiles[I],
+                                 Args);
+          }))
+    return Err;
+
+  for (size_t I = 0, E = AOTFiles.size(); I != E; ++I)
+    SplitModules[I].ModuleFilePath = AOTFiles[I];
+  return Error::success();
+}
+
 /// Performs the following steps:
 /// 1. Link all input bitcode files together with library files.
 /// 2. Optionally split the linked module according to the requested
@@ -992,19 +1025,12 @@ static Error 
runSYCLLink(ArrayRef<std::unique_ptr<MemoryBuffer>> Inputs,
     }
 
     SplitModules[I].ModuleFilePath = CodeGenFile;
-    if (IsAOTCompileNeeded) {
-      // Reuse CodeGenFile's unique name so the AOT output can be correlated
-      // with the SPIR-V file it was compiled from.
-      SmallString<128> AOTFile(CodeGenFile);
-      sys::path::replace_extension(AOTFile, "out");
-      TempFiles.push_back(AOTFile);
-      StringRef AOTFileRef = TempFiles.back();
-      if (Error Err = runAOTCompile(CodeGenFile, AOTFileRef, Args))
-        return Err;
-      SplitModules[I].ModuleFilePath = AOTFileRef;
-    }
   }
 
+  if (IsAOTCompileNeeded)
+    if (Error Err = aotCompileSplitModules(SplitModules, Args))
+      return Err;
+
   // Collect all images to be packed into a single OffloadBinary.
   SmallVector<OffloadingImage> Images;
   for (SplitModule &SI : SplitModules) {


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to