From 5ad24cb2c47678d7d589f879c7ddfc630bd0fc1a Mon Sep 17 00:00:00 2001 From: koparasy Date: Thu, 20 Feb 2025 21:15:55 -0800 Subject: [PATCH 1/3] Rename file --- clang/lib/CIR/CodeGen/{CIRGenCUDARuntime.cpp => CIRGenCUDANV.cpp} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename clang/lib/CIR/CodeGen/{CIRGenCUDARuntime.cpp => CIRGenCUDANV.cpp} (100%) diff --git a/clang/lib/CIR/CodeGen/CIRGenCUDARuntime.cpp b/clang/lib/CIR/CodeGen/CIRGenCUDANV.cpp similarity index 100% rename from clang/lib/CIR/CodeGen/CIRGenCUDARuntime.cpp rename to clang/lib/CIR/CodeGen/CIRGenCUDANV.cpp From 8fb242a9ebfcad6fafe22d215c95fa08b98163e8 Mon Sep 17 00:00:00 2001 From: koparasy Date: Thu, 20 Feb 2025 21:19:22 -0800 Subject: [PATCH 2/3] Modify files to match OG Co-authored-by: seven-mile --- clang/lib/CIR/CodeGen/CIRGenCUDANV.cpp | 107 ++++++++++++-------- clang/lib/CIR/CodeGen/CIRGenCUDARuntime.cpp | 46 +++++++++ clang/lib/CIR/CodeGen/CIRGenCUDARuntime.h | 32 ++---- clang/lib/CIR/CodeGen/CIRGenModule.cpp | 2 +- clang/lib/CIR/CodeGen/CMakeLists.txt | 1 + 5 files changed, 121 insertions(+), 67 deletions(-) create mode 100644 clang/lib/CIR/CodeGen/CIRGenCUDARuntime.cpp diff --git a/clang/lib/CIR/CodeGen/CIRGenCUDANV.cpp b/clang/lib/CIR/CodeGen/CIRGenCUDANV.cpp index 71041f1493cc..e76f20026bf6 100644 --- a/clang/lib/CIR/CodeGen/CIRGenCUDANV.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenCUDANV.cpp @@ -1,4 +1,4 @@ -//===--- CIRGenCUDARuntime.cpp - Interface to CUDA Runtimes ----*- C++ -*--===// +//===- CIRGenCUDANV.cpp - Interface to NVIDIA CUDA Runtime -----===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -15,6 +15,7 @@ #include "CIRGenCUDARuntime.h" #include "CIRGenCXXABI.h" #include "CIRGenFunction.h" +#include "CIRGenModule.h" #include "mlir/IR/Operation.h" #include "clang/Basic/Cuda.h" #include "clang/CIR/Dialect/IR/CIRTypes.h" @@ -40,10 +41,57 @@ static std::unique_ptr initDeviceMC(CIRGenModule &cgm) { cgm.getASTContext().getAuxTargetInfo())); } -CIRGenCUDARuntime::~CIRGenCUDARuntime() {} +namespace { -CIRGenCUDARuntime::CIRGenCUDARuntime(CIRGenModule &cgm) - : cgm(cgm), deviceMC(initDeviceMC(cgm)) { +class CIRGenNVCUDARuntime : public CIRGenCUDARuntime { +protected: + StringRef Prefix; + + // Map a device stub function to a symbol for identifying kernel in host + // code. For CUDA, the symbol for identifying the kernel is the same as the + // device stub function. For HIP, they are different. + llvm::DenseMap KernelHandles; + + // Map a kernel handle to the kernel stub. + llvm::DenseMap KernelStubs; + + // Mangle context for device. + std::unique_ptr deviceMC; + +private: + void emitDeviceStubBodyLegacy(CIRGenFunction &cgf, cir::FuncOp fn, + FunctionArgList &args); + void emitDeviceStubBodyNew(CIRGenFunction &cgf, cir::FuncOp fn, + FunctionArgList &args); + std::string addPrefixToName(StringRef FuncName) const; + std::string addUnderscoredPrefixToName(StringRef FuncName) const; + +public: + CIRGenNVCUDARuntime(CIRGenModule &cgm); + ~CIRGenNVCUDARuntime(); + + void emitDeviceStub(CIRGenFunction &cgf, cir::FuncOp fn, + FunctionArgList &args) override; + + mlir::Operation *getKernelHandle(cir::FuncOp fn, GlobalDecl GD) override; + + void internalizeDeviceSideVar(const VarDecl *d, + cir::GlobalLinkageKind &linkage) override; + /// Returns function or variable name on device side even if the current + /// compilation is for host. + std::string getDeviceSideName(const NamedDecl *nd) override; +}; + +} // namespace + +CIRGenCUDARuntime *clang::CIRGen::CreateNVCUDARuntime(CIRGenModule &cgm) { + return new CIRGenNVCUDARuntime(cgm); +} + +CIRGenNVCUDARuntime::~CIRGenNVCUDARuntime() {} + +CIRGenNVCUDARuntime::CIRGenNVCUDARuntime(CIRGenModule &cgm) + : CIRGenCUDARuntime(cgm), deviceMC(initDeviceMC(cgm)) { if (cgm.getLangOpts().OffloadViaLLVM) llvm_unreachable("NYI"); else if (cgm.getLangOpts().HIP) @@ -52,23 +100,23 @@ CIRGenCUDARuntime::CIRGenCUDARuntime(CIRGenModule &cgm) Prefix = "cuda"; } -std::string CIRGenCUDARuntime::addPrefixToName(StringRef FuncName) const { +std::string CIRGenNVCUDARuntime::addPrefixToName(StringRef FuncName) const { return (Prefix + FuncName).str(); } std::string -CIRGenCUDARuntime::addUnderscoredPrefixToName(StringRef FuncName) const { +CIRGenNVCUDARuntime::addUnderscoredPrefixToName(StringRef FuncName) const { return ("__" + Prefix + FuncName).str(); } -void CIRGenCUDARuntime::emitDeviceStubBodyLegacy(CIRGenFunction &cgf, - cir::FuncOp fn, - FunctionArgList &args) { +void CIRGenNVCUDARuntime::emitDeviceStubBodyLegacy(CIRGenFunction &cgf, + cir::FuncOp fn, + FunctionArgList &args) { llvm_unreachable("NYI"); } -void CIRGenCUDARuntime::emitDeviceStubBodyNew(CIRGenFunction &cgf, - cir::FuncOp fn, - FunctionArgList &args) { +void CIRGenNVCUDARuntime::emitDeviceStubBodyNew(CIRGenFunction &cgf, + cir::FuncOp fn, + FunctionArgList &args) { // This requires arguments to be sent to kernels in a different way. if (cgm.getLangOpts().OffloadViaLLVM) @@ -212,8 +260,8 @@ void CIRGenCUDARuntime::emitDeviceStubBodyNew(CIRGenFunction &cgf, launchArgs); } -void CIRGenCUDARuntime::emitDeviceStub(CIRGenFunction &cgf, cir::FuncOp fn, - FunctionArgList &args) { +void CIRGenNVCUDARuntime::emitDeviceStub(CIRGenFunction &cgf, cir::FuncOp fn, + FunctionArgList &args) { if (auto globalOp = llvm::dyn_cast(KernelHandles[fn.getSymName()])) { auto symbol = mlir::FlatSymbolRefAttr::get(fn.getSymNameAttr()); @@ -230,31 +278,8 @@ void CIRGenCUDARuntime::emitDeviceStub(CIRGenFunction &cgf, cir::FuncOp fn, emitDeviceStubBodyLegacy(cgf, fn, args); } -RValue CIRGenCUDARuntime::emitCUDAKernelCallExpr(CIRGenFunction &cgf, - const CUDAKernelCallExpr *expr, - ReturnValueSlot retValue) { - auto builder = cgm.getBuilder(); - mlir::Location loc = - cgf.currSrcLoc ? cgf.currSrcLoc.value() : builder.getUnknownLoc(); - - cgf.emitIfOnBoolExpr( - expr->getConfig(), - [&](mlir::OpBuilder &b, mlir::Location l) { - b.create(loc); - }, - loc, - [&](mlir::OpBuilder &b, mlir::Location l) { - CIRGenCallee callee = cgf.emitCallee(expr->getCallee()); - cgf.emitCall(expr->getCallee()->getType(), callee, expr, retValue); - b.create(loc); - }, - loc); - - return RValue::get(nullptr); -} - -mlir::Operation *CIRGenCUDARuntime::getKernelHandle(cir::FuncOp fn, - GlobalDecl GD) { +mlir::Operation *CIRGenNVCUDARuntime::getKernelHandle(cir::FuncOp fn, + GlobalDecl GD) { // Check if we already have a kernel handle for this function auto Loc = KernelHandles.find(fn.getSymName()); @@ -307,7 +332,7 @@ mlir::Operation *CIRGenCUDARuntime::getKernelHandle(cir::FuncOp fn, return globalOp; } -std::string CIRGenCUDARuntime::getDeviceSideName(const NamedDecl *nd) { +std::string CIRGenNVCUDARuntime::getDeviceSideName(const NamedDecl *nd) { GlobalDecl gd; // nd could be either a kernel or a variable. if (auto *fd = dyn_cast(nd)) @@ -340,7 +365,7 @@ std::string CIRGenCUDARuntime::getDeviceSideName(const NamedDecl *nd) { return deviceSideName; } -void CIRGenCUDARuntime::internalizeDeviceSideVar( +void CIRGenNVCUDARuntime::internalizeDeviceSideVar( const VarDecl *d, cir::GlobalLinkageKind &linkage) { if (cgm.getLangOpts().GPURelocatableDeviceCode) llvm_unreachable("NYI"); diff --git a/clang/lib/CIR/CodeGen/CIRGenCUDARuntime.cpp b/clang/lib/CIR/CodeGen/CIRGenCUDARuntime.cpp new file mode 100644 index 000000000000..a558672879c5 --- /dev/null +++ b/clang/lib/CIR/CodeGen/CIRGenCUDARuntime.cpp @@ -0,0 +1,46 @@ +//===----- CIRGenCUDARuntime.cpp - Interface to CUDA Runtimes -------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This provides an abstract class for CUDA CIR generation. Concrete +// subclasses of this implement code generation for specific CUDA +// runtime libraries. +// +//===----------------------------------------------------------------------===// + +#include "CIRGenCUDARuntime.h" +#include "CIRGenFunction.h" +#include "clang/AST/ExprCXX.h" + +using namespace clang; +using namespace CIRGen; + +CIRGenCUDARuntime::~CIRGenCUDARuntime() {} + +RValue +CIRGenCUDARuntime::emitCUDAKernelCallExpr(CIRGenFunction &cgf, + const CUDAKernelCallExpr *expr, + ReturnValueSlot retValue) { + auto builder = cgm.getBuilder(); + mlir::Location loc = + cgf.currSrcLoc ? cgf.currSrcLoc.value() : builder.getUnknownLoc(); + + cgf.emitIfOnBoolExpr( + expr->getConfig(), + [&](mlir::OpBuilder &b, mlir::Location l) { + b.create(loc); + }, + loc, + [&](mlir::OpBuilder &b, mlir::Location l) { + CIRGenCallee callee = cgf.emitCallee(expr->getCallee()); + cgf.emitCall(expr->getCallee()->getType(), callee, expr, retValue); + b.create(loc); + }, + loc); + + return RValue::get(nullptr); +} diff --git a/clang/lib/CIR/CodeGen/CIRGenCUDARuntime.h b/clang/lib/CIR/CodeGen/CIRGenCUDARuntime.h index 84edcb6b7a3e..0aaecab03dc3 100644 --- a/clang/lib/CIR/CodeGen/CIRGenCUDARuntime.h +++ b/clang/lib/CIR/CodeGen/CIRGenCUDARuntime.h @@ -29,45 +29,27 @@ class ReturnValueSlot; class CIRGenCUDARuntime { protected: CIRGenModule &cgm; - StringRef Prefix; - - // Map a device stub function to a symbol for identifying kernel in host code. - // For CUDA, the symbol for identifying the kernel is the same as the device - // stub function. For HIP, they are different. - llvm::DenseMap KernelHandles; - - // Map a kernel handle to the kernel stub. - llvm::DenseMap KernelStubs; - -private: - void emitDeviceStubBodyLegacy(CIRGenFunction &cgf, cir::FuncOp fn, - FunctionArgList &args); - void emitDeviceStubBodyNew(CIRGenFunction &cgf, cir::FuncOp fn, - FunctionArgList &args); - std::string addPrefixToName(StringRef FuncName) const; - std::string addUnderscoredPrefixToName(StringRef FuncName) const; - - // Mangle context for device. - std::unique_ptr deviceMC; public: - CIRGenCUDARuntime(CIRGenModule &cgm); + CIRGenCUDARuntime(CIRGenModule &cgm) : cgm(cgm) {} virtual ~CIRGenCUDARuntime(); virtual void emitDeviceStub(CIRGenFunction &cgf, cir::FuncOp fn, - FunctionArgList &args); + FunctionArgList &args) = 0; virtual RValue emitCUDAKernelCallExpr(CIRGenFunction &cgf, const CUDAKernelCallExpr *expr, ReturnValueSlot retValue); - virtual mlir::Operation *getKernelHandle(cir::FuncOp fn, GlobalDecl GD); + virtual mlir::Operation *getKernelHandle(cir::FuncOp fn, GlobalDecl GD) = 0; virtual void internalizeDeviceSideVar(const VarDecl *d, - cir::GlobalLinkageKind &linkage); + cir::GlobalLinkageKind &linkage) = 0; /// Returns function or variable name on device side even if the current /// compilation is for host. - virtual std::string getDeviceSideName(const NamedDecl *nd); + virtual std::string getDeviceSideName(const NamedDecl *nd) = 0; }; +CIRGenCUDARuntime *CreateNVCUDARuntime(CIRGenModule &cgm); + } // namespace clang::CIRGen #endif // LLVM_CLANG_LIB_CIR_CIRGENCUDARUNTIME_H diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp index 90c632ec7066..70a75cea4044 100644 --- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp @@ -111,7 +111,7 @@ CIRGenModule::CIRGenModule(mlir::MLIRContext &mlirContext, target(astContext.getTargetInfo()), ABI(createCXXABI(*this)), genTypes{*this}, VTables{*this}, openMPRuntime(new CIRGenOpenMPRuntime(*this)), - cudaRuntime(new CIRGenCUDARuntime(*this)) { + cudaRuntime(clang::CIRGen::CreateNVCUDARuntime(*this)) { unsigned charSize = astContext.getTargetInfo().getCharWidth(); unsigned intSize = astContext.getTargetInfo().getIntWidth(); diff --git a/clang/lib/CIR/CodeGen/CMakeLists.txt b/clang/lib/CIR/CodeGen/CMakeLists.txt index 7c13e38e354b..096222e3f730 100644 --- a/clang/lib/CIR/CodeGen/CMakeLists.txt +++ b/clang/lib/CIR/CodeGen/CMakeLists.txt @@ -20,6 +20,7 @@ add_clang_library(clangCIR CIRGenClass.cpp CIRGenCleanup.cpp CIRGenCoroutine.cpp + CIRGenCUDANV.cpp CIRGenCUDARuntime.cpp CIRGenDecl.cpp CIRGenDeclCXX.cpp From c4e2c0af43dc43829af0d68ab2f95abb393bbced Mon Sep 17 00:00:00 2001 From: seven-mile Date: Wed, 26 Mar 2025 02:21:53 +0800 Subject: [PATCH 3/3] fix format --- clang/lib/CIR/CodeGen/CIRGenCUDARuntime.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/clang/lib/CIR/CodeGen/CIRGenCUDARuntime.cpp b/clang/lib/CIR/CodeGen/CIRGenCUDARuntime.cpp index a558672879c5..5ec8d86ab6c2 100644 --- a/clang/lib/CIR/CodeGen/CIRGenCUDARuntime.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenCUDARuntime.cpp @@ -21,10 +21,9 @@ using namespace CIRGen; CIRGenCUDARuntime::~CIRGenCUDARuntime() {} -RValue -CIRGenCUDARuntime::emitCUDAKernelCallExpr(CIRGenFunction &cgf, - const CUDAKernelCallExpr *expr, - ReturnValueSlot retValue) { +RValue CIRGenCUDARuntime::emitCUDAKernelCallExpr(CIRGenFunction &cgf, + const CUDAKernelCallExpr *expr, + ReturnValueSlot retValue) { auto builder = cgm.getBuilder(); mlir::Location loc = cgf.currSrcLoc ? cgf.currSrcLoc.value() : builder.getUnknownLoc();