[clang] af00034 - [clang-sycl-linker] AOT-compile split modules concurrently (#224548)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Sep 23 21:24:51 PDT 2026
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 <noreply at anthropic.com>
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) {
More information about the cfe-commits
mailing list