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:
parent
6f8d945dd6
commit
759ac33cd1
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue