llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Aditya Sinha (AdityaSinha149)

<details>
<summary>Changes</summary>

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.

---
Full diff: https://github.com/llvm/llvm-project/pull/235614.diff


3 Files Affected:

- (modified) clang/lib/Interpreter/DeviceOffload.cpp (+58-2) 
- (modified) clang/lib/Interpreter/DeviceOffload.h (+4) 
- (modified) clang/unittests/Interpreter/DeviceOffloadTest.cpp (+9) 


``````````diff
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);

``````````

</details>


https://github.com/llvm/llvm-project/pull/235614
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to