-
Notifications
You must be signed in to change notification settings - Fork 13.3k
[HLSL] Resource initialization by constructors #135120
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
- add resource record constructor with explicit binding - completes implementation of default resource constructor - removes resource initialization for Codegen for resource records - cbuffer still needs to be initialized in Codegen because it does not have a resource class type
✅ With the latest revision this PR passed the C/C++ code formatter. |
@llvm/pr-subscribers-clang-codegen @llvm/pr-subscribers-clang Author: Helena Kotas (hekota) Changes
Design proposal: llvm/wg-hlsl#197 Closes #134154 Patch is 75.97 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/135120.diff 22 Files Affected:
diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td
index 868e5b92acdc9..5e92715f59e57 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4789,6 +4789,18 @@ def HLSLResourceGetPointer : LangBuiltin<"HLSL_LANG"> {
let Prototype = "void(...)";
}
+def HLSLResourceCreatePoisonHandle : LangBuiltin<"HLSL_LANG"> {
+ let Spellings = ["__builtin_hlsl_resource_createpoisonhandle"];
+ let Attributes = [NoThrow];
+ let Prototype = "void(...)";
+}
+
+def HLSLResourceCreateHandleFromBinding : LangBuiltin<"HLSL_LANG"> {
+ let Spellings = ["__builtin_hlsl_resource_createhandlefrombinding"];
+ let Attributes = [NoThrow];
+ let Prototype = "void(...)";
+}
+
def HLSLAll : LangBuiltin<"HLSL_LANG"> {
let Spellings = ["__builtin_hlsl_all"];
let Attributes = [NoThrow, Const];
diff --git a/clang/include/clang/Sema/SemaHLSL.h b/clang/include/clang/Sema/SemaHLSL.h
index f333fe30e8da0..a913d6cce62bd 100644
--- a/clang/include/clang/Sema/SemaHLSL.h
+++ b/clang/include/clang/Sema/SemaHLSL.h
@@ -105,6 +105,7 @@ class SemaHLSL : public SemaBase {
HLSLParamModifierAttr::Spelling Spelling);
void ActOnTopLevelFunction(FunctionDecl *FD);
void ActOnVariableDeclarator(VarDecl *VD);
+ bool ActOnUninitializedVarDecl(VarDecl *D);
void ActOnEndOfTranslationUnit(TranslationUnitDecl *TU);
void CheckEntryPoint(FunctionDecl *FD);
void CheckSemanticAnnotation(FunctionDecl *EntryPoint, const Decl *Param,
diff --git a/clang/lib/CodeGen/CGHLSLBuiltins.cpp b/clang/lib/CodeGen/CGHLSLBuiltins.cpp
index 99c62808c323d..dfcade7a074ca 100644
--- a/clang/lib/CodeGen/CGHLSLBuiltins.cpp
+++ b/clang/lib/CodeGen/CGHLSLBuiltins.cpp
@@ -287,6 +287,24 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
RetTy, CGM.getHLSLRuntime().getCreateResourceGetPointerIntrinsic(),
ArrayRef<Value *>{HandleOp, IndexOp});
}
+ case Builtin::BI__builtin_hlsl_resource_createpoisonhandle: {
+ llvm::Type *HandleTy = CGM.getTypes().ConvertType(E->getType());
+ return llvm::PoisonValue::get(HandleTy);
+ }
+ case Builtin::BI__builtin_hlsl_resource_createhandlefrombinding: {
+ llvm::Type *HandleTy = CGM.getTypes().ConvertType(E->getType());
+ Value *RegisterNoOp = EmitScalarExpr(E->getArg(1));
+ Value *SpaceNoOp = EmitScalarExpr(E->getArg(2));
+ Value *RangeOp = EmitScalarExpr(E->getArg(3));
+ Value *IndexOp = EmitScalarExpr(E->getArg(4));
+ // FIXME: NonUniformResourceIndex bit is not yet implemented
+ Value *NonUniform =
+ llvm::ConstantInt::get(llvm::Type::getInt1Ty(getLLVMContext()), false);
+ return Builder.CreateIntrinsic(
+ HandleTy, CGM.getHLSLRuntime().getCreateHandleFromBindingIntrinsic(),
+ ArrayRef<Value *>{SpaceNoOp, RegisterNoOp, RangeOp, IndexOp,
+ NonUniform});
+ }
case Builtin::BI__builtin_hlsl_all: {
Value *Op0 = EmitScalarExpr(E->getArg(0));
return Builder.CreateIntrinsic(
diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp b/clang/lib/CodeGen/CGHLSLRuntime.cpp
index 3b1810b62a2cd..450213fcec676 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 *
@@ -494,15 +495,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 =
@@ -511,28 +512,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);
@@ -543,24 +528,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) {
diff --git a/clang/lib/CodeGen/CGHLSLRuntime.h b/clang/lib/CodeGen/CGHLSLRuntime.h
index 68151c0f0ea24..4d6db3f5d9f3e 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.h
+++ b/clang/lib/CodeGen/CGHLSLRuntime.h
@@ -150,7 +150,6 @@ class CGHLSLRuntime {
void emitEntryFunction(const FunctionDecl *FD, llvm::Function *Fn);
void setHLSLFunctionAttributes(const FunctionDecl *FD, llvm::Function *Fn);
- void handleGlobalVarDefinition(const VarDecl *VD, llvm::GlobalVariable *Var);
llvm::Instruction *getConvergenceToken(llvm::BasicBlock &BB);
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 8f9cf965af2b9..395b5c3ecc695 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -5698,9 +5698,6 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D,
getCUDARuntime().handleVarRegistration(D, *GV);
}
- if (LangOpts.HLSL)
- getHLSLRuntime().handleGlobalVarDefinition(D, GV);
-
GV->setInitializer(Init);
if (emitter)
emitter->finalize(GV);
diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
index 2d3e1088557ab..a680d6efcd67d 100644
--- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
+++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
@@ -400,6 +400,7 @@ void BuiltinTypeMethodBuilder::createDecl() {
// create params & set them to the function prototype
SmallVector<ParmVarDecl *> ParmDecls;
+ unsigned CurScopeDepth = DeclBuilder.SemaRef.getCurScope()->getDepth();
auto FnProtoLoc =
Method->getTypeSourceInfo()->getTypeLoc().getAs<FunctionProtoTypeLoc>();
for (int I = 0, E = Params.size(); I != E; I++) {
@@ -414,6 +415,7 @@ void BuiltinTypeMethodBuilder::createDecl() {
HLSLParamModifierAttr::Create(AST, SourceRange(), MP.Modifier);
Parm->addAttr(Mod);
}
+ Parm->setScopeInfo(CurScopeDepth, I);
ParmDecls.push_back(Parm);
FnProtoLoc.setParam(I, Parm);
}
@@ -447,10 +449,14 @@ BuiltinTypeMethodBuilder::callBuiltin(StringRef BuiltinName,
AST, NestedNameSpecifierLoc(), SourceLocation(), FD, false,
FD->getNameInfo(), AST.BuiltinFnTy, VK_PRValue);
+ auto *ImpCast = ImplicitCastExpr::Create(
+ AST, AST.getPointerType(FD->getType()), CK_BuiltinFnToFnPtr, DRE, nullptr,
+ VK_PRValue, FPOptionsOverride());
+
if (ReturnType.isNull())
ReturnType = FD->getReturnType();
- Expr *Call = CallExpr::Create(AST, DRE, Args, ReturnType, VK_PRValue,
+ Expr *Call = CallExpr::Create(AST, ImpCast, Args, ReturnType, VK_PRValue,
SourceLocation(), FPOptionsOverride());
StmtsList.push_back(Call);
return *this;
@@ -632,11 +638,33 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addDefaultHandleConstructor() {
if (Record->isCompleteDefinition())
return *this;
- // FIXME: initialize handle to poison value; this can be added after
- // resource constructor from binding is implemented, otherwise the handle
- // value will get overwritten.
+ using PH = BuiltinTypeMethodBuilder::PlaceHolder;
+ QualType HandleType = getResourceHandleField()->getType();
return BuiltinTypeMethodBuilder(*this, "", SemaRef.getASTContext().VoidTy,
false, true)
+ .callBuiltin("__builtin_hlsl_resource_createpoisonhandle", HandleType,
+ PH::Handle)
+ .assign(PH::Handle, PH::LastStmt)
+ .finalize();
+}
+
+BuiltinTypeDeclBuilder &
+BuiltinTypeDeclBuilder::addHandleConstructorFromBinding() {
+ if (Record->isCompleteDefinition())
+ return *this;
+
+ using PH = BuiltinTypeMethodBuilder::PlaceHolder;
+ ASTContext &AST = SemaRef.getASTContext();
+ QualType HandleType = getResourceHandleField()->getType();
+
+ return BuiltinTypeMethodBuilder(*this, "", AST.VoidTy, false, true)
+ .addParam("registerNo", AST.UnsignedIntTy)
+ .addParam("spaceNo", AST.UnsignedIntTy)
+ .addParam("range", AST.IntTy)
+ .addParam("index", AST.UnsignedIntTy)
+ .callBuiltin("__builtin_hlsl_resource_createhandlefrombinding",
+ HandleType, PH::Handle, PH::_0, PH::_1, PH::_2, PH::_3)
+ .assign(PH::Handle, PH::LastStmt)
.finalize();
}
diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h
index dbf54dfd9ecd9..db617dc53c899 100644
--- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h
+++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h
@@ -78,6 +78,7 @@ class BuiltinTypeDeclBuilder {
// Builtin types methods
BuiltinTypeDeclBuilder &addDefaultHandleConstructor();
+ BuiltinTypeDeclBuilder &addHandleConstructorFromBinding();
// Builtin types methods
BuiltinTypeDeclBuilder &addLoadMethods();
diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp
index f5477ac912693..f09232a9db4da 100644
--- a/clang/lib/Sema/HLSLExternalSemaSource.cpp
+++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp
@@ -131,7 +131,8 @@ static BuiltinTypeDeclBuilder setupBufferType(CXXRecordDecl *Decl, Sema &S,
bool RawBuffer) {
return BuiltinTypeDeclBuilder(S, Decl)
.addHandleMember(RC, IsROV, RawBuffer)
- .addDefaultHandleConstructor();
+ .addDefaultHandleConstructor()
+ .addHandleConstructorFromBinding();
}
// This function is responsible for constructing the constraint expression for
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 540f5f23fe89a..22699644c0a1a 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -14345,10 +14345,8 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl) {
Var->getType().getAddressSpace() == LangAS::opencl_local)
return;
- // In HLSL, objects in the hlsl_constant address space are initialized
- // externally, so don't synthesize an implicit initializer.
- if (getLangOpts().HLSL &&
- Var->getType().getAddressSpace() == LangAS::hlsl_constant)
+ // Handle HLSL uninitialized decls
+ if (getLangOpts().HLSL && HLSL().ActOnUninitializedVarDecl(Var))
return;
// C++03 [dcl.init]p9:
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index fe600386e6fa9..27959f61f1dc3 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -32,6 +32,7 @@
#include "clang/Sema/ParsedAttr.h"
#include "clang/Sema/Sema.h"
#include "clang/Sema/Template.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
@@ -305,6 +306,10 @@ static bool isResourceRecordTypeOrArrayOf(const Type *Ty) {
return HLSLAttributedResourceType::findHandleTypeOnResource(Ty) != nullptr;
}
+static bool isResourceRecordTypeOrArrayOf(VarDecl *VD) {
+ return isResourceRecordTypeOrArrayOf(VD->getType().getTypePtr());
+}
+
// Returns true if the type is a leaf element type that is not valid to be
// included in HLSL Buffer, such as a resource class, empty struct, zero-sized
// array, or a builtin intangible type. Returns false it is a valid leaf element
@@ -2385,6 +2390,29 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
break;
}
+ case Builtin::BI__builtin_hlsl_resource_createpoisonhandle: {
+ if (SemaRef.checkArgCount(TheCall, 1) ||
+ CheckResourceHandle(&SemaRef, TheCall, 0))
+ return true;
+ // use the type of the handle (arg0) as a return type
+ QualType ResourceTy = TheCall->getArg(0)->getType();
+ TheCall->setType(ResourceTy);
+ break;
+ }
+ case Builtin::BI__builtin_hlsl_resource_createhandlefrombinding: {
+ ASTContext &AST = SemaRef.getASTContext();
+ if (SemaRef.checkArgCount(TheCall, 5) ||
+ CheckResourceHandle(&SemaRef, TheCall, 0) ||
+ CheckArgTypeMatches(&SemaRef, TheCall->getArg(1), AST.UnsignedIntTy) ||
+ CheckArgTypeMatches(&SemaRef, TheCall->getArg(2), AST.UnsignedIntTy) ||
+ CheckArgTypeMatches(&SemaRef, TheCall->getArg(3), AST.IntTy) ||
+ CheckArgTypeMatches(&SemaRef, TheCall->getArg(4), AST.UnsignedIntTy))
+ return true;
+ // use the type of the handle (arg0) as a return type
+ QualType ResourceTy = TheCall->getArg(0)->getType();
+ TheCall->setType(ResourceTy);
+ break;
+ }
case Builtin::BI__builtin_hlsl_and:
case Builtin::BI__builtin_hlsl_or: {
if (SemaRef.checkArgCount(TheCall, 2))
@@ -3179,6 +3207,67 @@ void SemaHLSL::ActOnVariableDeclarator(VarDecl *VD) {
}
}
+static bool initVarDeclWithCtor(Sema &S, VarDecl *VD,
+ MutableArrayRef<Expr *> Args) {
+ InitializedEntity Entity = InitializedEntity::InitializeVariable(VD);
+ InitializationKind Kind = InitializationKind::CreateDirect(
+ VD->getLocation(), SourceLocation(), SourceLocation());
+
+ InitializationSequence InitSeq(S, Entity, Kind, Args);
+ ExprResult Init = InitSeq.Perform(S, Entity, Kind, Args);
+
+ if (!Init.get())
+ return false;
+
+ VD->setInit(S.MaybeCreateExprWithCleanups(Init.get()));
+ VD->setInitStyle(VarDecl::CallInit);
+ S.CheckCompleteVariableDeclaration(VD);
+ return true;
+}
+
+static bool initGlobalResourceDecl(Sema &S, VarDecl *VD) {
+ HLSLResourceBindingAttr *RBA = VD->getAttr<HLSLResourceBindingAttr>();
+ if (!RBA)
+ // FIXME: add support for implicit binding (llvm/llvm-project#110722)
+ return false;
+
+ ASTContext &AST = S.getASTContext();
+ uint64_t UIntTySize = AST.getTypeSize(AST.UnsignedIntTy);
+ uint64_t IntTySize = AST.getTypeSize(AST.IntTy);
+ Expr *Args[] = {
+ IntegerLiteral::Create(AST, llvm::APInt(UIntTySize, RBA->getSlotNumber()),
+ AST.UnsignedIntTy, SourceLocation()),
+ IntegerLiteral::Create(AST,
+ llvm::APInt(UIntTySize, RBA->getSpaceNumber()),
+ AST.UnsignedIntTy, SourceLocation()),
+ IntegerLiteral::Create(AST, llvm::APInt(IntTySize, 1), AST.IntTy,
+ SourceLocation()),
+ IntegerLiteral::Create(AST, llvm::APInt(UIntTySize, 0), AST.UnsignedIntTy,
+ SourceLocation())};
+
+ return initVarDeclWithCtor(S, VD, Args);
+}
+
+// Returns true in the initialization has been handled;
+// Return false to let Clang handle the default initializaton.
+bool SemaHLSL::ActOnUninitializedVarDecl(VarDecl *VD) {
+ // Objects in the hlsl_constant address space are initialized
+ // externally, so don't synthesize an implicit initializer.
+ if (VD->getType().getAddressSpace() == LangAS::hlsl_constant)
+ return true;
+
+ // Initialize resources
+ if (!isResourceRecordTypeOrArrayOf(VD))
+ return false;
+
+ // FIXME: We currectly support only simple resources - no arrays of resources
+ // or resources in user defined structs).
+ if (VD->getType()->isHLSLResourceRecord())
+ return initGlobalResourceDecl(SemaRef, VD);
+
+ return false;
+}
+
// Walks though the global variable declaration, collects all resource binding
// requirements and adds them to Bindings
void SemaHLSL::collectResourceBindingsOnVarDecl(VarDecl *VD) {
diff --git a/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl b/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl
index 38e5b6281c42e..c8b584171f007 100644
--- a/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl
+++ b/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl
@@ -42,5 +42,41 @@ RESOURCE Buffer;
// CHECK-SAME{LITERAL}: [[hlsl::raw_buffer]]
// CHECK-SAME{LITERAL}: [[hlsl::contained_type(char8_t)]]
+// Default constructor
+
+// CHECK: CXXConstructorDecl {{.*}} [[RESOURCE]] 'void ()' inline
+// CHECK-...
[truncated]
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM but I don't have enough domain knowledge to approve
// Buf1 initialization part 1 - global init function that calls ByteAddressBuffer C1 constructor with explicit binding | ||
// CHECK: define internal void @__cxx_global_var_init() | ||
// CHECK-NEXT: entry: | ||
// CHECK-NEXT: call void @_ZN4hlsl17ByteAddressBufferC1Ejjij(ptr noundef nonnull align 4 dereferenceable(4) @_ZL4Buf1, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we rely on consistent name mangling? I've been encouraging the new folks to regex out the mangled bit but maybe that isn't necessary?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, the Itanium ABI name mangling is a standard and it should be stable.
poison
.cbuffer
still needs to happen inCGHLSLRuntime
because it does not have a corresponding resource class type.ImplicitCastExpr
for builtin function calls. Sema adds these automatically when a method of a template class is instantiated, but some resource classes likeByteAddressBuffer
are not templates so they need to have this added explicitly.Design proposal: llvm/wg-hlsl#197
Closes #134154