[clang] [clang-repl] : Fix clang-repl crash with --cuda flag (PR #136404)
Vassil Vassilev via cfe-commits
cfe-commits at lists.llvm.org
Sat Apr 19 10:57:44 PDT 2025
================
@@ -451,13 +451,44 @@ const char *const Runtimes = R"(
)";
llvm::Expected<std::unique_ptr<Interpreter>>
-Interpreter::create(std::unique_ptr<CompilerInstance> CI) {
+Interpreter::create(std::unique_ptr<CompilerInstance> CI,
+ std::unique_ptr<CompilerInstance> DeviceCI) {
llvm::Error Err = llvm::Error::success();
auto Interp =
std::unique_ptr<Interpreter>(new Interpreter(std::move(CI), Err));
if (Err)
return std::move(Err);
+ if (DeviceCI) {
+ // auto DeviceLLVMCtx = std::make_unique<llvm::LLVMContext>();
+ // auto DeviceTSCtx =
+ // std::make_unique<llvm::orc::ThreadSafeContext>(std::move(DeviceLLVMCtx));
+
+ // llvm::Error DeviceErr = llvm::Error::success();
+ // llvm::ErrorAsOutParameter EAO(&DeviceErr);
+
+ // auto DeviceAct = std::make_unique<IncrementalAction>(
+ // *DeviceCI, *DeviceTSCtx->getContext(), DeviceErr, *Interp);
+
+ // if (DeviceErr)
+ // return std::move(DeviceErr);
+
+ // DeviceCI->ExecuteAction(*DeviceAct);
+ DeviceCI->ExecuteAction(*Interp->Act);
----------------
vgvassilev wrote:
While doing testing I came across on a patch of mine which does not crash:
```patch
commit bcc670b90af2cefedbb654d3057cda4f891fa4b7
Author: Vassil Vassilev <v.g.vassilev at gmail.com>
Date: Sat Apr 19 15:39:41 2025 +0000
fix cuda
diff --git a/clang/include/clang/Interpreter/Interpreter.h b/clang/include/clang/Interpreter/Interpreter.h
index b1b63aedf86a..ba61c063d96a 100644
--- a/clang/include/clang/Interpreter/Interpreter.h
+++ b/clang/include/clang/Interpreter/Interpreter.h
@@ -94,6 +94,8 @@ class Interpreter {
// An optional parser for CUDA offloading
std::unique_ptr<IncrementalParser> DeviceParser;
+ // An optional action for CUDA offloading
+ std::unique_ptr<IncrementalAction> DeviceAct;
/// List containing information about each incrementally parsed piece of code.
std::list<PartialTranslationUnit> PTUs;
@@ -129,7 +131,8 @@ protected:
public:
virtual ~Interpreter();
static llvm::Expected<std::unique_ptr<Interpreter>>
- create(std::unique_ptr<CompilerInstance> CI);
+ create(std::unique_ptr<CompilerInstance> CI,
+ std::unique_ptr<CompilerInstance> DeviceCI = nullptr);
static llvm::Expected<std::unique_ptr<Interpreter>>
createWithCUDA(std::unique_ptr<CompilerInstance> CI,
std::unique_ptr<CompilerInstance> DCI);
diff --git a/clang/lib/Interpreter/DeviceOffload.cpp b/clang/lib/Interpreter/DeviceOffload.cpp
index 1999d63d1aa0..3db96a6fd517 100644
--- a/clang/lib/Interpreter/DeviceOffload.cpp
+++ b/clang/lib/Interpreter/DeviceOffload.cpp
@@ -27,18 +27,27 @@ namespace clang {
IncrementalCUDADeviceParser::IncrementalCUDADeviceParser(
std::unique_ptr<CompilerInstance> DeviceInstance,
CompilerInstance &HostInstance,
- llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> FS,
llvm::Error &Err, const std::list<PartialTranslationUnit> &PTUs)
- : IncrementalParser(*DeviceInstance, Err), PTUs(PTUs), VFS(FS),
- CodeGenOpts(HostInstance.getCodeGenOpts()),
- TargetOpts(HostInstance.getTargetOpts()) {
+ : IncrementalParser([this](CompilerInstance *DCI) -> CompilerInstance& {
+ // Avoid writing fat binary to disk using an in-memory virtual file system.
+ VFS = new llvm::vfs::InMemoryFileSystem();
+ llvm::IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> OverlayVFS =
+ std::make_unique<llvm::vfs::OverlayFileSystem>(
+ llvm::vfs::getRealFileSystem());
+ OverlayVFS->pushOverlay(VFS);
+ DCI->createFileManager(OverlayVFS);
+ return *DCI;
+ }(DeviceInstance.get()), Err), PTUs(PTUs),
+ HostCodeGenOpts(HostInstance.getCodeGenOpts()),
+ HostTargetOpts(HostInstance.getTargetOpts()) {
if (Err)
return;
DeviceCI = std::move(DeviceInstance);
- StringRef Arch = TargetOpts.CPU;
+ StringRef Arch = HostTargetOpts.CPU;
if (!Arch.starts_with("sm_") || Arch.substr(3).getAsInteger(10, SMVersion)) {
Err = llvm::joinErrors(std::move(Err), llvm::make_error<llvm::StringError>(
- "Invalid CUDA architecture",
+ "Invalid CUDA architecture '" +
+ Arch + "'",
llvm::inconvertibleErrorCode()));
return;
}
@@ -65,7 +74,7 @@ IncrementalCUDADeviceParser::Parse(llvm::StringRef Input) {
llvm::StringRef(FatbinContent.data(), FatbinContent.size()),
"", false));
- CodeGenOpts.CudaGpuBinaryFileName = FatbinFileName;
+ HostCodeGenOpts.CudaGpuBinaryFileName = FatbinFileName;
FatbinContent.clear();
@@ -83,7 +92,7 @@ llvm::Expected<llvm::StringRef> IncrementalCUDADeviceParser::GeneratePTX() {
std::error_code());
llvm::TargetOptions TO = llvm::TargetOptions();
llvm::TargetMachine *TargetMachine = Target->createTargetMachine(
- PTU.TheModule->getTargetTriple(), TargetOpts.CPU, "", TO,
+ PTU.TheModule->getTargetTriple(), HostTargetOpts.CPU, "", TO,
llvm::Reloc::Model::PIC_);
PTU.TheModule->setDataLayout(TargetMachine->createDataLayout());
diff --git a/clang/lib/Interpreter/DeviceOffload.h b/clang/lib/Interpreter/DeviceOffload.h
index b9a1acab004c..07994ccb40eb 100644
--- a/clang/lib/Interpreter/DeviceOffload.h
+++ b/clang/lib/Interpreter/DeviceOffload.h
@@ -30,7 +30,6 @@ public:
IncrementalCUDADeviceParser(
std::unique_ptr<CompilerInstance> DeviceInstance,
CompilerInstance &HostInstance,
- llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> VFS,
llvm::Error &Err, const std::list<PartialTranslationUnit> &PTUs);
llvm::Expected<TranslationUnitDecl *> Parse(llvm::StringRef Input) override;
@@ -49,8 +48,8 @@ protected:
llvm::SmallString<1024> PTXCode;
llvm::SmallVector<char, 1024> FatbinContent;
llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> VFS;
- CodeGenOptions &CodeGenOpts; // Intentionally a reference.
- const TargetOptions &TargetOpts;
+ CodeGenOptions &HostCodeGenOpts; // Intentionally a reference.
+ const TargetOptions &HostTargetOpts;
};
} // namespace clang
diff --git a/clang/lib/Interpreter/Interpreter.cpp b/clang/lib/Interpreter/Interpreter.cpp
index 1859c6802c6f..3ca2e21d6f8a 100644
--- a/clang/lib/Interpreter/Interpreter.cpp
+++ b/clang/lib/Interpreter/Interpreter.cpp
@@ -450,13 +450,33 @@ const char *const Runtimes = R"(
)";
llvm::Expected<std::unique_ptr<Interpreter>>
-Interpreter::create(std::unique_ptr<CompilerInstance> CI) {
+Interpreter::create(std::unique_ptr<CompilerInstance> CI,
+ std::unique_ptr<CompilerInstance> DeviceCI/*=nullptr*/) {
llvm::Error Err = llvm::Error::success();
+
auto Interp =
std::unique_ptr<Interpreter>(new Interpreter(std::move(CI), Err));
+ CompilerInstance &HostCI = *(Interp->getCompilerInstance());
if (Err)
return std::move(Err);
+ if (DeviceCI) {
+ Interp->DeviceAct = std::make_unique<IncrementalAction>(*DeviceCI, *Interp->TSCtx->getContext(), Err,
+ *Interp);
+
+ if (Err)
+ return std::move(Err);
+
+ DeviceCI->ExecuteAction(*Interp->DeviceAct);
+
+ auto DeviceParser = new IncrementalCUDADeviceParser(std::move(DeviceCI),
+ HostCI, Err, Interp->PTUs);
+ if (Err)
+ return std::move(Err);
+
+ Interp->DeviceParser.reset(DeviceParser);
+ }
+
// Add runtime code and set a marker to hide it from user code. Undo will not
// go through that.
auto PTU = Interp->Parse(Runtimes);
@@ -471,29 +491,7 @@ Interpreter::create(std::unique_ptr<CompilerInstance> CI) {
llvm::Expected<std::unique_ptr<Interpreter>>
Interpreter::createWithCUDA(std::unique_ptr<CompilerInstance> CI,
std::unique_ptr<CompilerInstance> DCI) {
- // avoid writing fat binary to disk using an in-memory virtual file system
- llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> IMVFS =
- std::make_unique<llvm::vfs::InMemoryFileSystem>();
- llvm::IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> OverlayVFS =
- std::make_unique<llvm::vfs::OverlayFileSystem>(
- llvm::vfs::getRealFileSystem());
- OverlayVFS->pushOverlay(IMVFS);
- CI->createFileManager(OverlayVFS);
-
- auto Interp = Interpreter::create(std::move(CI));
- if (auto E = Interp.takeError())
- return std::move(E);
-
- llvm::Error Err = llvm::Error::success();
- auto DeviceParser = std::make_unique<IncrementalCUDADeviceParser>(
- std::move(DCI), *(*Interp)->getCompilerInstance(), IMVFS, Err,
- (*Interp)->PTUs);
- if (Err)
- return std::move(Err);
-
- (*Interp)->DeviceParser = std::move(DeviceParser);
-
- return Interp;
+ return Interpreter::create(std::move(CI), std::move(DCI));
}
const CompilerInstance *Interpreter::getCompilerInstance() const {
```
but shows:
```
./bin/clang-repl --cuda
module flag identifiers must be unique (or of 'require' type)
!"wchar_size"
module flag identifiers must be unique (or of 'require' type)
!"nvvm-reflect-ftz"
module flag identifiers must be unique (or of 'require' type)
!"frame-pointer"
fatal error: error in backend: Broken module found, compilation aborted!
```
https://github.com/llvm/llvm-project/pull/136404
More information about the cfe-commits
mailing list