Skip to content

Commit db3df8c

Browse files
committed
code review feedback - renaming, improve tests, bug fix for duplicate bindings
1 parent e9747e5 commit db3df8c

File tree

3 files changed

+70
-20
lines changed

3 files changed

+70
-20
lines changed

llvm/include/llvm/Analysis/DXILResource.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -635,9 +635,9 @@ class DXILResourceBindingInfo {
635635
};
636636

637637
struct BindingSpaces {
638-
dxil::ResourceClass ResClass;
638+
dxil::ResourceClass RC;
639639
llvm::SmallVector<RegisterSpace> Spaces;
640-
BindingSpaces(dxil::ResourceClass ResClass) : ResClass(ResClass) {}
640+
BindingSpaces(dxil::ResourceClass RC) : RC(RC) {}
641641
};
642642

643643
private:

llvm/lib/Analysis/DXILResource.cpp

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -885,12 +885,14 @@ SmallVector<dxil::ResourceInfo *> DXILResourceMap::findByUse(const Value *Key) {
885885

886886
void DXILResourceBindingInfo::populate(Module &M, DXILResourceTypeMap &DRTM) {
887887
struct Binding {
888-
ResourceClass ResClass;
888+
ResourceClass RC;
889889
uint32_t Space;
890890
uint32_t LowerBound;
891891
uint32_t UpperBound;
892-
Binding(ResourceClass RC, uint32_t Sp, uint32_t LB, uint32_t UB)
893-
: ResClass(RC), Space(Sp), LowerBound(LB), UpperBound(UB) {}
892+
Binding(ResourceClass RC, uint32_t Space, uint32_t LowerBound,
893+
uint32_t UpperBound)
894+
: RC(RC), Space(Space), LowerBound(LowerBound), UpperBound(UpperBound) {
895+
}
894896
};
895897
SmallVector<Binding> Bindings;
896898

@@ -935,15 +937,17 @@ void DXILResourceBindingInfo::populate(Module &M, DXILResourceTypeMap &DRTM) {
935937

936938
// sort all the collected bindings
937939
llvm::stable_sort(Bindings, [](auto &LHS, auto &RHS) {
938-
return std::tie(LHS.ResClass, LHS.Space, LHS.LowerBound) <
939-
std::tie(RHS.ResClass, RHS.Space, RHS.LowerBound);
940+
return std::tie(LHS.RC, LHS.Space, LHS.LowerBound) <
941+
std::tie(RHS.RC, RHS.Space, RHS.LowerBound);
940942
});
941943

942944
// remove duplicates
943-
llvm::unique(Bindings, [](auto &LHS, auto &RHS) {
944-
return std::tie(LHS.ResClass, LHS.Space, LHS.LowerBound, LHS.UpperBound) ==
945-
std::tie(RHS.ResClass, RHS.Space, RHS.LowerBound, RHS.UpperBound);
945+
Binding *NewEnd = llvm::unique(Bindings, [](auto &LHS, auto &RHS) {
946+
return std::tie(LHS.RC, LHS.Space, LHS.LowerBound, LHS.UpperBound) ==
947+
std::tie(RHS.RC, RHS.Space, RHS.LowerBound, RHS.UpperBound);
946948
});
949+
if (NewEnd != Bindings.end())
950+
Bindings.erase(NewEnd);
947951

948952
// Go over the sorted bindings and build up lists of free register ranges
949953
// for each binding type and used spaces. Bindings are sorted by resource
@@ -952,9 +956,9 @@ void DXILResourceBindingInfo::populate(Module &M, DXILResourceTypeMap &DRTM) {
952956
for (unsigned I = 0, E = Bindings.size(); I != E; ++I) {
953957
Binding &B = Bindings[I];
954958

955-
if (BS->ResClass != B.ResClass)
959+
if (BS->RC != B.RC)
956960
// move to the next resource class spaces
957-
BS = &getBindingSpaces(B.ResClass);
961+
BS = &getBindingSpaces(B.RC);
958962

959963
RegisterSpace *S = BS->Spaces.empty() ? &BS->Spaces.emplace_back(B.Space)
960964
: &BS->Spaces.back();

llvm/unittests/Target/DirectX/ResourceBindingAnalysisTests.cpp

Lines changed: 54 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ define void @main() {
8080
// check that UAV has exactly one gap
8181
DXILResourceBindingInfo::BindingSpaces &UAVSpaces =
8282
DRBI.getBindingSpaces(ResourceClass::UAV);
83-
EXPECT_EQ(UAVSpaces.ResClass, ResourceClass::UAV);
83+
EXPECT_EQ(UAVSpaces.RC, ResourceClass::UAV);
8484
EXPECT_EQ(UAVSpaces.Spaces.size(), 1u);
8585
checkExpectedSpaceAndFreeRanges(UAVSpaces.Spaces[0], 0,
8686
{0, 4, 6, UINT32_MAX});
@@ -89,7 +89,7 @@ define void @main() {
8989
for (auto RC :
9090
{ResourceClass::SRV, ResourceClass::CBuffer, ResourceClass::Sampler}) {
9191
DXILResourceBindingInfo::BindingSpaces &Spaces = DRBI.getBindingSpaces(RC);
92-
EXPECT_EQ(Spaces.ResClass, RC);
92+
EXPECT_EQ(Spaces.RC, RC);
9393
EXPECT_EQ(Spaces.Spaces.size(), 0u);
9494
}
9595
}
@@ -101,6 +101,8 @@ TEST_F(ResourceBindingAnalysisTest, TestManyBindings) {
101101
// RWBuffer<float> C : register(u5);
102102
// StructuredBuffer<int> D[5] : register(t0);
103103
// RWBuffer<float> E[2] : register(u2);
104+
// SamplerState S1 : register(s5, space2);
105+
// SamplerState S2 : register(s4, space2);
104106
StringRef Assembly = R"(
105107
%__cblayout_CB = type <{ i32 }>
106108
define void @main() {
@@ -111,6 +113,10 @@ define void @main() {
111113
%handleC = call target("dx.TypedBuffer", float, 1, 0, 0) @llvm.dx.resource.handlefrombinding(i32 0, i32 5, i32 1, i32 0, i1 false)
112114
%handleD = call target("dx.RawBuffer", i32, 0, 0) @llvm.dx.resource.handlefrombinding(i32 0, i32 0, i32 5, i32 4, i1 false)
113115
%handleE = call target("dx.TypedBuffer", float, 1, 0, 0) @llvm.dx.resource.handlefrombinding(i32 0, i32 2, i32 2, i32 0, i1 false)
116+
%handleS1 = call target("dx.Sampler", 0) @llvm.dx.resource.handlefrombinding(i32 2, i32 5, i32 1, i32 0, i1 false)
117+
%handleS2 = call target("dx.Sampler", 0) @llvm.dx.resource.handlefrombinding(i32 2, i32 4, i32 1, i32 0, i1 false)
118+
; duplicate binding for the same resource
119+
%handleD2 = call target("dx.RawBuffer", i32, 0, 0) @llvm.dx.resource.handlefrombinding(i32 0, i32 0, i32 5, i32 4, i1 false)
114120
ret void
115121
}
116122
)";
@@ -125,13 +131,15 @@ define void @main() {
125131

126132
DXILResourceBindingInfo::BindingSpaces &SRVSpaces =
127133
DRBI.getBindingSpaces(ResourceClass::SRV);
128-
EXPECT_EQ(SRVSpaces.ResClass, ResourceClass::SRV);
134+
EXPECT_EQ(SRVSpaces.RC, ResourceClass::SRV);
129135
EXPECT_EQ(SRVSpaces.Spaces.size(), 1u);
136+
// verify that consecutive bindings are merged
137+
// (SRVSpaces has only one free space range {6, UINT32_MAX}).
130138
checkExpectedSpaceAndFreeRanges(SRVSpaces.Spaces[0], 0, {6, UINT32_MAX});
131139

132140
DXILResourceBindingInfo::BindingSpaces &UAVSpaces =
133141
DRBI.getBindingSpaces(ResourceClass::UAV);
134-
EXPECT_EQ(UAVSpaces.ResClass, ResourceClass::UAV);
142+
EXPECT_EQ(UAVSpaces.RC, ResourceClass::UAV);
135143
EXPECT_EQ(UAVSpaces.Spaces.size(), 2u);
136144
checkExpectedSpaceAndFreeRanges(UAVSpaces.Spaces[0], 0,
137145
{0, 1, 4, 4, 6, UINT32_MAX});
@@ -140,10 +148,17 @@ define void @main() {
140148

141149
DXILResourceBindingInfo::BindingSpaces &CBufferSpaces =
142150
DRBI.getBindingSpaces(ResourceClass::CBuffer);
143-
EXPECT_EQ(CBufferSpaces.ResClass, ResourceClass::CBuffer);
151+
EXPECT_EQ(CBufferSpaces.RC, ResourceClass::CBuffer);
144152
EXPECT_EQ(CBufferSpaces.Spaces.size(), 1u);
145153
checkExpectedSpaceAndFreeRanges(CBufferSpaces.Spaces[0], 0,
146154
{0, 2, 4, UINT32_MAX});
155+
156+
DXILResourceBindingInfo::BindingSpaces &SamplerSpaces =
157+
DRBI.getBindingSpaces(ResourceClass::Sampler);
158+
EXPECT_EQ(SamplerSpaces.RC, ResourceClass::Sampler);
159+
EXPECT_EQ(SamplerSpaces.Spaces.size(), 1u);
160+
checkExpectedSpaceAndFreeRanges(SamplerSpaces.Spaces[0], 2,
161+
{0, 3, 6, UINT32_MAX});
147162
}
148163

149164
TEST_F(ResourceBindingAnalysisTest, TestUnboundedAndOverlap) {
@@ -173,12 +188,43 @@ define void @main() {
173188

174189
DXILResourceBindingInfo::BindingSpaces &SRVSpaces =
175190
DRBI.getBindingSpaces(ResourceClass::SRV);
176-
EXPECT_EQ(SRVSpaces.ResClass, ResourceClass::SRV);
191+
EXPECT_EQ(SRVSpaces.RC, ResourceClass::SRV);
177192
EXPECT_EQ(SRVSpaces.Spaces.size(), 2u);
178193
checkExpectedSpaceAndFreeRanges(SRVSpaces.Spaces[0], 0, {3, 4});
179194
checkExpectedSpaceAndFreeRanges(SRVSpaces.Spaces[1], 2, {});
180195
}
181196

197+
TEST_F(ResourceBindingAnalysisTest, TestExactOverlap) {
198+
// StructuredBuffer<float> A : register(t5);
199+
// StructuredBuffer<float> B : register(t5);
200+
StringRef Assembly = R"(
201+
%__cblayout_CB = type <{ i32 }>
202+
define void @main() {
203+
entry:
204+
%handleA = call target("dx.RawBuffer", float, 0, 0) @llvm.dx.resource.handlefrombinding(i32 0, i32 5, i32 1, i32 0, i1 false)
205+
%handleB = call target("dx.RawBuffer", float, 0, 0) @llvm.dx.resource.handlefrombinding(i32 0, i32 5, i32 1, i32 0, i1 false)
206+
ret void
207+
}
208+
)";
209+
210+
auto M = parseAsm(Assembly);
211+
212+
DXILResourceBindingInfo &DRBI =
213+
MAM->getResult<DXILResourceBindingAnalysis>(*M);
214+
215+
EXPECT_EQ(false, DRBI.hasImplicitBinding());
216+
// FIXME (XFAIL): detecting overlap of two resource with identical binding
217+
// is not yet supported (llvm/llvm-project#110723).
218+
EXPECT_EQ(false, DRBI.hasOverlappingBinding());
219+
220+
DXILResourceBindingInfo::BindingSpaces &SRVSpaces =
221+
DRBI.getBindingSpaces(ResourceClass::SRV);
222+
EXPECT_EQ(SRVSpaces.RC, ResourceClass::SRV);
223+
EXPECT_EQ(SRVSpaces.Spaces.size(), 1u);
224+
checkExpectedSpaceAndFreeRanges(SRVSpaces.Spaces[0], 0,
225+
{0, 4, 6, UINT32_MAX});
226+
}
227+
182228
TEST_F(ResourceBindingAnalysisTest, TestEndOfRange) {
183229
// RWBuffer<float> A : register(u4294967295); /* UINT32_MAX */
184230
// RWBuffer<float> B[10] : register(u4294967286, space1);
@@ -206,7 +252,7 @@ define void @main() {
206252

207253
DXILResourceBindingInfo::BindingSpaces &UAVSpaces =
208254
DRBI.getBindingSpaces(ResourceClass::UAV);
209-
EXPECT_EQ(UAVSpaces.ResClass, ResourceClass::UAV);
255+
EXPECT_EQ(UAVSpaces.RC, ResourceClass::UAV);
210256
EXPECT_EQ(UAVSpaces.Spaces.size(), 3u);
211257
checkExpectedSpaceAndFreeRanges(UAVSpaces.Spaces[0], 0, {0, UINT32_MAX - 1});
212258
checkExpectedSpaceAndFreeRanges(UAVSpaces.Spaces[1], 1, {0, UINT32_MAX - 10});
@@ -236,7 +282,7 @@ define void @main() {
236282

237283
DXILResourceBindingInfo::BindingSpaces &UAVSpaces =
238284
DRBI.getBindingSpaces(ResourceClass::UAV);
239-
EXPECT_EQ(UAVSpaces.ResClass, ResourceClass::UAV);
285+
EXPECT_EQ(UAVSpaces.RC, ResourceClass::UAV);
240286
EXPECT_EQ(UAVSpaces.Spaces.size(), 1u);
241287
checkExpectedSpaceAndFreeRanges(UAVSpaces.Spaces[0], 100,
242288
{0, 4, 6, UINT32_MAX});

0 commit comments

Comments
 (0)