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:
parent
b205b872ae
commit
6052d41d51
|
@ -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 {
|
||||
|
|
|
@ -60,6 +60,7 @@ class Alias : public Castable<Alias, Type> {
|
|||
private:
|
||||
Symbol const symbol_;
|
||||
Type* const subtype_;
|
||||
std::string const type_name_;
|
||||
};
|
||||
|
||||
} // namespace ast
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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");
|
||||
|
|
Loading…
Reference in New Issue