https://github.com/anutosh491 updated https://github.com/llvm/llvm-project/pull/136404
>From 6c64e64c4a3b56f50808cae244b29da1231525f1 Mon Sep 17 00:00:00 2001 From: anutosh491 <andersonbhat...@gmail.com> Date: Fri, 18 Apr 2025 18:45:00 +0530 Subject: [PATCH 1/3] Fix cuda flag with clang-repl --- clang/include/clang/Interpreter/Interpreter.h | 13 ++-- clang/lib/Interpreter/DeviceOffload.cpp | 39 ++++++------ clang/lib/Interpreter/DeviceOffload.h | 4 +- clang/lib/Interpreter/Interpreter.cpp | 59 ++++++++++++++----- 4 files changed, 72 insertions(+), 43 deletions(-) diff --git a/clang/include/clang/Interpreter/Interpreter.h b/clang/include/clang/Interpreter/Interpreter.h index b1b63aedf86ab..56213f88b9e30 100644 --- a/clang/include/clang/Interpreter/Interpreter.h +++ b/clang/include/clang/Interpreter/Interpreter.h @@ -41,6 +41,7 @@ class CXXRecordDecl; class Decl; class IncrementalExecutor; class IncrementalParser; +class IncrementalCUDADeviceParser; /// Create a pre-configured \c CompilerInstance for incremental processing. class IncrementalCompilerBuilder { @@ -93,7 +94,10 @@ class Interpreter { std::unique_ptr<IncrementalExecutor> IncrExecutor; // An optional parser for CUDA offloading - std::unique_ptr<IncrementalParser> DeviceParser; + std::unique_ptr<IncrementalCUDADeviceParser> 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; @@ -175,10 +179,11 @@ class Interpreter { llvm::Expected<Expr *> ExtractValueFromExpr(Expr *E); llvm::Expected<llvm::orc::ExecutorAddr> CompileDtorCall(CXXRecordDecl *CXXRD); - CodeGenerator *getCodeGen() const; - std::unique_ptr<llvm::Module> GenModule(); + CodeGenerator *getCodeGen(IncrementalAction *Action = nullptr) const; + std::unique_ptr<llvm::Module> GenModule(IncrementalAction *Action = nullptr); PartialTranslationUnit &RegisterPTU(TranslationUnitDecl *TU, - std::unique_ptr<llvm::Module> M = {}); + std::unique_ptr<llvm::Module> M = {}, + IncrementalAction *Action = nullptr); // A cache for the compiled destructors used to for de-allocation of managed // clang::Values. diff --git a/clang/lib/Interpreter/DeviceOffload.cpp b/clang/lib/Interpreter/DeviceOffload.cpp index 1999d63d1aa04..d9b00787f038d 100644 --- a/clang/lib/Interpreter/DeviceOffload.cpp +++ b/clang/lib/Interpreter/DeviceOffload.cpp @@ -28,20 +28,21 @@ IncrementalCUDADeviceParser::IncrementalCUDADeviceParser( std::unique_ptr<CompilerInstance> DeviceInstance, CompilerInstance &HostInstance, llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> FS, - llvm::Error &Err, const std::list<PartialTranslationUnit> &PTUs) + llvm::Error &Err, std::list<PartialTranslationUnit> &PTUs) : IncrementalParser(*DeviceInstance, Err), PTUs(PTUs), VFS(FS), CodeGenOpts(HostInstance.getCodeGenOpts()), - TargetOpts(HostInstance.getTargetOpts()) { + TargetOpts(DeviceInstance->getTargetOpts()) { if (Err) return; - DeviceCI = std::move(DeviceInstance); StringRef Arch = TargetOpts.CPU; if (!Arch.starts_with("sm_") || Arch.substr(3).getAsInteger(10, SMVersion)) { + DeviceInstance.release(); Err = llvm::joinErrors(std::move(Err), llvm::make_error<llvm::StringError>( "Invalid CUDA architecture", llvm::inconvertibleErrorCode())); return; } + DeviceCI = std::move(DeviceInstance); } llvm::Expected<TranslationUnitDecl *> @@ -50,25 +51,6 @@ IncrementalCUDADeviceParser::Parse(llvm::StringRef Input) { if (!PTU) return PTU.takeError(); - auto PTX = GeneratePTX(); - if (!PTX) - return PTX.takeError(); - - auto Err = GenerateFatbinary(); - if (Err) - return std::move(Err); - - std::string FatbinFileName = - "/incr_module_" + std::to_string(PTUs.size()) + ".fatbin"; - VFS->addFile(FatbinFileName, 0, - llvm::MemoryBuffer::getMemBuffer( - llvm::StringRef(FatbinContent.data(), FatbinContent.size()), - "", false)); - - CodeGenOpts.CudaGpuBinaryFileName = FatbinFileName; - - FatbinContent.clear(); - return PTU; } @@ -172,6 +154,19 @@ llvm::Error IncrementalCUDADeviceParser::GenerateFatbinary() { FatbinContent.append(PTXCode.begin(), PTXCode.end()); + auto &PTU = PTUs.back(); + + std::string FatbinFileName = "/" + PTU.TheModule->getName().str() + ".fatbin"; + + VFS->addFile(FatbinFileName, 0, + llvm::MemoryBuffer::getMemBuffer( + llvm::StringRef(FatbinContent.data(), FatbinContent.size()), + "", false)); + + CodeGenOpts.CudaGpuBinaryFileName = FatbinFileName; + + FatbinContent.clear(); + return llvm::Error::success(); } diff --git a/clang/lib/Interpreter/DeviceOffload.h b/clang/lib/Interpreter/DeviceOffload.h index b9a1acab004c3..23d89046c09e1 100644 --- a/clang/lib/Interpreter/DeviceOffload.h +++ b/clang/lib/Interpreter/DeviceOffload.h @@ -24,14 +24,14 @@ class CodeGenOptions; class TargetOptions; class IncrementalCUDADeviceParser : public IncrementalParser { - const std::list<PartialTranslationUnit> &PTUs; + std::list<PartialTranslationUnit> &PTUs; public: IncrementalCUDADeviceParser( std::unique_ptr<CompilerInstance> DeviceInstance, CompilerInstance &HostInstance, llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> VFS, - llvm::Error &Err, const std::list<PartialTranslationUnit> &PTUs); + llvm::Error &Err, std::list<PartialTranslationUnit> &PTUs); llvm::Expected<TranslationUnitDecl *> Parse(llvm::StringRef Input) override; diff --git a/clang/lib/Interpreter/Interpreter.cpp b/clang/lib/Interpreter/Interpreter.cpp index f8c8d0a425659..f91563dd0378c 100644 --- a/clang/lib/Interpreter/Interpreter.cpp +++ b/clang/lib/Interpreter/Interpreter.cpp @@ -481,20 +481,34 @@ Interpreter::createWithCUDA(std::unique_ptr<CompilerInstance> CI, OverlayVFS->pushOverlay(IMVFS); CI->createFileManager(OverlayVFS); - auto Interp = Interpreter::create(std::move(CI)); - if (auto E = Interp.takeError()) - return std::move(E); + llvm::Expected<std::unique_ptr<Interpreter>> InterpOrErr = + Interpreter::create(std::move(CI)); + if (!InterpOrErr) + return InterpOrErr; + + std::unique_ptr<Interpreter> Interp = std::move(*InterpOrErr); llvm::Error Err = llvm::Error::success(); - auto DeviceParser = std::make_unique<IncrementalCUDADeviceParser>( - std::move(DCI), *(*Interp)->getCompilerInstance(), IMVFS, Err, - (*Interp)->PTUs); + llvm::LLVMContext &LLVMCtx = *Interp->TSCtx->getContext(); + + auto DeviceAct = + std::make_unique<IncrementalAction>(*DCI, LLVMCtx, Err, *Interp); + if (Err) return std::move(Err); - (*Interp)->DeviceParser = std::move(DeviceParser); + Interp->DeviceAct = std::move(DeviceAct); + + DCI->ExecuteAction(*Interp->DeviceAct); + + auto DeviceParser = std::make_unique<IncrementalCUDADeviceParser>( + std::move(DCI), *Interp->getCompilerInstance(), IMVFS, Err, Interp->PTUs); + + if (Err) + return std::move(Err); - return Interp; + Interp->DeviceParser = std::move(DeviceParser); + return std::move(Interp); } const CompilerInstance *Interpreter::getCompilerInstance() const { @@ -532,15 +546,17 @@ size_t Interpreter::getEffectivePTUSize() const { PartialTranslationUnit & Interpreter::RegisterPTU(TranslationUnitDecl *TU, - std::unique_ptr<llvm::Module> M /*={}*/) { + std::unique_ptr<llvm::Module> M /*={}*/, + IncrementalAction *Action) { PTUs.emplace_back(PartialTranslationUnit()); PartialTranslationUnit &LastPTU = PTUs.back(); LastPTU.TUPart = TU; if (!M) - M = GenModule(); + M = GenModule(Action); - assert((!getCodeGen() || M) && "Must have a llvm::Module at this point"); + assert((!getCodeGen(Action) || M) && + "Must have a llvm::Module at this point"); LastPTU.TheModule = std::move(M); LLVM_DEBUG(llvm::dbgs() << "compile-ptu " << PTUs.size() - 1 @@ -560,6 +576,16 @@ Interpreter::Parse(llvm::StringRef Code) { llvm::Expected<TranslationUnitDecl *> DeviceTU = DeviceParser->Parse(Code); if (auto E = DeviceTU.takeError()) return std::move(E); + + RegisterPTU(*DeviceTU, nullptr, DeviceAct.get()); + + llvm::Expected<llvm::StringRef> PTX = DeviceParser->GeneratePTX(); + if (!PTX) + return PTX.takeError(); + + llvm::Error Err = DeviceParser->GenerateFatbinary(); + if (Err) + return std::move(Err); } // Tell the interpreter sliently ignore unused expressions since value @@ -736,9 +762,10 @@ llvm::Error Interpreter::LoadDynamicLibrary(const char *name) { return llvm::Error::success(); } -std::unique_ptr<llvm::Module> Interpreter::GenModule() { +std::unique_ptr<llvm::Module> +Interpreter::GenModule(IncrementalAction *Action) { static unsigned ID = 0; - if (CodeGenerator *CG = getCodeGen()) { + if (CodeGenerator *CG = getCodeGen(Action)) { // Clang's CodeGen is designed to work with a single llvm::Module. In many // cases for convenience various CodeGen parts have a reference to the // llvm::Module (TheModule or Module) which does not change when a new @@ -760,8 +787,10 @@ std::unique_ptr<llvm::Module> Interpreter::GenModule() { return nullptr; } -CodeGenerator *Interpreter::getCodeGen() const { - FrontendAction *WrappedAct = Act->getWrapped(); +CodeGenerator *Interpreter::getCodeGen(IncrementalAction *Action) const { + if (!Action) + Action = Act.get(); + FrontendAction *WrappedAct = Action->getWrapped(); if (!WrappedAct->hasIRSupport()) return nullptr; return static_cast<CodeGenAction *>(WrappedAct)->getCodeGenerator(); >From a445870215b431bdd5b7675920b5d523491499b6 Mon Sep 17 00:00:00 2001 From: anutosh491 <andersonbhat...@gmail.com> Date: Thu, 24 Apr 2025 19:31:12 +0530 Subject: [PATCH 2/3] Address reviews --- clang/lib/Interpreter/DeviceOffload.cpp | 5 ++--- clang/lib/Interpreter/DeviceOffload.h | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/clang/lib/Interpreter/DeviceOffload.cpp b/clang/lib/Interpreter/DeviceOffload.cpp index d9b00787f038d..f35238f2b3734 100644 --- a/clang/lib/Interpreter/DeviceOffload.cpp +++ b/clang/lib/Interpreter/DeviceOffload.cpp @@ -28,7 +28,7 @@ IncrementalCUDADeviceParser::IncrementalCUDADeviceParser( std::unique_ptr<CompilerInstance> DeviceInstance, CompilerInstance &HostInstance, llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> FS, - llvm::Error &Err, std::list<PartialTranslationUnit> &PTUs) + llvm::Error &Err, const std::list<PartialTranslationUnit> &PTUs) : IncrementalParser(*DeviceInstance, Err), PTUs(PTUs), VFS(FS), CodeGenOpts(HostInstance.getCodeGenOpts()), TargetOpts(DeviceInstance->getTargetOpts()) { @@ -36,7 +36,6 @@ IncrementalCUDADeviceParser::IncrementalCUDADeviceParser( return; StringRef Arch = TargetOpts.CPU; if (!Arch.starts_with("sm_") || Arch.substr(3).getAsInteger(10, SMVersion)) { - DeviceInstance.release(); Err = llvm::joinErrors(std::move(Err), llvm::make_error<llvm::StringError>( "Invalid CUDA architecture", llvm::inconvertibleErrorCode())); @@ -154,7 +153,7 @@ llvm::Error IncrementalCUDADeviceParser::GenerateFatbinary() { FatbinContent.append(PTXCode.begin(), PTXCode.end()); - auto &PTU = PTUs.back(); + const PartialTranslationUnit &PTU = PTUs.back(); std::string FatbinFileName = "/" + PTU.TheModule->getName().str() + ".fatbin"; diff --git a/clang/lib/Interpreter/DeviceOffload.h b/clang/lib/Interpreter/DeviceOffload.h index 23d89046c09e1..b9a1acab004c3 100644 --- a/clang/lib/Interpreter/DeviceOffload.h +++ b/clang/lib/Interpreter/DeviceOffload.h @@ -24,14 +24,14 @@ class CodeGenOptions; class TargetOptions; class IncrementalCUDADeviceParser : public IncrementalParser { - std::list<PartialTranslationUnit> &PTUs; + const std::list<PartialTranslationUnit> &PTUs; public: IncrementalCUDADeviceParser( std::unique_ptr<CompilerInstance> DeviceInstance, CompilerInstance &HostInstance, llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> VFS, - llvm::Error &Err, std::list<PartialTranslationUnit> &PTUs); + llvm::Error &Err, const std::list<PartialTranslationUnit> &PTUs); llvm::Expected<TranslationUnitDecl *> Parse(llvm::StringRef Input) override; >From 7aed4345e7d769e859daac0f64eef9f132d507e5 Mon Sep 17 00:00:00 2001 From: anutosh491 <andersonbhat...@gmail.com> Date: Thu, 24 Apr 2025 20:56:36 +0530 Subject: [PATCH 3/3] use base class for parse --- clang/lib/Interpreter/DeviceOffload.cpp | 9 --------- clang/lib/Interpreter/DeviceOffload.h | 2 -- 2 files changed, 11 deletions(-) diff --git a/clang/lib/Interpreter/DeviceOffload.cpp b/clang/lib/Interpreter/DeviceOffload.cpp index f35238f2b3734..7d0125403ea52 100644 --- a/clang/lib/Interpreter/DeviceOffload.cpp +++ b/clang/lib/Interpreter/DeviceOffload.cpp @@ -44,15 +44,6 @@ IncrementalCUDADeviceParser::IncrementalCUDADeviceParser( DeviceCI = std::move(DeviceInstance); } -llvm::Expected<TranslationUnitDecl *> -IncrementalCUDADeviceParser::Parse(llvm::StringRef Input) { - auto PTU = IncrementalParser::Parse(Input); - if (!PTU) - return PTU.takeError(); - - return PTU; -} - llvm::Expected<llvm::StringRef> IncrementalCUDADeviceParser::GeneratePTX() { auto &PTU = PTUs.back(); std::string Error; diff --git a/clang/lib/Interpreter/DeviceOffload.h b/clang/lib/Interpreter/DeviceOffload.h index b9a1acab004c3..43645033c4840 100644 --- a/clang/lib/Interpreter/DeviceOffload.h +++ b/clang/lib/Interpreter/DeviceOffload.h @@ -33,8 +33,6 @@ class IncrementalCUDADeviceParser : public IncrementalParser { llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> VFS, llvm::Error &Err, const std::list<PartialTranslationUnit> &PTUs); - llvm::Expected<TranslationUnitDecl *> Parse(llvm::StringRef Input) override; - // Generate PTX for the last PTU. llvm::Expected<llvm::StringRef> GeneratePTX(); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits