From f9f48c60f7002640b9750a5a74351fd6cea419fc Mon Sep 17 00:00:00 2001 From: Ben Clayton Date: Thu, 4 Mar 2021 23:37:25 +0000 Subject: [PATCH] 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 Commit-Queue: Ben Clayton --- src/transform/renamer.cc | 48 ++++++++++++++++++++++++- src/transform/renamer_test.cc | 68 +++++++++++++++++++++++++++++++++++ 2 files changed, 115 insertions(+), 1 deletion(-) diff --git a/src/transform/renamer.cc b/src/transform/renamer.cc index 3527f4dee9..b9b74043cd 100644 --- a/src/transform/renamer.cc +++ b/src/transform/renamer.cc @@ -15,9 +15,14 @@ #include "src/transform/renamer.h" #include +#include #include +#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 @@ Transform::Output Renamer::Run(const Program* in) { ProgramBuilder out; CloneContext ctx(&out, in); + // Swizzles and intrinsic calls need to keep their symbols preserved. + std::unordered_set preserve; + for (auto* node : in->ASTNodes().Objects()) { + if (auto* member = node->As()) { + 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()) { + auto* sem = in->Sem().Get(call); + if (!sem) { + TINT_ICE(out.Diagnostics()) << "CallExpression has no semantic info"; + continue; + } + if (sem->Target()->Is()) { + preserve.emplace(call->func()->As()); + } + } + } + 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( + 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 63d68c36a4..2b3b039f49 100644 --- a/src/transform/renamer_test.cc +++ b/src/transform/renamer_test.cc @@ -80,6 +80,74 @@ fn _tint_3() -> void { EXPECT_THAT(data->remappings, ContainerEq(expected_remappings)); } +TEST_F(RenamerTest, PreserveSwizzles) { + auto* src = R"( +[[stage(vertex)]] +fn entry() -> void { + var v : vec4; + var rgba : f32; + var xyzw : f32; + return v.zyxw + v.rgab; +} +)"; + + auto* expect = R"( +[[stage(vertex)]] +fn _tint_1() -> void { + var _tint_2 : vec4; + var _tint_3 : f32; + var _tint_4 : f32; + return (_tint_2.zyxw + _tint_2.rgab); +} +)"; + + auto got = Transform(src); + + EXPECT_EQ(expect, str(got)); + + auto* data = got.data.Get(); + + 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; + return abs(blah); +} +)"; + + auto* expect = R"( +[[stage(vertex)]] +fn _tint_1() -> void { + var _tint_2 : vec4; + return abs(_tint_2); +} +)"; + + auto got = Transform(src); + + EXPECT_EQ(expect, str(got)); + + auto* data = got.data.Get(); + + 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