[clang] [clang-repl] Implement IncrementalHIPDeviceParser for HIP device compilation (PR #218337)

Aditya Sinha via cfe-commits cfe-commits at lists.llvm.org
Thu Sep 10 03:43:10 PDT 2026


================
@@ -11,19 +11,245 @@
 //===----------------------------------------------------------------------===//
 
 #include "DeviceOffload.h"
+#include "IncrementalAction.h"
 
 #include "clang/Basic/TargetOptions.h"
 #include "clang/CodeGen/ModuleBuilder.h"
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Interpreter/PartialTranslationUnit.h"
 
+#include "llvm/ADT/StringSet.h"
 #include "llvm/IR/LegacyPassManager.h"
 #include "llvm/IR/Module.h"
+#include "llvm/IRReader/IRReader.h"
+#include "llvm/Linker/Linker.h"
 #include "llvm/MC/TargetRegistry.h"
+#include "llvm/Passes/PassBuilder.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/FileUtilities.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/Program.h"
 #include "llvm/Target/TargetMachine.h"
+#include "llvm/TargetParser/Host.h"
+#include "llvm/Transforms/IPO/Internalize.h"
 
 namespace clang {
 
+static llvm::Expected<llvm::TargetMachine *>
+getOrCreateTargetMachine(std::unique_ptr<llvm::TargetMachine> &Cache,
+                         llvm::Module &M, llvm::StringRef CPU) {
+  if (!Cache) {
+    std::string Error;
+    const llvm::Target *Target =
+        llvm::TargetRegistry::lookupTarget(M.getTargetTriple(), Error);
+    if (!Target)
+      return llvm::make_error<llvm::StringError>(std::move(Error),
+                                                 std::error_code());
+    llvm::TargetOptions TO = llvm::TargetOptions();
+    Cache.reset(Target->createTargetMachine(M.getTargetTriple(), CPU, "", TO,
+                                            llvm::Reloc::Model::PIC_));
+  }
+  M.setDataLayout(Cache->createDataLayout());
+  return Cache.get();
+}
+
+IncrementalHIPDeviceParser::IncrementalHIPDeviceParser(
+    CompilerInstance &DeviceInstance, CompilerInstance &HostInstance,
+    IncrementalAction *DeviceAct,
+    llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> FS,
+    llvm::Error &Err, std::list<PartialTranslationUnit> &PTUs)
+    : IncrementalParser(DeviceInstance, DeviceAct, Err, PTUs), VFS(FS),
+      CodeGenOpts(HostInstance.getCodeGenOpts()),
+      DeviceCodeGenOpts(DeviceInstance.getCodeGenOpts()),
+      TargetOpts(DeviceInstance.getTargetOpts()) {
+  if (Err)
+    return;
+  StringRef Arch = TargetOpts.CPU;
+  if (!Arch.starts_with("gfx")) {
+    Err = llvm::joinErrors(std::move(Err), llvm::make_error<llvm::StringError>(
+                                               "Invalid HIP architecture",
+                                               llvm::inconvertibleErrorCode()));
+    return;
+  }
+}
+
+llvm::Error IncrementalHIPDeviceParser::optimize() {
+  auto &PTU = PTUs.back();
+
+  llvm::Expected<llvm::TargetMachine *> TMOrErr =
+      getOrCreateTargetMachine(TM, *PTU.TheModule, TargetOpts.CPU);
+  if (!TMOrErr)
+    return TMOrErr.takeError();
+
+  llvm::LoopAnalysisManager LAM;
+  llvm::FunctionAnalysisManager FAM;
+  llvm::CGSCCAnalysisManager CGAM;
+  llvm::ModuleAnalysisManager MAM;
+
+  llvm::PassBuilder PB(*TMOrErr);
+  PB.registerModuleAnalyses(MAM);
+  PB.registerCGSCCAnalyses(CGAM);
+  PB.registerFunctionAnalyses(FAM);
+  PB.registerLoopAnalyses(LAM);
+  PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
+
+  llvm::OptimizationLevel OptLevel;
+  switch (DeviceCodeGenOpts.OptimizationLevel) {
+  case 0:
+    OptLevel = llvm::OptimizationLevel::O0;
+    break;
+  case 1:
+    OptLevel = llvm::OptimizationLevel::O1;
+    break;
+  case 2:
+    OptLevel = llvm::OptimizationLevel::O2;
+    break;
+  default:
+    OptLevel = llvm::OptimizationLevel::O3;
+    break;
+  }
+
+  llvm::ModulePassManager MPM =
+      OptLevel == llvm::OptimizationLevel::O0
+          ? PB.buildO0DefaultPipeline(OptLevel)
+          : PB.buildPerModuleDefaultPipeline(OptLevel);
+  MPM.run(*PTU.TheModule, MAM);
+  return llvm::Error::success();
+}
+
+llvm::Expected<llvm::StringRef> IncrementalHIPDeviceParser::GenerateHSACO() {
+  auto &PTU = PTUs.back();
+
+  llvm::Expected<llvm::TargetMachine *> TMOrErr =
+      getOrCreateTargetMachine(TM, *PTU.TheModule, TargetOpts.CPU);
+  if (!TMOrErr)
+    return TMOrErr.takeError();
+  llvm::TargetMachine *TargetMachine = *TMOrErr;
+
+  llvm::SmallVector<char, 0> Object;
+  llvm::raw_svector_ostream ObjOS(Object);
+
+  llvm::legacy::PassManager PM;
+  if (TargetMachine->addPassesToEmitFile(PM, ObjOS, nullptr,
+                                         llvm::CodeGenFileType::ObjectFile))
+    return llvm::make_error<llvm::StringError>(
+        "AMDGPU backend cannot produce an object file.",
+        llvm::inconvertibleErrorCode());
+
+  if (!PM.run(*PTU.TheModule))
----------------
AdityaSinha149 wrote:

Removed the check, Thanks for the review.

https://github.com/llvm/llvm-project/pull/218337


More information about the cfe-commits mailing list