-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[HLSL] Use static create methods to initialize resources in arrays #157005
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
[HLSL] Use static create methods to initialize resources in arrays #157005
Conversation
Reorder the arguments of handle initialization builtins to match the order of the llvm intrinsics, and also to match the arguments on the static create methods for resources (coming soon).
…or from handle Adds static methods `__createFromBinding` and `__createFromImplicitBinding` to resource classes. These methods will be used for resource initialization instead of the resource constructors that take binding information. Also adds a private resource constructor that takes an initialized resource handle. This constructor will be called from the static create methods.
…create-0-reorder-builtin-args
…' of https://github.com/llvm/llvm-project into res-create-1-add-methods
…create-1-add-methods
…s-create-2-use-methods-single-res
Use static methods __createFromBinding and __createFromImplicitBinding to initialize resources in resource arrays. Depends on llvm#156544 Part 3 of llvm#154221
…create-1-add-methods
…s://github.com/llvm/llvm-project into res-create-2-use-methods-single-res
…es' of https://github.com/llvm/llvm-project into res-create-3-use-methods-res-arrays
@llvm/pr-subscribers-hlsl @llvm/pr-subscribers-clang-codegen Author: Helena Kotas (hekota) ChangesUse static methods __createFromBinding and __createFromImplicitBinding to initialize resources in resource arrays. Depends on #156544 Part 3 of #154221 Patch is 51.42 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/157005.diff 9 Files Affected:
diff --git a/clang/include/clang/Sema/SemaHLSL.h b/clang/include/clang/Sema/SemaHLSL.h
index 5cbe1b658f5cd..86265a51fb252 100644
--- a/clang/include/clang/Sema/SemaHLSL.h
+++ b/clang/include/clang/Sema/SemaHLSL.h
@@ -241,11 +241,6 @@ class SemaHLSL : public SemaBase {
bool initGlobalResourceDecl(VarDecl *VD);
bool initGlobalResourceArrayDecl(VarDecl *VD);
- void createResourceRecordCtorArgs(const Type *ResourceTy, StringRef VarName,
- HLSLResourceBindingAttr *RBA,
- HLSLVkBindingAttr *VkBinding,
- uint32_t ArrayIndex,
- llvm::SmallVectorImpl<Expr *> &Args);
};
} // namespace clang
diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp b/clang/lib/CodeGen/CGHLSLRuntime.cpp
index d27f3781c69a3..fa365f419cdb1 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.cpp
+++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp
@@ -13,6 +13,7 @@
//===----------------------------------------------------------------------===//
#include "CGHLSLRuntime.h"
+#include "Address.h"
#include "CGDebugInfo.h"
#include "CodeGenFunction.h"
#include "CodeGenModule.h"
@@ -38,6 +39,7 @@
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormatVariadic.h"
#include <cstdint>
+#include <optional>
using namespace clang;
using namespace CodeGen;
@@ -148,14 +150,22 @@ static Value *buildNameForResource(llvm::StringRef BaseName,
.getPointer();
}
-static void createResourceCtorArgs(CodeGenModule &CGM, CXXConstructorDecl *CD,
- llvm::Value *ThisPtr, llvm::Value *Range,
- llvm::Value *Index, StringRef Name,
- HLSLResourceBindingAttr *RBA,
- HLSLVkBindingAttr *VkBinding,
- CallArgList &Args) {
+static CXXMethodDecl *lookupMethod(CXXRecordDecl *Record, StringRef Name,
+ StorageClass SC = SC_None) {
+ for (auto *Method : Record->methods()) {
+ if (Method->getStorageClass() == SC && Method->getName() == Name)
+ return Method;
+ }
+ return nullptr;
+}
+
+static CXXMethodDecl *lookupResourceInitMethodAndSetupArgs(
+ CodeGenModule &CGM, CXXRecordDecl *ResourceDecl, llvm::Value *Range,
+ llvm::Value *Index, StringRef Name, HLSLResourceBindingAttr *RBA,
+ HLSLVkBindingAttr *VkBinding, CallArgList &Args) {
assert((VkBinding || RBA) && "at least one a binding attribute expected");
+ ASTContext &AST = CGM.getContext();
std::optional<uint32_t> RegisterSlot;
uint32_t SpaceNo = 0;
if (VkBinding) {
@@ -167,44 +177,57 @@ static void createResourceCtorArgs(CodeGenModule &CGM, CXXConstructorDecl *CD,
SpaceNo = RBA->getSpaceNumber();
}
- ASTContext &AST = CD->getASTContext();
+ CXXMethodDecl *CreateMethod = nullptr;
Value *NameStr = buildNameForResource(Name, CGM);
Value *Space = llvm::ConstantInt::get(CGM.IntTy, SpaceNo);
- Args.add(RValue::get(ThisPtr), CD->getThisType());
if (RegisterSlot.has_value()) {
// explicit binding
auto *RegSlot = llvm::ConstantInt::get(CGM.IntTy, RegisterSlot.value());
Args.add(RValue::get(RegSlot), AST.UnsignedIntTy);
- Args.add(RValue::get(Space), AST.UnsignedIntTy);
- Args.add(RValue::get(Range), AST.IntTy);
- Args.add(RValue::get(Index), AST.UnsignedIntTy);
-
+ CreateMethod = lookupMethod(ResourceDecl, "__createFromBinding", SC_Static);
} else {
// implicit binding
- assert(RBA && "missing implicit binding attribute");
auto *OrderID =
llvm::ConstantInt::get(CGM.IntTy, RBA->getImplicitBindingOrderID());
- Args.add(RValue::get(Space), AST.UnsignedIntTy);
- Args.add(RValue::get(Range), AST.IntTy);
- Args.add(RValue::get(Index), AST.UnsignedIntTy);
Args.add(RValue::get(OrderID), AST.UnsignedIntTy);
+ CreateMethod =
+ lookupMethod(ResourceDecl, "__createFromImplicitBinding", SC_Static);
}
+ Args.add(RValue::get(Space), AST.UnsignedIntTy);
+ Args.add(RValue::get(Range), AST.IntTy);
+ Args.add(RValue::get(Index), AST.UnsignedIntTy);
Args.add(RValue::get(NameStr), AST.getPointerType(AST.CharTy.withConst()));
+
+ return CreateMethod;
+}
+
+static void callResourceInitMethod(CodeGenFunction &CGF,
+ CXXMethodDecl *CreateMethod,
+ CallArgList &Args, Address ReturnAddress) {
+ llvm::Constant *CalleeFn = CGF.CGM.GetAddrOfFunction(CreateMethod);
+ const FunctionProtoType *Proto =
+ CreateMethod->getType()->getAs<FunctionProtoType>();
+ const CGFunctionInfo &FnInfo =
+ CGF.CGM.getTypes().arrangeFreeFunctionCall(Args, Proto, false);
+ ReturnValueSlot ReturnValue(ReturnAddress, false);
+ CGCallee Callee(CGCalleeInfo(Proto), CalleeFn);
+ CGF.EmitCall(FnInfo, Callee, ReturnValue, Args, nullptr);
}
// Initializes local resource array variable. For multi-dimensional arrays it
// calls itself recursively to initialize its sub-arrays. The Index used in the
// resource constructor calls will begin at StartIndex and will be incremented
// for each array element. The last used resource Index is returned to the
-// caller.
-static Value *initializeLocalResourceArray(
- CodeGenFunction &CGF, AggValueSlot &ValueSlot,
- const ConstantArrayType *ArrayTy, CXXConstructorDecl *CD,
+// caller. If the function returns std::nullopt, it indicates an error.
+static std::optional<llvm::Value *> initializeLocalResourceArray(
+ CodeGenFunction &CGF, CXXRecordDecl *ResourceDecl,
+ const ConstantArrayType *ArrayTy, AggValueSlot &ValueSlot,
llvm::Value *Range, llvm::Value *StartIndex, StringRef ResourceName,
HLSLResourceBindingAttr *RBA, HLSLVkBindingAttr *VkBinding,
ArrayRef<llvm::Value *> PrevGEPIndices, SourceLocation ArraySubsExprLoc) {
+ ASTContext &AST = CGF.getContext();
llvm::IntegerType *IntTy = CGF.CGM.IntTy;
llvm::Value *Index = StartIndex;
llvm::Value *One = llvm::ConstantInt::get(IntTy, 1);
@@ -225,16 +248,19 @@ static Value *initializeLocalResourceArray(
Index = CGF.Builder.CreateAdd(Index, One);
GEPIndices.back() = llvm::ConstantInt::get(IntTy, I);
}
- Index = initializeLocalResourceArray(
- CGF, ValueSlot, SubArrayTy, CD, Range, Index, ResourceName, RBA,
- VkBinding, GEPIndices, ArraySubsExprLoc);
+ std::optional<llvm::Value *> MaybeIndex = initializeLocalResourceArray(
+ CGF, ResourceDecl, SubArrayTy, ValueSlot, Range, Index, ResourceName,
+ RBA, VkBinding, GEPIndices, ArraySubsExprLoc);
+ if (!MaybeIndex)
+ return std::nullopt;
+ Index = *MaybeIndex;
}
return Index;
}
// For array of resources, initialize each resource in the array.
llvm::Type *Ty = CGF.ConvertTypeForMem(ElemType);
- CharUnits ElemSize = CD->getASTContext().getTypeSizeInChars(ElemType);
+ CharUnits ElemSize = AST.getTypeSizeInChars(ElemType);
CharUnits Align =
TmpArrayAddr.getAlignment().alignmentOfArrayElement(ElemSize);
@@ -243,16 +269,18 @@ static Value *initializeLocalResourceArray(
Index = CGF.Builder.CreateAdd(Index, One);
GEPIndices.back() = llvm::ConstantInt::get(IntTy, I);
}
- Address ThisAddress =
+ Address ReturnAddress =
CGF.Builder.CreateGEP(TmpArrayAddr, GEPIndices, Ty, Align);
- llvm::Value *ThisPtr = CGF.getAsNaturalPointerTo(ThisAddress, ElemType);
CallArgList Args;
- createResourceCtorArgs(CGF.CGM, CD, ThisPtr, Range, Index, ResourceName,
- RBA, VkBinding, Args);
- CGF.EmitCXXConstructorCall(CD, Ctor_Complete, false, false, ThisAddress,
- Args, ValueSlot.mayOverlap(), ArraySubsExprLoc,
- ValueSlot.isSanitizerChecked());
+ CXXMethodDecl *CreateMethod = lookupResourceInitMethodAndSetupArgs(
+ CGF.CGM, ResourceDecl, Range, Index, ResourceName, RBA, VkBinding,
+ Args);
+
+ if (!CreateMethod)
+ return std::nullopt;
+
+ callResourceInitMethod(CGF, CreateMethod, Args, ReturnAddress);
}
return Index;
}
@@ -906,11 +934,6 @@ std::optional<LValue> CGHLSLRuntime::emitResourceArraySubscriptExpr(
QualType ResourceTy =
ResultTy->isArrayType() ? AST.getBaseElementType(ResultTy) : ResultTy;
- // Lookup the resource class constructor based on the resource type and
- // binding.
- CXXConstructorDecl *CD = findResourceConstructorDecl(
- AST, ResourceTy, VkBinding || RBA->hasRegisterSlot());
-
// Create a temporary variable for the result, which is either going
// to be a single resource instance or a local array of resources (we need to
// return an LValue).
@@ -923,7 +946,6 @@ std::optional<LValue> CGHLSLRuntime::emitResourceArraySubscriptExpr(
TmpVar, Qualifiers(), AggValueSlot::IsDestructed_t(true),
AggValueSlot::DoesNotNeedGCBarriers, AggValueSlot::IsAliased_t(false),
AggValueSlot::DoesNotOverlap);
- Address TmpVarAddress = ValueSlot.getAddress();
// Calculate total array size (= range size).
llvm::Value *Range =
@@ -932,27 +954,27 @@ std::optional<LValue> CGHLSLRuntime::emitResourceArraySubscriptExpr(
// If the result of the subscript operation is a single resource, call the
// constructor.
if (ResultTy == ResourceTy) {
- QualType ThisType = CD->getThisType()->getPointeeType();
- llvm::Value *ThisPtr = CGF.getAsNaturalPointerTo(TmpVarAddress, ThisType);
-
- // Assemble the constructor parameters.
CallArgList Args;
- createResourceCtorArgs(CGM, CD, ThisPtr, Range, Index, ArrayDecl->getName(),
- RBA, VkBinding, Args);
- // Call the constructor.
- CGF.EmitCXXConstructorCall(CD, Ctor_Complete, false, false, TmpVarAddress,
- Args, ValueSlot.mayOverlap(),
- ArraySubsExpr->getExprLoc(),
- ValueSlot.isSanitizerChecked());
+ CXXMethodDecl *CreateMethod = lookupResourceInitMethodAndSetupArgs(
+ CGF.CGM, ResourceTy->getAsCXXRecordDecl(), Range, Index,
+ ArrayDecl->getName(), RBA, VkBinding, Args);
+
+ if (!CreateMethod)
+ return std::nullopt;
+
+ callResourceInitMethod(CGF, CreateMethod, Args, ValueSlot.getAddress());
+
} else {
// The result of the subscript operation is a local resource array which
// needs to be initialized.
const ConstantArrayType *ArrayTy =
cast<ConstantArrayType>(ResultTy.getTypePtr());
- initializeLocalResourceArray(CGF, ValueSlot, ArrayTy, CD, Range, Index,
- ArrayDecl->getName(), RBA, VkBinding,
- {llvm::ConstantInt::get(CGM.IntTy, 0)},
- ArraySubsExpr->getExprLoc());
+ std::optional<llvm::Value *> EndIndex = initializeLocalResourceArray(
+ CGF, ResourceTy->getAsCXXRecordDecl(), ArrayTy, ValueSlot, Range, Index,
+ ArrayDecl->getName(), RBA, VkBinding,
+ {llvm::ConstantInt::get(CGM.IntTy, 0)}, ArraySubsExpr->getExprLoc());
+ if (!EndIndex)
+ return std::nullopt;
}
return CGF.MakeAddrLValue(TmpVar, ResultTy, AlignmentSource::Decl);
}
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index 775098d06b18c..4e3bccf86ee9c 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -3696,55 +3696,6 @@ void SemaHLSL::ActOnVariableDeclarator(VarDecl *VD) {
deduceAddressSpace(VD);
}
-void SemaHLSL::createResourceRecordCtorArgs(
- const Type *ResourceTy, StringRef VarName, HLSLResourceBindingAttr *RBA,
- HLSLVkBindingAttr *VkBinding, uint32_t ArrayIndex,
- llvm::SmallVectorImpl<Expr *> &Args) {
- std::optional<uint32_t> RegisterSlot;
- uint32_t SpaceNo = 0;
- if (VkBinding) {
- RegisterSlot = VkBinding->getBinding();
- SpaceNo = VkBinding->getSet();
- } else if (RBA) {
- if (RBA->hasRegisterSlot())
- RegisterSlot = RBA->getSlotNumber();
- SpaceNo = RBA->getSpaceNumber();
- }
-
- ASTContext &AST = SemaRef.getASTContext();
- uint64_t UIntTySize = AST.getTypeSize(AST.UnsignedIntTy);
- uint64_t IntTySize = AST.getTypeSize(AST.IntTy);
- IntegerLiteral *RangeSize = IntegerLiteral::Create(
- AST, llvm::APInt(IntTySize, 1), AST.IntTy, SourceLocation());
- IntegerLiteral *Index =
- IntegerLiteral::Create(AST, llvm::APInt(UIntTySize, ArrayIndex),
- AST.UnsignedIntTy, SourceLocation());
- IntegerLiteral *Space =
- IntegerLiteral::Create(AST, llvm::APInt(UIntTySize, SpaceNo),
- AST.UnsignedIntTy, SourceLocation());
- StringLiteral *Name = StringLiteral::Create(
- AST, VarName, StringLiteralKind::Ordinary, false,
- AST.getStringLiteralArrayType(AST.CharTy.withConst(), VarName.size()),
- SourceLocation());
-
- // resource with explicit binding
- if (RegisterSlot.has_value()) {
- IntegerLiteral *RegSlot = IntegerLiteral::Create(
- AST, llvm::APInt(UIntTySize, RegisterSlot.value()), AST.UnsignedIntTy,
- SourceLocation());
- Args.append({RegSlot, Space, RangeSize, Index, Name});
- } else {
- // resource with implicit binding
- uint32_t OrderID = (RBA && RBA->hasImplicitBindingOrderID())
- ? RBA->getImplicitBindingOrderID()
- : getNextImplicitBindingOrderID();
- IntegerLiteral *OrderId =
- IntegerLiteral::Create(AST, llvm::APInt(UIntTySize, OrderID),
- AST.UnsignedIntTy, SourceLocation());
- Args.append({Space, RangeSize, Index, OrderId, Name});
- }
-}
-
bool SemaHLSL::initGlobalResourceDecl(VarDecl *VD) {
assert(VD->getType()->isHLSLResourceRecord() &&
"expected resource record type");
@@ -3849,28 +3800,37 @@ bool SemaHLSL::initGlobalResourceArrayDecl(VarDecl *VD) {
// Individual resources in a resource array are not initialized here. They
// are initialized later on during codegen when the individual resources are
- // accessed. Codegen will emit a call to the resource constructor with the
- // specified array index. We need to make sure though that the constructor
+ // accessed. Codegen will emit a call to the resource initialization method
+ // with the specified array index. We need to make sure though that the method
// for the specific resource type is instantiated, so codegen can emit a call
// to it when the array element is accessed.
- SmallVector<Expr *> Args;
- QualType ResElementTy = VD->getASTContext().getBaseElementType(VD->getType());
- createResourceRecordCtorArgs(ResElementTy.getTypePtr(), VD->getName(),
- VD->getAttr<HLSLResourceBindingAttr>(),
- VD->getAttr<HLSLVkBindingAttr>(), 0, Args);
- SourceLocation Loc = VD->getLocation();
- InitializedEntity Entity =
- InitializedEntity::InitializeTemporary(ResElementTy);
- InitializationKind Kind = InitializationKind::CreateDirect(Loc, Loc, Loc);
- InitializationSequence InitSeq(SemaRef, Entity, Kind, Args);
- if (InitSeq.Failed())
+ // Find correct initialization method based on the resource binding
+ // information.
+ ASTContext &AST = SemaRef.getASTContext();
+ QualType ResElementTy = AST.getBaseElementType(VD->getType());
+ CXXRecordDecl *ResourceDecl = ResElementTy->getAsCXXRecordDecl();
+
+ HLSLResourceBindingAttr *RBA = VD->getAttr<HLSLResourceBindingAttr>();
+ HLSLVkBindingAttr *VkBinding = VD->getAttr<HLSLVkBindingAttr>();
+ CXXMethodDecl *CreateMethod = nullptr;
+
+ if (VkBinding || (RBA && RBA->hasRegisterSlot()))
+ // Resource has explicit binding.
+ CreateMethod = lookupMethod(ResourceDecl, "__createFromBinding", SC_Static);
+ else
+ // Resource has implicit binding.
+ CreateMethod =
+ lookupMethod(ResourceDecl, "__createFromImplicitBinding", SC_Static);
+
+ if (!CreateMethod)
return false;
- // This takes care of instantiating and emitting of the constructor that will
- // be called from codegen when the array is accessed.
- ExprResult OneResInit = InitSeq.Perform(SemaRef, Entity, Kind, Args);
- return !OneResInit.isInvalid();
+ // Make sure the create method template is instantiated and emitted.
+ if (!CreateMethod->isDefined() && CreateMethod->isTemplateInstantiation())
+ SemaRef.InstantiateFunctionDefinition(VD->getLocation(), CreateMethod,
+ true);
+ return true;
}
// Returns true if the initialization has been handled.
diff --git a/clang/test/CodeGenHLSL/resources/res-array-global-dyn-index.hlsl b/clang/test/CodeGenHLSL/resources/res-array-global-dyn-index.hlsl
index bbd162e3aad20..f17cf12945e4a 100644
--- a/clang/test/CodeGenHLSL/resources/res-array-global-dyn-index.hlsl
+++ b/clang/test/CodeGenHLSL/resources/res-array-global-dyn-index.hlsl
@@ -1,17 +1,15 @@
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.6-compute -finclude-default-header \
-// RUN: -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s
+// RUN: -emit-llvm -disable-llvm-passes -o - %s | llvm-cxxfilt | FileCheck %s
// CHECK: @[[BufA:.*]] = private unnamed_addr constant [2 x i8] c"A\00", align 1
RWBuffer<float> A[4][3] : register(u2);
RWStructuredBuffer<float> Out;
-// Make sure A[GI.x][GI.y] is translated to a RWBuffer<float> constructor call with range 12 and dynamically calculated index
+// Make sure A[GI.x][GI.y] is translated to a RWBuffer<float>::__createFromBinding call
+// with range 12 and dynamically calculated index
-// NOTE:
-// Constructor call for explicit binding has "jjij" in the mangled name and the arguments are (register, space, range_size, index, name).
-
-// CHECK: define internal void @_Z4mainDv3_j(<3 x i32> noundef %GI)
+// CHECK: define internal void @main(unsigned int vector[3])(<3 x i32> noundef %GI)
// CHECK: %[[GI_alloca:.*]] = alloca <3 x i32>, align 16
// CHECK: %[[Tmp0:.*]] = alloca %"class.hlsl::RWBuffer
// CHECK: store <3 x i32> %GI, ptr %[[GI_alloca]]
@@ -22,7 +20,9 @@ RWStructuredBuffer<float> Out;
// CHECK: %[[GI_x:.*]] = extractelement <3 x i32> %[[GI]], i32 0
// CHECK: %[[Tmp1:.*]] = mul i32 %[[GI_x]], 3
// CHECK: %[[Index:.*]] = add i32 %[[GI_y]], %[[Tmp1]]
-// CHECK: call void @_ZN4hlsl8RWBufferIfEC1EjjijPKc(ptr {{.*}} %[[Tmp0]], i32 noundef 2, i32 noundef 0, i32 noundef 12, i32 noundef %[[Index]], ptr noundef @A.str)
+// CHECK: call void @hlsl::RWBuffer<float>::__createFromBinding(unsigned int, unsigned int, int, unsigned int, char const*)
+// CHECK-SAME: (ptr {{.*}} sret(%"class.hlsl::RWBuffer") align 4 %[[Tmp0]],
+// CHECK-SAME: i32 noundef 2, i32 noundef 0, i32 noundef 12, i32 noundef %[[Index]], ptr noundef @A.str)
[numthreads(4,1,1)]
void main(uint3 GI : SV_GroupThreadID) {
Out[0] = A[GI.x][GI.y][0];
diff --git a/clang/test/CodeGenHLSL/resources/res-array-global-multi-dim.hlsl b/clang/test/CodeGenHLSL/resources/res-array-global-multi-dim.hlsl
index 36871f9a63b3f..1a05897b9e70b 100644
--- a/clang/test/CodeGenHLSL/resources/res-array-global-multi-dim.hlsl
+++ b/clang/test/CodeGenHLSL/resources/res-array-global-multi-dim.hlsl
@@ -1,7 +1,7 @@
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.6-compute -finclude-default-header \
-// RUN: -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s
+// RUN: -emit-llvm -disable-llvm-passes -o - %s | llvm-cxxfilt | FileCheck %s
// RUN: %clang_cc1 -finclude-default-header -triple spirv-unknown-vulkan-compute \
-// RUN: -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s
+// RUN: -emit-llvm -disable-llvm-passes -o - %s | llvm-cxxfilt | FileCheck %s
// CHECK: @[[BufB:.*]] = private unnamed_addr constant [2 x i8] c"B\00", align 1
// CHECK: @[[BufC:.*]] = private unnamed_addr constant [2 x i8] c"C\00", align 1
@@ -17,30 +17,30 @@ RWStructuredBuffer<float> Out;
[numthreads(4,1,1)]
void main() {
- // CHECK: define internal{{.*}} void @_Z4mainv()
+ // CHECK: define internal{{.*}} void @main()
// CHECK: %[[Tmp0:.*]] = alloca %"class.hlsl::RWBuffer
// CHECK: %[[Tmp1:.*]] = alloca %"class.hlsl::RWBuffer
// CHECK: %[[Tmp2:.*]] = alloca %"class.hlsl::RWBuffer
// CHECK: %[[Tmp3:.*]] = alloca %"class.hlsl::RWBuffer
- // NOTE:
- // Constructor call for explicit binding has "jjij" in the mangled name and the arguments are (register, space, range_size, index, name).
- // For implicit binding the constructor has "ji...
[truncated]
|
…create-2-use-methods-single-res
…ctor for resource classes
…es' of https://github.com/llvm/llvm-project into res-create-3-use-methods-res-arrays
HLSLResourceBindingAttr *RBA, | ||
HLSLVkBindingAttr *VkBinding, | ||
CallArgList &Args) { | ||
static CXXMethodDecl *lookupMethod(CXXRecordDecl *Record, StringRef Name, |
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.
We should probably do this with Sema::LookupSingleName
.
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.
Unfortunately, this is in CodeGen and we do not have access to Sema anymore.
I can use Sema lookup in my previous PR though (#156544), so I will update it at least there.
Args); | ||
|
||
if (!CreateMethod) | ||
return std::nullopt; |
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.
Do we need to surface an error if this happens? Can this happen?
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.
This can happen when someone has an array of fake/custom(?) resource classes - array of structs with a __hlsl_resource_t member - and the struct does not have the create method.
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.
Chatted with @hekota offline. Seems like this happens for manually written structs containing handles, and the outcome here is that they just don't get bindings generated. I think not supporting automatically binding handles for people writing their own types against internal compiler details is completely reasonable.
ArrayDecl->getName(), RBA, VkBinding, Args); | ||
|
||
if (!CreateMethod) | ||
return std::nullopt; |
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.
Same as above, what happens if this happens?
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.
See above.
…create-3-use-methods-res-arrays
✅ With the latest revision this PR passed the C/C++ code formatter. |
Depends on llvm#157005 Part 4 of llvm#154221
Use static methods
__createFromBinding
and__createFromImplicitBinding
to initialize resources in resource arrays instead of calling resource constructors with binding information, per proposal update llvm/wg-hlsl#336.Test updates include the use of the
llvm-cxxfilt
tool which takes care of demangling of function names for a more readable test baseline.Depends on #156544
Part 3 of #154221