tint/resolver: Optimize intrinsic lookups

Replace use of std::unordered_map with a utils::Vector.
Significantly reduces heap allocations.

Change-Id: I501bfffb7620df9b4e09cd8569c39e418b25e32a
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/98080
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
Reviewed-by: Dan Sinclair <dsinclair@chromium.org>
This commit is contained in:
Ben Clayton 2022-08-03 06:55:57 +00:00 committed by Dawn LUCI CQ
parent 6f8d945dd6
commit 759ac33cd1
1 changed files with 33 additions and 17 deletions

View File

@ -123,17 +123,17 @@ class TemplateState {
/// If none of the above applies, then `ty` is a type mismatch for the template type, and /// If none of the above applies, then `ty` is a type mismatch for the template type, and
/// nullptr is returned. /// nullptr is returned.
const sem::Type* Type(size_t idx, const sem::Type* ty) { const sem::Type* Type(size_t idx, const sem::Type* ty) {
auto res = types_.emplace(idx, ty); if (idx >= types_.Length()) {
if (res.second) { types_.Resize(idx + 1);
}
auto& t = types_[idx];
if (t == nullptr) {
t = ty;
return ty; return ty;
} }
auto* existing = res.first->second; ty = sem::Type::Common(utils::Vector{t, ty});
if (existing == ty) {
return ty;
}
ty = sem::Type::Common(utils::Vector{existing, ty});
if (ty) { if (ty) {
res.first->second = ty; t = ty;
} }
return ty; return ty;
} }
@ -142,28 +142,44 @@ class TemplateState {
/// Num() returns true. If the number is defined, then `Num()` returns true iff it is equal to /// Num() returns true. If the number is defined, then `Num()` returns true iff it is equal to
/// `ty`. /// `ty`.
bool Num(size_t idx, Number number) { bool Num(size_t idx, Number number) {
auto res = numbers_.emplace(idx, number.Value()); if (idx >= numbers_.Length()) {
return res.second || res.first->second == number.Value(); numbers_.Resize(idx + 1, Number::invalid);
}
auto& n = numbers_[idx];
if (!n.IsValid()) {
n = number.Value();
return true;
}
return n.Value() == number.Value();
} }
/// Type returns the template type with index `idx`, or nullptr if the type was not defined. /// Type returns the template type with index `idx`, or nullptr if the type was not defined.
const sem::Type* Type(size_t idx) const { const sem::Type* Type(size_t idx) const {
auto it = types_.find(idx); if (idx >= types_.Length()) {
return (it != types_.end()) ? it->second : nullptr; return nullptr;
}
return types_[idx];
} }
/// SetType replaces the template type with index `idx` with type `ty`. /// SetType replaces the template type with index `idx` with type `ty`.
void SetType(size_t idx, const sem::Type* ty) { types_[idx] = ty; } void SetType(size_t idx, const sem::Type* ty) {
if (idx >= types_.Length()) {
types_.Resize(idx + 1);
}
types_[idx] = ty;
}
/// Type returns the number type with index `idx`. /// Type returns the number type with index `idx`.
Number Num(size_t idx) const { Number Num(size_t idx) const {
auto it = numbers_.find(idx); if (idx >= numbers_.Length()) {
return (it != numbers_.end()) ? Number(it->second) : Number::invalid; return Number::invalid;
}
return numbers_[idx];
} }
private: private:
std::unordered_map<size_t, const sem::Type*> types_; utils::Vector<const sem::Type*, 4> types_;
std::unordered_map<size_t, uint32_t> numbers_; utils::Vector<Number, 2> numbers_;
}; };
/// Index type used for matcher indices /// Index type used for matcher indices