transform/Renamer: Pass through swizzles and intrinsics These must not be mangled. Bug: tint:273 Change-Id: I05b02bf785c9d6ab587996bfed284e89912cd0cb Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/43941 Reviewed-by: James Price <jrprice@google.com> Commit-Queue: Ben Clayton <bclayton@google.com>
diff --git a/src/transform/renamer.cc b/src/transform/renamer.cc index 3527f4d..b9b7404 100644 --- a/src/transform/renamer.cc +++ b/src/transform/renamer.cc
@@ -15,9 +15,14 @@ #include "src/transform/renamer.h" #include <memory> +#include <unordered_set> #include <utility> +#include "src/ast/member_accessor_expression.h" #include "src/program_builder.h" +#include "src/semantic/call.h" +#include "src/semantic/intrinsic.h" +#include "src/semantic/member_accessor_expression.h" TINT_INSTANTIATE_TYPEINFO(tint::transform::Renamer::Data); @@ -40,16 +45,57 @@ ProgramBuilder out; CloneContext ctx(&out, in); + // Swizzles and intrinsic calls need to keep their symbols preserved. + std::unordered_set<ast::IdentifierExpression*> preserve; + for (auto* node : in->ASTNodes().Objects()) { + if (auto* member = node->As<ast::MemberAccessorExpression>()) { + auto* sem = in->Sem().Get(member); + if (!sem) { + TINT_ICE(out.Diagnostics()) + << "MemberAccessorExpression has no semantic info"; + continue; + } + if (sem->IsSwizzle()) { + preserve.emplace(member->member()); + } + } else if (auto* call = node->As<ast::CallExpression>()) { + auto* sem = in->Sem().Get(call); + if (!sem) { + TINT_ICE(out.Diagnostics()) << "CallExpression has no semantic info"; + continue; + } + if (sem->Target()->Is<semantic::Intrinsic>()) { + preserve.emplace(call->func()->As<ast::IdentifierExpression>()); + } + } + } + Data::Remappings remappings; switch (cfg_.method) { case Method::kMonotonic: ctx.ReplaceAll([&](Symbol sym) { auto str_in = in->Symbols().NameFor(sym); - auto str_out = "_tint_" + std::to_string(sym.value()); + auto it = remappings.find(str_in); + if (it != remappings.end()) { + return out.Symbols().Get(it->second); + } + auto str_out = "_tint_" + std::to_string(remappings.size() + 1); remappings.emplace(str_in, str_out); return out.Symbols().Register(str_out); }); + + ctx.ReplaceAll( + [&](ast::IdentifierExpression* ident) -> ast::IdentifierExpression* { + if (preserve.count(ident)) { + auto sym_in = ident->symbol(); + auto str = in->Symbols().NameFor(sym_in); + auto sym_out = out.Symbols().Register(str); + return ctx.dst->create<ast::IdentifierExpression>( + ctx.Clone(ident->source()), sym_out); + } + return nullptr; // Clone ident. Uses the symbol remapping above. + }); break; } ctx.Clone();
diff --git a/src/transform/renamer_test.cc b/src/transform/renamer_test.cc index 63d68c3..2b3b039 100644 --- a/src/transform/renamer_test.cc +++ b/src/transform/renamer_test.cc
@@ -80,6 +80,74 @@ EXPECT_THAT(data->remappings, ContainerEq(expected_remappings)); } +TEST_F(RenamerTest, PreserveSwizzles) { + auto* src = R"( +[[stage(vertex)]] +fn entry() -> void { + var v : vec4<f32>; + var rgba : f32; + var xyzw : f32; + return v.zyxw + v.rgab; +} +)"; + + auto* expect = R"( +[[stage(vertex)]] +fn _tint_1() -> void { + var _tint_2 : vec4<f32>; + var _tint_3 : f32; + var _tint_4 : f32; + return (_tint_2.zyxw + _tint_2.rgab); +} +)"; + + auto got = Transform<Renamer>(src); + + EXPECT_EQ(expect, str(got)); + + auto* data = got.data.Get<Renamer::Data>(); + + ASSERT_NE(data, nullptr); + Renamer::Data::Remappings expected_remappings = { + {"entry", "_tint_1"}, + {"v", "_tint_2"}, + {"rgba", "_tint_3"}, + {"xyzw", "_tint_4"}, + }; + EXPECT_THAT(data->remappings, ContainerEq(expected_remappings)); +} + +TEST_F(RenamerTest, PreserveIntrinsics) { + auto* src = R"( +[[stage(vertex)]] +fn entry() -> void { + var blah : vec4<f32>; + return abs(blah); +} +)"; + + auto* expect = R"( +[[stage(vertex)]] +fn _tint_1() -> void { + var _tint_2 : vec4<f32>; + return abs(_tint_2); +} +)"; + + auto got = Transform<Renamer>(src); + + EXPECT_EQ(expect, str(got)); + + auto* data = got.data.Get<Renamer::Data>(); + + ASSERT_NE(data, nullptr); + Renamer::Data::Remappings expected_remappings = { + {"entry", "_tint_1"}, + {"blah", "_tint_2"}, + }; + EXPECT_THAT(data->remappings, ContainerEq(expected_remappings)); +} + } // namespace } // namespace transform } // namespace tint