saiislam created this revision.
saiislam added reviewers: jdoerfert, ABataev, JonChesterfield, grokos.
Herald added subscribers: kerbowa, guansong, yaxunl, nhaehnle, jvesely.
saiislam requested review of this revision.
Herald added subscribers: cfe-commits, sstefan1.
Herald added a project: clang.
An archive containing device code object files can be passed to
clang command line for linking. For each given offload target
it creates a device specific archives and passes it to llvm-link.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D105191
Files:
clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp
clang/lib/Driver/ToolChains/CommonArgs.cpp
clang/lib/Driver/ToolChains/CommonArgs.h
clang/lib/Driver/ToolChains/Cuda.cpp
Index: clang/lib/Driver/ToolChains/Cuda.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Cuda.cpp
+++ clang/lib/Driver/ToolChains/Cuda.cpp
@@ -632,6 +632,9 @@
CmdArgs.push_back(CubinF);
}
+ AddStaticDeviceLibs(C, *this, JA, Inputs, Args, CmdArgs, "nvptx", GPUArch,
+ false, false);
+
const char *Exec =
Args.MakeArgString(getToolChain().GetProgramPath("nvlink"));
C.addCommand(std::make_unique<Command>(
@@ -754,6 +757,8 @@
std::string BitcodeSuffix = "nvptx-" + GpuArch.str();
addOpenMPDeviceRTL(getDriver(), DriverArgs, CC1Args, BitcodeSuffix,
getTriple());
+ AddStaticDeviceLibs(getDriver(), DriverArgs, CC1Args, "nvptx", GpuArch,
+ /* bitcode SDL?*/ true, /* PostClang Link? */ true);
}
}
Index: clang/lib/Driver/ToolChains/CommonArgs.h
===================================================================
--- clang/lib/Driver/ToolChains/CommonArgs.h
+++ clang/lib/Driver/ToolChains/CommonArgs.h
@@ -49,6 +49,38 @@
llvm::opt::ArgStringList &CmdArgs,
const llvm::opt::ArgList &Args);
+void AddStaticDeviceLibs(Compilation &C, const Tool &T, const JobAction &JA,
+ const InputInfoList &Inputs,
+ const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &CmdArgs, StringRef ArchName,
+ StringRef GPUArch, bool isBitCodeSDL,
+ bool postClangLink);
+void AddStaticDeviceLibs(const Driver &D, const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &CmdArgs, StringRef ArchName,
+ StringRef GPUArch, bool isBitCodeSDL,
+ bool postClangLink);
+void AddStaticDeviceLibs(Compilation *C, const Tool *T, const JobAction *JA,
+ const InputInfoList *Inputs, const Driver &D,
+ const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &CmdArgs, StringRef ArchName,
+ StringRef GPUArch, bool isBitCodeSDL,
+ bool postClangLink);
+
+bool SDLSearch(const Driver &D, const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &CmdArgs,
+ SmallVector<std::string, 8> LibraryPaths, std::string libname,
+ StringRef ArchName, StringRef GPUArch, bool isBitCodeSDL,
+ bool postClangLink);
+
+bool GetSDLFromOffloadArchive(Compilation &C, const Driver &D, const Tool &T,
+ const JobAction &JA, const InputInfoList &Inputs,
+ const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &CC1Args,
+ SmallVector<std::string, 8> LibraryPaths,
+ std::string libname, StringRef ArchName,
+ StringRef GPUArch, bool isBitCodeSDL,
+ bool postClangLink);
+
const char *SplitDebugName(const JobAction &JA, const llvm::opt::ArgList &Args,
const InputInfo &Input, const InputInfo &Output);
Index: clang/lib/Driver/ToolChains/CommonArgs.cpp
===================================================================
--- clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -1587,6 +1587,236 @@
}
}
+/// SDLSearch: Search for Static Device Library
+bool tools::SDLSearch(const Driver &D, const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &CC1Args,
+ SmallVector<std::string, 8> LibraryPaths,
+ std::string libname, StringRef ArchName,
+ StringRef GPUArch, bool isBitCodeSDL,
+ bool postClangLink) {
+ std::string archname = ArchName.str();
+ std::string Target = GPUArch.str();
+
+ SmallVector<std::string, 12> SDL_FileNames;
+ if (isBitCodeSDL) {
+ // For bitcode SDL, search for these 12 relative SDL filenames
+ SDL_FileNames.push_back(std::string("/libdevice/libbc-" + libname + "-" +
+ archname + "-" + Target + ".a"));
+ SDL_FileNames.push_back(std::string("/libbc-" + libname + "-" + archname +
+ "-" + Target + ".a"));
+ SDL_FileNames.push_back(
+ std::string("/libdevice/libbc-" + libname + "-" + archname + ".a"));
+ SDL_FileNames.push_back(
+ std::string("/libbc-" + libname + "-" + archname + ".a"));
+ SDL_FileNames.push_back(std::string("/libdevice/libbc-" + libname + ".a"));
+ SDL_FileNames.push_back(std::string("/libbc-" + libname + ".a"));
+ SDL_FileNames.push_back(std::string("/libdevice/lib" + libname + "-" +
+ archname + "-" + Target + ".bc"));
+ SDL_FileNames.push_back(
+ std::string("/lib" + libname + "-" + archname + "-" + Target + ".bc"));
+ SDL_FileNames.push_back(
+ std::string("/libdevice/lib" + libname + "-" + archname + ".bc"));
+ SDL_FileNames.push_back(
+ std::string("/lib" + libname + "-" + archname + ".bc"));
+ SDL_FileNames.push_back(std::string("/libdevice/lib" + libname + ".bc"));
+ SDL_FileNames.push_back(std::string("/lib" + libname + ".bc"));
+ } else {
+ // Otherwise only 4 names to search for machine-code SDL
+ SDL_FileNames.push_back(std::string("/libdevice/lib" + libname + "-" +
+ archname + "-" + Target + ".a"));
+ SDL_FileNames.push_back(
+ std::string("/lib" + libname + "-" + archname + "-" + Target + ".a"));
+ SDL_FileNames.push_back(
+ std::string("/libdevice/lib" + libname + "-" + archname + ".a"));
+ SDL_FileNames.push_back(
+ std::string("/lib" + libname + "-" + archname + ".a"));
+ }
+
+ // Add file for archive of bundles, this is the final fallback
+ bool FoundSDL = false;
+ for (std::string LibraryPath : LibraryPaths) {
+ for (std::string SDL_FileName : SDL_FileNames) {
+ std::string FullName = std::string(LibraryPath + SDL_FileName);
+ if (llvm::sys::fs::exists(FullName)) {
+ if (postClangLink)
+ CC1Args.push_back("-mlink-builtin-bitcode");
+ CC1Args.push_back(DriverArgs.MakeArgString(FullName));
+ FoundSDL = true;
+ break;
+ }
+ }
+ if (FoundSDL)
+ break;
+ }
+
+ return FoundSDL;
+}
+
+bool tools::GetSDLFromOffloadArchive(
+ Compilation &C, const Driver &D, const Tool &T, const JobAction &JA,
+ const InputInfoList &Inputs, const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &CC1Args, SmallVector<std::string, 8> LibraryPaths,
+ std::string libname, StringRef ArchName, StringRef GPUArch,
+ bool isBitCodeSDL, bool postClangLink) {
+ std::string archname = ArchName.str();
+ std::string gpuname = GPUArch.str();
+
+ // We don't support bitcode archive bundles for nvptx
+ if (isBitCodeSDL && archname == "nvptx")
+ return false;
+
+ bool FoundAOB = false;
+ SmallVector<std::string, 2> AOBFileNames;
+ std::string ArchiveOfBundles;
+ for (std::string LibraryPath : LibraryPaths) {
+ AOBFileNames.push_back(
+ std::string(LibraryPath + "/libdevice/lib" + libname + ".a"));
+ AOBFileNames.push_back(std::string(LibraryPath + "/lib" + libname + ".a"));
+
+ for (auto AOB : AOBFileNames) {
+ if (llvm::sys::fs::exists(AOB)) {
+ ArchiveOfBundles = AOB;
+ FoundAOB = true;
+ break;
+ }
+ }
+
+ if (FoundAOB) {
+ std::string Err;
+ std::string OutputLib = D.GetTemporaryPath(
+ isBitCodeSDL ? "libbc-" + libname + "-" + archname + "-" + gpuname
+ : "lib" + libname + "-" + archname + "-" + gpuname,
+ "a");
+
+ C.addTempFile(C.getArgs().MakeArgString(OutputLib.c_str()));
+
+ ArgStringList CmdArgs;
+ SmallString<128> DeviceTriple;
+ DeviceTriple += Action::GetOffloadKindName(JA.getOffloadingDeviceKind());
+ DeviceTriple += "-";
+ std::string NormalizedTriple = T.getToolChain().getTriple().normalize();
+ DeviceTriple += NormalizedTriple;
+ if (!GPUArch.empty()) {
+ // If GPUArch is present it can only appear as the 6th hypen
+ // sepearated field of Bundle Entry ID. So, pad required number of
+ // hyphens in Triple.
+ for (int i = 4 - StringRef(NormalizedTriple).count("-"); i > 0; i--)
+ DeviceTriple += "-";
+ DeviceTriple += GPUArch;
+ }
+
+ std::string UnbundleArg("-unbundle");
+ std::string TypeArg("-type=a");
+ std::string InputArg("-inputs=" + ArchiveOfBundles);
+ std::string OffloadArg("-targets=" + std::string(DeviceTriple));
+ std::string OutputArg("-outputs=" + OutputLib);
+
+ const char *UBProgram = DriverArgs.MakeArgString(
+ T.getToolChain().GetProgramPath("clang-offload-bundler"));
+
+ ArgStringList UBArgs;
+ UBArgs.push_back(C.getArgs().MakeArgString(UnbundleArg.c_str()));
+ UBArgs.push_back(C.getArgs().MakeArgString(TypeArg.c_str()));
+ UBArgs.push_back(C.getArgs().MakeArgString(InputArg.c_str()));
+ UBArgs.push_back(C.getArgs().MakeArgString(OffloadArg.c_str()));
+ UBArgs.push_back(C.getArgs().MakeArgString(OutputArg.c_str()));
+
+ // Add this flag to not exit from clang-offload-bundler if no compatible
+ // code object is found in heterogenous archive library.
+ std::string AdditionalArgs("-allow-missing-bundles");
+ UBArgs.push_back(C.getArgs().MakeArgString(AdditionalArgs.c_str()));
+
+ C.addCommand(std::make_unique<Command>(
+ JA, T, ResponseFileSupport::AtFileCurCP(), UBProgram, UBArgs, Inputs,
+ InputInfo(&JA, C.getArgs().MakeArgString(OutputLib.c_str()))));
+ if (postClangLink)
+ CC1Args.push_back("-mlink-builtin-bitcode");
+
+ CC1Args.push_back(DriverArgs.MakeArgString(OutputLib));
+ break;
+ }
+ }
+
+ return FoundAOB;
+}
+
+void tools::AddStaticDeviceLibs(Compilation &C, const Tool &T,
+ const JobAction &JA,
+ const InputInfoList &Inputs,
+ const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &CC1Args,
+ StringRef ArchName, StringRef GPUArch,
+ bool isBitCodeSDL, bool postClangLink) {
+ AddStaticDeviceLibs(&C, &T, &JA, &Inputs, C.getDriver(), DriverArgs, CC1Args,
+ ArchName, GPUArch, isBitCodeSDL, postClangLink);
+}
+
+void tools::AddStaticDeviceLibs(const Driver &D,
+ const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &CC1Args,
+ StringRef ArchName, StringRef GPUArch,
+ bool isBitCodeSDL, bool postClangLink) {
+ AddStaticDeviceLibs(nullptr, nullptr, nullptr, nullptr, D, DriverArgs,
+ CC1Args, ArchName, GPUArch, isBitCodeSDL, postClangLink);
+}
+
+void tools::AddStaticDeviceLibs(Compilation *C, const Tool *T,
+ const JobAction *JA,
+ const InputInfoList *Inputs, const Driver &D,
+ const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &CC1Args,
+ StringRef ArchName, StringRef GPUArch,
+ bool isBitCodeSDL, bool postClangLink) {
+
+ SmallVector<std::string, 8> LibraryPaths;
+ // Add search directories from LIBRARY_PATH env variable
+ llvm::Optional<std::string> LibPath =
+ llvm::sys::Process::GetEnv("LIBRARY_PATH");
+ if (LibPath) {
+ SmallVector<StringRef, 8> Frags;
+ const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator, '\0'};
+ llvm::SplitString(*LibPath, Frags, EnvPathSeparatorStr);
+ for (StringRef Path : Frags)
+ LibraryPaths.emplace_back(Path.trim());
+ }
+
+ // Add directories from user-specified -L options
+ for (std::string Search_Dir : DriverArgs.getAllArgValues(options::OPT_L))
+ LibraryPaths.emplace_back(Search_Dir);
+
+ // Add path to lib-debug folders
+ SmallString<256> DefaultLibPath = llvm::sys::path::parent_path(D.Dir);
+ llvm::sys::path::append(DefaultLibPath, Twine("lib") + CLANG_LIBDIR_SUFFIX);
+ LibraryPaths.emplace_back(DefaultLibPath.c_str());
+
+ // Build list of Static Device Libraries SDLs specified by -l option
+ SmallVector<std::string, 16> SDL_Names;
+ for (std::string SDL_Name : DriverArgs.getAllArgValues(options::OPT_l)) {
+ // No Device specific SDL for these libs: omp,cudart,m,gcc,gcc_s,pthread
+ if (SDL_Name != "omp" && SDL_Name != "cudart" && SDL_Name != "m" &&
+ SDL_Name != "gcc" && SDL_Name != "gcc_s" && SDL_Name != "pthread" &&
+ SDL_Name != "hip_hcc") {
+ bool inSDL_Names = false;
+ for (std::string OldName : SDL_Names) {
+ if (OldName == SDL_Name)
+ inSDL_Names = true;
+ }
+ if (!inSDL_Names) // Avoid duplicates in list of SDL_Names
+ SDL_Names.emplace_back(SDL_Name);
+ }
+ }
+
+ for (std::string SDL_Name : SDL_Names) {
+ // THIS IS THE ONLY CALL TO SDLSearch
+ if (!(SDLSearch(D, DriverArgs, CC1Args, LibraryPaths, SDL_Name, ArchName,
+ GPUArch, isBitCodeSDL, postClangLink))) {
+ GetSDLFromOffloadArchive(*C, D, *T, *JA, *Inputs, DriverArgs, CC1Args,
+ LibraryPaths, SDL_Name, ArchName, GPUArch,
+ isBitCodeSDL, postClangLink);
+ }
+ }
+}
+
static llvm::opt::Arg *
getAMDGPUCodeObjectArgument(const Driver &D, const llvm::opt::ArgList &Args) {
// The last of -mcode-object-v3, -mno-code-object-v3 and
Index: clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp
===================================================================
--- clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp
+++ clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp
@@ -92,6 +92,10 @@
for (const auto &II : Inputs)
if (II.isFilename())
CmdArgs.push_back(II.getFilename());
+ AddStaticDeviceLibs(C, *this, JA, Inputs, Args, CmdArgs, "amdgcn",
+ SubArchName,
+ /* bitcode SDL?*/ true,
+ /* PostClang Link? */ false);
// Add an intermediate output file.
CmdArgs.push_back("-o");
const char *OutputFileName =
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits