https://github.com/wenju-he updated 
https://github.com/llvm/llvm-project/pull/224548

>From 1ce31dddedbe12c8cad2cfc32835c09b009d88a5 Mon Sep 17 00:00:00 2001
From: Wenju He <[email protected]>
Date: Fri, 18 Sep 2026 09:49:21 +0200
Subject: [PATCH 1/5] [clang-sycl-linker] AOT-compile split modules
 concurrently

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]>
---
 .../clang-sycl-linker/ClangSYCLLinker.cpp     | 59 +++++++++++++++++--
 1 file changed, 53 insertions(+), 6 deletions(-)

diff --git a/clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp 
b/clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp
index 70afc6d6c4cea0..c1b964d58c2040 100644
--- a/clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp
+++ b/clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp
@@ -52,6 +52,7 @@
 #include "llvm/Support/Signals.h"
 #include "llvm/Support/StringSaver.h"
 #include "llvm/Support/TargetSelect.h"
+#include "llvm/Support/ThreadPool.h"
 #include "llvm/Support/TimeProfiler.h"
 #include "llvm/Support/WithColor.h"
 #include "llvm/Target/TargetMachine.h"
@@ -924,6 +925,54 @@ static bool canSkipModuleSplit(IRSplitMode Mode, const 
Module &M,
   });
 }
 
+/// AOT-compiles every already-produced 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, StringRef OutputFile) 
{
+  // Each worker thread writes only its own index, so this is race-free.
+  SmallVector<std::string, 0> AOTFiles(SplitModules.size());
+  // std::optional, not Error: pre-filled Error::success() move-assigned
+  // from a worker thread would abort on the unchecked-value assert.
+  SmallVector<std::optional<Error>, 0> AOTErrors(SplitModules.size());
+  for (size_t I = 0, E = SplitModules.size(); I != E; ++I) {
+    SmallString<64> Prefix;
+    (sys::path::filename(OutputFile).rsplit('.').first + "_" + Twine(I))
+        .toVector(Prefix);
+    Expected<StringRef> AOTFileOrErr = createTempFile(Args, Prefix, "out");
+    if (!AOTFileOrErr)
+      return AOTFileOrErr.takeError();
+    AOTFiles[I] = std::string(*AOTFileOrErr);
+  }
+  {
+    DefaultThreadPool AOTPool(llvm::heavyweight_hardware_concurrency());
+    for (size_t I = 0, E = SplitModules.size(); I != E; ++I)
+      AOTPool.async(
+          [&](size_t I) {
+            AOTErrors[I].emplace(runAOTCompile(SplitModules[I].ModuleFilePath,
+                                               AOTFiles[I], Args));
+          },
+          I);
+    AOTPool.wait();
+  }
+  // Every Error must be checked once, so visit all before returning
+  // instead of stopping at the first failure.
+  Error FirstErr = Error::success();
+  for (std::optional<Error> &Err : AOTErrors) {
+    if (!*Err)
+      continue;
+    if (FirstErr)
+      consumeError(std::move(*Err));
+    else
+      FirstErr = std::move(*Err);
+  }
+  if (FirstErr)
+    return FirstErr;
+
+  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
@@ -1000,14 +1049,12 @@ static Error 
runSYCLLink(ArrayRef<std::unique_ptr<MemoryBuffer>> Inputs,
     }
 
     SplitModules[I].ModuleFilePath = CodeGenFile;
-    if (IsAOTCompileNeeded) {
-      std::string AOTFile = (Stem + "_" + Twine(I) + ".out").str();
-      if (Error Err = runAOTCompile(CodeGenFile, AOTFile, Args))
-        return Err;
-      SplitModules[I].ModuleFilePath = AOTFile;
-    }
   }
 
+  if (IsAOTCompileNeeded)
+    if (Error Err = aotCompileSplitModules(SplitModules, Args, OutputFile))
+      return Err;
+
   // Collect all images to be packed into a single OffloadBinary.
   SmallVector<OffloadingImage> Images;
   for (SplitModule &SI : SplitModules) {

>From 96642b78e919c2613e608807f84529199499cbad Mon Sep 17 00:00:00 2001
From: Wenju He <[email protected]>
Date: Fri, 18 Sep 2026 12:39:39 +0200
Subject: [PATCH 2/5] fix test: now is basename + hash

---
 clang/test/OffloadTools/clang-sycl-linker/basic.ll | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/test/OffloadTools/clang-sycl-linker/basic.ll 
b/clang/test/OffloadTools/clang-sycl-linker/basic.ll
index 00e3bba8d297e5..b7f88acc9814fa 100644
--- a/clang/test/OffloadTools/clang-sycl-linker/basic.ll
+++ b/clang/test/OffloadTools/clang-sycl-linker/basic.ll
@@ -114,7 +114,7 @@
 ; RUN:   | FileCheck %s --check-prefix=AOT-INTEL-GPU
 ; AOT-INTEL-GPU:      link: inputs: {{.*}}.bc, {{.*}}.bc output: 
[[LLVMLINKOUT:.*]].bc
 ; AOT-INTEL-GPU-NEXT: LLVM backend: input: [[LLVMLINKOUT]].bc, output: 
[[SPIRVTRANSLATIONOUT:.*]]_0.spv
-; AOT-INTEL-GPU-NEXT: "{{.*}}ocloc{{.*}}" {{.*}}-device bmg_g21 -a -b 
{{.*}}-output [[SPIRVTRANSLATIONOUT]]_0.out -file [[SPIRVTRANSLATIONOUT]]_0.spv
+; AOT-INTEL-GPU-NEXT: "{{.*}}ocloc{{.*}}" {{.*}}-device bmg_g21 -a -b 
{{.*}}-output {{.*}}_0-{{.*}}.out -file [[SPIRVTRANSLATIONOUT]]_0.spv
 ; AOT-INTEL-GPU-NEXT: sycl-bundle: image kind: o, triple: spirv64, arch: 
bmg_g21
 ; AOT-INTEL-GPU-NOT:  {{.+}}
 ;
@@ -131,7 +131,7 @@
 ; RUN:   | FileCheck %s --check-prefix=AOT-INTEL-CPU
 ; AOT-INTEL-CPU:      link: inputs: {{.*}}.bc, {{.*}}.bc output: 
[[LLVMLINKOUT:.*]].bc
 ; AOT-INTEL-CPU-NEXT: LLVM backend: input: [[LLVMLINKOUT]].bc, output: 
[[SPIRVTRANSLATIONOUT:.*]]_0.spv
-; AOT-INTEL-CPU-NEXT: "{{.*}}opencl-aot{{.*}}" {{.*}}--device=cpu -a -b 
{{.*}}-o [[SPIRVTRANSLATIONOUT]]_0.out [[SPIRVTRANSLATIONOUT]]_0.spv
+; AOT-INTEL-CPU-NEXT: "{{.*}}opencl-aot{{.*}}" {{.*}}--device=cpu -a -b 
{{.*}}-o {{.*}}_0-{{.*}}.out [[SPIRVTRANSLATIONOUT]]_0.spv
 ; AOT-INTEL-CPU-NEXT: sycl-bundle: image kind: o, triple: spirv64, arch: 
graniterapids
 ; AOT-INTEL-CPU-NOT:  {{.+}}
 ;

>From 5dea9ce500f80ed47459f5d35504b36446b4cb3e Mon Sep 17 00:00:00 2001
From: Wenju He <[email protected]>
Date: Sat, 19 Sep 2026 06:55:37 +0200
Subject: [PATCH 3/5] JIT image

---
 clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp 
b/clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp
index c1b964d58c2040..e64cdb51f0ca44 100644
--- a/clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp
+++ b/clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp
@@ -925,8 +925,8 @@ static bool canSkipModuleSplit(IRSplitMode Mode, const 
Module &M,
   });
 }
 
-/// AOT-compiles every already-produced image in \p SplitModules concurrently
-/// and swaps each module's path to point at the compiled object.
+/// 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, StringRef OutputFile) 
{
   // Each worker thread writes only its own index, so this is race-free.

>From 55467baa1239ff88c8ded015e25d78eaf4db8a55 Mon Sep 17 00:00:00 2001
From: Wenju He <[email protected]>
Date: Sat, 19 Sep 2026 07:10:17 +0200
Subject: [PATCH 4/5] [SYCL] Fix data race on llvm::errs() in concurrent AOT
 command printing

aotCompileSplitModules dispatches runAOTCompile per split module onto
a thread pool; each call can reach executeCommands's -v/--dry-run
print of the command line, racing on the shared errs() stream.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
---
 clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp 
b/clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp
index e64cdb51f0ca44..2cb41d7de1cff5 100644
--- a/clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp
+++ b/clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp
@@ -58,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;
@@ -182,8 +184,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();

>From b9ce5073a75c2c87100bad6f867ce1b718b84d53 Mon Sep 17 00:00:00 2001
From: Wenju He <[email protected]>
Date: Tue, 22 Sep 2026 01:59:27 +0200
Subject: [PATCH 5/5] [clang-sycl-linker] Simplify AOT compile error handling
 with parallelForEachError

Use parallelForEachError, matching clang-linker-wrapper's pattern, instead of
manually managing a thread pool and a per-index optional-Error array.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
---
 .../clang-sycl-linker/ClangSYCLLinker.cpp     | 36 +++++--------------
 1 file changed, 8 insertions(+), 28 deletions(-)

diff --git a/clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp 
b/clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp
index 2cb41d7de1cff5..7e876656ed62ec 100644
--- a/clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp
+++ b/clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp
@@ -47,12 +47,12 @@
 #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"
 #include "llvm/Support/StringSaver.h"
 #include "llvm/Support/TargetSelect.h"
-#include "llvm/Support/ThreadPool.h"
 #include "llvm/Support/TimeProfiler.h"
 #include "llvm/Support/WithColor.h"
 #include "llvm/Target/TargetMachine.h"
@@ -936,9 +936,6 @@ static Error 
aotCompileSplitModules(SmallVectorImpl<SplitModule> &SplitModules,
                                     const ArgList &Args, StringRef OutputFile) 
{
   // Each worker thread writes only its own index, so this is race-free.
   SmallVector<std::string, 0> AOTFiles(SplitModules.size());
-  // std::optional, not Error: pre-filled Error::success() move-assigned
-  // from a worker thread would abort on the unchecked-value assert.
-  SmallVector<std::optional<Error>, 0> AOTErrors(SplitModules.size());
   for (size_t I = 0, E = SplitModules.size(); I != E; ++I) {
     SmallString<64> Prefix;
     (sys::path::filename(OutputFile).rsplit('.').first + "_" + Twine(I))
@@ -948,30 +945,13 @@ static Error 
aotCompileSplitModules(SmallVectorImpl<SplitModule> &SplitModules,
       return AOTFileOrErr.takeError();
     AOTFiles[I] = std::string(*AOTFileOrErr);
   }
-  {
-    DefaultThreadPool AOTPool(llvm::heavyweight_hardware_concurrency());
-    for (size_t I = 0, E = SplitModules.size(); I != E; ++I)
-      AOTPool.async(
-          [&](size_t I) {
-            AOTErrors[I].emplace(runAOTCompile(SplitModules[I].ModuleFilePath,
-                                               AOTFiles[I], Args));
-          },
-          I);
-    AOTPool.wait();
-  }
-  // Every Error must be checked once, so visit all before returning
-  // instead of stopping at the first failure.
-  Error FirstErr = Error::success();
-  for (std::optional<Error> &Err : AOTErrors) {
-    if (!*Err)
-      continue;
-    if (FirstErr)
-      consumeError(std::move(*Err));
-    else
-      FirstErr = std::move(*Err);
-  }
-  if (FirstErr)
-    return FirstErr;
+
+  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];

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

Reply via email to