mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-07-10 23:26:06 +00:00
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:
parent
65985d870f
commit
973a685ad3
@ -47,43 +47,55 @@ struct LocalizeStructArrayAssignment::State {
|
|||||||
utils::Vector<const ast::Statement*, 4> insert_after_stmts;
|
utils::Vector<const ast::Statement*, 4> insert_after_stmts;
|
||||||
} s;
|
} s;
|
||||||
|
|
||||||
ctx.ReplaceAll([&](const ast::AssignmentStatement* assign_stmt) -> const ast::Statement* {
|
bool made_changes = false;
|
||||||
// Process if it's an assignment statement to a dynamically indexed array
|
|
||||||
// within a struct on a function or private storage variable. This
|
for (auto* node : ctx.src->ASTNodes().Objects()) {
|
||||||
// specific use-case is what FXC fails to compile with:
|
if (auto* assign_stmt = node->As<ast::AssignmentStatement>()) {
|
||||||
// error X3500: array reference cannot be used as an l-value; not natively
|
// Process if it's an assignment statement to a dynamically indexed array
|
||||||
// addressable
|
// within a struct on a function or private storage variable. This
|
||||||
if (!ContainsStructArrayIndex(assign_stmt->lhs)) {
|
// specific use-case is what FXC fails to compile with:
|
||||||
return nullptr;
|
// error X3500: array reference cannot be used as an l-value; not natively
|
||||||
}
|
// addressable
|
||||||
auto og = GetOriginatingTypeAndAddressSpace(assign_stmt);
|
if (!ContainsStructArrayIndex(assign_stmt->lhs)) {
|
||||||
if (!(og.first->Is<sem::Struct>() && (og.second == ast::AddressSpace::kFunction ||
|
continue;
|
||||||
og.second == ast::AddressSpace::kPrivate))) {
|
}
|
||||||
return nullptr;
|
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
|
if (!made_changes) {
|
||||||
s = Shared{};
|
return SkipTransform;
|
||||||
|
}
|
||||||
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));
|
|
||||||
});
|
|
||||||
|
|
||||||
ctx.ReplaceAll(
|
ctx.ReplaceAll(
|
||||||
[&](const ast::IndexAccessorExpression* index_access) -> const ast::Expression* {
|
[&](const ast::IndexAccessorExpression* index_access) -> const ast::Expression* {
|
||||||
|
@ -25,9 +25,7 @@ using LocalizeStructArrayAssignmentTest = TransformTest;
|
|||||||
|
|
||||||
TEST_F(LocalizeStructArrayAssignmentTest, EmptyModule) {
|
TEST_F(LocalizeStructArrayAssignmentTest, EmptyModule) {
|
||||||
auto* src = R"()";
|
auto* src = R"()";
|
||||||
auto* expect = src;
|
EXPECT_FALSE(ShouldRun<LocalizeStructArrayAssignment>(src));
|
||||||
auto got = Run<Unshadow, SimplifyPointers, LocalizeStructArrayAssignment>(src);
|
|
||||||
EXPECT_EQ(expect, str(got));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(LocalizeStructArrayAssignmentTest, StructArray) {
|
TEST_F(LocalizeStructArrayAssignmentTest, StructArray) {
|
||||||
@ -842,10 +840,7 @@ fn main() {
|
|||||||
|
|
||||||
// Transform does nothing here as we're not actually assigning to the array in
|
// Transform does nothing here as we're not actually assigning to the array in
|
||||||
// the struct.
|
// the struct.
|
||||||
auto* expect = src;
|
EXPECT_FALSE(ShouldRun<LocalizeStructArrayAssignment>(src));
|
||||||
|
|
||||||
auto got = Run<Unshadow, SimplifyPointers, LocalizeStructArrayAssignment>(src);
|
|
||||||
EXPECT_EQ(expect, str(got));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
Loading…
x
Reference in New Issue
Block a user