Skip to content

Commit 945e7d3

Browse files
authored
[DirectX] Update resource type names in DXIL metadata to include element type (#140937)
Update resource type names for globals variables that we generate in `DXILTranslateMetadata` pass to include element type. This change prevents duplicate types for identical resources and brings the DXIL metadata names it closer to what DXC generates.
1 parent 4de69f7 commit 945e7d3

File tree

10 files changed

+164
-83
lines changed

10 files changed

+164
-83
lines changed

llvm/include/llvm/Analysis/DXILResource.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ class ResourceTypeInfo {
300300
: ResourceTypeInfo(HandleTy, {}, dxil::ResourceKind::Invalid) {}
301301

302302
TargetExtType *getHandleTy() const { return HandleTy; }
303-
LLVM_ABI StructType *createElementStruct();
303+
LLVM_ABI StructType *createElementStruct(StringRef CBufferName = "");
304304

305305
// Conditions to check before accessing specific views.
306306
LLVM_ABI bool isUAV() const;

llvm/lib/Analysis/DXILResource.cpp

Lines changed: 101 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ static StringRef getResourceKindName(ResourceKind RK) {
6464
case ResourceKind::TextureCubeArray:
6565
return "TextureCubeArray";
6666
case ResourceKind::TypedBuffer:
67-
return "TypedBuffer";
67+
return "Buffer";
6868
case ResourceKind::RawBuffer:
6969
return "RawBuffer";
7070
case ResourceKind::StructuredBuffer:
@@ -132,6 +132,44 @@ static StringRef getElementTypeName(ElementType ET) {
132132
llvm_unreachable("Unhandled ElementType");
133133
}
134134

135+
static StringRef getElementTypeNameForTemplate(ElementType ET) {
136+
switch (ET) {
137+
case ElementType::I1:
138+
return "bool";
139+
case ElementType::I16:
140+
return "int16_t";
141+
case ElementType::U16:
142+
return "uint16_t";
143+
case ElementType::I32:
144+
return "int32_t";
145+
case ElementType::U32:
146+
return "uint32_t";
147+
case ElementType::I64:
148+
return "int64_t";
149+
case ElementType::U64:
150+
return "uint32_t";
151+
case ElementType::F16:
152+
case ElementType::SNormF16:
153+
case ElementType::UNormF16:
154+
return "half";
155+
case ElementType::F32:
156+
case ElementType::SNormF32:
157+
case ElementType::UNormF32:
158+
return "float";
159+
case ElementType::F64:
160+
case ElementType::SNormF64:
161+
case ElementType::UNormF64:
162+
return "double";
163+
case ElementType::PackedS8x32:
164+
return "int8_t4_packed";
165+
case ElementType::PackedU8x32:
166+
return "uint8_t4_packed";
167+
case ElementType::Invalid:
168+
return "<invalid>";
169+
}
170+
llvm_unreachable("Unhandled ElementType");
171+
}
172+
135173
static StringRef getSamplerTypeName(SamplerType ST) {
136174
switch (ST) {
137175
case SamplerType::Default:
@@ -219,12 +257,44 @@ ResourceTypeInfo::ResourceTypeInfo(TargetExtType *HandleTy,
219257
}
220258

221259
static void formatTypeName(SmallString<64> &Dest, StringRef Name,
222-
bool isWriteable, bool isROV) {
223-
Dest = isWriteable ? (isROV ? "RasterizerOrdered" : "RW") : "";
224-
Dest += Name;
260+
bool IsWriteable, bool IsROV,
261+
Type *ContainedType = nullptr,
262+
bool IsSigned = true) {
263+
raw_svector_ostream DestStream(Dest);
264+
if (IsWriteable)
265+
DestStream << (IsROV ? "RasterizerOrdered" : "RW");
266+
DestStream << Name;
267+
268+
if (!ContainedType)
269+
return;
270+
271+
StringRef ElementName;
272+
ElementType ET = toDXILElementType(ContainedType, IsSigned);
273+
if (ET != ElementType::Invalid) {
274+
ElementName = getElementTypeNameForTemplate(ET);
275+
} else {
276+
assert(isa<StructType>(ContainedType) &&
277+
"invalid element type for raw buffer");
278+
StructType *ST = cast<StructType>(ContainedType);
279+
if (!ST->hasName())
280+
return;
281+
ElementName = ST->getStructName();
282+
}
283+
284+
DestStream << "<" << ElementName;
285+
if (const FixedVectorType *VTy = dyn_cast<FixedVectorType>(ContainedType))
286+
DestStream << VTy->getNumElements();
287+
DestStream << ">";
288+
}
289+
290+
static StructType *getOrCreateElementStruct(Type *ElemType, StringRef Name) {
291+
StructType *Ty = StructType::getTypeByName(ElemType->getContext(), Name);
292+
if (Ty && Ty->getNumElements() == 1 && Ty->getElementType(0) == ElemType)
293+
return Ty;
294+
return StructType::create(ElemType, Name);
225295
}
226296

227-
StructType *ResourceTypeInfo::createElementStruct() {
297+
StructType *ResourceTypeInfo::createElementStruct(StringRef CBufferName) {
228298
SmallString<64> TypeName;
229299

230300
switch (Kind) {
@@ -237,51 +307,61 @@ StructType *ResourceTypeInfo::createElementStruct() {
237307
case ResourceKind::TextureCubeArray: {
238308
auto *RTy = cast<TextureExtType>(HandleTy);
239309
formatTypeName(TypeName, getResourceKindName(Kind), RTy->isWriteable(),
240-
RTy->isROV());
241-
return StructType::create(RTy->getResourceType(), TypeName);
310+
RTy->isROV(), RTy->getResourceType(), RTy->isSigned());
311+
return getOrCreateElementStruct(RTy->getResourceType(), TypeName);
242312
}
243313
case ResourceKind::Texture2DMS:
244314
case ResourceKind::Texture2DMSArray: {
245315
auto *RTy = cast<MSTextureExtType>(HandleTy);
246316
formatTypeName(TypeName, getResourceKindName(Kind), RTy->isWriteable(),
247-
/*IsROV=*/false);
248-
return StructType::create(RTy->getResourceType(), TypeName);
317+
/*IsROV=*/false, RTy->getResourceType(), RTy->isSigned());
318+
return getOrCreateElementStruct(RTy->getResourceType(), TypeName);
249319
}
250320
case ResourceKind::TypedBuffer: {
251321
auto *RTy = cast<TypedBufferExtType>(HandleTy);
252322
formatTypeName(TypeName, getResourceKindName(Kind), RTy->isWriteable(),
253-
RTy->isROV());
254-
return StructType::create(RTy->getResourceType(), TypeName);
323+
RTy->isROV(), RTy->getResourceType(), RTy->isSigned());
324+
return getOrCreateElementStruct(RTy->getResourceType(), TypeName);
255325
}
256326
case ResourceKind::RawBuffer: {
257327
auto *RTy = cast<RawBufferExtType>(HandleTy);
258328
formatTypeName(TypeName, "ByteAddressBuffer", RTy->isWriteable(),
259329
RTy->isROV());
260-
return StructType::create(Type::getInt32Ty(HandleTy->getContext()),
261-
TypeName);
330+
return getOrCreateElementStruct(Type::getInt32Ty(HandleTy->getContext()),
331+
TypeName);
262332
}
263333
case ResourceKind::StructuredBuffer: {
264334
auto *RTy = cast<RawBufferExtType>(HandleTy);
335+
Type *Ty = RTy->getResourceType();
265336
formatTypeName(TypeName, "StructuredBuffer", RTy->isWriteable(),
266-
RTy->isROV());
267-
return StructType::create(RTy->getResourceType(), TypeName);
337+
RTy->isROV(), RTy->getResourceType(), true);
338+
return getOrCreateElementStruct(Ty, TypeName);
268339
}
269340
case ResourceKind::FeedbackTexture2D:
270341
case ResourceKind::FeedbackTexture2DArray: {
271342
auto *RTy = cast<FeedbackTextureExtType>(HandleTy);
272343
TypeName = formatv("{0}<{1}>", getResourceKindName(Kind),
273344
llvm::to_underlying(RTy->getFeedbackType()));
274-
return StructType::create(Type::getInt32Ty(HandleTy->getContext()),
275-
TypeName);
345+
return getOrCreateElementStruct(Type::getInt32Ty(HandleTy->getContext()),
346+
TypeName);
347+
}
348+
case ResourceKind::CBuffer: {
349+
auto *RTy = cast<CBufferExtType>(HandleTy);
350+
LayoutExtType *LayoutType = cast<LayoutExtType>(RTy->getResourceType());
351+
StructType *Ty = cast<StructType>(LayoutType->getWrappedType());
352+
SmallString<64> Name = getResourceKindName(Kind);
353+
if (!CBufferName.empty()) {
354+
Name.append(".");
355+
Name.append(CBufferName);
356+
}
357+
return StructType::create(Ty->elements(), Name);
276358
}
277-
case ResourceKind::CBuffer:
278-
return StructType::create(HandleTy->getContext(), "cbuffer");
279359
case ResourceKind::Sampler: {
280360
auto *RTy = cast<SamplerExtType>(HandleTy);
281361
TypeName = formatv("SamplerState<{0}>",
282362
llvm::to_underlying(RTy->getSamplerType()));
283-
return StructType::create(Type::getInt32Ty(HandleTy->getContext()),
284-
TypeName);
363+
return getOrCreateElementStruct(Type::getInt32Ty(HandleTy->getContext()),
364+
TypeName);
285365
}
286366
case ResourceKind::TBuffer:
287367
case ResourceKind::RTAccelerationStructure:

llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,8 @@ static NamedMDNode *emitResourceMetadata(Module &M, DXILResourceMap &DRM,
7979

8080
for (ResourceInfo &RI : DRM)
8181
if (!RI.hasSymbol())
82-
RI.createSymbol(M, DRTM[RI.getHandleTy()].createElementStruct());
82+
RI.createSymbol(M,
83+
DRTM[RI.getHandleTy()].createElementStruct(RI.getName()));
8384

8485
SmallVector<Metadata *> SRVs, UAVs, CBufs, Smps;
8586
for (const ResourceInfo &RI : DRM.srvs())

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ define void @test_typedbuffer() {
5353
; CHECK: Lower Bound: 3
5454
; CHECK: Size: 24
5555
; CHECK: Class: SRV
56-
; CHECK: Kind: TypedBuffer
56+
; CHECK: Kind: Buffer
5757
; CHECK: Element Type: u32
5858
; CHECK: Element Count: 4
5959

@@ -70,7 +70,7 @@ define void @test_typedbuffer() {
7070
; CHECK: Globally Coherent: 0
7171
; CHECK: Counter Direction: Unknown
7272
; CHECK: Class: UAV
73-
; CHECK: Kind: TypedBuffer
73+
; CHECK: Kind: Buffer
7474
; CHECK: IsROV: 0
7575
; CHECK: Element Type: i32
7676
; CHECK: Element Count: 1
@@ -89,7 +89,7 @@ define void @test_typedbuffer() {
8989
; CHECK: Globally Coherent: 0
9090
; CHECK: Counter Direction: Decrement
9191
; CHECK: Class: UAV
92-
; CHECK: Kind: TypedBuffer
92+
; CHECK: Kind: Buffer
9393
; CHECK: IsROV: 0
9494
; CHECK: Element Type: f32
9595
; CHECK: Element Count: 4
@@ -112,7 +112,7 @@ define void @test_typedbuffer() {
112112
; CHECK: Globally Coherent: 0
113113
; CHECK: Counter Direction: Increment
114114
; CHECK: Class: UAV
115-
; CHECK: Kind: TypedBuffer
115+
; CHECK: Kind: Buffer
116116
; CHECK: IsROV: 0
117117
; CHECK: Element Type: f32
118118
; CHECK: Element Count: 4
@@ -132,7 +132,7 @@ define void @test_typedbuffer() {
132132
; CHECK: Globally Coherent: 0
133133
; CHECK: Counter Direction: Invalid
134134
; CHECK: Class: UAV
135-
; CHECK: Kind: TypedBuffer
135+
; CHECK: Kind: Buffer
136136
; CHECK: IsROV: 0
137137
; CHECK: Element Type: f32
138138
; CHECK: Element Count: 4

llvm/test/CodeGen/DirectX/Metadata/cbuffer-only.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@ target triple = "dxil-pc-shadermodel6.6-compute"
99
define void @cbuffer_is_only_binding() {
1010
%cbuf = call target("dx.CBuffer", target("dx.Layout", {float}, 4, 0))
1111
@llvm.dx.resource.handlefrombinding(i32 1, i32 8, i32 1, i32 0, i1 false, ptr null)
12-
; CHECK: %cbuffer = type
12+
; CHECK: %CBuffer = type { float }
1313

1414
ret void
1515
}
1616

17-
; CHECK: @[[CB0:.*]] = external constant %cbuffer
17+
; CHECK: @[[CB0:.*]] = external constant %CBuffer
1818

1919
; CHECK: !{i32 0, ptr @[[CB0]], !""

llvm/test/CodeGen/DirectX/Metadata/cbuffer_metadata.ll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,9 @@ define void @test() #0 {
6666

6767
attributes #0 = { noinline nounwind "hlsl.shader"="compute" }
6868

69-
; CHECK: @CB1 = external constant %cbuffer
70-
; CHECK: @CB2 = external constant %cbuffer.0
71-
; CHECK: @MyConstants = external constant %cbuffer.1
69+
; CHECK: @CB1 = external constant %CBuffer.CB1
70+
; CHECK: @CB2 = external constant %CBuffer.CB2
71+
; CHECK: @MyConstants = external constant %CBuffer.MyConstants
7272

7373
; CHECK: !dx.resources = !{[[ResList:[!][0-9]+]]}
7474

llvm/test/CodeGen/DirectX/Metadata/resource-symbols.ll

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,22 @@ define void @test() {
1111
; Buffer<float4>
1212
%float4 = call target("dx.TypedBuffer", <4 x float>, 0, 0, 0)
1313
@llvm.dx.resource.handlefrombinding(i32 0, i32 0, i32 1, i32 0, i1 false, ptr @A.str)
14-
; CHECK: %TypedBuffer = type { <4 x float> }
14+
; CHECK: %"Buffer<float4>" = type { <4 x float> }
1515

1616
; Buffer<int>
1717
%int = call target("dx.TypedBuffer", i32, 0, 0, 1)
1818
@llvm.dx.resource.handlefrombinding(i32 0, i32 1, i32 1, i32 0, i1 false, ptr null)
19-
; CHECK: %TypedBuffer.0 = type { i32 }
19+
; CHECK: %"Buffer<int32_t>" = type { i32 }
2020

2121
; Buffer<uint3>
2222
%uint3 = call target("dx.TypedBuffer", <3 x i32>, 0, 0, 0)
2323
@llvm.dx.resource.handlefrombinding(i32 0, i32 2, i32 1, i32 0, i1 false, ptr null)
24-
; CHECK: %TypedBuffer.1 = type { <3 x i32> }
24+
; CHECK: %"Buffer<uint32_t3>" = type { <3 x i32> }
2525

2626
; StructuredBuffer<S>
2727
%struct0 = call target("dx.RawBuffer", %struct.S, 0, 0)
2828
@llvm.dx.resource.handlefrombinding(i32 0, i32 10, i32 1, i32 0, i1 true, ptr @SB.str)
29-
; CHECK: %StructuredBuffer = type { %struct.S }
29+
; CHECK: %"StructuredBuffer<struct.S>" = type { %struct.S }
3030

3131
; ByteAddressBuffer
3232
%byteaddr = call target("dx.RawBuffer", i8, 0, 0)
@@ -36,10 +36,10 @@ define void @test() {
3636
ret void
3737
}
3838

39-
; CHECK: @[[T0:.*]] = external constant %TypedBuffer
40-
; CHECK-NEXT: @[[T1:.*]] = external constant %TypedBuffer.0
41-
; CHECK-NEXT: @[[T2:.*]] = external constant %TypedBuffer.1
42-
; CHECK-NEXT: @[[S0:.*]] = external constant %StructuredBuffer
39+
; CHECK: @[[T0:.*]] = external constant %"Buffer<float4>"
40+
; CHECK-NEXT: @[[T1:.*]] = external constant %"Buffer<int32_t>"
41+
; CHECK-NEXT: @[[T2:.*]] = external constant %"Buffer<uint32_t3>"
42+
; CHECK-NEXT: @[[S0:.*]] = external constant %"StructuredBuffer<struct.S>"
4343
; CHECK-NEXT: @[[B0:.*]] = external constant %ByteAddressBuffer
4444

4545
; CHECK: !{i32 0, ptr @[[T0]], !"A"

llvm/test/CodeGen/DirectX/Metadata/srv_metadata.ll

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -78,25 +78,24 @@ define void @test() #0 {
7878

7979
attributes #0 = { noinline nounwind "hlsl.shader"="compute" }
8080

81-
; CHECK: %TypedBuffer = type { <4 x half> }
82-
; CHECK: %TypedBuffer.0 = type { <2 x float> }
83-
; CHECK: %TypedBuffer.1 = type { double }
84-
; CHECK: %TypedBuffer.2 = type { <4 x i32> }
81+
; CHECK: %"Buffer<half4>" = type { <4 x half> }
82+
; CHECK: %"Buffer<float2>" = type { <2 x float> }
83+
; CHECK: %"Buffer<double>" = type { double }
84+
; CHECK: %"Buffer<int32_t4>" = type { <4 x i32> }
8585
; CHECK: %ByteAddressBuffer = type { i32 }
86-
; CHECK: %StructuredBuffer = type { i16 }
87-
; CHECK: %TypedBuffer.3 = type { i64 }
88-
; CHECK: %TypedBuffer.4 = type { <4 x float> }
89-
; CHECK: %TypedBuffer.5 = type { i64 }
90-
91-
; CHECK: @Zero = external constant %TypedBuffer
92-
; CHECK: @One = external constant %TypedBuffer.0
93-
; CHECK: @Two = external constant %TypedBuffer.1
94-
; CHECK: @Three = external constant %TypedBuffer.2
86+
; CHECK: %"StructuredBuffer<int16_t>" = type { i16 }
87+
; CHECK: %"Buffer<uint32_t>" = type { i64 }
88+
; CHECK: %"Buffer<float4>" = type { <4 x float> }
89+
90+
; CHECK: @Zero = external constant %"Buffer<half4>"
91+
; CHECK: @One = external constant %"Buffer<float2>"
92+
; CHECK: @Two = external constant %"Buffer<double>"
93+
; CHECK: @Three = external constant %"Buffer<int32_t4>"
9594
; CHECK: @Four = external constant %ByteAddressBuffer
96-
; CHECK: @Five = external constant %StructuredBuffer
97-
; CHECK: @Six = external constant %TypedBuffer.3
98-
; CHECK: @Array = external constant %TypedBuffer.4
99-
; CHECK: @Seven = external constant %TypedBuffer.5
95+
; CHECK: @Five = external constant %"StructuredBuffer<int16_t>"
96+
; CHECK: @Six = external constant %"Buffer<uint32_t>"
97+
; CHECK: @Array = external constant %"Buffer<float4>"
98+
; CHECK: @Seven = external constant %"Buffer<uint32_t>"
10099

101100
; CHECK: !dx.resources = !{[[ResList:[!][0-9]+]]}
102101

0 commit comments

Comments
 (0)