Skip to content

Commit b8cef90

Browse files
committed
[SYCL] Refactor SYCL Post Link Library
Post Link compilation flow consists of Module spliting, specializaition constants processing and ESIMD processing. To correspond to the all functionalities this patch adds renames in order to be less confusing. The following changes are added: * ModuleSplitProcessingSettings structure is renamed to ModuleProcessingSettings. * Added function convertProcessingSettingsToString to add additional piece of information in the testing. * SplitModule structure is renamed to ProcessedModule. * runSYCLSplitLibrary is renamed to runSYCLPostLinkLibrary. * DryRun mode in runSYCLPostLinkLibrary is combined with Verbose mode in order to remove code duplication. * splitSYCLModule is renamed to SYCLPostLinkProcess.
1 parent 1194277 commit b8cef90

File tree

5 files changed

+132
-96
lines changed

5 files changed

+132
-96
lines changed

clang/test/Driver/linker-wrapper-sycl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
// CHK-SPLIT-CMDS: "{{.*}}spirv-to-ir-wrapper" {{.*}} -o [[FIRSTLLVMLINKIN:.*]].bc --llvm-spirv-opts --spirv-preserve-auxdata --spirv-target-env=SPV-IR --spirv-builtin-format=global
3030
// CHK-SPLIT-CMDS-NEXT: "{{.*}}llvm-link" [[FIRSTLLVMLINKIN]].bc -o [[FIRSTLLVMLINKOUT:.*]].bc --suppress-warnings
3131
// CHK-SPLIT-CMDS-NEXT: "{{.*}}llvm-link" -only-needed [[FIRSTLLVMLINKOUT]].bc {{.*}}.bc -o [[SECONDLLVMLINKOUT:.*]].bc --suppress-warnings
32-
// CHK-SPLIT-CMDS-NEXT: sycl-module-split: input: [[SECONDLLVMLINKOUT]].bc, output: [[SYCLMODULESPLITOUT:.*]].bc
32+
// CHK-SPLIT-CMDS-NEXT: sycl-post-link-library: input: [[SECONDLLVMLINKOUT]].bc, output: [[SYCLMODULESPLITOUT:.*]].bc, split_mode: auto, output_assembly: false, output_prefix:
3333
// CHK-SPLIT-CMDS-NEXT: "{{.*}}llvm-spirv"{{.*}} LLVM_SPIRV_OPTIONS -o [[SPIRVOUT:.*]].spv [[SYCLMODULESPLITOUT]].bc
3434
// LLVM-SPIRV is not called in dry-run
3535
// CHK-SPLIT-CMDS-NEXT: offload-wrapper: input: [[SPIRVOUT]].spv, output: [[WRAPPEROUT:.*]].bc

clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp

Lines changed: 63 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -707,7 +707,7 @@ getTripleBasedSYCLPostLinkOpts(const ArgList &Args,
707707
/// 'Args' encompasses all arguments required for linking and wrapping device
708708
/// code and will be parsed to generate options required to be passed into the
709709
/// sycl-post-link tool.
710-
static Expected<std::vector<module_split::SplitModule>>
710+
static Expected<std::vector<module_split::ProcessedModule>>
711711
runSYCLPostLinkTool(ArrayRef<StringRef> InputFiles, const ArgList &Args) {
712712
Expected<std::string> SYCLPostLinkPath =
713713
findProgram("sycl-post-link", {getMainExecutable("sycl-post-link")});
@@ -743,76 +743,76 @@ runSYCLPostLinkTool(ArrayRef<StringRef> InputFiles, const ArgList &Args) {
743743
if (!ImageFileOrErr)
744744
return ImageFileOrErr.takeError();
745745

746-
std::vector Modules = {module_split::SplitModule(
746+
std::vector Modules = {module_split::ProcessedModule(
747747
*ImageFileOrErr, util::PropertySetRegistry(), "")};
748748
return Modules;
749749
}
750750

751-
return llvm::module_split::parseSplitModulesFromFile(*TempFileOrErr);
751+
return llvm::module_split::parseProcessedModulesFromFile(*TempFileOrErr);
752752
}
753753

754-
/// Invokes SYCL Split library for SYCL offloading.
754+
/// Invokes SYCL Post Link library for SYCL offloading.
755755
///
756756
/// \param InputFiles the list of input LLVM IR files.
757757
/// \param Args Encompasses all arguments for linking and wrapping device code.
758-
/// It will be parsed to generate options required to be passed to SYCL split
759-
/// library.
758+
/// It will be parsed to generate options required to be passed to SYCL Post
759+
/// Link library.
760760
/// \param Mode The splitting mode.
761761
/// \returns The vector of split modules.
762-
static Expected<std::vector<module_split::SplitModule>>
763-
runSYCLSplitLibrary(ArrayRef<StringRef> InputFiles, const ArgList &Args,
764-
module_split::IRSplitMode Mode) {
765-
std::vector<module_split::SplitModule> SplitModules;
766-
if (DryRun) {
767-
auto OutputFileOrErr = createOutputFile(
768-
sys::path::filename(ExecutableName) + ".sycl.split.image", "bc");
769-
if (!OutputFileOrErr)
770-
return OutputFileOrErr.takeError();
771-
772-
StringRef OutputFilePath = *OutputFileOrErr;
773-
auto InputFilesStr = llvm::join(InputFiles.begin(), InputFiles.end(), ",");
774-
errs() << formatv("sycl-module-split: input: {0}, output: {1}\n",
775-
InputFilesStr, OutputFilePath);
776-
SplitModules.emplace_back(OutputFilePath, util::PropertySetRegistry(), "");
777-
return SplitModules;
778-
}
779-
780-
llvm::module_split::ModuleSplitterSettings Settings;
762+
static Expected<std::vector<module_split::ProcessedModule>>
763+
runSYCLPostLinkLibrary(ArrayRef<StringRef> InputFiles, const ArgList &Args,
764+
module_split::IRSplitMode Mode) {
765+
std::vector<module_split::ProcessedModule> OutputModules;
766+
llvm::module_split::ModuleProcessingSettings Settings;
781767
Settings.Mode = Mode;
782768
Settings.OutputPrefix = "";
783769

784770
for (StringRef InputFile : InputFiles) {
771+
if (DryRun)
772+
break;
773+
785774
SMDiagnostic Err;
786775
LLVMContext C;
787776
std::unique_ptr<Module> M = parseIRFile(InputFile, Err, C);
788777
if (!M)
789778
return createStringError(inconvertibleErrorCode(), Err.getMessage());
790779

791-
auto SplitModulesOrErr =
792-
module_split::splitSYCLModule(std::move(M), Settings);
793-
if (!SplitModulesOrErr)
794-
return SplitModulesOrErr.takeError();
780+
auto ModulesOrErr =
781+
module_split::SYCLPostLinkProcess(std::move(M), Settings);
782+
if (!ModulesOrErr)
783+
return ModulesOrErr.takeError();
795784

796-
auto &NewSplitModules = *SplitModulesOrErr;
797-
SplitModules.insert(SplitModules.end(), NewSplitModules.begin(),
798-
NewSplitModules.end());
785+
auto &NewModules = *ModulesOrErr;
786+
OutputModules.insert(OutputModules.end(), NewModules.begin(),
787+
NewModules.end());
799788
}
800789

801-
if (Verbose) {
790+
if (Verbose || DryRun) {
791+
if (DryRun) {
792+
auto OutputFileOrErr = createOutputFile(
793+
sys::path::filename(ExecutableName) + ".sycl.split.image", "bc");
794+
if (!OutputFileOrErr)
795+
return OutputFileOrErr.takeError();
796+
797+
OutputModules.emplace_back(*OutputFileOrErr, util::PropertySetRegistry(),
798+
"");
799+
}
800+
802801
auto InputFilesStr = llvm::join(InputFiles.begin(), InputFiles.end(), ",");
803802
std::string SplitOutputFilesStr;
804-
for (size_t I = 0, E = SplitModules.size(); I != E; ++I) {
803+
for (size_t I = 0, E = OutputModules.size(); I != E; ++I) {
805804
if (I > 0)
806805
SplitOutputFilesStr += ',';
807806

808-
SplitOutputFilesStr += SplitModules[I].ModuleFilePath;
807+
SplitOutputFilesStr += OutputModules[I].ModuleFilePath;
809808
}
810809

811-
errs() << formatv("sycl-module-split: input: {0}, output: {1}\n",
812-
InputFilesStr, SplitOutputFilesStr);
810+
errs() << formatv("sycl-post-link-library: input: {0}, output: {1}, {2}\n",
811+
InputFilesStr, SplitOutputFilesStr,
812+
convertProcessingSettingsToString(Settings));
813813
}
814814

815-
return SplitModules;
815+
return OutputModules;
816816
}
817817

818818
/// Add any llvm-spirv option that relies on a specific Triple in addition
@@ -1063,7 +1063,7 @@ static Expected<StringRef> runAOTCompile(StringRef InputFile,
10631063
///
10641064
/// \returns A path to the LLVM Module that contains wrapped images.
10651065
Expected<StringRef>
1066-
wrapSYCLBinariesFromFile(std::vector<module_split::SplitModule> &SplitModules,
1066+
wrapSYCLBinariesFromFile(std::vector<module_split::ProcessedModule> &Modules,
10671067
const ArgList &Args, bool IsEmbeddedIR) {
10681068
auto OutputFileOrErr = createOutputFile(
10691069
sys::path::filename(ExecutableName) + ".sycl.image.wrapper", "bc");
@@ -1073,8 +1073,8 @@ wrapSYCLBinariesFromFile(std::vector<module_split::SplitModule> &SplitModules,
10731073
StringRef OutputFilePath = *OutputFileOrErr;
10741074
if (Verbose || DryRun) {
10751075
std::string InputFiles;
1076-
for (size_t I = 0, E = SplitModules.size(); I != E; ++I) {
1077-
InputFiles += SplitModules[I].ModuleFilePath;
1076+
for (size_t I = 0, E = Modules.size(); I != E; ++I) {
1077+
InputFiles += Modules[I].ModuleFilePath;
10781078
if (I + 1 < E)
10791079
InputFiles += ',';
10801080
}
@@ -1102,13 +1102,14 @@ wrapSYCLBinariesFromFile(std::vector<module_split::SplitModule> &SplitModules,
11021102
if (RegularTarget == "spirv64")
11031103
RegularTarget = "spir64";
11041104

1105-
for (auto &SI : SplitModules) {
1106-
auto MBOrDesc = MemoryBuffer::getFile(SI.ModuleFilePath);
1105+
for (auto &M : Modules) {
1106+
auto MBOrDesc = MemoryBuffer::getFile(M.ModuleFilePath);
11071107
if (!MBOrDesc)
1108-
return createFileError(SI.ModuleFilePath, MBOrDesc.getError());
1108+
return createFileError(M.ModuleFilePath, MBOrDesc.getError());
11091109

11101110
StringRef ImageTarget = IsEmbeddedIR ? StringRef(EmbeddedIRTarget) : StringRef(RegularTarget);
1111-
Images.emplace_back(std::move(*MBOrDesc), SI.Properties, SI.Symbols, ImageTarget);
1111+
Images.emplace_back(std::move(*MBOrDesc), M.Properties, M.Symbols,
1112+
ImageTarget);
11121113
}
11131114

11141115
LLVMContext C;
@@ -1183,9 +1184,9 @@ static Expected<StringRef> runCompile(StringRef &InputFile,
11831184

11841185
// Run wrapping library and llc
11851186
static Expected<StringRef>
1186-
runWrapperAndCompile(std::vector<module_split::SplitModule> &SplitModules,
1187+
runWrapperAndCompile(std::vector<module_split::ProcessedModule> &Modules,
11871188
const ArgList &Args, bool IsEmbeddedIR = false) {
1188-
auto OutputFile = sycl::wrapSYCLBinariesFromFile(SplitModules, Args, IsEmbeddedIR);
1189+
auto OutputFile = sycl::wrapSYCLBinariesFromFile(Modules, Args, IsEmbeddedIR);
11891190
if (!OutputFile)
11901191
return OutputFile.takeError();
11911192
// call to llc
@@ -2252,15 +2253,15 @@ Expected<SmallVector<StringRef>> linkAndWrapDeviceFiles(
22522253
return TmpOutputOrErr.takeError();
22532254
SmallVector<StringRef> InputFilesSYCL;
22542255
InputFilesSYCL.emplace_back(*TmpOutputOrErr);
2255-
auto SplitModulesOrErr =
2256+
auto ProcessedModulesOrErr =
22562257
SYCLModuleSplitMode
2257-
? sycl::runSYCLSplitLibrary(InputFilesSYCL, LinkerArgs,
2258-
*SYCLModuleSplitMode)
2258+
? sycl::runSYCLPostLinkLibrary(InputFilesSYCL, LinkerArgs,
2259+
*SYCLModuleSplitMode)
22592260
: sycl::runSYCLPostLinkTool(InputFilesSYCL, LinkerArgs);
2260-
if (!SplitModulesOrErr)
2261-
return SplitModulesOrErr.takeError();
2261+
if (!ProcessedModulesOrErr)
2262+
return ProcessedModulesOrErr.takeError();
22622263

2263-
auto &SplitModules = *SplitModulesOrErr;
2264+
auto &ProcessedModules = *ProcessedModulesOrErr;
22642265
const llvm::Triple Triple(LinkerArgs.getLastArgValue(OPT_triple_EQ));
22652266
if ((Triple.isNVPTX() || Triple.isAMDGCN()) &&
22662267
LinkerArgs.hasArg(OPT_sycl_embed_ir)) {
@@ -2269,14 +2270,14 @@ Expected<SmallVector<StringRef>> linkAndWrapDeviceFiles(
22692270
// of sycl-post-link (filetable referencing LLVM Bitcode + symbols)
22702271
// through the offload wrapper and link the resulting object to the
22712272
// application.
2272-
auto OutputFile =
2273-
sycl::runWrapperAndCompile(SplitModules, LinkerArgs, /* IsEmbeddedIR */ true);
2273+
auto OutputFile = sycl::runWrapperAndCompile(
2274+
ProcessedModules, LinkerArgs, /* IsEmbeddedIR */ true);
22742275
if (!OutputFile)
22752276
return OutputFile.takeError();
22762277
WrappedOutput.push_back(*OutputFile);
22772278
}
2278-
for (size_t I = 0, E = SplitModules.size(); I != E; ++I) {
2279-
SmallVector<StringRef> Files = {SplitModules[I].ModuleFilePath};
2279+
for (size_t I = 0, E = ProcessedModules.size(); I != E; ++I) {
2280+
SmallVector<StringRef> Files = {ProcessedModules[I].ModuleFilePath};
22802281
StringRef Arch = LinkerArgs.getLastArgValue(OPT_arch_EQ);
22812282
if (Arch.empty())
22822283
Arch = "native";
@@ -2298,21 +2299,22 @@ Expected<SmallVector<StringRef>> linkAndWrapDeviceFiles(
22982299
nvptx::fatbinary(BundlerInputFiles, LinkerArgs);
22992300
if (!BundledFileOrErr)
23002301
return BundledFileOrErr.takeError();
2301-
SplitModules[I].ModuleFilePath = *BundledFileOrErr;
2302+
ProcessedModules[I].ModuleFilePath = *BundledFileOrErr;
23022303
} else if (Triple.isAMDGCN()) {
23032304
BundlerInputFiles.emplace_back(*ClangOutputOrErr, Arch);
23042305
auto BundledFileOrErr =
23052306
amdgcn::fatbinary(BundlerInputFiles, LinkerArgs);
23062307
if (!BundledFileOrErr)
23072308
return BundledFileOrErr.takeError();
2308-
SplitModules[I].ModuleFilePath = *BundledFileOrErr;
2309+
ProcessedModules[I].ModuleFilePath = *BundledFileOrErr;
23092310
} else {
2310-
SplitModules[I].ModuleFilePath = *ClangOutputOrErr;
2311+
ProcessedModules[I].ModuleFilePath = *ClangOutputOrErr;
23112312
}
23122313
}
23132314

23142315
// TODO(NOM7): Remove this call and use community flow for bundle/wrap
2315-
auto OutputFile = sycl::runWrapperAndCompile(SplitModules, LinkerArgs);
2316+
auto OutputFile =
2317+
sycl::runWrapperAndCompile(ProcessedModules, LinkerArgs);
23162318
if (!OutputFile)
23172319
return OutputFile.takeError();
23182320

llvm/include/llvm/SYCLLowerIR/ModuleSplitter.h

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ enum IRSplitMode {
5050
// returned.
5151
std::optional<IRSplitMode> convertStringToSplitMode(StringRef S);
5252

53+
StringRef convertSplitModeToString(IRSplitMode SM);
54+
5355
// A vector that contains all entry point functions in a split module.
5456
using EntryPointSet = SetVector<Function *>;
5557

@@ -289,35 +291,41 @@ void dumpEntryPoints(const Module &M, bool OnlyKernelsAreEntryPoints = false,
289291
const char *Msg = "", int Tab = 0);
290292
#endif // NDEBUG
291293

292-
struct SplitModule {
294+
struct ProcessedModule {
293295
std::string ModuleFilePath;
294296
util::PropertySetRegistry Properties;
295297
std::string Symbols;
296298

297-
SplitModule() = default;
298-
SplitModule(const SplitModule &) = default;
299-
SplitModule &operator=(const SplitModule &) = default;
300-
SplitModule(SplitModule &&) = default;
301-
SplitModule &operator=(SplitModule &&) = default;
299+
ProcessedModule() = default;
300+
ProcessedModule(const ProcessedModule &) = default;
301+
ProcessedModule &operator=(const ProcessedModule &) = default;
302+
ProcessedModule(ProcessedModule &&) = default;
303+
ProcessedModule &operator=(ProcessedModule &&) = default;
302304

303-
SplitModule(std::string_view File, util::PropertySetRegistry Properties,
304-
std::string Symbols)
305+
ProcessedModule(std::string_view File, util::PropertySetRegistry Properties,
306+
std::string Symbols)
305307
: ModuleFilePath(File), Properties(std::move(Properties)),
306308
Symbols(std::move(Symbols)) {}
307309
};
308310

309-
struct ModuleSplitterSettings {
311+
struct ModuleProcessingSettings {
310312
IRSplitMode Mode;
311313
bool OutputAssembly = false; // Bitcode or LLVM IR.
312314
StringRef OutputPrefix;
313315
};
314316

315-
/// Parses the output table file from sycl-post-link tool.
316-
Expected<std::vector<SplitModule>> parseSplitModulesFromFile(StringRef File);
317+
SmallString<64>
318+
convertProcessingSettingsToString(const ModuleProcessingSettings &S);
317319

318-
/// Splits the given module \p M according to the given \p Settings.
319-
Expected<std::vector<SplitModule>>
320-
splitSYCLModule(std::unique_ptr<Module> M, ModuleSplitterSettings Settings);
320+
/// Parses the output table file from sycl-post-link tool.
321+
Expected<std::vector<ProcessedModule>>
322+
parseProcessedModulesFromFile(StringRef File);
323+
324+
/// Performs post-link processing of the given module \p M according to the
325+
/// given \p Settings.
326+
Expected<std::vector<ProcessedModule>>
327+
SYCLPostLinkProcess(std::unique_ptr<Module> M,
328+
ModuleProcessingSettings Settings);
321329

322330
bool isESIMDFunction(const Function &F);
323331
bool canBeImportedFunction(const Function &F);

0 commit comments

Comments
 (0)