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