Skip to content

Commit c44271b

Browse files
dj2Dawn LUCI CQ
authored andcommitted
[hlsl][ir] Only move a value to a let once.
In promote initializers once we've moved an initializer to a let, if that value is used again, we can re-use the let that was already created. Bug: 369450791 Change-Id: I0911793cb129335bddd74c4c5e4aab2f65bcface Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/212214 Reviewed-by: Antonio Maiorano <[email protected]> Reviewed-by: James Price <[email protected]> Commit-Queue: dan sinclair <[email protected]>
1 parent ed15f85 commit c44271b

File tree

34 files changed

+212
-203
lines changed

34 files changed

+212
-203
lines changed

src/tint/lang/hlsl/writer/raise/promote_initializers.cc

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,16 @@ struct State {
5050

5151
/// Process the module.
5252
void Process() {
53+
/// Map of values to the new let versions
54+
Hashmap<core::ir::Value*, core::ir::Let*, 8> values_in_lets{};
55+
5356
for (auto* block : ir.blocks.Objects()) {
57+
values_in_lets.Clear();
58+
5459
// In the root block, all structs need to be split out, no nested structs
5560
bool is_root_block = block == ir.root_block;
5661

57-
Process(block, is_root_block);
62+
Process(block, is_root_block, values_in_lets);
5863
}
5964
}
6065

@@ -64,7 +69,9 @@ struct State {
6469
core::ir::Value* val;
6570
};
6671

67-
void Process(core::ir::Block* block, bool is_root_block) {
72+
void Process(core::ir::Block* block,
73+
bool is_root_block,
74+
Hashmap<core::ir::Value*, core::ir::Let*, 8>& values_in_lets) {
6875
Vector<ValueInfo, 4> worklist;
6976

7077
for (auto* inst : *block) {
@@ -98,10 +105,10 @@ struct State {
98105
if (auto* res = As<core::ir::InstructionResult>(item.val)) {
99106
// If the value isn't already a `let`, put it into a `let`.
100107
if (!res->Instruction()->Is<core::ir::Let>()) {
101-
PutInLet(item.inst, item.index, res);
108+
PutInLet(item.inst, item.index, res, values_in_lets);
102109
}
103110
} else if (auto* val = As<core::ir::Constant>(item.val)) {
104-
auto* let = PutInLet(item.inst, item.index, val);
111+
auto* let = PutInLet(item.inst, item.index, val, values_in_lets);
105112
auto ret = HoistModuleScopeLetToConstruct(is_root_block, item.inst, let, val);
106113
if (ret.has_value()) {
107114
const_worklist.Insert(0, *ret);
@@ -210,9 +217,18 @@ struct State {
210217
return let;
211218
}
212219

213-
core::ir::Let* PutInLet(core::ir::Instruction* inst, size_t index, core::ir::Value* value) {
214-
auto* let = MakeLet(value);
215-
let->InsertBefore(inst);
220+
core::ir::Let* PutInLet(core::ir::Instruction* inst,
221+
size_t index,
222+
core::ir::Value* value,
223+
Hashmap<core::ir::Value*, core::ir::Let*, 8>& values_in_lets) {
224+
core::ir::Let* let = nullptr;
225+
if (auto res = values_in_lets.Get(value); res) {
226+
let = *res;
227+
} else {
228+
let = MakeLet(value);
229+
let->InsertBefore(inst);
230+
values_in_lets.Add(value, let);
231+
}
216232

217233
inst->SetOperand(index, let->Result(0));
218234
return let;

src/tint/lang/hlsl/writer/raise/promote_initializers_test.cc

Lines changed: 115 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -682,8 +682,7 @@ A = struct @align(4) {
682682
$B2: {
683683
%4:A = let A(1i)
684684
%5:void = call %bar, %4
685-
%6:A = let A(1i)
686-
%7:void = call %bar, %6
685+
%6:void = call %bar, %4
687686
ret
688687
}
689688
}
@@ -753,8 +752,7 @@ TEST_F(HlslWriterPromoteInitializersTest, DuplicateConstant) {
753752
EXPECT_EQ(expect, str());
754753
}
755754

756-
// TODO(dsinclair): Fixup duplicate let creation
757-
TEST_F(HlslWriterPromoteInitializersTest, DISABLED_DuplicateAccess) {
755+
TEST_F(HlslWriterPromoteInitializersTest, DuplicateAccess) {
758756
capabilities = core::ir::Capabilities{core::ir::Capability::kAllowModuleScopeLets};
759757

760758
auto* func = b.Function("foo", ty.void_(), core::ir::Function::PipelineStage::kFragment);
@@ -796,6 +794,119 @@ TEST_F(HlslWriterPromoteInitializersTest, DISABLED_DuplicateAccess) {
796794
EXPECT_EQ(expect, str());
797795
}
798796

797+
TEST_F(HlslWriterPromoteInitializersTest, DuplicateAccessDifferentFunction) {
798+
capabilities = core::ir::Capabilities{core::ir::Capability::kAllowModuleScopeLets};
799+
800+
auto* a = b.Function("a", ty.void_());
801+
b.Append(a->Block(), [&] {
802+
auto* ary = b.Splat(ty.array(ty.f32(), 8), 8_f);
803+
b.Access(ty.f32(), ary, 0_u);
804+
b.Return(a);
805+
});
806+
807+
auto* func = b.Function("foo", ty.void_(), core::ir::Function::PipelineStage::kFragment);
808+
b.Append(func->Block(), [&] {
809+
auto* ary = b.Splat(ty.array(ty.f32(), 8), 8_f);
810+
b.Access(ty.f32(), ary, 0_u);
811+
b.Return(func);
812+
});
813+
814+
auto* src = R"(
815+
%a = func():void {
816+
$B1: {
817+
%2:f32 = access array<f32, 8>(8.0f), 0u
818+
ret
819+
}
820+
}
821+
%foo = @fragment func():void {
822+
$B2: {
823+
%4:f32 = access array<f32, 8>(8.0f), 0u
824+
ret
825+
}
826+
}
827+
)";
828+
EXPECT_EQ(src, str());
829+
830+
auto* expect = R"(
831+
%a = func():void {
832+
$B1: {
833+
%2:array<f32, 8> = let array<f32, 8>(8.0f)
834+
%3:f32 = access %2, 0u
835+
ret
836+
}
837+
}
838+
%foo = @fragment func():void {
839+
$B2: {
840+
%5:array<f32, 8> = let array<f32, 8>(8.0f)
841+
%6:f32 = access %5, 0u
842+
ret
843+
}
844+
}
845+
)";
846+
847+
Run(PromoteInitializers);
848+
EXPECT_EQ(expect, str());
849+
}
850+
851+
TEST_F(HlslWriterPromoteInitializersTest, DuplicateAccessDifferentScope) {
852+
capabilities = core::ir::Capabilities{core::ir::Capability::kAllowModuleScopeLets};
853+
854+
auto* func = b.Function("foo", ty.void_(), core::ir::Function::PipelineStage::kFragment);
855+
b.Append(func->Block(), [&] {
856+
auto* ary = b.Construct(ty.array(ty.f32(), 8));
857+
858+
auto* if_ = b.If(true);
859+
b.Append(if_->True(), [&] {
860+
b.Access(ty.f32(), ary, 0_u);
861+
b.ExitIf(if_);
862+
});
863+
864+
b.Access(ty.f32(), ary, 1_u);
865+
b.Access(ty.f32(), ary, 2_u);
866+
b.Return(func);
867+
});
868+
869+
auto* src = R"(
870+
%foo = @fragment func():void {
871+
$B1: {
872+
%2:array<f32, 8> = construct
873+
if true [t: $B2] { # if_1
874+
$B2: { # true
875+
%3:f32 = access %2, 0u
876+
exit_if # if_1
877+
}
878+
}
879+
%4:f32 = access %2, 1u
880+
%5:f32 = access %2, 2u
881+
ret
882+
}
883+
}
884+
)";
885+
EXPECT_EQ(src, str());
886+
887+
auto* expect = R"(
888+
%foo = @fragment func():void {
889+
$B1: {
890+
%2:array<f32, 8> = construct
891+
if true [t: $B2] { # if_1
892+
$B2: { # true
893+
%3:array<f32, 8> = let %2
894+
%4:f32 = access %3, 0u
895+
exit_if # if_1
896+
}
897+
}
898+
%5:array<f32, 8> = let %2
899+
%6:f32 = access %5, 1u
900+
%7:f32 = access %5, 2u
901+
ret
902+
}
903+
}
904+
)";
905+
906+
Run(PromoteInitializers);
907+
EXPECT_EQ(expect, str());
908+
}
909+
799910
TEST_F(HlslWriterPromoteInitializersTest, LetOfLet) {
800911
capabilities = core::ir::Capabilities{core::ir::Capability::kAllowModuleScopeLets};
801912

test/tint/bug/tint/366037039.wgsl.expected.ir.dxc.hlsl

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,7 @@ void foo() {
101101
S w = v_9(0u);
102102
S v_23 = (S)0;
103103
v_3(0u, v_23);
104-
S v_24 = (S)0;
105-
wbuffer = v_24;
104+
wbuffer = v_23;
106105
}
107106

108107
[numthreads(1, 1, 1)]

test/tint/bug/tint/366037039.wgsl.expected.ir.fxc.hlsl

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,7 @@ void foo() {
101101
S w = v_9(0u);
102102
S v_23 = (S)0;
103103
v_3(0u, v_23);
104-
S v_24 = (S)0;
105-
wbuffer = v_24;
104+
wbuffer = v_23;
106105
}
107106

108107
[numthreads(1, 1, 1)]

test/tint/extensions/clip_distances/first_member/clip_distances_size_2.wgsl.expected.ir.dxc.hlsl

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@ VertexOutputs main_inner() {
1717
main_outputs main() {
1818
VertexOutputs v_1 = main_inner();
1919
float v_2[2] = v_1.clipDistance;
20-
float v_3[2] = v_1.clipDistance;
21-
main_outputs v_4 = {v_1.position, float2(v_2[0u], v_3[1u])};
22-
return v_4;
20+
main_outputs v_3 = {v_1.position, float2(v_2[0u], v_2[1u])};
21+
return v_3;
2322
}
2423

test/tint/extensions/clip_distances/first_member/clip_distances_size_2.wgsl.expected.ir.fxc.hlsl

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@ VertexOutputs main_inner() {
1717
main_outputs main() {
1818
VertexOutputs v_1 = main_inner();
1919
float v_2[2] = v_1.clipDistance;
20-
float v_3[2] = v_1.clipDistance;
21-
main_outputs v_4 = {v_1.position, float2(v_2[0u], v_3[1u])};
22-
return v_4;
20+
main_outputs v_3 = {v_1.position, float2(v_2[0u], v_2[1u])};
21+
return v_3;
2322
}
2423

test/tint/extensions/clip_distances/first_member/clip_distances_size_3.wgsl.expected.ir.dxc.hlsl

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,7 @@ VertexOutputs main_inner() {
1717
main_outputs main() {
1818
VertexOutputs v_1 = main_inner();
1919
float v_2[3] = v_1.clipDistance;
20-
float v_3[3] = v_1.clipDistance;
21-
float v_4[3] = v_1.clipDistance;
22-
main_outputs v_5 = {v_1.position, float3(v_2[0u], v_3[1u], v_4[2u])};
23-
return v_5;
20+
main_outputs v_3 = {v_1.position, float3(v_2[0u], v_2[1u], v_2[2u])};
21+
return v_3;
2422
}
2523

test/tint/extensions/clip_distances/first_member/clip_distances_size_3.wgsl.expected.ir.fxc.hlsl

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,7 @@ VertexOutputs main_inner() {
1717
main_outputs main() {
1818
VertexOutputs v_1 = main_inner();
1919
float v_2[3] = v_1.clipDistance;
20-
float v_3[3] = v_1.clipDistance;
21-
float v_4[3] = v_1.clipDistance;
22-
main_outputs v_5 = {v_1.position, float3(v_2[0u], v_3[1u], v_4[2u])};
23-
return v_5;
20+
main_outputs v_3 = {v_1.position, float3(v_2[0u], v_2[1u], v_2[2u])};
21+
return v_3;
2422
}
2523

test/tint/extensions/clip_distances/first_member/clip_distances_size_4.wgsl.expected.ir.dxc.hlsl

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,7 @@ VertexOutputs main_inner() {
1717
main_outputs main() {
1818
VertexOutputs v_1 = main_inner();
1919
float v_2[4] = v_1.clipDistance;
20-
float v_3[4] = v_1.clipDistance;
21-
float v_4[4] = v_1.clipDistance;
22-
float v_5[4] = v_1.clipDistance;
23-
main_outputs v_6 = {v_1.position, float4(v_2[0u], v_3[1u], v_4[2u], v_5[3u])};
24-
return v_6;
20+
main_outputs v_3 = {v_1.position, float4(v_2[0u], v_2[1u], v_2[2u], v_2[3u])};
21+
return v_3;
2522
}
2623

test/tint/extensions/clip_distances/first_member/clip_distances_size_4.wgsl.expected.ir.fxc.hlsl

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,7 @@ VertexOutputs main_inner() {
1717
main_outputs main() {
1818
VertexOutputs v_1 = main_inner();
1919
float v_2[4] = v_1.clipDistance;
20-
float v_3[4] = v_1.clipDistance;
21-
float v_4[4] = v_1.clipDistance;
22-
float v_5[4] = v_1.clipDistance;
23-
main_outputs v_6 = {v_1.position, float4(v_2[0u], v_3[1u], v_4[2u], v_5[3u])};
24-
return v_6;
20+
main_outputs v_3 = {v_1.position, float4(v_2[0u], v_2[1u], v_2[2u], v_2[3u])};
21+
return v_3;
2522
}
2623

0 commit comments

Comments
 (0)