Skip to content

Commit 5d5a70b

Browse files
author
git apple-llvm automerger
committed
Merge commit 'b6dfa3d47db7' from llvm.org/main into next
2 parents f06adc4 + b6dfa3d commit 5d5a70b

File tree

4 files changed

+118
-89
lines changed

4 files changed

+118
-89
lines changed
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
//===- HLSLResource.h - Routines for HLSL resources and bindings ----------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This file provides shared routines to help analyze HLSL resources and
10+
// theirs bindings during Sema and CodeGen.
11+
//
12+
//===----------------------------------------------------------------------===//
13+
14+
#ifndef LLVM_CLANG_AST_HLSLRESOURCE_H
15+
#define LLVM_CLANG_AST_HLSLRESOURCE_H
16+
17+
#include "clang/AST/ASTContext.h"
18+
#include "clang/AST/Attrs.inc"
19+
#include "clang/AST/DeclBase.h"
20+
#include "clang/Basic/TargetInfo.h"
21+
22+
namespace clang {
23+
24+
class HLSLResourceBindingAttr;
25+
class HLSLRVkBindingAttr;
26+
27+
namespace hlsl {
28+
29+
struct ResourceBindingAttrs {
30+
HLSLResourceBindingAttr *RegBinding;
31+
HLSLVkBindingAttr *VkBinding;
32+
33+
ResourceBindingAttrs(const Decl *D) {
34+
RegBinding = D->getAttr<HLSLResourceBindingAttr>();
35+
bool IsSpirv = D->getASTContext().getTargetInfo().getTriple().isSPIRV();
36+
VkBinding = IsSpirv ? D->getAttr<HLSLVkBindingAttr>() : nullptr;
37+
}
38+
39+
bool hasBinding() const { return RegBinding || VkBinding; }
40+
bool isExplicit() const {
41+
return (RegBinding && RegBinding->hasRegisterSlot()) || VkBinding;
42+
}
43+
44+
unsigned getSlot() const {
45+
assert(isExplicit() && "no explicit binding");
46+
if (VkBinding)
47+
return VkBinding->getBinding();
48+
if (RegBinding && RegBinding->hasRegisterSlot())
49+
return RegBinding->getSlotNumber();
50+
llvm_unreachable("no explicit binding");
51+
}
52+
53+
unsigned getSpace() const {
54+
if (VkBinding)
55+
return VkBinding->getSet();
56+
if (RegBinding)
57+
return RegBinding->getSpaceNumber();
58+
return 0;
59+
}
60+
61+
bool hasImplicitOrderID() const {
62+
return RegBinding && RegBinding->hasImplicitBindingOrderID();
63+
}
64+
65+
unsigned getImplicitOrderID() const {
66+
assert(hasImplicitOrderID());
67+
return RegBinding->getImplicitBindingOrderID();
68+
}
69+
};
70+
71+
} // namespace hlsl
72+
73+
} // namespace clang
74+
75+
#endif // LLVM_CLANG_AST_HLSLRESOURCE_H

clang/lib/CodeGen/CGHLSLRuntime.cpp

Lines changed: 31 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "clang/AST/ASTContext.h"
2222
#include "clang/AST/Attrs.inc"
2323
#include "clang/AST/Decl.h"
24+
#include "clang/AST/HLSLResource.h"
2425
#include "clang/AST/RecursiveASTVisitor.h"
2526
#include "clang/AST/Type.h"
2627
#include "clang/Basic/TargetOptions.h"
@@ -131,35 +132,24 @@ static CXXMethodDecl *lookupMethod(CXXRecordDecl *Record, StringRef Name,
131132

132133
static CXXMethodDecl *lookupResourceInitMethodAndSetupArgs(
133134
CodeGenModule &CGM, CXXRecordDecl *ResourceDecl, llvm::Value *Range,
134-
llvm::Value *Index, StringRef Name, HLSLResourceBindingAttr *RBA,
135-
HLSLVkBindingAttr *VkBinding, CallArgList &Args) {
136-
assert((VkBinding || RBA) && "at least one a binding attribute expected");
135+
llvm::Value *Index, StringRef Name, ResourceBindingAttrs &Binding,
136+
CallArgList &Args) {
137+
assert(Binding.hasBinding() && "at least one binding attribute expected");
137138

138139
ASTContext &AST = CGM.getContext();
139-
std::optional<uint32_t> RegisterSlot;
140-
uint32_t SpaceNo = 0;
141-
if (VkBinding) {
142-
RegisterSlot = VkBinding->getBinding();
143-
SpaceNo = VkBinding->getSet();
144-
} else {
145-
if (RBA->hasRegisterSlot())
146-
RegisterSlot = RBA->getSlotNumber();
147-
SpaceNo = RBA->getSpaceNumber();
148-
}
149-
150140
CXXMethodDecl *CreateMethod = nullptr;
151141
Value *NameStr = buildNameForResource(Name, CGM);
152-
Value *Space = llvm::ConstantInt::get(CGM.IntTy, SpaceNo);
142+
Value *Space = llvm::ConstantInt::get(CGM.IntTy, Binding.getSpace());
153143

154-
if (RegisterSlot.has_value()) {
144+
if (Binding.isExplicit()) {
155145
// explicit binding
156-
auto *RegSlot = llvm::ConstantInt::get(CGM.IntTy, RegisterSlot.value());
146+
auto *RegSlot = llvm::ConstantInt::get(CGM.IntTy, Binding.getSlot());
157147
Args.add(RValue::get(RegSlot), AST.UnsignedIntTy);
158148
CreateMethod = lookupMethod(ResourceDecl, "__createFromBinding", SC_Static);
159149
} else {
160150
// implicit binding
161151
auto *OrderID =
162-
llvm::ConstantInt::get(CGM.IntTy, RBA->getImplicitBindingOrderID());
152+
llvm::ConstantInt::get(CGM.IntTy, Binding.getImplicitOrderID());
163153
Args.add(RValue::get(OrderID), AST.UnsignedIntTy);
164154
CreateMethod =
165155
lookupMethod(ResourceDecl, "__createFromImplicitBinding", SC_Static);
@@ -194,8 +184,8 @@ static std::optional<llvm::Value *> initializeLocalResourceArray(
194184
CodeGenFunction &CGF, CXXRecordDecl *ResourceDecl,
195185
const ConstantArrayType *ArrayTy, AggValueSlot &ValueSlot,
196186
llvm::Value *Range, llvm::Value *StartIndex, StringRef ResourceName,
197-
HLSLResourceBindingAttr *RBA, HLSLVkBindingAttr *VkBinding,
198-
ArrayRef<llvm::Value *> PrevGEPIndices, SourceLocation ArraySubsExprLoc) {
187+
ResourceBindingAttrs &Binding, ArrayRef<llvm::Value *> PrevGEPIndices,
188+
SourceLocation ArraySubsExprLoc) {
199189

200190
ASTContext &AST = CGF.getContext();
201191
llvm::IntegerType *IntTy = CGF.CGM.IntTy;
@@ -220,7 +210,7 @@ static std::optional<llvm::Value *> initializeLocalResourceArray(
220210
}
221211
std::optional<llvm::Value *> MaybeIndex = initializeLocalResourceArray(
222212
CGF, ResourceDecl, SubArrayTy, ValueSlot, Range, Index, ResourceName,
223-
RBA, VkBinding, GEPIndices, ArraySubsExprLoc);
213+
Binding, GEPIndices, ArraySubsExprLoc);
224214
if (!MaybeIndex)
225215
return std::nullopt;
226216
Index = *MaybeIndex;
@@ -244,8 +234,7 @@ static std::optional<llvm::Value *> initializeLocalResourceArray(
244234

245235
CallArgList Args;
246236
CXXMethodDecl *CreateMethod = lookupResourceInitMethodAndSetupArgs(
247-
CGF.CGM, ResourceDecl, Range, Index, ResourceName, RBA, VkBinding,
248-
Args);
237+
CGF.CGM, ResourceDecl, Range, Index, ResourceName, Binding, Args);
249238

250239
if (!CreateMethod)
251240
// This can happen if someone creates an array of structs that looks like
@@ -439,14 +428,7 @@ void CGHLSLRuntime::addBuffer(const HLSLBufferDecl *BufDecl) {
439428
emitBufferGlobalsAndMetadata(BufDecl, BufGV);
440429

441430
// Initialize cbuffer from binding (implicit or explicit)
442-
if (HLSLVkBindingAttr *VkBinding = BufDecl->getAttr<HLSLVkBindingAttr>()) {
443-
initializeBufferFromBinding(BufDecl, BufGV, VkBinding);
444-
} else {
445-
HLSLResourceBindingAttr *RBA = BufDecl->getAttr<HLSLResourceBindingAttr>();
446-
assert(RBA &&
447-
"cbuffer/tbuffer should always have resource binding attribute");
448-
initializeBufferFromBinding(BufDecl, BufGV, RBA);
449-
}
431+
initializeBufferFromBinding(BufDecl, BufGV);
450432
}
451433

452434
void CGHLSLRuntime::addRootSignature(
@@ -810,44 +792,29 @@ static void initializeBuffer(CodeGenModule &CGM, llvm::GlobalVariable *GV,
810792
}
811793

812794
void CGHLSLRuntime::initializeBufferFromBinding(const HLSLBufferDecl *BufDecl,
813-
llvm::GlobalVariable *GV,
814-
HLSLVkBindingAttr *VkBinding) {
815-
assert(VkBinding && "expect a nonnull binding attribute");
816-
auto *Index = llvm::ConstantInt::get(CGM.IntTy, 0);
817-
auto *RangeSize = llvm::ConstantInt::get(CGM.IntTy, 1);
818-
auto *Set = llvm::ConstantInt::get(CGM.IntTy, VkBinding->getSet());
819-
auto *Binding = llvm::ConstantInt::get(CGM.IntTy, VkBinding->getBinding());
820-
Value *Name = buildNameForResource(BufDecl->getName(), CGM);
821-
llvm::Intrinsic::ID IntrinsicID =
822-
CGM.getHLSLRuntime().getCreateHandleFromBindingIntrinsic();
823-
824-
SmallVector<Value *> Args{Set, Binding, RangeSize, Index, Name};
825-
initializeBuffer(CGM, GV, IntrinsicID, Args);
826-
}
795+
llvm::GlobalVariable *GV) {
796+
ResourceBindingAttrs Binding(BufDecl);
797+
assert(Binding.hasBinding() &&
798+
"cbuffer/tbuffer should always have resource binding attribute");
827799

828-
void CGHLSLRuntime::initializeBufferFromBinding(const HLSLBufferDecl *BufDecl,
829-
llvm::GlobalVariable *GV,
830-
HLSLResourceBindingAttr *RBA) {
831-
assert(RBA && "expect a nonnull binding attribute");
832800
auto *Index = llvm::ConstantInt::get(CGM.IntTy, 0);
833801
auto *RangeSize = llvm::ConstantInt::get(CGM.IntTy, 1);
834-
auto *Space = llvm::ConstantInt::get(CGM.IntTy, RBA->getSpaceNumber());
802+
auto *Space = llvm::ConstantInt::get(CGM.IntTy, Binding.getSpace());
835803
Value *Name = buildNameForResource(BufDecl->getName(), CGM);
836804

837-
llvm::Intrinsic::ID IntrinsicID =
838-
RBA->hasRegisterSlot()
839-
? CGM.getHLSLRuntime().getCreateHandleFromBindingIntrinsic()
840-
: CGM.getHLSLRuntime().getCreateHandleFromImplicitBindingIntrinsic();
841-
842805
// buffer with explicit binding
843-
if (RBA->hasRegisterSlot()) {
844-
auto *RegSlot = llvm::ConstantInt::get(CGM.IntTy, RBA->getSlotNumber());
806+
if (Binding.isExplicit()) {
807+
llvm::Intrinsic::ID IntrinsicID =
808+
CGM.getHLSLRuntime().getCreateHandleFromBindingIntrinsic();
809+
auto *RegSlot = llvm::ConstantInt::get(CGM.IntTy, Binding.getSlot());
845810
SmallVector<Value *> Args{Space, RegSlot, RangeSize, Index, Name};
846811
initializeBuffer(CGM, GV, IntrinsicID, Args);
847812
} else {
848813
// buffer with implicit binding
814+
llvm::Intrinsic::ID IntrinsicID =
815+
CGM.getHLSLRuntime().getCreateHandleFromImplicitBindingIntrinsic();
849816
auto *OrderID =
850-
llvm::ConstantInt::get(CGM.IntTy, RBA->getImplicitBindingOrderID());
817+
llvm::ConstantInt::get(CGM.IntTy, Binding.getImplicitOrderID());
851818
SmallVector<Value *> Args{OrderID, Space, RangeSize, Index, Name};
852819
initializeBuffer(CGM, GV, IntrinsicID, Args);
853820
}
@@ -960,9 +927,9 @@ std::optional<LValue> CGHLSLRuntime::emitResourceArraySubscriptExpr(
960927

961928
// Find binding info for the resource array. For implicit binding
962929
// an HLSLResourceBindingAttr should have been added by SemaHLSL.
963-
HLSLVkBindingAttr *VkBinding = ArrayDecl->getAttr<HLSLVkBindingAttr>();
964-
HLSLResourceBindingAttr *RBA = ArrayDecl->getAttr<HLSLResourceBindingAttr>();
965-
assert((VkBinding || RBA) && "resource array must have a binding attribute");
930+
ResourceBindingAttrs Binding(ArrayDecl);
931+
assert((Binding.hasBinding()) &&
932+
"resource array must have a binding attribute");
966933

967934
// Find the individual resource type.
968935
QualType ResultTy = ArraySubsExpr->getType();
@@ -992,7 +959,7 @@ std::optional<LValue> CGHLSLRuntime::emitResourceArraySubscriptExpr(
992959
CallArgList Args;
993960
CXXMethodDecl *CreateMethod = lookupResourceInitMethodAndSetupArgs(
994961
CGF.CGM, ResourceTy->getAsCXXRecordDecl(), Range, Index,
995-
ArrayDecl->getName(), RBA, VkBinding, Args);
962+
ArrayDecl->getName(), Binding, Args);
996963

997964
if (!CreateMethod)
998965
// This can happen if someone creates an array of structs that looks like
@@ -1009,8 +976,8 @@ std::optional<LValue> CGHLSLRuntime::emitResourceArraySubscriptExpr(
1009976
cast<ConstantArrayType>(ResultTy.getTypePtr());
1010977
std::optional<llvm::Value *> EndIndex = initializeLocalResourceArray(
1011978
CGF, ResourceTy->getAsCXXRecordDecl(), ArrayTy, ValueSlot, Range, Index,
1012-
ArrayDecl->getName(), RBA, VkBinding,
1013-
{llvm::ConstantInt::get(CGM.IntTy, 0)}, ArraySubsExpr->getExprLoc());
979+
ArrayDecl->getName(), Binding, {llvm::ConstantInt::get(CGM.IntTy, 0)},
980+
ArraySubsExpr->getExprLoc());
1014981
if (!EndIndex)
1015982
return std::nullopt;
1016983
}

clang/lib/CodeGen/CGHLSLRuntime.h

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -200,11 +200,7 @@ class CGHLSLRuntime {
200200
void emitBufferGlobalsAndMetadata(const HLSLBufferDecl *BufDecl,
201201
llvm::GlobalVariable *BufGV);
202202
void initializeBufferFromBinding(const HLSLBufferDecl *BufDecl,
203-
llvm::GlobalVariable *GV,
204-
HLSLVkBindingAttr *VkBinding);
205-
void initializeBufferFromBinding(const HLSLBufferDecl *BufDecl,
206-
llvm::GlobalVariable *GV,
207-
HLSLResourceBindingAttr *RBA);
203+
llvm::GlobalVariable *GV);
208204
llvm::Triple::ArchType getArch();
209205

210206
llvm::DenseMap<const clang::RecordType *, llvm::TargetExtType *> LayoutTypes;

clang/lib/Sema/SemaHLSL.cpp

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "clang/AST/DeclarationName.h"
2020
#include "clang/AST/DynamicRecursiveASTVisitor.h"
2121
#include "clang/AST/Expr.h"
22+
#include "clang/AST/HLSLResource.h"
2223
#include "clang/AST/Type.h"
2324
#include "clang/AST/TypeLoc.h"
2425
#include "clang/Basic/Builtins.h"
@@ -52,6 +53,7 @@
5253
#include <utility>
5354

5455
using namespace clang;
56+
using namespace clang::hlsl;
5557
using RegisterType = HLSLResourceBindingAttr::RegisterType;
5658

5759
static CXXRecordDecl *createHostLayoutStruct(Sema &S,
@@ -3799,41 +3801,30 @@ bool SemaHLSL::initGlobalResourceDecl(VarDecl *VD) {
37993801
uint64_t UIntTySize = AST.getTypeSize(AST.UnsignedIntTy);
38003802
uint64_t IntTySize = AST.getTypeSize(AST.IntTy);
38013803

3802-
// Gather resource binding information from attributes.
3803-
HLSLResourceBindingAttr *RBA = VD->getAttr<HLSLResourceBindingAttr>();
3804-
HLSLVkBindingAttr *VkBinding = VD->getAttr<HLSLVkBindingAttr>();
3805-
std::optional<uint32_t> RegisterSlot;
3806-
uint32_t SpaceNo = 0;
3807-
if (VkBinding) {
3808-
RegisterSlot = VkBinding->getBinding();
3809-
SpaceNo = VkBinding->getSet();
3810-
} else if (RBA) {
3811-
if (RBA->hasRegisterSlot())
3812-
RegisterSlot = RBA->getSlotNumber();
3813-
SpaceNo = RBA->getSpaceNumber();
3814-
}
3804+
// Gather resource binding attributes.
3805+
ResourceBindingAttrs Binding(VD);
38153806

38163807
// Find correct initialization method and create its arguments.
38173808
QualType ResourceTy = VD->getType();
38183809
CXXRecordDecl *ResourceDecl = ResourceTy->getAsCXXRecordDecl();
38193810
CXXMethodDecl *CreateMethod = nullptr;
38203811
llvm::SmallVector<Expr *> Args;
38213812

3822-
if (RegisterSlot.has_value()) {
3813+
if (Binding.isExplicit()) {
38233814
// The resource has explicit binding.
38243815
CreateMethod = lookupMethod(SemaRef, ResourceDecl, "__createFromBinding",
38253816
VD->getLocation());
3826-
IntegerLiteral *RegSlot = IntegerLiteral::Create(
3827-
AST, llvm::APInt(UIntTySize, RegisterSlot.value()), AST.UnsignedIntTy,
3828-
SourceLocation());
3817+
IntegerLiteral *RegSlot =
3818+
IntegerLiteral::Create(AST, llvm::APInt(UIntTySize, Binding.getSlot()),
3819+
AST.UnsignedIntTy, SourceLocation());
38293820
Args.push_back(RegSlot);
38303821
} else {
38313822
// The resource has implicit binding.
38323823
CreateMethod =
38333824
lookupMethod(SemaRef, ResourceDecl, "__createFromImplicitBinding",
38343825
VD->getLocation());
3835-
uint32_t OrderID = (RBA && RBA->hasImplicitBindingOrderID())
3836-
? RBA->getImplicitBindingOrderID()
3826+
uint32_t OrderID = (Binding.hasImplicitOrderID())
3827+
? Binding.getImplicitOrderID()
38373828
: getNextImplicitBindingOrderID();
38383829
IntegerLiteral *OrderId =
38393830
IntegerLiteral::Create(AST, llvm::APInt(UIntTySize, OrderID),
@@ -3848,7 +3839,7 @@ bool SemaHLSL::initGlobalResourceDecl(VarDecl *VD) {
38483839
return false;
38493840

38503841
IntegerLiteral *Space =
3851-
IntegerLiteral::Create(AST, llvm::APInt(UIntTySize, SpaceNo),
3842+
IntegerLiteral::Create(AST, llvm::APInt(UIntTySize, Binding.getSpace()),
38523843
AST.UnsignedIntTy, SourceLocation());
38533844
Args.push_back(Space);
38543845

0 commit comments

Comments
 (0)