Skip to content

Commit b07fc0f

Browse files
authored
[HLSL] Move Resource Instance Properties from TypeInfo (#135259)
Fixes #134741 Moves Resource Instance properties from type info into resource info as described in https://github.com/llvm/wg-hlsl/blob/main/proposals/0022-resource-instance-analysis.md
1 parent 9deb08a commit b07fc0f

File tree

6 files changed

+94
-79
lines changed

6 files changed

+94
-79
lines changed

llvm/include/llvm/Analysis/DXILResource.h

Lines changed: 19 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -222,19 +222,11 @@ class LayoutExtType : public TargetExtType {
222222
class ResourceTypeInfo {
223223
public:
224224
struct UAVInfo {
225-
bool GloballyCoherent;
226-
bool HasCounter;
227225
bool IsROV;
228226

229-
bool operator==(const UAVInfo &RHS) const {
230-
return std::tie(GloballyCoherent, HasCounter, IsROV) ==
231-
std::tie(RHS.GloballyCoherent, RHS.HasCounter, RHS.IsROV);
232-
}
227+
bool operator==(const UAVInfo &RHS) const { return IsROV == RHS.IsROV; }
233228
bool operator!=(const UAVInfo &RHS) const { return !(*this == RHS); }
234-
bool operator<(const UAVInfo &RHS) const {
235-
return std::tie(GloballyCoherent, HasCounter, IsROV) <
236-
std::tie(RHS.GloballyCoherent, RHS.HasCounter, RHS.IsROV);
237-
}
229+
bool operator<(const UAVInfo &RHS) const { return IsROV < RHS.IsROV; }
238230
};
239231

240232
struct StructInfo {
@@ -272,23 +264,14 @@ class ResourceTypeInfo {
272264
private:
273265
TargetExtType *HandleTy;
274266

275-
// GloballyCoherent and HasCounter aren't really part of the type and need to
276-
// be determined by analysis, so they're just provided directly by the
277-
// DXILResourceTypeMap when we construct these.
278-
bool GloballyCoherent;
279-
bool HasCounter;
280-
281267
dxil::ResourceClass RC;
282268
dxil::ResourceKind Kind;
283269

284270
public:
285271
ResourceTypeInfo(TargetExtType *HandleTy, const dxil::ResourceClass RC,
286-
const dxil::ResourceKind Kind, bool GloballyCoherent = false,
287-
bool HasCounter = false);
288-
ResourceTypeInfo(TargetExtType *HandleTy, bool GloballyCoherent = false,
289-
bool HasCounter = false)
290-
: ResourceTypeInfo(HandleTy, {}, dxil::ResourceKind::Invalid,
291-
GloballyCoherent, HasCounter) {}
272+
const dxil::ResourceKind Kind);
273+
ResourceTypeInfo(TargetExtType *HandleTy)
274+
: ResourceTypeInfo(HandleTy, {}, dxil::ResourceKind::Invalid) {}
292275

293276
TargetExtType *getHandleTy() const { return HandleTy; }
294277
StructType *createElementStruct();
@@ -314,9 +297,6 @@ class ResourceTypeInfo {
314297
dxil::ResourceClass getResourceClass() const { return RC; }
315298
dxil::ResourceKind getResourceKind() const { return Kind; }
316299

317-
void setGloballyCoherent(bool V) { GloballyCoherent = V; }
318-
void setHasCounter(bool V) { HasCounter = V; }
319-
320300
bool operator==(const ResourceTypeInfo &RHS) const;
321301
bool operator!=(const ResourceTypeInfo &RHS) const { return !(*this == RHS); }
322302
bool operator<(const ResourceTypeInfo &RHS) const;
@@ -326,6 +306,13 @@ class ResourceTypeInfo {
326306

327307
//===----------------------------------------------------------------------===//
328308

309+
enum class ResourceCounterDirection {
310+
Increment,
311+
Decrement,
312+
Unknown,
313+
Invalid,
314+
};
315+
329316
class ResourceInfo {
330317
public:
331318
struct ResourceBinding {
@@ -353,6 +340,9 @@ class ResourceInfo {
353340
GlobalVariable *Symbol = nullptr;
354341

355342
public:
343+
bool GloballyCoherent = false;
344+
ResourceCounterDirection CounterDirection = ResourceCounterDirection::Unknown;
345+
356346
ResourceInfo(uint32_t RecordID, uint32_t Space, uint32_t LowerBound,
357347
uint32_t Size, TargetExtType *HandleTy,
358348
GlobalVariable *Symbol = nullptr)
@@ -361,6 +351,10 @@ class ResourceInfo {
361351

362352
void setBindingID(unsigned ID) { Binding.RecordID = ID; }
363353

354+
bool hasCounter() const {
355+
return CounterDirection != ResourceCounterDirection::Unknown;
356+
}
357+
364358
const ResourceBinding &getBinding() const { return Binding; }
365359
TargetExtType *getHandleTy() const { return HandleTy; }
366360
const StringRef getName() const { return Symbol ? Symbol->getName() : ""; }

llvm/lib/Analysis/DXILResource.cpp

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -179,10 +179,8 @@ static dxil::ElementType toDXILElementType(Type *Ty, bool IsSigned) {
179179

180180
ResourceTypeInfo::ResourceTypeInfo(TargetExtType *HandleTy,
181181
const dxil::ResourceClass RC_,
182-
const dxil::ResourceKind Kind_,
183-
bool GloballyCoherent, bool HasCounter)
184-
: HandleTy(HandleTy), GloballyCoherent(GloballyCoherent),
185-
HasCounter(HasCounter) {
182+
const dxil::ResourceKind Kind_)
183+
: HandleTy(HandleTy) {
186184
// If we're provided a resource class and kind, trust them.
187185
if (Kind_ != dxil::ResourceKind::Invalid) {
188186
RC = RC_;
@@ -377,7 +375,7 @@ static bool isROV(dxil::ResourceKind Kind, TargetExtType *Ty) {
377375

378376
ResourceTypeInfo::UAVInfo ResourceTypeInfo::getUAV() const {
379377
assert(isUAV() && "Not a UAV");
380-
return {GloballyCoherent, HasCounter, isROV(Kind, HandleTy)};
378+
return {isROV(Kind, HandleTy)};
381379
}
382380

383381
uint32_t ResourceTypeInfo::getCBufferSize(const DataLayout &DL) const {
@@ -469,8 +467,7 @@ uint32_t ResourceTypeInfo::getMultiSampleCount() const {
469467
}
470468

471469
bool ResourceTypeInfo::operator==(const ResourceTypeInfo &RHS) const {
472-
return std::tie(HandleTy, GloballyCoherent, HasCounter) ==
473-
std::tie(RHS.HandleTy, RHS.GloballyCoherent, RHS.HasCounter);
470+
return HandleTy == RHS.HandleTy;
474471
}
475472

476473
bool ResourceTypeInfo::operator<(const ResourceTypeInfo &RHS) const {
@@ -510,9 +507,7 @@ void ResourceTypeInfo::print(raw_ostream &OS, const DataLayout &DL) const {
510507
} else {
511508
if (isUAV()) {
512509
UAVInfo UAVFlags = getUAV();
513-
OS << " Globally Coherent: " << UAVFlags.GloballyCoherent << "\n"
514-
<< " HasCounter: " << UAVFlags.HasCounter << "\n"
515-
<< " IsROV: " << UAVFlags.IsROV << "\n";
510+
OS << " IsROV: " << UAVFlags.IsROV << "\n";
516511
}
517512
if (isMultiSample())
518513
OS << " Sample Count: " << getMultiSampleCount() << "\n";
@@ -577,8 +572,8 @@ MDTuple *ResourceInfo::getAsMetadata(Module &M,
577572

578573
if (RTI.isUAV()) {
579574
ResourceTypeInfo::UAVInfo UAVFlags = RTI.getUAV();
580-
MDVals.push_back(getBoolMD(UAVFlags.GloballyCoherent));
581-
MDVals.push_back(getBoolMD(UAVFlags.HasCounter));
575+
MDVals.push_back(getBoolMD(GloballyCoherent));
576+
MDVals.push_back(getBoolMD(hasCounter()));
582577
MDVals.push_back(getBoolMD(UAVFlags.IsROV));
583578
} else {
584579
// All SRVs include sample count in the metadata, but it's only meaningful
@@ -619,10 +614,10 @@ ResourceInfo::getAnnotateProps(Module &M, dxil::ResourceTypeInfo &RTI) const {
619614
ResourceTypeInfo::UAVInfo UAVFlags =
620615
IsUAV ? RTI.getUAV() : ResourceTypeInfo::UAVInfo{};
621616
bool IsROV = IsUAV && UAVFlags.IsROV;
622-
bool IsGloballyCoherent = IsUAV && UAVFlags.GloballyCoherent;
617+
bool IsGloballyCoherent = IsUAV && GloballyCoherent;
623618
uint8_t SamplerCmpOrHasCounter = 0;
624619
if (IsUAV)
625-
SamplerCmpOrHasCounter = UAVFlags.HasCounter;
620+
SamplerCmpOrHasCounter = hasCounter();
626621
else if (RTI.isSampler())
627622
SamplerCmpOrHasCounter = RTI.getSamplerType() == SamplerType::Comparison;
628623

@@ -671,6 +666,24 @@ void ResourceInfo::print(raw_ostream &OS, dxil::ResourceTypeInfo &RTI,
671666
<< " Lower Bound: " << Binding.LowerBound << "\n"
672667
<< " Size: " << Binding.Size << "\n";
673668

669+
OS << " Globally Coherent: " << GloballyCoherent << "\n";
670+
OS << " Counter Direction: ";
671+
672+
switch (CounterDirection) {
673+
case ResourceCounterDirection::Increment:
674+
OS << "Increment\n";
675+
break;
676+
case ResourceCounterDirection::Decrement:
677+
OS << "Decrement\n";
678+
break;
679+
case ResourceCounterDirection::Unknown:
680+
OS << "Unknown\n";
681+
break;
682+
case ResourceCounterDirection::Invalid:
683+
OS << "Invalid\n";
684+
break;
685+
}
686+
674687
RTI.print(OS, DL);
675688
}
676689

@@ -767,7 +780,7 @@ void DXILResourceMap::populate(Module &M, DXILResourceTypeMap &DRTM) {
767780
void DXILResourceMap::print(raw_ostream &OS, DXILResourceTypeMap &DRTM,
768781
const DataLayout &DL) const {
769782
for (unsigned I = 0, E = Infos.size(); I != E; ++I) {
770-
OS << "Binding " << I << ":\n";
783+
OS << "Resource " << I << ":\n";
771784
const dxil::ResourceInfo &RI = Infos[I];
772785
RI.print(OS, DRTM[RI.getHandleTy()], DL);
773786
OS << "\n";

llvm/lib/Target/DirectX/DXContainerGlobals.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ void DXContainerGlobals::addResourcesForPSV(Module &M, PSVRuntimeInfo &PSV) {
229229

230230
dxil::ResourceTypeInfo &TypeInfo = DRTM[RI.getHandleTy()];
231231
dxbc::PSV::ResourceType ResType;
232-
if (TypeInfo.getUAV().HasCounter)
232+
if (RI.hasCounter())
233233
ResType = dxbc::PSV::ResourceType::UAVStructuredWithCounter;
234234
else if (TypeInfo.isStruct())
235235
ResType = dxbc::PSV::ResourceType::UAVStructured;

llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -139,8 +139,11 @@ static StringRef getTextureDimName(dxil::ResourceKind RK) {
139139
namespace {
140140
struct FormatResourceDimension
141141
: public llvm::FormatAdapter<const dxil::ResourceTypeInfo &> {
142-
explicit FormatResourceDimension(const dxil::ResourceTypeInfo &RI)
143-
: llvm::FormatAdapter<const dxil::ResourceTypeInfo &>(RI) {}
142+
FormatResourceDimension(const dxil::ResourceTypeInfo &RI, bool HasCounter)
143+
: llvm::FormatAdapter<const dxil::ResourceTypeInfo &>(RI),
144+
HasCounter(HasCounter) {}
145+
146+
bool HasCounter;
144147

145148
void format(llvm::raw_ostream &OS, StringRef Style) override {
146149
dxil::ResourceKind RK = Item.getResourceKind();
@@ -155,7 +158,7 @@ struct FormatResourceDimension
155158
case dxil::ResourceKind::StructuredBuffer:
156159
if (!Item.isUAV())
157160
OS << "r/o";
158-
else if (Item.getUAV().HasCounter)
161+
else if (HasCounter)
159162
OS << "r/w+cnt";
160163
else
161164
OS << "r/w";
@@ -238,7 +241,7 @@ static void prettyPrintResources(raw_ostream &OS, const DXILResourceMap &DRM,
238241
StringRef Name(RI.getName());
239242
StringRef Type(getRCName(RC));
240243
StringRef Format(getFormatName(RTI));
241-
FormatResourceDimension Dim(RTI);
244+
FormatResourceDimension Dim(RTI, RI.hasCounter());
242245
FormatBindingID ID(RI, RTI);
243246
FormatBindingLocation Bind(RI, RTI);
244247
FormatBindingSize Count(RI);

llvm/test/Analysis/DXILResource/buffer-frombinding.ll

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ define void @test_typedbuffer() {
77
%srv0 = call target("dx.RawBuffer", void, 0, 0)
88
@llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i8_0_0t(
99
i32 1, i32 8, i32 1, i32 0, i1 false)
10-
; CHECK: Binding [[SRV0:[0-9]+]]:
10+
; CHECK: Resource [[SRV0:[0-9]+]]:
1111
; CHECK: Binding:
1212
; CHECK: Record ID: 0
1313
; CHECK: Space: 1
@@ -21,7 +21,7 @@ define void @test_typedbuffer() {
2121
%srv1 = call target("dx.RawBuffer", {<4 x float>, <4 x i32>}, 0, 0)
2222
@llvm.dx.resource.handlefrombinding.tdx.RawBuffer_sl_v4f32v4i32s_0_0t(
2323
i32 4, i32 2, i32 1, i32 0, i1 false)
24-
; CHECK: Binding [[SRV1:[0-9]+]]:
24+
; CHECK: Resource [[SRV1:[0-9]+]]:
2525
; CHECK: Binding:
2626
; CHECK: Record ID: 1
2727
; CHECK: Space: 4
@@ -36,7 +36,7 @@ define void @test_typedbuffer() {
3636
%srv2 = call target("dx.TypedBuffer", <4 x i32>, 0, 0, 0)
3737
@llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_i32_0_0t(
3838
i32 5, i32 3, i32 24, i32 0, i1 false)
39-
; CHECK: Binding [[SRV2:[0-9]+]]:
39+
; CHECK: Resource [[SRV2:[0-9]+]]:
4040
; CHECK: Binding:
4141
; CHECK: Record ID: 2
4242
; CHECK: Space: 5
@@ -51,16 +51,16 @@ define void @test_typedbuffer() {
5151
%uav0 = call target("dx.TypedBuffer", i32, 1, 0, 1)
5252
@llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_i32_1_0t(
5353
i32 2, i32 7, i32 1, i32 0, i1 false)
54-
; CHECK: Binding [[UAV0:[0-9]+]]:
54+
; CHECK: Resource [[UAV0:[0-9]+]]:
5555
; CHECK: Binding:
5656
; CHECK: Record ID: 0
5757
; CHECK: Space: 2
5858
; CHECK: Lower Bound: 7
5959
; CHECK: Size: 1
60+
; CHECK: Globally Coherent: 0
61+
; CHECK: Counter Direction: Unknown
6062
; CHECK: Class: UAV
6163
; CHECK: Kind: TypedBuffer
62-
; CHECK: Globally Coherent: 0
63-
; CHECK: HasCounter: 0
6464
; CHECK: IsROV: 0
6565
; CHECK: Element Type: i32
6666
; CHECK: Element Count: 1
@@ -69,16 +69,16 @@ define void @test_typedbuffer() {
6969
%uav1 = call target("dx.TypedBuffer", <4 x float>, 1, 0, 0)
7070
@llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0(
7171
i32 3, i32 5, i32 1, i32 0, i1 false)
72-
; CHECK: Binding [[UAV1:[0-9]+]]:
72+
; CHECK: Resource [[UAV1:[0-9]+]]:
7373
; CHECK: Binding:
7474
; CHECK: Record ID: 1
7575
; CHECK: Space: 3
7676
; CHECK: Lower Bound: 5
7777
; CHECK: Size: 1
78+
; CHECK: Globally Coherent: 0
79+
; CHECK: Counter Direction: Unknown
7880
; CHECK: Class: UAV
7981
; CHECK: Kind: TypedBuffer
80-
; CHECK: Globally Coherent: 0
81-
; CHECK: HasCounter: 0
8282
; CHECK: IsROV: 0
8383
; CHECK: Element Type: f32
8484
; CHECK: Element Count: 4
@@ -92,23 +92,23 @@ define void @test_typedbuffer() {
9292
%uav2_2 = call target("dx.TypedBuffer", <4 x float>, 1, 0, 0)
9393
@llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0(
9494
i32 4, i32 0, i32 10, i32 5, i1 false)
95-
; CHECK: Binding [[UAV2:[0-9]+]]:
95+
; CHECK: Resource [[UAV2:[0-9]+]]:
9696
; CHECK: Binding:
9797
; CHECK: Record ID: 2
9898
; CHECK: Space: 4
9999
; CHECK: Lower Bound: 0
100100
; CHECK: Size: 10
101+
; CHECK: Globally Coherent: 0
102+
; CHECK: Counter Direction: Unknown
101103
; CHECK: Class: UAV
102104
; CHECK: Kind: TypedBuffer
103-
; CHECK: Globally Coherent: 0
104-
; CHECK: HasCounter: 0
105105
; CHECK: IsROV: 0
106106
; CHECK: Element Type: f32
107107
; CHECK: Element Count: 4
108108

109109
%cb0 = call target("dx.CBuffer", {float})
110110
@llvm.dx.resource.handlefrombinding(i32 1, i32 0, i32 1, i32 0, i1 false)
111-
; CHECK: Binding [[CB0:[0-9]+]]:
111+
; CHECK: Resource [[CB0:[0-9]+]]:
112112
; CHECK: Binding:
113113
; CHECK: Record ID: 0
114114
; CHECK: Space: 1
@@ -120,7 +120,7 @@ define void @test_typedbuffer() {
120120

121121
%cb1 = call target("dx.CBuffer", target("dx.Layout", {float}, 4, 0))
122122
@llvm.dx.resource.handlefrombinding(i32 1, i32 8, i32 1, i32 0, i1 false)
123-
; CHECK: Binding [[CB1:[0-9]+]]:
123+
; CHECK: Resource [[CB1:[0-9]+]]:
124124
; CHECK: Binding:
125125
; CHECK: Record ID: 1
126126
; CHECK: Space: 1
@@ -130,7 +130,7 @@ define void @test_typedbuffer() {
130130
; CHECK: Kind: CBuffer
131131
; CHECK: CBuffer size: 4
132132

133-
; CHECK-NOT: Binding {{[0-9]+}}:
133+
; CHECK-NOT: Resource {{[0-9]+}}:
134134

135135
ret void
136136
}

0 commit comments

Comments
 (0)