mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-17 08:57:26 +00:00
tint/writer: Replace use of strings for cache keys
Concatenating strings to use for cache keys is horribly inefficent and very error prone. Add a UnorderedKeyWrapper helper to allow types to be used as a unordered_map and unordered_set key. Use this for the type_constructor_to_id_ map. Produces SPIR-V with some duplicate SPIR-V instructions for constructors removed. Change-Id: Ib072d485ca28bb07f03e979c133cdce1f69ee482 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/88300 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:
committed by
Dawn LUCI CQ
parent
89fe801dff
commit
046abc08e8
@@ -18,6 +18,7 @@
|
||||
#include <stdint.h>
|
||||
#include <cstdio>
|
||||
#include <functional>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace tint::utils {
|
||||
@@ -76,6 +77,53 @@ size_t Hash(const ARGS&... args) {
|
||||
return hash;
|
||||
}
|
||||
|
||||
/// Wrapper for a hashable type enabling the wrapped value to be used as a key
|
||||
/// for an unordered_map or unordered_set.
|
||||
template <typename T>
|
||||
struct UnorderedKeyWrapper {
|
||||
/// The wrapped value
|
||||
const T value;
|
||||
/// The hash of value
|
||||
const size_t hash;
|
||||
|
||||
/// Constructor
|
||||
/// @param v the value to wrap
|
||||
explicit UnorderedKeyWrapper(const T& v) : value(v), hash(Hash(v)) {}
|
||||
|
||||
/// Move constructor
|
||||
/// @param v the value to wrap
|
||||
explicit UnorderedKeyWrapper(T&& v)
|
||||
: value(std::move(v)), hash(Hash(value)) {}
|
||||
|
||||
/// @returns true if this wrapper comes before other
|
||||
/// @param other the RHS of the operator
|
||||
bool operator<(const UnorderedKeyWrapper& other) const {
|
||||
return hash < other.hash;
|
||||
}
|
||||
|
||||
/// @returns true if this wrapped value is equal to the other wrapped value
|
||||
/// @param other the RHS of the operator
|
||||
bool operator==(const UnorderedKeyWrapper& other) const {
|
||||
return value == other.value;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace tint::utils
|
||||
|
||||
namespace std {
|
||||
|
||||
/// Custom std::hash specialization for tint::utils::UnorderedKeyWrapper
|
||||
template <typename T>
|
||||
class hash<tint::utils::UnorderedKeyWrapper<T>> {
|
||||
public:
|
||||
/// @param w the UnorderedKeyWrapper
|
||||
/// @return the hash value
|
||||
inline std::size_t operator()(
|
||||
const tint::utils::UnorderedKeyWrapper<T>& w) const {
|
||||
return w.hash;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace std
|
||||
|
||||
#endif // SRC_TINT_UTILS_HASH_H_
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "src/tint/utils/hash.h"
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
@@ -43,5 +44,30 @@ TEST(HashTests, Vector) {
|
||||
Hash(std::vector<int>({1, 2, 3, 4})));
|
||||
}
|
||||
|
||||
TEST(HashTests, UnorderedKeyWrapper) {
|
||||
using W = UnorderedKeyWrapper<std::vector<int>>;
|
||||
|
||||
std::unordered_map<W, int> m;
|
||||
|
||||
m.emplace(W{{1, 2}}, -1);
|
||||
EXPECT_EQ(m.size(), 1u);
|
||||
EXPECT_EQ(m[W({1, 2})], -1);
|
||||
|
||||
m.emplace(W{{3, 2}}, 1);
|
||||
EXPECT_EQ(m.size(), 2u);
|
||||
EXPECT_EQ(m[W({3, 2})], 1);
|
||||
EXPECT_EQ(m[W({1, 2})], -1);
|
||||
|
||||
m.emplace(W{{100}}, 100);
|
||||
EXPECT_EQ(m.size(), 3u);
|
||||
EXPECT_EQ(m[W({100})], 100);
|
||||
EXPECT_EQ(m[W({3, 2})], 1);
|
||||
EXPECT_EQ(m[W({1, 2})], -1);
|
||||
|
||||
// Reversed vector element order
|
||||
EXPECT_EQ(m[W({2, 3})], 0);
|
||||
EXPECT_EQ(m[W({2, 1})], 0);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace tint::utils
|
||||
|
||||
Reference in New Issue
Block a user