diff --git a/src/BUILD.gn b/src/BUILD.gn index 7fdc018e7b..b225b19dfe 100644 --- a/src/BUILD.gn +++ b/src/BUILD.gn @@ -448,8 +448,6 @@ libtint_source_set("libtint_core_all_src") { "transform/fold_trivial_single_use_lets.h", "transform/for_loop_to_loop.cc", "transform/for_loop_to_loop.h", - "transform/inline_pointer_lets.cc", - "transform/inline_pointer_lets.h", "transform/loop_to_for_loop.cc", "transform/loop_to_for_loop.h", "transform/manager.cc", @@ -470,8 +468,8 @@ libtint_source_set("libtint_core_all_src") { "transform/renamer.h", "transform/robustness.cc", "transform/robustness.h", - "transform/simplify.cc", - "transform/simplify.h", + "transform/simplify_pointers.cc", + "transform/simplify_pointers.h", "transform/single_entry_point.cc", "transform/single_entry_point.h", "transform/transform.cc", diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d605d49309..8d098349ff 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -312,8 +312,6 @@ set(TINT_LIB_SRCS transform/for_loop_to_loop.h transform/glsl.cc transform/glsl.h - transform/inline_pointer_lets.cc - transform/inline_pointer_lets.h transform/loop_to_for_loop.cc transform/loop_to_for_loop.h transform/manager.cc @@ -334,8 +332,8 @@ set(TINT_LIB_SRCS transform/renamer.h transform/robustness.cc transform/robustness.h - transform/simplify.cc - transform/simplify.h + transform/simplify_pointers.cc + transform/simplify_pointers.h transform/single_entry_point.cc transform/single_entry_point.h transform/transform.cc @@ -959,7 +957,6 @@ if(${TINT_BUILD_TESTS}) transform/fold_constants_test.cc transform/fold_trivial_single_use_lets_test.cc transform/for_loop_to_loop_test.cc - transform/inline_pointer_lets_test.cc transform/loop_to_for_loop_test.cc transform/module_scope_var_to_entry_point_param_test.cc transform/multiplanar_external_texture_test.cc @@ -969,7 +966,7 @@ if(${TINT_BUILD_TESTS}) transform/remove_phonies_test.cc transform/renamer_test.cc transform/robustness_test.cc - transform/simplify_test.cc + transform/simplify_pointers_test.cc transform/single_entry_point_test.cc transform/test_helper.h transform/vectorize_scalar_matrix_constructors.cc diff --git a/src/reader/spirv/parser.cc b/src/reader/spirv/parser.cc index 0f71d997a0..c5ffebbbe3 100644 --- a/src/reader/spirv/parser.cc +++ b/src/reader/spirv/parser.cc @@ -18,9 +18,8 @@ #include "src/reader/spirv/parser_impl.h" #include "src/transform/decompose_strided_matrix.h" -#include "src/transform/inline_pointer_lets.h" #include "src/transform/manager.h" -#include "src/transform/simplify.h" +#include "src/transform/simplify_pointers.h" namespace tint { namespace reader { @@ -53,8 +52,7 @@ Program Parse(const std::vector& input) { // attribute then we need to decompose these into an array of vectors if (transform::DecomposeStridedMatrix::ShouldRun(&program)) { transform::Manager manager; - manager.Add(); - manager.Add(); + manager.Add(); manager.Add(); return manager.Run(&program).program; } diff --git a/src/transform/array_length_from_uniform.cc b/src/transform/array_length_from_uniform.cc index a30e550ca0..fa04126e85 100644 --- a/src/transform/array_length_from_uniform.cc +++ b/src/transform/array_length_from_uniform.cc @@ -22,8 +22,7 @@ #include "src/program_builder.h" #include "src/sem/call.h" #include "src/sem/variable.h" -#include "src/transform/inline_pointer_lets.h" -#include "src/transform/simplify.h" +#include "src/transform/simplify_pointers.h" TINT_INSTANTIATE_TYPEINFO(tint::transform::ArrayLengthFromUniform); TINT_INSTANTIATE_TYPEINFO(tint::transform::ArrayLengthFromUniform::Config); @@ -62,8 +61,8 @@ static void IterateArrayLengthOnStorageVar(CloneContext& ctx, F&& functor) { // Get the storage buffer that contains the runtime array. // We assume that the argument to `arrayLength` has the form - // `&resource.array`, which requires that `InlinePointerLets` and - // `Simplify` have been run before this transform. + // `&resource.array`, which requires that `SimplifyPointers` have been run + // before this transform. auto* param = call_expr->args[0]->As(); if (!param || param->op != ast::UnaryOp::kAddressOf) { TINT_ICE(Transform, ctx.dst->Diagnostics()) @@ -102,7 +101,7 @@ static void IterateArrayLengthOnStorageVar(CloneContext& ctx, F&& functor) { void ArrayLengthFromUniform::Run(CloneContext& ctx, const DataMap& inputs, DataMap& outputs) { - if (!Requires(ctx)) { + if (!Requires(ctx)) { return; } @@ -161,42 +160,43 @@ void ArrayLengthFromUniform::Run(CloneContext& ctx, std::unordered_set used_size_indices; - IterateArrayLengthOnStorageVar(ctx, [&](const ast::CallExpression* call_expr, - const sem::VariableUser* - storage_buffer_sem, - const sem::GlobalVariable* var) { - auto binding = var->BindingPoint(); - auto idx_itr = cfg->bindpoint_to_size_index.find(binding); - if (idx_itr == cfg->bindpoint_to_size_index.end()) { - return; - } + IterateArrayLengthOnStorageVar( + ctx, [&](const ast::CallExpression* call_expr, + const sem::VariableUser* storage_buffer_sem, + const sem::GlobalVariable* var) { + auto binding = var->BindingPoint(); + auto idx_itr = cfg->bindpoint_to_size_index.find(binding); + if (idx_itr == cfg->bindpoint_to_size_index.end()) { + return; + } - uint32_t size_index = idx_itr->second; - used_size_indices.insert(size_index); + uint32_t size_index = idx_itr->second; + used_size_indices.insert(size_index); - // Load the total storage buffer size from the UBO. - uint32_t array_index = size_index / 4; - auto* vec_expr = ctx.dst->IndexAccessor( - ctx.dst->MemberAccessor(get_ubo()->symbol, kBufferSizeMemberName), - array_index); - uint32_t vec_index = size_index % 4; - auto* total_storage_buffer_size = - ctx.dst->IndexAccessor(vec_expr, vec_index); + // Load the total storage buffer size from the UBO. + uint32_t array_index = size_index / 4; + auto* vec_expr = ctx.dst->IndexAccessor( + ctx.dst->MemberAccessor(get_ubo()->symbol, kBufferSizeMemberName), + array_index); + uint32_t vec_index = size_index % 4; + auto* total_storage_buffer_size = + ctx.dst->IndexAccessor(vec_expr, vec_index); - // Calculate actual array length - // total_storage_buffer_size - array_offset - // array_length = ---------------------------------------- - // array_stride - auto* storage_buffer_type = - storage_buffer_sem->Type()->UnwrapRef()->As(); - auto* array_member_sem = storage_buffer_type->Members().back(); - uint32_t array_offset = array_member_sem->Offset(); - uint32_t array_stride = array_member_sem->Size(); - auto* array_length = ctx.dst->Div( - ctx.dst->Sub(total_storage_buffer_size, array_offset), array_stride); + // Calculate actual array length + // total_storage_buffer_size - array_offset + // array_length = ---------------------------------------- + // array_stride + auto* storage_buffer_type = + storage_buffer_sem->Type()->UnwrapRef()->As(); + auto* array_member_sem = storage_buffer_type->Members().back(); + uint32_t array_offset = array_member_sem->Offset(); + uint32_t array_stride = array_member_sem->Size(); + auto* array_length = + ctx.dst->Div(ctx.dst->Sub(total_storage_buffer_size, array_offset), + array_stride); - ctx.Replace(call_expr, array_length); - }); + ctx.Replace(call_expr, array_length); + }); ctx.Clone(); diff --git a/src/transform/array_length_from_uniform.h b/src/transform/array_length_from_uniform.h index 7063a27f5d..f981f670a6 100644 --- a/src/transform/array_length_from_uniform.h +++ b/src/transform/array_length_from_uniform.h @@ -47,7 +47,7 @@ namespace transform { /// from a storage buffer's `BindingPoint` to the array index that will be used /// to get the size of that buffer. /// -/// This transform assumes that the `InlinePointerLets` and `Simplify` +/// This transform assumes that the `SimplifyPointers` /// transforms have been run before it so that arguments to the arrayLength /// builtin always have the form `&resource.array`. class ArrayLengthFromUniform diff --git a/src/transform/array_length_from_uniform_test.cc b/src/transform/array_length_from_uniform_test.cc index fd4eef922b..13aca0ae90 100644 --- a/src/transform/array_length_from_uniform_test.cc +++ b/src/transform/array_length_from_uniform_test.cc @@ -16,8 +16,7 @@ #include -#include "src/transform/inline_pointer_lets.h" -#include "src/transform/simplify.h" +#include "src/transform/simplify_pointers.h" #include "src/transform/test_helper.h" namespace tint { @@ -33,31 +32,19 @@ TEST_F(ArrayLengthFromUniformTest, Error_MissingTransformData) { "error: missing transform data for " "tint::transform::ArrayLengthFromUniform"; - auto got = Run(src); + auto got = Run(src); EXPECT_EQ(expect, str(got)); } -TEST_F(ArrayLengthFromUniformTest, Error_MissingInlinePointerLets) { +TEST_F(ArrayLengthFromUniformTest, Error_MissingSimplifyPointers) { auto* src = ""; auto* expect = "error: tint::transform::ArrayLengthFromUniform depends on " - "tint::transform::InlinePointerLets but the dependency was not run"; + "tint::transform::SimplifyPointers but the dependency was not run"; - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(ArrayLengthFromUniformTest, Error_MissingSimplify) { - auto* src = ""; - - auto* expect = - "error: tint::transform::ArrayLengthFromUniform depends on " - "tint::transform::Simplify but the dependency was not run"; - - auto got = Run(src); + auto got = Run(src); EXPECT_EQ(expect, str(got)); } @@ -106,8 +93,7 @@ fn main() { DataMap data; data.Add(std::move(cfg)); - auto got = - Run(src, data); + auto got = Run(src, data); EXPECT_EQ(expect, str(got)); EXPECT_EQ(std::unordered_set({0}), @@ -160,8 +146,7 @@ fn main() { DataMap data; data.Add(std::move(cfg)); - auto got = - Run(src, data); + auto got = Run(src, data); EXPECT_EQ(expect, str(got)); EXPECT_EQ(std::unordered_set({0}), @@ -282,8 +267,7 @@ fn main() { DataMap data; data.Add(std::move(cfg)); - auto got = - Run(src, data); + auto got = Run(src, data); EXPECT_EQ(expect, str(got)); EXPECT_EQ(std::unordered_set({0, 1, 2, 3, 4}), @@ -398,8 +382,7 @@ fn main() { DataMap data; data.Add(std::move(cfg)); - auto got = - Run(src, data); + auto got = Run(src, data); EXPECT_EQ(expect, str(got)); EXPECT_EQ(std::unordered_set({0, 2}), @@ -428,8 +411,7 @@ fn main() { DataMap data; data.Add(std::move(cfg)); - auto got = - Run(src, data); + auto got = Run(src, data); EXPECT_EQ(src, str(got)); EXPECT_EQ(std::unordered_set(), @@ -500,8 +482,7 @@ fn main() { DataMap data; data.Add(std::move(cfg)); - auto got = - Run(src, data); + auto got = Run(src, data); EXPECT_EQ(expect, str(got)); EXPECT_EQ(std::unordered_set({0}), diff --git a/src/transform/decompose_strided_matrix.cc b/src/transform/decompose_strided_matrix.cc index 0b89315b94..9b55528bcc 100644 --- a/src/transform/decompose_strided_matrix.cc +++ b/src/transform/decompose_strided_matrix.cc @@ -21,10 +21,9 @@ #include "src/program_builder.h" #include "src/sem/expression.h" #include "src/sem/member_accessor_expression.h" -#include "src/transform/inline_pointer_lets.h" -#include "src/transform/simplify.h" -#include "src/utils/map.h" +#include "src/transform/simplify_pointers.h" #include "src/utils/hash.h" +#include "src/utils/map.h" TINT_INSTANTIATE_TYPEINFO(tint::transform::DecomposeStridedMatrix); @@ -119,7 +118,7 @@ bool DecomposeStridedMatrix::ShouldRun(const Program* program) { } void DecomposeStridedMatrix::Run(CloneContext& ctx, const DataMap&, DataMap&) { - if (!Requires(ctx)) { + if (!Requires(ctx)) { return; } diff --git a/src/transform/decompose_strided_matrix_test.cc b/src/transform/decompose_strided_matrix_test.cc index 5c34ff727c..714e8a1818 100644 --- a/src/transform/decompose_strided_matrix_test.cc +++ b/src/transform/decompose_strided_matrix_test.cc @@ -20,8 +20,7 @@ #include "src/ast/disable_validation_decoration.h" #include "src/program_builder.h" -#include "src/transform/inline_pointer_lets.h" -#include "src/transform/simplify.h" +#include "src/transform/simplify_pointers.h" #include "src/transform/test_helper.h" namespace tint { @@ -35,17 +34,7 @@ TEST_F(DecomposeStridedMatrixTest, Empty) { auto* src = R"()"; auto* expect = src; - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(DecomposeStridedMatrixTest, MissingDependencyInlinePointerLets) { - auto* src = R"()"; - auto* expect = - R"(error: tint::transform::DecomposeStridedMatrix depends on tint::transform::InlinePointerLets but the dependency was not run)"; - - auto got = Run(src); + auto got = Run(src); EXPECT_EQ(expect, str(got)); } @@ -53,9 +42,9 @@ TEST_F(DecomposeStridedMatrixTest, MissingDependencyInlinePointerLets) { TEST_F(DecomposeStridedMatrixTest, MissingDependencySimplify) { auto* src = R"()"; auto* expect = - R"(error: tint::transform::DecomposeStridedMatrix depends on tint::transform::Simplify but the dependency was not run)"; + R"(error: tint::transform::DecomposeStridedMatrix depends on tint::transform::SimplifyPointers but the dependency was not run)"; - auto got = Run(src); + auto got = Run(src); EXPECT_EQ(expect, str(got)); } @@ -120,8 +109,8 @@ fn f() { } )"; - auto got = Run( - Program(std::move(b))); + auto got = + Run(Program(std::move(b))); EXPECT_EQ(expect, str(got)); } @@ -182,8 +171,8 @@ fn f() { } )"; - auto got = Run( - Program(std::move(b))); + auto got = + Run(Program(std::move(b))); EXPECT_EQ(expect, str(got)); } @@ -245,8 +234,8 @@ fn f() { } )"; - auto got = Run( - Program(std::move(b))); + auto got = + Run(Program(std::move(b))); EXPECT_EQ(expect, str(got)); } @@ -311,8 +300,8 @@ fn f() { } )"; - auto got = Run( - Program(std::move(b))); + auto got = + Run(Program(std::move(b))); EXPECT_EQ(expect, str(got)); } @@ -373,8 +362,8 @@ fn f() { } )"; - auto got = Run( - Program(std::move(b))); + auto got = + Run(Program(std::move(b))); EXPECT_EQ(expect, str(got)); } @@ -440,8 +429,8 @@ fn f() { } )"; - auto got = Run( - Program(std::move(b))); + auto got = + Run(Program(std::move(b))); EXPECT_EQ(expect, str(got)); } @@ -502,8 +491,8 @@ fn f() { } )"; - auto got = Run( - Program(std::move(b))); + auto got = + Run(Program(std::move(b))); EXPECT_EQ(expect, str(got)); } @@ -591,8 +580,8 @@ fn f() { } )"; - auto got = Run( - Program(std::move(b))); + auto got = + Run(Program(std::move(b))); EXPECT_EQ(expect, str(got)); } @@ -648,8 +637,8 @@ fn f() { } )"; - auto got = Run( - Program(std::move(b))); + auto got = + Run(Program(std::move(b))); EXPECT_EQ(expect, str(got)); } @@ -706,8 +695,8 @@ fn f() { } )"; - auto got = Run( - Program(std::move(b))); + auto got = + Run(Program(std::move(b))); EXPECT_EQ(expect, str(got)); } diff --git a/src/transform/glsl.cc b/src/transform/glsl.cc index b06941643b..4b4512d196 100644 --- a/src/transform/glsl.cc +++ b/src/transform/glsl.cc @@ -22,13 +22,12 @@ #include "src/transform/decompose_memory_access.h" #include "src/transform/external_texture_transform.h" #include "src/transform/fold_trivial_single_use_lets.h" -#include "src/transform/inline_pointer_lets.h" #include "src/transform/loop_to_for_loop.h" #include "src/transform/manager.h" #include "src/transform/pad_array_elements.h" #include "src/transform/promote_initializers_to_const_var.h" #include "src/transform/remove_phonies.h" -#include "src/transform/simplify.h" +#include "src/transform/simplify_pointers.h" #include "src/transform/single_entry_point.h" #include "src/transform/zero_init_workgroup_memory.h" @@ -58,7 +57,7 @@ Output Glsl::Run(const Program* in, const DataMap& inputs) { manager.Add(); } manager.Add(); - manager.Add(); + manager.Add(); // Running SingleEntryPoint before RemovePhonies prevents variables // referenced only by phonies from being optimized out. Strictly @@ -69,8 +68,6 @@ Output Glsl::Run(const Program* in, const DataMap& inputs) { data.Add(cfg->entry_point); } manager.Add(); - // Simplify cleans up messy `*(&(expr))` expressions from InlinePointerLets. - manager.Add(); manager.Add(); manager.Add(); manager.Add(); diff --git a/src/transform/inline_pointer_lets.cc b/src/transform/inline_pointer_lets.cc deleted file mode 100644 index 5bdf0fca95..0000000000 --- a/src/transform/inline_pointer_lets.cc +++ /dev/null @@ -1,188 +0,0 @@ -// Copyright 2021 The Tint Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "src/transform/inline_pointer_lets.h" - -#include -#include -#include - -#include "src/program_builder.h" -#include "src/sem/block_statement.h" -#include "src/sem/function.h" -#include "src/sem/statement.h" -#include "src/sem/variable.h" -#include "src/utils/scoped_assignment.h" - -TINT_INSTANTIATE_TYPEINFO(tint::transform::InlinePointerLets); - -namespace tint { -namespace transform { -namespace { - -/// Traverses the expression `expr` looking for non-literal array indexing -/// expressions that would affect the computed address of a pointer expression. -/// The function-like argument `cb` is called for each found. -/// @param program the program that owns all the expression nodes -/// @param expr the expression to traverse -/// @param cb a function-like object with the signature -/// `void(const ast::Expression*)`, which is called for each array index -/// expression -template -void CollectSavedArrayIndices(const Program* program, - const ast::Expression* expr, - F&& cb) { - if (auto* a = expr->As()) { - CollectSavedArrayIndices(program, a->object, cb); - - if (!a->index->Is()) { - cb(a->index); - } - return; - } - - if (auto* m = expr->As()) { - CollectSavedArrayIndices(program, m->structure, cb); - return; - } - - if (auto* u = expr->As()) { - CollectSavedArrayIndices(program, u->expr, cb); - return; - } - - // Note: Other ast::Expression types can be safely ignored as they cannot be - // used to generate a reference or pointer. - // See https://gpuweb.github.io/gpuweb/wgsl/#forming-references-and-pointers -} - -// PtrLet represents a `let` declaration of a pointer type. -struct PtrLet { - // A map of ptr-let initializer sub-expression to the name of generated - // variable that holds the saved value of this sub-expression, when resolved - // at the point of the ptr-let declaration. - std::unordered_map saved_vars; -}; - -} // namespace - -InlinePointerLets::InlinePointerLets() = default; - -InlinePointerLets::~InlinePointerLets() = default; - -void InlinePointerLets::Run(CloneContext& ctx, const DataMap&, DataMap&) { - // If not null, current_ptr_let is the current PtrLet being operated on. - PtrLet* current_ptr_let = nullptr; - // A map of the AST `let` variable to the PtrLet - std::unordered_map> ptr_lets; - - // Register the ast::Expression transform handler. - // This performs two different transformations: - // * Identifiers that resolve to the pointer-typed `let` declarations are - // replaced with the inlined (and recursively transformed) initializer - // expression for the `let` declaration. - // * Sub-expressions inside the pointer-typed `let` initializer expression - // that have been hoisted to a saved variable are replaced with the saved - // variable identifier. - ctx.ReplaceAll([&](const ast::Expression* expr) -> const ast::Expression* { - if (current_ptr_let) { - // We're currently processing the initializer expression of a - // pointer-typed `let` declaration. Look to see if we need to swap this - // Expression with a saved variable. - auto it = current_ptr_let->saved_vars.find(expr); - if (it != current_ptr_let->saved_vars.end()) { - return ctx.dst->Expr(it->second); - } - } - if (auto* ident = expr->As()) { - if (auto* vu = ctx.src->Sem().Get(ident)) { - auto* var = vu->Variable()->Declaration(); - auto it = ptr_lets.find(var); - if (it != ptr_lets.end()) { - // We've found an identifier that resolves to a `let` declaration. - // We need to replace this identifier with the initializer expression - // of the `let` declaration. Clone the initializer expression to make - // a copy. Note that this will call back into this ReplaceAll() - // handler for sub-expressions of the initializer. - auto* ptr_let = it->second.get(); - // TINT_SCOPED_ASSIGNMENT provides a stack of PtrLet*, this is - // required to handle the 'chaining' of inlined `let`s. - TINT_SCOPED_ASSIGNMENT(current_ptr_let, ptr_let); - return ctx.Clone(var->constructor); - } - } - } - return nullptr; - }); - - // Find all the pointer-typed `let` declarations. - // Note that these must be function-scoped, as module-scoped `let`s are not - // permitted. - for (auto* node : ctx.src->ASTNodes().Objects()) { - if (auto* let = node->As()) { - if (!let->variable->is_const) { - continue; // Not a `let` declaration. Ignore. - } - - auto* var = ctx.src->Sem().Get(let->variable); - if (!var->Type()->Is()) { - continue; // Not a pointer type. Ignore. - } - - // We're dealing with a pointer-typed `let` declaration. - auto ptr_let = std::make_unique(); - TINT_SCOPED_ASSIGNMENT(current_ptr_let, ptr_let.get()); - - auto* block = ctx.src->Sem().Get(let)->Block()->Declaration(); - - // Scan the initializer expression for array index expressions that need - // to be hoist to temporary "saved" variables. - CollectSavedArrayIndices( - ctx.src, var->Declaration()->constructor, - [&](const ast::Expression* idx_expr) { - // We have a sub-expression that needs to be saved. - // Create a new variable - auto saved_name = ctx.dst->Symbols().New( - ctx.src->Symbols().NameFor(var->Declaration()->symbol) + - "_save"); - auto* saved = ctx.dst->Decl( - ctx.dst->Const(saved_name, nullptr, ctx.Clone(idx_expr))); - // Place this variable after the pointer typed let. Order here is - // important as order-of-operations needs to be preserved. - // CollectSavedArrayIndices() visits the LHS of an index accessor - // before the index expression. - // Note that repeated calls to InsertAfter() with the same `after` - // argument will result in nodes to inserted in the order the calls - // are made (last call is inserted last). - ctx.InsertAfter(block->statements, let, saved); - // Record the substitution of `idx_expr` to the saved variable with - // the symbol `saved_name`. This will be used by the ReplaceAll() - // handler above. - ptr_let->saved_vars.emplace(idx_expr, saved_name); - }); - - // Record the pointer-typed `let` declaration. - // This will be used by the ReplaceAll() handler above. - ptr_lets.emplace(let->variable, std::move(ptr_let)); - // As the original `let` declaration will be fully inlined, there's no - // need for the original declaration to exist. Remove it. - RemoveStatement(ctx, let); - } - } - - ctx.Clone(); -} - -} // namespace transform -} // namespace tint diff --git a/src/transform/simplify.cc b/src/transform/simplify.cc deleted file mode 100644 index 7d26ee2004..0000000000 --- a/src/transform/simplify.cc +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright 2021 The Tint Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "src/transform/simplify.h" - -#include -#include -#include - -#include "src/program_builder.h" -#include "src/sem/block_statement.h" -#include "src/sem/function.h" -#include "src/sem/statement.h" -#include "src/sem/variable.h" -#include "src/utils/scoped_assignment.h" - -TINT_INSTANTIATE_TYPEINFO(tint::transform::Simplify); - -namespace tint { -namespace transform { - -Simplify::Simplify() = default; - -Simplify::~Simplify() = default; - -void Simplify::Run(CloneContext& ctx, const DataMap&, DataMap&) { - ctx.ReplaceAll([&](const ast::Expression* expr) -> const ast::Expression* { - if (auto* outer = expr->As()) { - if (auto* inner = outer->expr->As()) { - if (outer->op == ast::UnaryOp::kAddressOf && - inner->op == ast::UnaryOp::kIndirection) { - // &(*(expr)) => expr - return ctx.Clone(inner->expr); - } - if (outer->op == ast::UnaryOp::kIndirection && - inner->op == ast::UnaryOp::kAddressOf) { - // *(&(expr)) => expr - return ctx.Clone(inner->expr); - } - } - } - return nullptr; - }); - - ctx.Clone(); -} - -} // namespace transform -} // namespace tint diff --git a/src/transform/simplify.h b/src/transform/simplify.h deleted file mode 100644 index 084e0baa7c..0000000000 --- a/src/transform/simplify.h +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2021 The Tint Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef SRC_TRANSFORM_SIMPLIFY_H_ -#define SRC_TRANSFORM_SIMPLIFY_H_ - -#include -#include - -#include "src/transform/transform.h" - -namespace tint { -namespace transform { - -/// Simplify is a peephole optimizer Transform that simplifies ASTs by removing -/// unnecessary operations. -/// Simplify currently optimizes the following: -/// `&(*(expr))` => `expr` -/// `*(&(expr))` => `expr` -class Simplify : public Castable { - public: - /// Constructor - Simplify(); - - /// Destructor - ~Simplify() override; - - protected: - /// Runs the transform using the CloneContext built for transforming a - /// program. Run() is responsible for calling Clone() on the CloneContext. - /// @param ctx the CloneContext primed with the input program and - /// ProgramBuilder - /// @param inputs optional extra transform-specific input data - /// @param outputs optional extra transform-specific output data - void Run(CloneContext& ctx, const DataMap& inputs, DataMap& outputs) override; -}; - -} // namespace transform -} // namespace tint - -#endif // SRC_TRANSFORM_SIMPLIFY_H_ diff --git a/src/transform/simplify_pointers.cc b/src/transform/simplify_pointers.cc new file mode 100644 index 0000000000..6ab7b6a418 --- /dev/null +++ b/src/transform/simplify_pointers.cc @@ -0,0 +1,238 @@ +// Copyright 2021 The Tint Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "src/transform/simplify_pointers.h" + +#include +#include +#include +#include + +#include "src/program_builder.h" +#include "src/sem/block_statement.h" +#include "src/sem/function.h" +#include "src/sem/statement.h" +#include "src/sem/variable.h" + +TINT_INSTANTIATE_TYPEINFO(tint::transform::SimplifyPointers); + +namespace tint { +namespace transform { + +namespace { + +/// PointerOp describes either possible indirection or address-of action on an +/// expression. +struct PointerOp { + /// Positive: Number of times the `expr` was dereferenced (*expr) + /// Negative: Number of times the `expr` was 'addressed-of' (&expr) + /// Zero: no pointer op on `expr` + int indirections = 0; + /// The expression being operated on + const ast::Expression* expr = nullptr; +}; + +} // namespace + +/// The PIMPL state for the SimplifyPointers transform +struct SimplifyPointers::State { + /// The clone context + CloneContext& ctx; + + /// Constructor + /// @param context the clone context + explicit State(CloneContext& context) : ctx(context) {} + + /// Traverses the expression `expr` looking for non-literal array indexing + /// expressions that would affect the computed address of a pointer + /// expression. The function-like argument `cb` is called for each found. + /// @param expr the expression to traverse + /// @param cb a function-like object with the signature + /// `void(const ast::Expression*)`, which is called for each array index + /// expression + template + static void CollectSavedArrayIndices(const ast::Expression* expr, F&& cb) { + if (auto* a = expr->As()) { + CollectSavedArrayIndices(a->object, cb); + if (!a->index->Is()) { + cb(a->index); + } + return; + } + + if (auto* m = expr->As()) { + CollectSavedArrayIndices(m->structure, cb); + return; + } + + if (auto* u = expr->As()) { + CollectSavedArrayIndices(u->expr, cb); + return; + } + + // Note: Other ast::Expression types can be safely ignored as they cannot be + // used to generate a reference or pointer. + // See https://gpuweb.github.io/gpuweb/wgsl/#forming-references-and-pointers + } + + /// Reduce walks the expression chain, collapsing all address-of and + /// indirection ops into a PointerOp. + /// @param in the expression to walk + /// @returns the reduced PointerOp + PointerOp Reduce(const ast::Expression* in) const { + PointerOp op{0, in}; + while (true) { + if (auto* unary = op.expr->As()) { + switch (unary->op) { + case ast::UnaryOp::kIndirection: + op.indirections++; + op.expr = unary->expr; + continue; + case ast::UnaryOp::kAddressOf: + op.indirections--; + op.expr = unary->expr; + continue; + default: + break; + } + } + if (auto* user = ctx.src->Sem().Get(op.expr)) { + auto* var = user->Variable(); + if (var->Is() && // + var->Declaration()->is_const && // + var->Type()->Is()) { + op.expr = var->Declaration()->constructor; + continue; + } + } + return op; + } + } + + /// Performs the transformation + void Run() { + // A map of saved expressions to their saved variable name + std::unordered_map saved_vars; + + // Register the ast::Expression transform handler. + // This performs two different transformations: + // * Identifiers that resolve to the pointer-typed `let` declarations are + // replaced with the recursively inlined initializer expression for the + // `let` declaration. + // * Sub-expressions inside the pointer-typed `let` initializer expression + // that have been hoisted to a saved variable are replaced with the saved + // variable identifier. + ctx.ReplaceAll([&](const ast::Expression* expr) -> const ast::Expression* { + // Look to see if we need to swap this Expression with a saved variable. + auto it = saved_vars.find(expr); + if (it != saved_vars.end()) { + return ctx.dst->Expr(it->second); + } + + // Reduce the expression, folding away chains of address-of / indirections + auto op = Reduce(expr); + + // Clone the reduced root expression + expr = ctx.CloneWithoutTransform(op.expr); + + // And reapply the minimum number of address-of / indirections + for (int i = 0; i < op.indirections; i++) { + expr = ctx.dst->Deref(expr); + } + for (int i = 0; i > op.indirections; i--) { + expr = ctx.dst->AddressOf(expr); + } + return expr; + }); + + // Find all the pointer-typed `let` declarations. + // Note that these must be function-scoped, as module-scoped `let`s are not + // permitted. + for (auto* node : ctx.src->ASTNodes().Objects()) { + if (auto* let = node->As()) { + if (!let->variable->is_const) { + continue; // Not a `let` declaration. Ignore. + } + + auto* var = ctx.src->Sem().Get(let->variable); + if (!var->Type()->Is()) { + continue; // Not a pointer type. Ignore. + } + + // We're dealing with a pointer-typed `let` declaration. + + // Scan the initializer expression for array index expressions that need + // to be hoist to temporary "saved" variables. + std::vector saved; + CollectSavedArrayIndices( + var->Declaration()->constructor, + [&](const ast::Expression* idx_expr) { + // We have a sub-expression that needs to be saved. + // Create a new variable + auto saved_name = ctx.dst->Symbols().New( + ctx.src->Symbols().NameFor(var->Declaration()->symbol) + + "_save"); + auto* decl = ctx.dst->Decl( + ctx.dst->Const(saved_name, nullptr, ctx.Clone(idx_expr))); + saved.emplace_back(decl); + // Record the substitution of `idx_expr` to the saved variable + // with the symbol `saved_name`. This will be used by the + // ReplaceAll() handler above. + saved_vars.emplace(idx_expr, saved_name); + }); + + // Find the place to insert the saved declarations. + // Special care needs to be made for lets declared as the initializer + // part of for-loops. In this case the block will hold the for-loop + // statement, not the let. + if (!saved.empty()) { + auto* stmt = ctx.src->Sem().Get(let); + auto* block = stmt->Block(); + // Find the statement owned by the block (either the let decl or a + // for-loop) + while (block != stmt->Parent()) { + stmt = stmt->Parent(); + } + // Declare the stored variables just before stmt. Order here is + // important as order-of-operations needs to be preserved. + // CollectSavedArrayIndices() visits the LHS of an index accessor + // before the index expression. + for (auto* decl : saved) { + // Note that repeated calls to InsertBefore() with the same `before` + // argument will result in nodes to inserted in the order the + // calls are made (last call is inserted last). + ctx.InsertBefore(block->Declaration()->statements, + stmt->Declaration(), decl); + } + } + + // As the original `let` declaration will be fully inlined, there's no + // need for the original declaration to exist. Remove it. + RemoveStatement(ctx, let); + } + } + ctx.Clone(); + } +}; + +SimplifyPointers::SimplifyPointers() = default; + +SimplifyPointers::~SimplifyPointers() = default; + +void SimplifyPointers::Run(CloneContext& ctx, const DataMap&, DataMap&) { + State(ctx).Run(); +} + +} // namespace transform +} // namespace tint diff --git a/src/transform/inline_pointer_lets.h b/src/transform/simplify_pointers.h similarity index 78% rename from src/transform/inline_pointer_lets.h rename to src/transform/simplify_pointers.h index 21bb919d8f..9f00f9c0e3 100644 --- a/src/transform/inline_pointer_lets.h +++ b/src/transform/simplify_pointers.h @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef SRC_TRANSFORM_INLINE_POINTER_LETS_H_ -#define SRC_TRANSFORM_INLINE_POINTER_LETS_H_ +#ifndef SRC_TRANSFORM_SIMPLIFY_POINTERS_H_ +#define SRC_TRANSFORM_SIMPLIFY_POINTERS_H_ #include #include @@ -23,23 +23,25 @@ namespace tint { namespace transform { -/// InlinePointerLets is a Transform that moves all usage of function-scope +/// SimplifyPointers is a Transform that moves all usage of function-scope /// `let` statements of a pointer type into their places of usage. /// /// Parameters of a pointer type are not adjusted. /// -/// Note: InlinePointerLets does not operate on module-scope `let`s, as these +/// Note: SimplifyPointers does not operate on module-scope `let`s, as these /// cannot be pointers: https://gpuweb.github.io/gpuweb/wgsl/#module-constants /// `A module-scope let-declared constant must be of constructible type.` -class InlinePointerLets : public Castable { +class SimplifyPointers : public Castable { public: /// Constructor - InlinePointerLets(); + SimplifyPointers(); /// Destructor - ~InlinePointerLets() override; + ~SimplifyPointers() override; protected: + struct State; + /// Runs the transform using the CloneContext built for transforming a /// program. Run() is responsible for calling Clone() on the CloneContext. /// @param ctx the CloneContext primed with the input program and @@ -52,4 +54,4 @@ class InlinePointerLets : public Castable { } // namespace transform } // namespace tint -#endif // SRC_TRANSFORM_INLINE_POINTER_LETS_H_ +#endif // SRC_TRANSFORM_SIMPLIFY_POINTERS_H_ diff --git a/src/transform/inline_pointer_lets_test.cc b/src/transform/simplify_pointers_test.cc similarity index 60% rename from src/transform/inline_pointer_lets_test.cc rename to src/transform/simplify_pointers_test.cc index 742ff6453c..b2816abfcd 100644 --- a/src/transform/inline_pointer_lets_test.cc +++ b/src/transform/simplify_pointers_test.cc @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "src/transform/inline_pointer_lets.h" +#include "src/transform/simplify_pointers.h" #include #include @@ -24,18 +24,18 @@ namespace tint { namespace transform { namespace { -using InlinePointerLetsTest = TransformTest; +using SimplifyPointersTest = TransformTest; -TEST_F(InlinePointerLetsTest, EmptyModule) { +TEST_F(SimplifyPointersTest, EmptyModule) { auto* src = ""; auto* expect = ""; - auto got = Run(src); + auto got = Run(src); EXPECT_EQ(expect, str(got)); } -TEST_F(InlinePointerLetsTest, Basic) { +TEST_F(SimplifyPointersTest, FoldPointer) { auto* src = R"( fn f() { var v : i32; @@ -47,16 +47,68 @@ fn f() { auto* expect = R"( fn f() { var v : i32; - let x : i32 = *(&(v)); + let x : i32 = v; } )"; - auto got = Run(src); + auto got = Run(src); EXPECT_EQ(expect, str(got)); } -TEST_F(InlinePointerLetsTest, ComplexChain) { +TEST_F(SimplifyPointersTest, AddressOfDeref) { + auto* src = R"( +fn f() { + var v : i32; + let p : ptr = &(v); + let x : ptr = &(*(p)); + let y : ptr = &(*(&(*(p)))); + let z : ptr = &(*(&(*(&(*(&(*(p)))))))); + var a = *x; + var b = *y; + var c = *z; +} +)"; + + auto* expect = R"( +fn f() { + var v : i32; + var a = v; + var b = v; + var c = v; +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(SimplifyPointersTest, DerefAddressOf) { + auto* src = R"( +fn f() { + var v : i32; + let x : i32 = *(&(v)); + let y : i32 = *(&(*(&(v)))); + let z : i32 = *(&(*(&(*(&(*(&(v)))))))); +} +)"; + + auto* expect = R"( +fn f() { + var v : i32; + let x : i32 = v; + let y : i32 = v; + let z : i32 = v; +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(SimplifyPointersTest, ComplexChain) { auto* src = R"( fn f() { var a : array, 4>; @@ -70,16 +122,16 @@ fn f() { auto* expect = R"( fn f() { var a : array, 4>; - let v : vec4 = *(&((*(&((*(&(a)))[3])))[2])); + let v : vec4 = a[3][2]; } )"; - auto got = Run(src); + auto got = Run(src); EXPECT_EQ(expect, str(got)); } -TEST_F(InlinePointerLetsTest, SavedVars) { +TEST_F(SimplifyPointersTest, SavedVars) { auto* src = R"( struct S { i : i32; @@ -115,7 +167,7 @@ fn arr() { var j : i32 = 0; let p_save = (i + j); i = 2; - *(&(a[p_save].i)) = 4; + a[p_save].i = 4; } fn matrix() { @@ -124,16 +176,16 @@ fn matrix() { var j : i32 = 0; let p_save_1 = (i + j); i = 2; - *(&(m[p_save_1])) = vec3(4.0, 5.0, 6.0); + m[p_save_1] = vec3(4.0, 5.0, 6.0); } )"; - auto got = Run(src); + auto got = Run(src); EXPECT_EQ(expect, str(got)); } -TEST_F(InlinePointerLetsTest, DontSaveLiterals) { +TEST_F(SimplifyPointersTest, DontSaveLiterals) { auto* src = R"( fn f() { var arr : array; @@ -145,16 +197,16 @@ fn f() { auto* expect = R"( fn f() { var arr : array; - *(&(arr[1])) = 4; + arr[1] = 4; } )"; - auto got = Run(src); + auto got = Run(src); EXPECT_EQ(expect, str(got)); } -TEST_F(InlinePointerLetsTest, SavedVarsChain) { +TEST_F(SimplifyPointersTest, SavedVarsChain) { auto* src = R"( fn f() { var arr : array, 2>; @@ -173,16 +225,51 @@ fn f() { let j : i32 = 1; let p_save = i; let q_save = j; - *(&((*(&(arr[p_save])))[q_save])) = 12; + arr[p_save][q_save] = 12; } )"; - auto got = Run(src); + auto got = Run(src); EXPECT_EQ(expect, str(got)); } -TEST_F(InlinePointerLetsTest, MultiSavedVarsInSinglePtrLetExpr) { +TEST_F(SimplifyPointersTest, ForLoopInit) { + auto* src = R"( +fn foo() -> i32 { + return 1; +} + +[[stage(fragment)]] +fn main() { + var arr = array(); + for (let a = &arr[foo()]; ;) { + let x = *a; + } +} +)"; + + auto* expect = R"( +fn foo() -> i32 { + return 1; +} + +[[stage(fragment)]] +fn main() { + var arr = array(); + let a_save = foo(); + for(; ; ) { + let x = arr[a_save]; + } +} +)"; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(SimplifyPointersTest, MultiSavedVarsInSinglePtrLetExpr) { auto* src = R"( fn x() -> i32 { return 1; @@ -238,18 +325,18 @@ fn f() { let p_save = x(); let p_save_1 = y(); let p_save_2 = z(); - *(&(arr[p_save].a[p_save_1].a[p_save_2])) = 1; - *(&(arr[p_save].a[p_save_1].a[p_save_2])) = 2; + arr[p_save].a[p_save_1].a[p_save_2] = 1; + arr[p_save].a[p_save_1].a[p_save_2] = 2; } )"; - auto got = Run(src); + auto got = Run(src); EXPECT_EQ(expect, str(got)); } // TODO(crbug.com/tint/819): Enable when we support inter-scope shadowing. -TEST_F(InlinePointerLetsTest, DISABLED_ModificationAfterInline) { +TEST_F(SimplifyPointersTest, DISABLED_ModificationAfterInline) { auto* src = R"( fn x(p : ptr) -> i32 { return *p; @@ -267,7 +354,7 @@ fn f() { auto* expect = R"()"; - auto got = Run(src); + auto got = Run(src); EXPECT_EQ(expect, str(got)); } diff --git a/src/transform/simplify_test.cc b/src/transform/simplify_test.cc deleted file mode 100644 index d552cb14ae..0000000000 --- a/src/transform/simplify_test.cc +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright 2021 The Tint Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "src/transform/simplify.h" - -#include -#include -#include - -#include "src/transform/test_helper.h" - -namespace tint { -namespace transform { -namespace { - -using SimplifyTest = TransformTest; - -TEST_F(SimplifyTest, EmptyModule) { - auto* src = ""; - auto* expect = ""; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(SimplifyTest, AddressOfDeref) { - auto* src = R"( -fn f() { - var v : i32; - let p : ptr = &(v); - let x : ptr = &(*(p)); - let y : ptr = &(*(&(*(p)))); - let z : ptr = &(*(&(*(&(*(&(*(p)))))))); -} -)"; - - auto* expect = R"( -fn f() { - var v : i32; - let p : ptr = &(v); - let x : ptr = p; - let y : ptr = p; - let z : ptr = p; -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(SimplifyTest, DerefAddressOf) { - auto* src = R"( -fn f() { - var v : i32; - let x : i32 = *(&(v)); - let y : i32 = *(&(*(&(v)))); - let z : i32 = *(&(*(&(*(&(*(&(v)))))))); -} -)"; - - auto* expect = R"( -fn f() { - var v : i32; - let x : i32 = v; - let y : i32 = v; - let z : i32 = v; -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -TEST_F(SimplifyTest, NoChange) { - auto* src = R"( -fn f() { - var v : i32; - let p : ptr = &(v); - let x : i32 = *(p); -} -)"; - - auto* expect = R"( -fn f() { - var v : i32; - let p : ptr = &(v); - let x : i32 = *(p); -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -} // namespace -} // namespace transform -} // namespace tint diff --git a/src/writer/hlsl/generator_impl.cc b/src/writer/hlsl/generator_impl.cc index 664ca0a852..3bf5394ba4 100644 --- a/src/writer/hlsl/generator_impl.cc +++ b/src/writer/hlsl/generator_impl.cc @@ -51,14 +51,13 @@ #include "src/transform/decompose_memory_access.h" #include "src/transform/external_texture_transform.h" #include "src/transform/fold_trivial_single_use_lets.h" -#include "src/transform/inline_pointer_lets.h" #include "src/transform/loop_to_for_loop.h" #include "src/transform/manager.h" #include "src/transform/num_workgroups_from_uniform.h" #include "src/transform/pad_array_elements.h" #include "src/transform/promote_initializers_to_const_var.h" #include "src/transform/remove_phonies.h" -#include "src/transform/simplify.h" +#include "src/transform/simplify_pointers.h" #include "src/transform/zero_init_workgroup_memory.h" #include "src/utils/defer.h" #include "src/utils/map.h" @@ -151,9 +150,7 @@ SanitizedResult Sanitize( // assumes that num_workgroups builtins only appear as struct members and are // only accessed directly via member accessors. manager.Add(); - manager.Add(); - // Simplify cleans up messy `*(&(expr))` expressions from InlinePointerLets. - manager.Add(); + manager.Add(); manager.Add(); // ArrayLengthFromUniform must come after InlinePointerLets and Simplify, as // it assumes that the form of the array length argument is &var.array. diff --git a/src/writer/msl/generator_impl.cc b/src/writer/msl/generator_impl.cc index 73cd51fcac..6054609a99 100644 --- a/src/writer/msl/generator_impl.cc +++ b/src/writer/msl/generator_impl.cc @@ -60,13 +60,12 @@ #include "src/transform/array_length_from_uniform.h" #include "src/transform/canonicalize_entry_point_io.h" #include "src/transform/external_texture_transform.h" -#include "src/transform/inline_pointer_lets.h" #include "src/transform/manager.h" #include "src/transform/module_scope_var_to_entry_point_param.h" #include "src/transform/pad_array_elements.h" #include "src/transform/promote_initializers_to_const_var.h" #include "src/transform/remove_phonies.h" -#include "src/transform/simplify.h" +#include "src/transform/simplify_pointers.h" #include "src/transform/vectorize_scalar_matrix_constructors.h" #include "src/transform/wrap_arrays_in_structs.h" #include "src/transform/zero_init_workgroup_memory.h" @@ -164,10 +163,9 @@ SanitizedResult Sanitize( manager.Add(); manager.Add(); manager.Add(); - manager.Add(); manager.Add(); - manager.Add(); - // ArrayLengthFromUniform must come after InlinePointerLets and Simplify, as + manager.Add(); + // ArrayLengthFromUniform must come after SimplifyPointers, as // it assumes that the form of the array length argument is &var.array. manager.Add(); manager.Add(); diff --git a/src/writer/spirv/builder.cc b/src/writer/spirv/builder.cc index 1894795e2f..b911359576 100644 --- a/src/writer/spirv/builder.cc +++ b/src/writer/spirv/builder.cc @@ -45,9 +45,8 @@ #include "src/transform/external_texture_transform.h" #include "src/transform/fold_constants.h" #include "src/transform/for_loop_to_loop.h" -#include "src/transform/inline_pointer_lets.h" #include "src/transform/manager.h" -#include "src/transform/simplify.h" +#include "src/transform/simplify_pointers.h" #include "src/transform/vectorize_scalar_matrix_constructors.h" #include "src/transform/zero_init_workgroup_memory.h" #include "src/utils/defer.h" @@ -270,8 +269,7 @@ SanitizedResult Sanitize(const Program* in, if (!disable_workgroup_init) { manager.Add(); } - manager.Add(); // Required for arrayLength() - manager.Add(); // Required for arrayLength() + manager.Add(); // Required for arrayLength() manager.Add(); manager.Add(); manager.Add(); diff --git a/test/BUILD.gn b/test/BUILD.gn index 010013a8c2..41e106913b 100644 --- a/test/BUILD.gn +++ b/test/BUILD.gn @@ -314,7 +314,6 @@ tint_unittests_source_set("tint_unittests_transform_src") { "../src/transform/fold_constants_test.cc", "../src/transform/fold_trivial_single_use_lets_test.cc", "../src/transform/for_loop_to_loop_test.cc", - "../src/transform/inline_pointer_lets_test.cc", "../src/transform/loop_to_for_loop_test.cc", "../src/transform/module_scope_var_to_entry_point_param_test.cc", "../src/transform/multiplanar_external_texture_test.cc", @@ -324,7 +323,7 @@ tint_unittests_source_set("tint_unittests_transform_src") { "../src/transform/remove_phonies_test.cc", "../src/transform/renamer_test.cc", "../src/transform/robustness_test.cc", - "../src/transform/simplify_test.cc", + "../src/transform/simplify_pointers_test.cc", "../src/transform/single_entry_point_test.cc", "../src/transform/test_helper.h", "../src/transform/transform_test.cc",