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>
This commit is contained in:
Ben Clayton 2021-03-04 23:37:25 +00:00 committed by Commit Bot service account
parent 97b92178c5
commit f9f48c60f7
2 changed files with 115 additions and 1 deletions

View File

@ -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 @@ 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<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();

View File

@ -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<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