sem::Alias::type_name(): Optimize complexity

Precalculate the type_name to reduce complexity from O(N²) to O(N).

Fixed: chromium:1199700
Fixed: chromium:1200936
Change-Id: Ifd16508ace42d4a686f06d58121cc106842df7d3
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/48691
Commit-Queue: Ben Clayton <bclayton@google.com>
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
This commit is contained in:
Ben Clayton 2021-04-23 18:21:34 +00:00 committed by Commit Bot service account
parent b205b872ae
commit 6052d41d51
6 changed files with 38 additions and 5 deletions

View File

@ -25,7 +25,10 @@ Alias::Alias(ProgramID program_id,
const Source& source,
const Symbol& sym,
Type* subtype)
: Base(program_id, source), symbol_(sym), subtype_(subtype) {
: Base(program_id, source),
symbol_(sym),
subtype_(subtype),
type_name_("__alias_" + sym.to_str() + subtype->type_name()) {
TINT_ASSERT(subtype_);
}
@ -34,7 +37,7 @@ Alias::Alias(Alias&&) = default;
Alias::~Alias() = default;
std::string Alias::type_name() const {
return "__alias_" + symbol_.to_str() + subtype_->type_name();
return type_name_;
}
std::string Alias::FriendlyName(const SymbolTable& symbols) const {

View File

@ -60,6 +60,7 @@ class Alias : public Castable<Alias, Type> {
private:
Symbol const symbol_;
Type* const subtype_;
std::string const type_name_;
};
} // namespace ast

View File

@ -57,6 +57,19 @@ TEST_F(AstAliasTest, Is) {
EXPECT_FALSE(ty->Is<Vector>());
}
// Check for linear-time evaluation of Alias::type_name().
// If type_name() is non-linear, this test should noticeably stall.
// See: crbug.com/1200936
TEST_F(AstAliasTest, TypeName_LinearTime) {
Type* type = ty.i32();
for (int i = 0; i < 1024; i++) {
type = create<Alias>(Symbols().New(), type);
}
for (int i = 0; i < 16384; i++) {
type->type_name();
}
}
TEST_F(AstAliasTest, TypeName) {
auto* at = create<Alias>(Sym("Particle"), create<I32>());
EXPECT_EQ(at->type_name(), "__alias_$1__i32");

View File

@ -22,7 +22,9 @@ namespace tint {
namespace sem {
Alias::Alias(const Symbol& sym, const Type* subtype)
: symbol_(sym), subtype_(subtype) {
: symbol_(sym),
subtype_(subtype),
type_name_("__alias_" + sym.to_str() + subtype->type_name()) {
TINT_ASSERT(subtype_);
}
@ -31,7 +33,7 @@ Alias::Alias(Alias&&) = default;
Alias::~Alias() = default;
std::string Alias::type_name() const {
return "__alias_" + symbol_.to_str() + subtype_->type_name();
return type_name_;
}
std::string Alias::FriendlyName(const SymbolTable& symbols) const {

View File

@ -54,7 +54,8 @@ class Alias : public Castable<Alias, Type> {
private:
Symbol const symbol_;
const Type* const subtype_;
Type const* const subtype_;
std::string const type_name_;
};
} // namespace sem

View File

@ -46,6 +46,19 @@ TEST_F(AliasTest, Is) {
EXPECT_FALSE(ty->Is<Vector>());
}
// Check for linear-time evaluation of Alias::type_name().
// If type_name() is non-linear, this test should noticeably stall.
// See: crbug.com/1200936
TEST_F(AliasTest, TypeName_LinearTime) {
Type* type = ty.i32();
for (int i = 0; i < 1024; i++) {
type = create<Alias>(Symbols().New(), type);
}
for (int i = 0; i < 16384; i++) {
type->type_name();
}
}
TEST_F(AliasTest, TypeName) {
auto* at = create<Alias>(Sym("Particle"), ty.i32());
EXPECT_EQ(at->type_name(), "__alias_$1__i32");