summaryrefslogtreecommitdiff
path: root/clang/lib/CodeGen/CGHLSLRuntime.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CodeGen/CGHLSLRuntime.cpp')
-rw-r--r--clang/lib/CodeGen/CGHLSLRuntime.cpp115
1 files changed, 48 insertions, 67 deletions
diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp b/clang/lib/CodeGen/CGHLSLRuntime.cpp
index cf018c8c7de2..ecab9336a9f8 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.cpp
+++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp
@@ -21,6 +21,7 @@
#include "clang/AST/ASTContext.h"
#include "clang/AST/Attrs.inc"
#include "clang/AST/Decl.h"
+#include "clang/AST/HLSLResource.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/Type.h"
#include "clang/Basic/TargetOptions.h"
@@ -131,43 +132,42 @@ static CXXMethodDecl *lookupMethod(CXXRecordDecl *Record, StringRef Name,
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");
+ llvm::Value *Index, StringRef Name, ResourceBindingAttrs &Binding,
+ CallArgList &Args) {
+ assert(Binding.hasBinding() && "at least one binding attribute expected");
ASTContext &AST = CGM.getContext();
- std::optional<uint32_t> RegisterSlot;
- uint32_t SpaceNo = 0;
- if (VkBinding) {
- RegisterSlot = VkBinding->getBinding();
- SpaceNo = VkBinding->getSet();
- } else {
- if (RBA->hasRegisterSlot())
- RegisterSlot = RBA->getSlotNumber();
- SpaceNo = RBA->getSpaceNumber();
- }
-
CXXMethodDecl *CreateMethod = nullptr;
Value *NameStr = buildNameForResource(Name, CGM);
- Value *Space = llvm::ConstantInt::get(CGM.IntTy, SpaceNo);
+ Value *Space = llvm::ConstantInt::get(CGM.IntTy, Binding.getSpace());
- if (RegisterSlot.has_value()) {
+ if (Binding.isExplicit()) {
// explicit binding
- auto *RegSlot = llvm::ConstantInt::get(CGM.IntTy, RegisterSlot.value());
+ auto *RegSlot = llvm::ConstantInt::get(CGM.IntTy, Binding.getSlot());
Args.add(RValue::get(RegSlot), AST.UnsignedIntTy);
- CreateMethod = lookupMethod(ResourceDecl, "__createFromBinding", SC_Static);
+ const char *Name = Binding.hasCounterImplicitOrderID()
+ ? "__createFromBindingWithImplicitCounter"
+ : "__createFromBinding";
+ CreateMethod = lookupMethod(ResourceDecl, Name, SC_Static);
} else {
// implicit binding
auto *OrderID =
- llvm::ConstantInt::get(CGM.IntTy, RBA->getImplicitBindingOrderID());
+ llvm::ConstantInt::get(CGM.IntTy, Binding.getImplicitOrderID());
Args.add(RValue::get(OrderID), AST.UnsignedIntTy);
- CreateMethod =
- lookupMethod(ResourceDecl, "__createFromImplicitBinding", SC_Static);
+ const char *Name = Binding.hasCounterImplicitOrderID()
+ ? "__createFromImplicitBindingWithImplicitCounter"
+ : "__createFromImplicitBinding";
+ CreateMethod = lookupMethod(ResourceDecl, Name, 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()));
+ if (Binding.hasCounterImplicitOrderID()) {
+ uint32_t CounterBinding = Binding.getCounterImplicitOrderID();
+ auto *CounterOrderID = llvm::ConstantInt::get(CGM.IntTy, CounterBinding);
+ Args.add(RValue::get(CounterOrderID), AST.UnsignedIntTy);
+ }
return CreateMethod;
}
@@ -194,8 +194,8 @@ 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) {
+ ResourceBindingAttrs &Binding, ArrayRef<llvm::Value *> PrevGEPIndices,
+ SourceLocation ArraySubsExprLoc) {
ASTContext &AST = CGF.getContext();
llvm::IntegerType *IntTy = CGF.CGM.IntTy;
@@ -220,7 +220,7 @@ static std::optional<llvm::Value *> initializeLocalResourceArray(
}
std::optional<llvm::Value *> MaybeIndex = initializeLocalResourceArray(
CGF, ResourceDecl, SubArrayTy, ValueSlot, Range, Index, ResourceName,
- RBA, VkBinding, GEPIndices, ArraySubsExprLoc);
+ Binding, GEPIndices, ArraySubsExprLoc);
if (!MaybeIndex)
return std::nullopt;
Index = *MaybeIndex;
@@ -244,8 +244,7 @@ static std::optional<llvm::Value *> initializeLocalResourceArray(
CallArgList Args;
CXXMethodDecl *CreateMethod = lookupResourceInitMethodAndSetupArgs(
- CGF.CGM, ResourceDecl, Range, Index, ResourceName, RBA, VkBinding,
- Args);
+ CGF.CGM, ResourceDecl, Range, Index, ResourceName, Binding, Args);
if (!CreateMethod)
// This can happen if someone creates an array of structs that looks like
@@ -439,14 +438,7 @@ void CGHLSLRuntime::addBuffer(const HLSLBufferDecl *BufDecl) {
emitBufferGlobalsAndMetadata(BufDecl, BufGV);
// Initialize cbuffer from binding (implicit or explicit)
- if (HLSLVkBindingAttr *VkBinding = BufDecl->getAttr<HLSLVkBindingAttr>()) {
- initializeBufferFromBinding(BufDecl, BufGV, VkBinding);
- } else {
- HLSLResourceBindingAttr *RBA = BufDecl->getAttr<HLSLResourceBindingAttr>();
- assert(RBA &&
- "cbuffer/tbuffer should always have resource binding attribute");
- initializeBufferFromBinding(BufDecl, BufGV, RBA);
- }
+ initializeBufferFromBinding(BufDecl, BufGV);
}
void CGHLSLRuntime::addRootSignature(
@@ -527,6 +519,10 @@ void clang::CodeGen::CGHLSLRuntime::setHLSLEntryAttributes(
if (CGM.getCodeGenOpts().OptimizationLevel == 0)
Fn->addFnAttr(llvm::Attribute::OptimizeNone);
Fn->addFnAttr(llvm::Attribute::NoInline);
+
+ if (CGM.getLangOpts().HLSLSpvEnableMaximalReconvergence) {
+ Fn->addFnAttr("enable-maximal-reconvergence", "true");
+ }
}
static Value *buildVectorInput(IRBuilder<> &B, Function *F, llvm::Type *Ty) {
@@ -810,44 +806,29 @@ static void initializeBuffer(CodeGenModule &CGM, llvm::GlobalVariable *GV,
}
void CGHLSLRuntime::initializeBufferFromBinding(const HLSLBufferDecl *BufDecl,
- llvm::GlobalVariable *GV,
- HLSLVkBindingAttr *VkBinding) {
- assert(VkBinding && "expect a nonnull binding attribute");
- auto *Index = llvm::ConstantInt::get(CGM.IntTy, 0);
- auto *RangeSize = llvm::ConstantInt::get(CGM.IntTy, 1);
- auto *Set = llvm::ConstantInt::get(CGM.IntTy, VkBinding->getSet());
- auto *Binding = llvm::ConstantInt::get(CGM.IntTy, VkBinding->getBinding());
- Value *Name = buildNameForResource(BufDecl->getName(), CGM);
- llvm::Intrinsic::ID IntrinsicID =
- CGM.getHLSLRuntime().getCreateHandleFromBindingIntrinsic();
+ llvm::GlobalVariable *GV) {
+ ResourceBindingAttrs Binding(BufDecl);
+ assert(Binding.hasBinding() &&
+ "cbuffer/tbuffer should always have resource binding attribute");
- SmallVector<Value *> Args{Set, Binding, RangeSize, Index, Name};
- initializeBuffer(CGM, GV, IntrinsicID, Args);
-}
-
-void CGHLSLRuntime::initializeBufferFromBinding(const HLSLBufferDecl *BufDecl,
- llvm::GlobalVariable *GV,
- HLSLResourceBindingAttr *RBA) {
- assert(RBA && "expect a nonnull binding attribute");
auto *Index = llvm::ConstantInt::get(CGM.IntTy, 0);
auto *RangeSize = llvm::ConstantInt::get(CGM.IntTy, 1);
- auto *Space = llvm::ConstantInt::get(CGM.IntTy, RBA->getSpaceNumber());
+ auto *Space = llvm::ConstantInt::get(CGM.IntTy, Binding.getSpace());
Value *Name = buildNameForResource(BufDecl->getName(), CGM);
- llvm::Intrinsic::ID IntrinsicID =
- RBA->hasRegisterSlot()
- ? CGM.getHLSLRuntime().getCreateHandleFromBindingIntrinsic()
- : CGM.getHLSLRuntime().getCreateHandleFromImplicitBindingIntrinsic();
-
// buffer with explicit binding
- if (RBA->hasRegisterSlot()) {
- auto *RegSlot = llvm::ConstantInt::get(CGM.IntTy, RBA->getSlotNumber());
+ if (Binding.isExplicit()) {
+ llvm::Intrinsic::ID IntrinsicID =
+ CGM.getHLSLRuntime().getCreateHandleFromBindingIntrinsic();
+ auto *RegSlot = llvm::ConstantInt::get(CGM.IntTy, Binding.getSlot());
SmallVector<Value *> Args{Space, RegSlot, RangeSize, Index, Name};
initializeBuffer(CGM, GV, IntrinsicID, Args);
} else {
// buffer with implicit binding
+ llvm::Intrinsic::ID IntrinsicID =
+ CGM.getHLSLRuntime().getCreateHandleFromImplicitBindingIntrinsic();
auto *OrderID =
- llvm::ConstantInt::get(CGM.IntTy, RBA->getImplicitBindingOrderID());
+ llvm::ConstantInt::get(CGM.IntTy, Binding.getImplicitOrderID());
SmallVector<Value *> Args{OrderID, Space, RangeSize, Index, Name};
initializeBuffer(CGM, GV, IntrinsicID, Args);
}
@@ -960,9 +941,9 @@ std::optional<LValue> CGHLSLRuntime::emitResourceArraySubscriptExpr(
// Find binding info for the resource array. For implicit binding
// an HLSLResourceBindingAttr should have been added by SemaHLSL.
- HLSLVkBindingAttr *VkBinding = ArrayDecl->getAttr<HLSLVkBindingAttr>();
- HLSLResourceBindingAttr *RBA = ArrayDecl->getAttr<HLSLResourceBindingAttr>();
- assert((VkBinding || RBA) && "resource array must have a binding attribute");
+ ResourceBindingAttrs Binding(ArrayDecl);
+ assert((Binding.hasBinding()) &&
+ "resource array must have a binding attribute");
// Find the individual resource type.
QualType ResultTy = ArraySubsExpr->getType();
@@ -992,7 +973,7 @@ std::optional<LValue> CGHLSLRuntime::emitResourceArraySubscriptExpr(
CallArgList Args;
CXXMethodDecl *CreateMethod = lookupResourceInitMethodAndSetupArgs(
CGF.CGM, ResourceTy->getAsCXXRecordDecl(), Range, Index,
- ArrayDecl->getName(), RBA, VkBinding, Args);
+ ArrayDecl->getName(), Binding, Args);
if (!CreateMethod)
// This can happen if someone creates an array of structs that looks like
@@ -1009,8 +990,8 @@ std::optional<LValue> CGHLSLRuntime::emitResourceArraySubscriptExpr(
cast<ConstantArrayType>(ResultTy.getTypePtr());
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());
+ ArrayDecl->getName(), Binding, {llvm::ConstantInt::get(CGM.IntTy, 0)},
+ ArraySubsExpr->getExprLoc());
if (!EndIndex)
return std::nullopt;
}