diff options
author | Helena Kotas <hekotas@microsoft.com> | 2025-04-29 18:42:22 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-04-29 18:42:22 -0700 |
commit | f1750300aad0e49383cd4b206e2354f1300a40a8 (patch) | |
tree | e6443b8ca2289d7bada44ad1804823c95e672303 /clang/lib/CodeGen/CGHLSLRuntime.cpp | |
parent | 6bb4ce0f6ff462b58bacc8dbc47719b7009f9b18 (diff) | |
download | llvm-f1750300aad0e49383cd4b206e2354f1300a40a8.zip llvm-f1750300aad0e49383cd4b206e2354f1300a40a8.tar.gz llvm-f1750300aad0e49383cd4b206e2354f1300a40a8.tar.bz2 |
[HLSL] Resource initialization by constructors (#135120)
- Adds resource constructor that takes explicit binding for all resource
classes.
- Updates implementation of default resource constructor to initialize
resource handle to `poison`.
- Removes initialization of resource classes from Codegen.
- Initialization of `cbuffer` still needs to happen in `CGHLSLRuntime`
because it does not have a corresponding resource class type.
- Adds `ImplicitCastExpr` for builtin function calls. Sema adds these
automatically when a method of a template class is instantiated, but
some resource classes like `ByteAddressBuffer` are not templates so they
need to have this added explicitly.
Design proposal: llvm/wg-hlsl#197
Closes #134154
Diffstat (limited to 'clang/lib/CodeGen/CGHLSLRuntime.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGHLSLRuntime.cpp | 75 |
1 files changed, 28 insertions, 47 deletions
diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp b/clang/lib/CodeGen/CGHLSLRuntime.cpp index a756c3f..b787595 100644 --- a/clang/lib/CodeGen/CGHLSLRuntime.cpp +++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp @@ -41,8 +41,9 @@ using namespace llvm; using llvm::hlsl::CBufferRowSizeInBytes; -static void createResourceInitFn(CodeGenModule &CGM, llvm::GlobalVariable *GV, - unsigned Slot, unsigned Space); +static void initializeBufferFromBinding(CodeGenModule &CGM, + llvm::GlobalVariable *GV, unsigned Slot, + unsigned Space); namespace { @@ -255,14 +256,14 @@ void CGHLSLRuntime::addBuffer(const HLSLBufferDecl *BufDecl) { // Add globals for constant buffer elements and create metadata nodes emitBufferGlobalsAndMetadata(BufDecl, BufGV); - // Resource initialization + // Initialize cbuffer from binding (implicit or explicit) const HLSLResourceBindingAttr *RBA = BufDecl->getAttr<HLSLResourceBindingAttr>(); // FIXME: handle implicit binding if no binding attribute is found // (llvm/llvm-project#110722) if (RBA) - createResourceInitFn(CGM, BufGV, RBA->getSlotNumber(), - RBA->getSpaceNumber()); + initializeBufferFromBinding(CGM, BufGV, RBA->getSlotNumber(), + RBA->getSpaceNumber()); } llvm::TargetExtType * @@ -505,15 +506,15 @@ void CGHLSLRuntime::generateGlobalCtorDtorCalls() { } } -static void createResourceInitFn(CodeGenModule &CGM, llvm::GlobalVariable *GV, - unsigned Slot, unsigned Space) { - LLVMContext &Ctx = CGM.getLLVMContext(); - llvm::Type *Int1Ty = llvm::Type::getInt1Ty(Ctx); +static void initializeBuffer(CodeGenModule &CGM, llvm::GlobalVariable *GV, + Intrinsic::ID IntrID, + ArrayRef<llvm::Value *> Args) { + LLVMContext &Ctx = CGM.getLLVMContext(); llvm::Function *InitResFunc = llvm::Function::Create( llvm::FunctionType::get(CGM.VoidTy, false), llvm::GlobalValue::InternalLinkage, - ("_init_resource_" + GV->getName()).str(), CGM.getModule()); + ("_init_buffer_" + GV->getName()).str(), CGM.getModule()); InitResFunc->addFnAttr(llvm::Attribute::AlwaysInline); llvm::BasicBlock *EntryBB = @@ -522,28 +523,12 @@ static void createResourceInitFn(CodeGenModule &CGM, llvm::GlobalVariable *GV, const DataLayout &DL = CGM.getModule().getDataLayout(); Builder.SetInsertPoint(EntryBB); - // Make sure the global variable is resource handle (cbuffer) or - // resource class (=class where the first element is a resource handle). + // Make sure the global variable is buffer resource handle llvm::Type *HandleTy = GV->getValueType(); - assert((HandleTy->isTargetExtTy() || - (HandleTy->isStructTy() && - HandleTy->getStructElementType(0)->isTargetExtTy())) && - "unexpected type of the global"); - if (!HandleTy->isTargetExtTy()) - HandleTy = HandleTy->getStructElementType(0); + assert(HandleTy->isTargetExtTy() && "unexpected type of the buffer global"); - llvm::Value *Args[] = { - llvm::ConstantInt::get(CGM.IntTy, Space), /* reg_space */ - llvm::ConstantInt::get(CGM.IntTy, Slot), /* lower_bound */ - // FIXME: resource arrays are not yet implemented - llvm::ConstantInt::get(CGM.IntTy, 1), /* range_size */ - llvm::ConstantInt::get(CGM.IntTy, 0), /* index */ - // FIXME: NonUniformResourceIndex bit is not yet implemented - llvm::ConstantInt::get(Int1Ty, false) /* non-uniform */ - }; llvm::Value *CreateHandle = Builder.CreateIntrinsic( - /*ReturnType=*/HandleTy, - CGM.getHLSLRuntime().getCreateHandleFromBindingIntrinsic(), Args, nullptr, + /*ReturnType=*/HandleTy, IntrID, Args, nullptr, Twine(GV->getName()).concat("_h")); llvm::Value *HandleRef = Builder.CreateStructGEP(GV->getValueType(), GV, 0); @@ -554,24 +539,20 @@ static void createResourceInitFn(CodeGenModule &CGM, llvm::GlobalVariable *GV, CGM.AddCXXGlobalInit(InitResFunc); } -void CGHLSLRuntime::handleGlobalVarDefinition(const VarDecl *VD, - llvm::GlobalVariable *GV) { - - // If the global variable has resource binding, create an init function - // for the resource - const HLSLResourceBindingAttr *RBA = VD->getAttr<HLSLResourceBindingAttr>(); - if (!RBA) - // FIXME: collect unbound resources for implicit binding resolution later - // on? - return; - - if (!VD->getType().getTypePtr()->isHLSLResourceRecord()) - // FIXME: Only simple declarations of resources are supported for now. - // Arrays of resources or resources in user defined classes are - // not implemented yet. - return; - - createResourceInitFn(CGM, GV, RBA->getSlotNumber(), RBA->getSpaceNumber()); +static void initializeBufferFromBinding(CodeGenModule &CGM, + llvm::GlobalVariable *GV, unsigned Slot, + unsigned Space) { + llvm::Type *Int1Ty = llvm::Type::getInt1Ty(CGM.getLLVMContext()); + llvm::Value *Args[] = { + llvm::ConstantInt::get(CGM.IntTy, Space), /* reg_space */ + llvm::ConstantInt::get(CGM.IntTy, Slot), /* lower_bound */ + llvm::ConstantInt::get(CGM.IntTy, 1), /* range_size */ + llvm::ConstantInt::get(CGM.IntTy, 0), /* index */ + llvm::ConstantInt::get(Int1Ty, false) /* non-uniform */ + }; + initializeBuffer(CGM, GV, + CGM.getHLSLRuntime().getCreateHandleFromBindingIntrinsic(), + Args); } llvm::Instruction *CGHLSLRuntime::getConvergenceToken(BasicBlock &BB) { |