tint/transform: Skip LocalizeStructArrayAssignment if possible

Change-Id: I148c576f97359923c0d6fd6ffe864ca84ccd5b6b
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/116869
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Dan Sinclair <dsinclair@chromium.org>
Commit-Queue: Ben Clayton <bclayton@google.com>
This commit is contained in:
Ben Clayton 2023-01-12 08:16:46 +00:00 committed by Dawn LUCI CQ
parent 65985d870f
commit 973a685ad3
2 changed files with 49 additions and 42 deletions

View File

@ -47,43 +47,55 @@ struct LocalizeStructArrayAssignment::State {
utils::Vector<const ast::Statement*, 4> insert_after_stmts;
} s;
ctx.ReplaceAll([&](const ast::AssignmentStatement* assign_stmt) -> const ast::Statement* {
// Process if it's an assignment statement to a dynamically indexed array
// within a struct on a function or private storage variable. This
// specific use-case is what FXC fails to compile with:
// error X3500: array reference cannot be used as an l-value; not natively
// addressable
if (!ContainsStructArrayIndex(assign_stmt->lhs)) {
return nullptr;
}
auto og = GetOriginatingTypeAndAddressSpace(assign_stmt);
if (!(og.first->Is<sem::Struct>() && (og.second == ast::AddressSpace::kFunction ||
og.second == ast::AddressSpace::kPrivate))) {
return nullptr;
bool made_changes = false;
for (auto* node : ctx.src->ASTNodes().Objects()) {
if (auto* assign_stmt = node->As<ast::AssignmentStatement>()) {
// Process if it's an assignment statement to a dynamically indexed array
// within a struct on a function or private storage variable. This
// specific use-case is what FXC fails to compile with:
// error X3500: array reference cannot be used as an l-value; not natively
// addressable
if (!ContainsStructArrayIndex(assign_stmt->lhs)) {
continue;
}
auto og = GetOriginatingTypeAndAddressSpace(assign_stmt);
if (!(og.first->Is<sem::Struct>() && (og.second == ast::AddressSpace::kFunction ||
og.second == ast::AddressSpace::kPrivate))) {
continue;
}
ctx.Replace(assign_stmt, [&, assign_stmt] {
// Reset shared state for this assignment statement
s = Shared{};
const ast::Expression* new_lhs = nullptr;
{
TINT_SCOPED_ASSIGNMENT(s.process_nested_nodes, true);
new_lhs = ctx.Clone(assign_stmt->lhs);
}
auto* new_assign_stmt = b.Assign(new_lhs, ctx.Clone(assign_stmt->rhs));
// Combine insert_before_stmts + new_assign_stmt + insert_after_stmts into
// a block and return it
auto stmts = std::move(s.insert_before_stmts);
stmts.Reserve(1 + s.insert_after_stmts.Length());
stmts.Push(new_assign_stmt);
for (auto* stmt : s.insert_after_stmts) {
stmts.Push(stmt);
}
return b.Block(std::move(stmts));
});
made_changes = true;
}
}
// Reset shared state for this assignment statement
s = Shared{};
const ast::Expression* new_lhs = nullptr;
{
TINT_SCOPED_ASSIGNMENT(s.process_nested_nodes, true);
new_lhs = ctx.Clone(assign_stmt->lhs);
}
auto* new_assign_stmt = b.Assign(new_lhs, ctx.Clone(assign_stmt->rhs));
// Combine insert_before_stmts + new_assign_stmt + insert_after_stmts into
// a block and return it
auto stmts = std::move(s.insert_before_stmts);
stmts.Reserve(1 + s.insert_after_stmts.Length());
stmts.Push(new_assign_stmt);
for (auto* stmt : s.insert_after_stmts) {
stmts.Push(stmt);
}
return b.Block(std::move(stmts));
});
if (!made_changes) {
return SkipTransform;
}
ctx.ReplaceAll(
[&](const ast::IndexAccessorExpression* index_access) -> const ast::Expression* {

View File

@ -25,9 +25,7 @@ using LocalizeStructArrayAssignmentTest = TransformTest;
TEST_F(LocalizeStructArrayAssignmentTest, EmptyModule) {
auto* src = R"()";
auto* expect = src;
auto got = Run<Unshadow, SimplifyPointers, LocalizeStructArrayAssignment>(src);
EXPECT_EQ(expect, str(got));
EXPECT_FALSE(ShouldRun<LocalizeStructArrayAssignment>(src));
}
TEST_F(LocalizeStructArrayAssignmentTest, StructArray) {
@ -842,10 +840,7 @@ fn main() {
// Transform does nothing here as we're not actually assigning to the array in
// the struct.
auto* expect = src;
auto got = Run<Unshadow, SimplifyPointers, LocalizeStructArrayAssignment>(src);
EXPECT_EQ(expect, str(got));
EXPECT_FALSE(ShouldRun<LocalizeStructArrayAssignment>(src));
}
} // namespace