https://github.com/AdityaSinha149 created https://github.com/llvm/llvm-project/pull/235614
This PR adds a function `IncrementalHIPDeviceParser::GenerateHSACO` which takes the HIP device object and links it into an HSACO. The test `DeviceOffloadHIPTest.DeviceObjectIsGenerated` is updated to only run on machines that have ld.lld on it. >From b3f379421b6ba61c395facceca338f13de558e91 Mon Sep 17 00:00:00 2001 From: AdityaSinha149 <[email protected]> Date: Mon, 26 Oct 2026 10:58:56 +0530 Subject: [PATCH] [clang-repl] Link HIP device object into an HSACO --- clang/lib/Interpreter/DeviceOffload.cpp | 60 ++++++++++++++++++- clang/lib/Interpreter/DeviceOffload.h | 4 ++ .../Interpreter/DeviceOffloadTest.cpp | 9 +++ 3 files changed, 71 insertions(+), 2 deletions(-) diff --git a/clang/lib/Interpreter/DeviceOffload.cpp b/clang/lib/Interpreter/DeviceOffload.cpp index 94fec23b1c0b2f..15c0903da9e8b1 100644 --- a/clang/lib/Interpreter/DeviceOffload.cpp +++ b/clang/lib/Interpreter/DeviceOffload.cpp @@ -22,6 +22,12 @@ #include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/Module.h" #include "llvm/MC/TargetRegistry.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/FileUtilities.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/Path.h" +#include "llvm/Support/Program.h" +#include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetMachine.h" #include "llvm/TargetParser/Triple.h" @@ -79,13 +85,63 @@ IncrementalHIPDeviceParser::GenerateDeviceObject() { return llvm::StringRef(ObjectContent.data(), ObjectContent.size()); } +llvm::Expected<llvm::StringRef> +IncrementalHIPDeviceParser::GenerateHSACO(llvm::StringRef Object) { + std::string Exe = llvm::sys::fs::getMainExecutable(nullptr, nullptr); + llvm::ErrorOr<std::string> LLDPath = llvm::sys::findProgramByName( + "ld.lld", {llvm::sys::path::parent_path(Exe)}); + if (!LLDPath) + LLDPath = llvm::sys::findProgramByName("ld.lld"); + if (!LLDPath) + return llvm::make_error<llvm::StringError>( + "Could not find ld.lld next to the executable or on PATH.", + llvm::inconvertibleErrorCode()); + + int ObjFD = -1; + llvm::SmallString<128> ObjFile; + if (llvm::sys::fs::createTemporaryFile("kernel", "o", ObjFD, ObjFile)) + return llvm::make_error<llvm::StringError>( + "Failed to create a temporary object file.", + llvm::inconvertibleErrorCode()); + llvm::FileRemover ObjRemover(ObjFile); + { + llvm::raw_fd_ostream OS(ObjFD, /*shouldClose=*/true); + OS << Object; + } + + llvm::SmallString<128> HSACOFile; + if (llvm::sys::fs::createTemporaryFile("kernel", "hsaco", HSACOFile)) + return llvm::make_error<llvm::StringError>( + "Failed to create a temporary code object file.", + llvm::inconvertibleErrorCode()); + llvm::FileRemover HSACORemover(HSACOFile); + + llvm::StringRef Args[] = {"ld.lld", "-shared", "--no-undefined", + ObjFile, "-o", HSACOFile}; + if (llvm::sys::ExecuteAndWait(*LLDPath, Args) != 0) + return llvm::make_error<llvm::StringError>("ld.lld invocation failed.", + llvm::inconvertibleErrorCode()); + + auto HSACOBuf = llvm::MemoryBuffer::getFile(HSACOFile, /*IsText=*/false); + if (!HSACOBuf) + return llvm::make_error<llvm::StringError>( + "Failed to read the code object.", llvm::inconvertibleErrorCode()); + + llvm::StringRef Buffer = (*HSACOBuf)->getBuffer(); + HSACOContent.assign(Buffer.begin(), Buffer.end()); + return llvm::StringRef(HSACOContent.data(), HSACOContent.size()); +} + llvm::Error IncrementalHIPDeviceParser::GenerateOffloadBinary() { llvm::Expected<llvm::StringRef> Object = GenerateDeviceObject(); if (!Object) return Object.takeError(); - // FIXME: Link the object into an HSACO and bundle it for the host - // compilation. + llvm::Expected<llvm::StringRef> HSACO = GenerateHSACO(*Object); + if (!HSACO) + return HSACO.takeError(); + + // FIXME: Bundle the HSACO and embed it into the host compilation. return llvm::make_error<llvm::StringError>( "HIP offload binary generation is not supported yet.", llvm::inconvertibleErrorCode()); diff --git a/clang/lib/Interpreter/DeviceOffload.h b/clang/lib/Interpreter/DeviceOffload.h index c01e373d5a2f94..68e8ea9601ec15 100644 --- a/clang/lib/Interpreter/DeviceOffload.h +++ b/clang/lib/Interpreter/DeviceOffload.h @@ -47,10 +47,14 @@ class IncrementalDeviceParser : public IncrementalParser { class IncrementalHIPDeviceParser : public IncrementalDeviceParser { CompilerInstance &DeviceCI; llvm::SmallVector<char, 0> ObjectContent; + llvm::SmallVector<char, 0> HSACOContent; // Generate the AMDGPU object file for the last PTU. llvm::Expected<llvm::StringRef> GenerateDeviceObject(); + // Link the object file into a loadable AMDGPU code object (HSACO). + llvm::Expected<llvm::StringRef> GenerateHSACO(llvm::StringRef Object); + public: IncrementalHIPDeviceParser( CompilerInstance &DeviceInstance, CompilerInstance &HostInstance, diff --git a/clang/unittests/Interpreter/DeviceOffloadTest.cpp b/clang/unittests/Interpreter/DeviceOffloadTest.cpp index fa624f23f435b7..e3143d7ba73a14 100644 --- a/clang/unittests/Interpreter/DeviceOffloadTest.cpp +++ b/clang/unittests/Interpreter/DeviceOffloadTest.cpp @@ -27,6 +27,8 @@ #include "llvm/Support/Error.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/FileUtilities.h" +#include "llvm/Support/Path.h" +#include "llvm/Support/Program.h" #include "llvm/Support/TargetSelect.h" #include "llvm/Support/VirtualFileSystem.h" #include "llvm/Support/raw_ostream.h" @@ -144,6 +146,13 @@ TEST(DeviceOffloadBuilderTest, MultipleOffloadArchsAreRejected) { } TEST_F(DeviceOffloadHIPTest, DeviceObjectIsGenerated) { + // The device object is linked into an HSACO with ld.lld. + std::string Exe = llvm::sys::fs::getMainExecutable(nullptr, nullptr); + if (!llvm::sys::findProgramByName("ld.lld", + {llvm::sys::path::parent_path(Exe)}) && + !llvm::sys::findProgramByName("ld.lld")) + GTEST_SKIP() << "ld.lld not found"; + IncrementalCompilerBuilder CB; CB.SetCompilerArgs({"--offload-arch=gfx1100", "-nogpulib", "-nogpuinc"}); auto DeviceCI = CB.CreateDevice(OffloadType::HIP); _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
