From b34ffd527efcde30fdcc788b87a72ea50e37d6bf Mon Sep 17 00:00:00 2001 From: "Sabianin, Maksim" Date: Tue, 6 Feb 2024 07:25:29 -0800 Subject: [PATCH] [SYCL] Move module splitting functionality from sycl-post-link into SYCLLowerIR This is a part of migration to New Offloading model and clang-linker-wrapper tool. --- .../llvm/SYCLLowerIR}/ModuleSplitter.h | 10 +++-- llvm/lib/SYCLLowerIR/CMakeLists.txt | 1 + .../SYCLLowerIR}/ModuleSplitter.cpp | 43 ++++++++++++------- llvm/tools/sycl-post-link/CMakeLists.txt | 1 - .../sycl-post-link/SYCLDeviceRequirements.cpp | 2 +- llvm/tools/sycl-post-link/sycl-post-link.cpp | 8 ++-- 6 files changed, 41 insertions(+), 24 deletions(-) rename llvm/{tools/sycl-post-link => include/llvm/SYCLLowerIR}/ModuleSplitter.h (97%) rename llvm/{tools/sycl-post-link => lib/SYCLLowerIR}/ModuleSplitter.cpp (97%) diff --git a/llvm/tools/sycl-post-link/ModuleSplitter.h b/llvm/include/llvm/SYCLLowerIR/ModuleSplitter.h similarity index 97% rename from llvm/tools/sycl-post-link/ModuleSplitter.h rename to llvm/include/llvm/SYCLLowerIR/ModuleSplitter.h index aaf6108325765..eb09e7528ff49 100644 --- a/llvm/tools/sycl-post-link/ModuleSplitter.h +++ b/llvm/include/llvm/SYCLLowerIR/ModuleSplitter.h @@ -10,7 +10,8 @@ // of the split is new modules containing corresponding callgraph. //===----------------------------------------------------------------------===// -#pragma once +#ifndef LLVM_SYCLLOWERIR_MODULE_SPLITTER_H +#define LLVM_SYCLLOWERIR_MODULE_SPLITTER_H #include "llvm/ADT/SetVector.h" #include "llvm/ADT/StringRef.h" @@ -18,6 +19,7 @@ #include "llvm/Support/Error.h" #include +#include #include namespace llvm { @@ -229,8 +231,8 @@ class ModuleSplitterBase { // For device global variables with the 'device_image_scope' property, // the function checks that there are no usages of a single device global // variable from kernels grouped to different modules. Otherwise, an error is - // issued and the tool is aborted. - void verifyNoCrossModuleDeviceGlobalUsage(); + // returned. + Error verifyNoCrossModuleDeviceGlobalUsage(); virtual ~ModuleSplitterBase() = default; @@ -262,3 +264,5 @@ void dumpEntryPoints(const Module &M, bool OnlyKernelsAreEntryPoints = false, } // namespace module_split } // namespace llvm + +#endif // LLVM_SYCLLOWERIR_MODULE_SPLITTER_H diff --git a/llvm/lib/SYCLLowerIR/CMakeLists.txt b/llvm/lib/SYCLLowerIR/CMakeLists.txt index cfafbe1a66c87..b2afa8150aa4f 100644 --- a/llvm/lib/SYCLLowerIR/CMakeLists.txt +++ b/llvm/lib/SYCLLowerIR/CMakeLists.txt @@ -62,6 +62,7 @@ add_llvm_component_library(LLVMSYCLLowerIR LowerInvokeSimd.cpp LowerWGLocalMemory.cpp LowerWGScope.cpp + ModuleSplitter.cpp MutatePrintfAddrspace.cpp SYCLAddOptLevelAttribute.cpp SYCLPropagateAspectsUsage.cpp diff --git a/llvm/tools/sycl-post-link/ModuleSplitter.cpp b/llvm/lib/SYCLLowerIR/ModuleSplitter.cpp similarity index 97% rename from llvm/tools/sycl-post-link/ModuleSplitter.cpp rename to llvm/lib/SYCLLowerIR/ModuleSplitter.cpp index 87cbf42da2df2..978125475a869 100644 --- a/llvm/tools/sycl-post-link/ModuleSplitter.cpp +++ b/llvm/lib/SYCLLowerIR/ModuleSplitter.cpp @@ -8,9 +8,7 @@ // See comments in the header. //===----------------------------------------------------------------------===// -#include "ModuleSplitter.h" -#include "Support.h" - +#include "llvm/SYCLLowerIR/ModuleSplitter.h" #include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/StringExtras.h" @@ -23,6 +21,7 @@ #include "llvm/SYCLLowerIR/DeviceGlobals.h" #include "llvm/SYCLLowerIR/LowerInvokeSimd.h" #include "llvm/SYCLLowerIR/SYCLUtils.h" +#include "llvm/Support/Error.h" #include "llvm/Transforms/IPO.h" #include "llvm/Transforms/IPO/GlobalDCE.h" #include "llvm/Transforms/IPO/StripDeadPrototypes.h" @@ -426,14 +425,15 @@ class ModuleSplitter : public ModuleSplitterBase { DependencyGraph CG; }; } // namespace + namespace llvm { namespace module_split { -void ModuleSplitterBase::verifyNoCrossModuleDeviceGlobalUsage() { +Error ModuleSplitterBase::verifyNoCrossModuleDeviceGlobalUsage() { const Module &M = getInputModule(); // Early exit if there is only one group if (Groups.size() < 2) - return; + return Error::success(); // Reverse the EntryPointGroupMap to get a map of entry point -> module's name unsigned EntryPointNumber = 0; @@ -451,19 +451,25 @@ void ModuleSplitterBase::verifyNoCrossModuleDeviceGlobalUsage() { std::optional VarEntryPointModule{}; auto CheckEntryPointModule = [&VarEntryPointModule, &EntryPointModules, - &GV](const auto *F) { + &GV](const auto *F) -> Error { auto EntryPointModulesIt = EntryPointModules.find(F); - assert(EntryPointModulesIt != EntryPointModules.end() && - "There is no group for an entry point"); + if (EntryPointModulesIt == EntryPointModules.end()) + return createStringError(inconvertibleErrorCode(), + "There is no group for an entry point"); + if (!VarEntryPointModule.has_value()) { VarEntryPointModule = EntryPointModulesIt->second; - return; - } - if (EntryPointModulesIt->second != *VarEntryPointModule) { - error("device_global variable '" + Twine(GV.getName()) + - "' with property \"device_image_scope\" is used in more " - "than one device image."); + return Error::success(); } + + if (EntryPointModulesIt->second != *VarEntryPointModule) + return createStringError( + inconvertibleErrorCode(), + "device_global variable '" + Twine(GV.getName()) + + "' with property \"device_image_scope\" is used in more " + "than one device image."); + + return Error::success(); }; SmallSetVector Workqueue; @@ -478,13 +484,18 @@ void ModuleSplitterBase::verifyNoCrossModuleDeviceGlobalUsage() { continue; } if (auto *F = dyn_cast(U)) { - if (EntryPointModules.count(F)) - CheckEntryPointModule(F); + if (EntryPointModules.count(F)) { + auto E = CheckEntryPointModule(F); + if (!E) + return E; + } } for (auto *UU : U->users()) Workqueue.insert(UU); } } + + return Error::success(); } #ifndef NDEBUG diff --git a/llvm/tools/sycl-post-link/CMakeLists.txt b/llvm/tools/sycl-post-link/CMakeLists.txt index 40bd3f899e487..3905e836aaae8 100644 --- a/llvm/tools/sycl-post-link/CMakeLists.txt +++ b/llvm/tools/sycl-post-link/CMakeLists.txt @@ -24,7 +24,6 @@ include_directories( add_llvm_tool(sycl-post-link sycl-post-link.cpp - ModuleSplitter.cpp SpecConstants.cpp SYCLDeviceLibReqMask.cpp SYCLKernelParamOptInfo.cpp diff --git a/llvm/tools/sycl-post-link/SYCLDeviceRequirements.cpp b/llvm/tools/sycl-post-link/SYCLDeviceRequirements.cpp index 70d3a90f51785..5255ce7bf2a66 100644 --- a/llvm/tools/sycl-post-link/SYCLDeviceRequirements.cpp +++ b/llvm/tools/sycl-post-link/SYCLDeviceRequirements.cpp @@ -7,11 +7,11 @@ //===----------------------------------------------------------------------===// #include "SYCLDeviceRequirements.h" -#include "ModuleSplitter.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringRef.h" #include "llvm/IR/Module.h" +#include "llvm/SYCLLowerIR/ModuleSplitter.h" #include "llvm/Support/PropertySetIO.h" #include diff --git a/llvm/tools/sycl-post-link/sycl-post-link.cpp b/llvm/tools/sycl-post-link/sycl-post-link.cpp index 85728be8aabf0..77903cb2a6cc8 100644 --- a/llvm/tools/sycl-post-link/sycl-post-link.cpp +++ b/llvm/tools/sycl-post-link/sycl-post-link.cpp @@ -13,7 +13,6 @@ // - specialization constant intrinsic transformation //===----------------------------------------------------------------------===// -#include "ModuleSplitter.h" #include "SYCLDeviceLibReqMask.h" #include "SYCLDeviceRequirements.h" #include "SYCLKernelParamOptInfo.h" @@ -40,6 +39,7 @@ #include "llvm/SYCLLowerIR/ESIMD/LowerESIMD.h" #include "llvm/SYCLLowerIR/HostPipes.h" #include "llvm/SYCLLowerIR/LowerInvokeSimd.h" +#include "llvm/SYCLLowerIR/ModuleSplitter.h" #include "llvm/SYCLLowerIR/SYCLUtils.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/FileSystem.h" @@ -1009,8 +1009,10 @@ processInputModule(std::unique_ptr M) { Modified |= SplitOccurred; // FIXME: this check is not performed for ESIMD splits - if (DeviceGlobals) - Splitter->verifyNoCrossModuleDeviceGlobalUsage(); + if (DeviceGlobals) { + auto E = Splitter->verifyNoCrossModuleDeviceGlobalUsage(); + CHECK_AND_EXIT(E); + } // It is important that we *DO NOT* preserve all the splits in memory at the // same time, because it leads to a huge RAM consumption by the tool on bigger