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:
parent
97b92178c5
commit
f9f48c60f7
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue