diff --git a/toolchain/base/BUILD b/toolchain/base/BUILD index aed3bda08bb3..72b47aff85be 100644 --- a/toolchain/base/BUILD +++ b/toolchain/base/BUILD @@ -14,7 +14,10 @@ exports_files([ cc_library( name = "block_value_store", - hdrs = ["block_value_store.h"], + hdrs = [ + "block_value_store.h", + "block_value_store_impl.h", + ], deps = [ ":id_tag", ":mem_usage", @@ -29,7 +32,10 @@ cc_library( cc_library( name = "canonical_value_store", - hdrs = ["canonical_value_store.h"], + hdrs = [ + "canonical_value_store.h", + "canonical_value_store_impl.h", + ], deps = [ ":mem_usage", ":value_store", @@ -46,7 +52,9 @@ cc_test( srcs = ["canonical_value_store_test.cpp"], deps = [ ":canonical_value_store", + ":shared_value_stores", ":value_ids", + ":value_store", "//testing/base:gtest_main", "@googletest//:gtest", "@llvm-project//llvm:Support", @@ -233,7 +241,10 @@ cc_library( cc_library( name = "value_store", - hdrs = ["value_store.h"], + hdrs = [ + "value_store.h", + "value_store_impl.h", + ], deps = [ ":id_tag", ":mem_usage", @@ -252,6 +263,7 @@ cc_test( size = "small", srcs = ["value_store_test.cpp"], deps = [ + ":shared_value_stores", ":value_ids", ":value_store", "//common:raw_string_ostream", @@ -334,6 +346,7 @@ generate_runtimes_build_info_cc_library(name = "runtimes_build_info") cc_library( name = "shared_value_stores", + srcs = ["shared_value_stores.cpp"], hdrs = ["shared_value_stores.h"], deps = [ ":canonical_value_store", diff --git a/toolchain/base/block_value_store.h b/toolchain/base/block_value_store.h index 1c3da4d8abd4..3de482c49638 100644 --- a/toolchain/base/block_value_store.h +++ b/toolchain/base/block_value_store.h @@ -15,7 +15,7 @@ #include "toolchain/base/value_store.h" #include "toolchain/base/yaml.h" -namespace Carbon::SemIR { +namespace Carbon { // Provides a block-based ValueStore, which uses slab allocation of added // blocks. This allows references to values to outlast vector resizes that might @@ -23,6 +23,16 @@ namespace Carbon::SemIR { // // BlockValueStore is used as-is, but there are also children that expose the // protected members for type-specific functionality. +// +// This template class is designed to be explicitly instantiated to improve +// compile times. Heavy method definitions are in `block_value_store_impl.h`. +// +// To use a new instantiation: +// 1. Add an `extern template class BlockValueStore<...>;` declaration in the +// header where the instantiation is anchored. +// 2. Add `template class BlockValueStore<...>;` definition in the associated +// `.cpp` file. +// 3. Include `toolchain/base/block_value_store_impl.h` in that `.cpp` file. template class BlockValueStore : public Yaml::Printable> { @@ -36,15 +46,11 @@ class BlockValueStore explicit BlockValueStore(llvm::BumpPtrAllocator& allocator, IdTagType::TagIdType tag_id, int32_t initial_reserved_ids = 0) - requires(!IdTagIsUntagged) - : allocator_(&allocator), values_(tag_id, initial_reserved_ids) { - if constexpr (requires { IdT::Empty; }) { - auto empty = RefType(); - auto empty_val = canonical_blocks_.Insert( - empty, [&] { return values_.Add(empty); }, KeyContext(this)); - CARBON_CHECK(empty_val.key() == IdT::Empty); - } - } + requires(!IdTagIsUntagged); + + ~BlockValueStore(); + BlockValueStore(BlockValueStore&&) noexcept; + auto operator=(BlockValueStore&&) noexcept -> BlockValueStore&; // Adds a block with the given content, returning an ID to reference it. auto Add(ConstRefType content) -> IdT { @@ -96,26 +102,11 @@ class BlockValueStore return result.key(); } - auto OutputYaml() const -> Yaml::OutputMapping { - return Yaml::OutputMapping([&](Yaml::OutputMapping::Map map) { - for (auto [block_id, block] : values_.enumerate()) { - map.Add(PrintToString(block_id), - Yaml::OutputMapping([&](Yaml::OutputMapping::Map map) { - for (auto [i, elem_id] : llvm::enumerate(block)) { - map.Add(llvm::itostr(i), Yaml::OutputScalar(elem_id)); - } - })); - } - }); - } + auto OutputYaml() const -> Yaml::OutputMapping; // Collects memory usage of members. auto CollectMemUsage(MemUsage& mem_usage, llvm::StringRef label) const - -> void { - mem_usage.Collect(MemUsage::ConcatLabel(label, "values_"), values_); - mem_usage.Collect(MemUsage::ConcatLabel(label, "canonical_blocks_"), - canonical_blocks_, KeyContext(this)); - } + -> void; auto size() const -> size_t { return values_.size(); } @@ -127,21 +118,10 @@ class BlockValueStore protected: // Allocates a copy of the given data using our slab allocator. - auto AllocateCopy(ConstRefType data) -> RefType { - auto result = AllocateUninitialized(data.size()); - std::uninitialized_copy(data.begin(), data.end(), result.begin()); - return result; - } + auto AllocateCopy(ConstRefType data) -> RefType; // Allocates an uninitialized array using our slab allocator. - auto AllocateUninitialized(size_t size) -> RefType { - // We're not going to run a destructor, so ensure that's OK. - static_assert(std::is_trivially_destructible_v); - - auto storage = static_cast( - allocator_->Allocate(size * sizeof(ElementType), alignof(ElementType))); - return RefType(storage, size); - } + auto AllocateUninitialized(size_t size) -> RefType; // Allow children to have more complex value handling. auto values() -> ValueStore& { return values_; } @@ -166,6 +146,6 @@ class BlockValueStore::KeyContext const BlockValueStore* store_; }; -} // namespace Carbon::SemIR +} // namespace Carbon #endif // CARBON_TOOLCHAIN_BASE_BLOCK_VALUE_STORE_H_ diff --git a/toolchain/base/block_value_store_impl.h b/toolchain/base/block_value_store_impl.h new file mode 100644 index 000000000000..2f04fd03b763 --- /dev/null +++ b/toolchain/base/block_value_store_impl.h @@ -0,0 +1,88 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#ifndef CARBON_TOOLCHAIN_BASE_BLOCK_VALUE_STORE_IMPL_H_ +#define CARBON_TOOLCHAIN_BASE_BLOCK_VALUE_STORE_IMPL_H_ + +#include "toolchain/base/block_value_store.h" + +namespace Carbon { + +template +BlockValueStore::BlockValueStore( + llvm::BumpPtrAllocator& allocator, IdTagType::TagIdType tag_id, + int32_t initial_reserved_ids) + requires(!IdTagIsUntagged) + : allocator_(&allocator), values_(tag_id, initial_reserved_ids) { + if constexpr (requires { IdT::Empty; }) { + auto empty = RefType(); + auto empty_val = canonical_blocks_.Insert( + empty, [&] { return values_.Add(empty); }, KeyContext(this)); + CARBON_CHECK(empty_val.key() == IdT::Empty); + } +} + +template +BlockValueStore::~BlockValueStore() = default; + +template +BlockValueStore::BlockValueStore( + BlockValueStore&&) noexcept = default; + +template +auto BlockValueStore::operator=( + BlockValueStore&&) noexcept -> BlockValueStore& = default; + +template +auto BlockValueStore::OutputYaml() const + -> Yaml::OutputMapping { + return Yaml::OutputMapping([&](Yaml::OutputMapping::Map map) { + for (auto [block_id, block] : values_.enumerate()) { + map.Add(PrintToString(block_id), + Yaml::OutputMapping([&](Yaml::OutputMapping::Map map) { + for (auto [i, elem_id] : llvm::enumerate(block)) { + if constexpr (requires(llvm::raw_ostream& out) { + out << elem_id; + }) { + map.Add(llvm::itostr(i), Yaml::OutputScalar(elem_id)); + } else { + map.Add(llvm::itostr(i), + Yaml::OutputScalar("")); + } + } + })); + } + }); +} + +template +auto BlockValueStore::CollectMemUsage( + MemUsage& mem_usage, llvm::StringRef label) const -> void { + mem_usage.Collect(MemUsage::ConcatLabel(label, "values_"), values_); + mem_usage.Collect(MemUsage::ConcatLabel(label, "canonical_blocks_"), + canonical_blocks_, KeyContext(this)); +} + +template +auto BlockValueStore::AllocateCopy(ConstRefType data) + -> RefType { + auto result = AllocateUninitialized(data.size()); + std::uninitialized_copy(data.begin(), data.end(), result.begin()); + return result; +} + +template +auto BlockValueStore::AllocateUninitialized(size_t size) + -> RefType { + // We're not going to run a destructor, so ensure that's OK. + static_assert(std::is_trivially_destructible_v); + + auto storage = static_cast( + allocator_->Allocate(size * sizeof(ElementType), alignof(ElementType))); + return RefType(storage, size); +} + +} // namespace Carbon + +#endif // CARBON_TOOLCHAIN_BASE_BLOCK_VALUE_STORE_IMPL_H_ diff --git a/toolchain/base/canonical_value_store.h b/toolchain/base/canonical_value_store.h index 27c74f7656cd..700a4f46f0fc 100644 --- a/toolchain/base/canonical_value_store.h +++ b/toolchain/base/canonical_value_store.h @@ -22,6 +22,17 @@ namespace Carbon { // `KeyT` can optionally be different from `ValueT`, and if so is used for the // argument to `Lookup`. In this case, `ValueT` must provide a `GetAsKey` member // function that returns the corresponding key. +// +// This template class is designed to be explicitly instantiated to improve +// compile times. Heavy method definitions are in +// `canonical_value_store_impl.h`. +// +// To use a new instantiation: +// 1. Add an `extern template class CanonicalValueStore<...>;` declaration in +// the header where the instantiation is anchored. +// 2. Add `template class CanonicalValueStore<...>;` definition in the +// associated `.cpp` file. +// 3. Include `toolchain/base/canonical_value_store_impl.h` in that `.cpp` file. template class CanonicalValueStore { @@ -33,10 +44,15 @@ class CanonicalValueStore { using RefType = ValueStoreTypes::RefType; using ConstRefType = ValueStoreTypes::ConstRefType; - CanonicalValueStore() = default; - template - explicit CanonicalValueStore(Id id, int32_t initial_reserved_ids = 0) - : values_(id, initial_reserved_ids) {} + CanonicalValueStore() + requires(IdTagIsUntagged>); + explicit CanonicalValueStore(IdTagType::TagIdType id, + int32_t initial_reserved_ids = 0) + requires(!IdTagIsUntagged>); + + ~CanonicalValueStore(); + CanonicalValueStore(CanonicalValueStore&&) noexcept; + auto operator=(CanonicalValueStore&&) noexcept -> CanonicalValueStore&; // Stores a canonical copy of the value and returns an ID to reference it. If // the value is already in the store, returns the ID of the existing value. @@ -53,9 +69,7 @@ class CanonicalValueStore { auto Reserve(size_t size) -> void; // These are to support printable structures, and are not guaranteed. - auto OutputYaml() const -> Yaml::OutputMapping { - return values_.OutputYaml(); - } + auto OutputYaml() const -> Yaml::OutputMapping; auto values() const [[clang::lifetimebound]] -> ValueStore::Range { @@ -66,11 +80,7 @@ class CanonicalValueStore { // Collects memory usage of the values and deduplication set. auto CollectMemUsage(MemUsage& mem_usage, llvm::StringRef label) const - -> void { - mem_usage.Collect(MemUsage::ConcatLabel(label, "values_"), values_); - auto bytes = set_.ComputeMetrics(KeyContext(&values_)).storage_bytes; - mem_usage.Add(MemUsage::ConcatLabel(label, "set_"), bytes, bytes); - } + -> void; auto GetRawIndex(IdT id) const -> int32_t { return values_.GetRawIndex(id); } @@ -112,24 +122,42 @@ class CanonicalValueStore::KeyContext const ValueStore* values_; }; +// The definition of `Add` needs to be outside the class body as it relies on +// the definition of `KeyContext` being complete. +// +// Note that the `inline` keyword is necessary here even though this is a +// template because we do explicit instantiations of this template which will +// make inlining this routine impossible despite it being performance sensitive. template -auto CanonicalValueStore::Add(ValueType value) +inline auto CanonicalValueStore::Add(ValueType value) -> IdT { auto make_key = [&] { return IdT(values_.Add(std::move(value))); }; return set_.Insert(GetAsKey(value), make_key, KeyContext(&values_)).key(); } +// The definition of `Lookup` needs to be outside the class body as it relies on +// the definition of `KeyContext` being complete. +// +// Note that the `inline` keyword is necessary here even though this is a +// template because we do explicit instantiations of this template which will +// make inlining this routine impossible despite it being performance sensitive. template -auto CanonicalValueStore::Lookup(KeyType key) const - -> IdT { +inline auto CanonicalValueStore::Lookup( + KeyType key) const -> IdT { if (auto result = set_.Lookup(key, KeyContext(&values_))) { return result.key(); } return IdT::None; } +// The definition of `Reserve` needs to be outside the class body as it relies +// on the definition of `KeyContext` being complete. +// +// Note that the `inline` keyword is necessary here even though this is a +// template because we do explicit instantiations of this template which will +// make inlining this routine impossible despite it being performance sensitive. template -auto CanonicalValueStore::Reserve(size_t size) +inline auto CanonicalValueStore::Reserve(size_t size) -> void { // Compute the resulting new insert count using the size of values -- the // set doesn't have a fast to compute current size. diff --git a/toolchain/base/canonical_value_store_impl.h b/toolchain/base/canonical_value_store_impl.h new file mode 100644 index 000000000000..a5f42c102d3c --- /dev/null +++ b/toolchain/base/canonical_value_store_impl.h @@ -0,0 +1,51 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#ifndef CARBON_TOOLCHAIN_BASE_CANONICAL_VALUE_STORE_IMPL_H_ +#define CARBON_TOOLCHAIN_BASE_CANONICAL_VALUE_STORE_IMPL_H_ + +#include "toolchain/base/canonical_value_store.h" + +namespace Carbon { + +template +CanonicalValueStore::CanonicalValueStore() + requires(IdTagIsUntagged>) += default; + +template +CanonicalValueStore::CanonicalValueStore( + typename IdTagType::TagIdType id, int32_t initial_reserved_ids) + requires(!IdTagIsUntagged>) + : values_(id, initial_reserved_ids) {} + +template +CanonicalValueStore::~CanonicalValueStore() = + default; + +template +CanonicalValueStore::CanonicalValueStore( + CanonicalValueStore&&) noexcept = default; + +template +auto CanonicalValueStore::operator=( + CanonicalValueStore&&) noexcept -> CanonicalValueStore& = default; + +template +auto CanonicalValueStore::OutputYaml() const + -> Yaml::OutputMapping { + return values_.OutputYaml(); +} + +template +auto CanonicalValueStore::CollectMemUsage( + MemUsage& mem_usage, llvm::StringRef label) const -> void { + mem_usage.Collect(MemUsage::ConcatLabel(label, "values_"), values_); + auto bytes = set_.ComputeMetrics(KeyContext(&values_)).storage_bytes; + mem_usage.Add(MemUsage::ConcatLabel(label, "set_"), bytes, bytes); +} + +} // namespace Carbon + +#endif // CARBON_TOOLCHAIN_BASE_CANONICAL_VALUE_STORE_IMPL_H_ diff --git a/toolchain/base/canonical_value_store_test.cpp b/toolchain/base/canonical_value_store_test.cpp index 441c88f0b94f..642a9538fab4 100644 --- a/toolchain/base/canonical_value_store_test.cpp +++ b/toolchain/base/canonical_value_store_test.cpp @@ -11,7 +11,9 @@ #include "llvm/ADT/APFloat.h" #include "llvm/ADT/StringRef.h" +#include "toolchain/base/canonical_value_store_impl.h" #include "toolchain/base/value_ids.h" +#include "toolchain/base/value_store_impl.h" namespace Carbon::Testing { namespace { diff --git a/toolchain/base/int.cpp b/toolchain/base/int.cpp index 6d292b7444be..9ecb519c1b81 100644 --- a/toolchain/base/int.cpp +++ b/toolchain/base/int.cpp @@ -7,6 +7,9 @@ #include #include +#include "toolchain/base/canonical_value_store_impl.h" +#include "toolchain/base/value_store_impl.h" + namespace Carbon { auto IntStore::CanonicalBitWidth(int significant_bits) -> int { @@ -66,4 +69,7 @@ auto IntStore::CollectMemUsage(MemUsage& mem_usage, llvm::StringRef label) const mem_usage.Collect(std::string(label), values_); } +template class CanonicalValueStore; +template class ValueStore; + } // namespace Carbon diff --git a/toolchain/base/int.h b/toolchain/base/int.h index 52e3ae264496..f450bb67a133 100644 --- a/toolchain/base/int.h +++ b/toolchain/base/int.h @@ -432,6 +432,9 @@ class IntStore { inline constexpr IntStore::APIntId IntStore::APIntId::None( IntId::None.AsIndex()); +extern template class CanonicalValueStore; +extern template class ValueStore; + } // namespace Carbon #endif // CARBON_TOOLCHAIN_BASE_INT_H_ diff --git a/toolchain/base/shared_value_stores.cpp b/toolchain/base/shared_value_stores.cpp new file mode 100644 index 000000000000..d292b2723efe --- /dev/null +++ b/toolchain/base/shared_value_stores.cpp @@ -0,0 +1,20 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include "toolchain/base/shared_value_stores.h" + +#include "toolchain/base/canonical_value_store_impl.h" +#include "toolchain/base/value_store_impl.h" + +namespace Carbon { + +template class CanonicalValueStore; +template class CanonicalValueStore; +template class CanonicalValueStore; +template class ValueStore; +template class ValueStore; +template class ValueStore; +template class ValueStore; + +} // namespace Carbon diff --git a/toolchain/base/shared_value_stores.h b/toolchain/base/shared_value_stores.h index dd5501f1d486..f4dd30752810 100644 --- a/toolchain/base/shared_value_stores.h +++ b/toolchain/base/shared_value_stores.h @@ -87,6 +87,15 @@ class SharedValueStores : public Yaml::Printable { StringLiteralStore string_literals_; }; +extern template class CanonicalValueStore; +extern template class CanonicalValueStore; +extern template class CanonicalValueStore; +extern template class ValueStore; +extern template class ValueStore; +extern template class ValueStore; +extern template class ValueStore; + } // namespace Carbon #endif // CARBON_TOOLCHAIN_BASE_SHARED_VALUE_STORES_H_ diff --git a/toolchain/base/value_store.h b/toolchain/base/value_store.h index 9f3b059e41a8..16e0e8d639e2 100644 --- a/toolchain/base/value_store.h +++ b/toolchain/base/value_store.h @@ -35,6 +35,16 @@ class ValueStoreNotPrintable {}; // A simple wrapper for accumulating values, providing IDs to later retrieve the // value. This does not do deduplication. +// +// This template class is designed to be explicitly instantiated to improve +// compile times. Heavy method definitions are in `value_store_impl.h`. +// +// To use a new instantiation: +// 1. Add an `extern template class ValueStore<...>;` declaration in the header +// where the instantiation is anchored. +// 2. Add `template class ValueStore<...>;` definition in the associated `.cpp` +// file. +// 3. Include `toolchain/base/value_store_impl.h` in that `.cpp` file. template class ValueStore : public std::conditional, ValueT>, @@ -76,21 +86,18 @@ class ValueStore FlattenedRangeType flattened_range_; }; - // Default constructor, only valid when the IdTag's tag type is Untagged. ValueStore() - requires(IdTagIsUntagged) - = default; + requires(IdTagIsUntagged); - // Construct a ValueStore sharing the IdTag from another ValueStore. Useful - // for when two ValueStores are sharing the same ID types. explicit ValueStore(IdTagType tag) - requires(!IdTagIsUntagged) - : tag_(tag) {} + requires(!IdTagIsUntagged); - // Construct a ValueStore with a given tag and set of untagged (reserved) ids. explicit ValueStore(IdTagType::TagIdType id, int32_t initial_reserved_ids = 0) - requires(!IdTagIsUntagged) - : tag_(id, initial_reserved_ids) {} + requires(!IdTagIsUntagged); + + ~ValueStore(); + ValueStore(ValueStore&&) noexcept; + auto operator=(ValueStore&&) noexcept -> ValueStore&; // Stores the value and returns an ID to reference it. auto Add(ValueType value) -> IdType { @@ -142,7 +149,8 @@ class ValueStore return chunks_[chunk_index].Get(pos); } - // Reserves space. + // Reserves space. Note that this method has surprising performance impact on + // the lexer unless available for inlining. auto Reserve(int32_t size) -> void { if (size <= size_) { return; @@ -152,51 +160,15 @@ class ValueStore } // Grows the ValueStore to `size`. Fills entries with `default_value`. - auto Resize(int32_t size, ConstRefType default_value) -> void { - if (size <= size_) { - return; - } - - auto [begin_chunk_index, begin_pos] = RawIndexToChunkIndices(size_); - // Use an inclusive range so that if `size` would be the next chunk, we - // don't try doing something with it. - auto [end_chunk_index, end_pos] = RawIndexToChunkIndices(size - 1); - chunks_.resize(end_chunk_index + 1); - - // If the begin and end chunks are the same, we only fill from begin to end. - if (begin_chunk_index == end_chunk_index) { - chunks_[begin_chunk_index].UninitializedFill(end_pos - begin_pos + 1, - default_value); - } else { - // Otherwise, we do partial fills on the begin and end chunk, and full - // fills on intermediate chunks. - chunks_[begin_chunk_index].UninitializedFill( - Chunk::Capacity() - begin_pos, default_value); - for (auto i = begin_chunk_index + 1; i < end_chunk_index; ++i) { - chunks_[i].UninitializedFill(Chunk::Capacity(), default_value); - } - chunks_[end_chunk_index].UninitializedFill(end_pos + 1, default_value); - } - - // Update size. - size_ = size; - } + auto Resize(int32_t size, ConstRefType default_value) -> void + requires(std::is_copy_constructible_v); // These are to support printable structures, and are not guaranteed. - auto OutputYaml() const -> Yaml::OutputMapping { - return Yaml::OutputMapping([&](Yaml::OutputMapping::Map map) { - for (auto [id, value] : enumerate()) { - map.Add(PrintToString(id), Yaml::OutputScalar(value)); - } - }); - } + auto OutputYaml() const -> Yaml::OutputMapping; // Collects memory usage of the values. auto CollectMemUsage(MemUsage& mem_usage, llvm::StringRef label) const - -> void { - mem_usage.Add(label.str(), size_ * sizeof(ValueType), - Chunk::CapacityBytes * chunks_.size()); - } + -> void; auto size() const -> size_t { return size_; } @@ -358,11 +330,8 @@ class ValueStore // Fills `fill_count` entries with `default_value`, increasing the size // respectively. auto UninitializedFill(int32_t fill_count, ConstRefType default_value) - -> void { - CARBON_DCHECK(num_ + fill_count <= Capacity()); - std::uninitialized_fill_n(buf_ + num_, fill_count, default_value); - num_ += fill_count; - } + -> void + requires(std::is_copy_constructible_v); auto size() const -> int32_t { return num_; } diff --git a/toolchain/base/value_store_impl.h b/toolchain/base/value_store_impl.h new file mode 100644 index 000000000000..a3018699e76d --- /dev/null +++ b/toolchain/base/value_store_impl.h @@ -0,0 +1,108 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#ifndef CARBON_TOOLCHAIN_BASE_VALUE_STORE_IMPL_H_ +#define CARBON_TOOLCHAIN_BASE_VALUE_STORE_IMPL_H_ + +#include "toolchain/base/value_store.h" + +namespace Carbon { + +template +ValueStore::ValueStore() + requires(IdTagIsUntagged) += default; + +template +ValueStore::ValueStore(IdTagType tag) + requires(!IdTagIsUntagged) + : tag_(tag) {} + +template +ValueStore::ValueStore( + typename ValueStore::IdTagType::TagIdType id, + int32_t initial_reserved_ids) + requires(!IdTagIsUntagged) + : tag_(id, initial_reserved_ids) {} + +template +ValueStore::~ValueStore() = default; + +template +ValueStore::ValueStore(ValueStore&&) noexcept = default; + +template +auto ValueStore::operator=(ValueStore&&) noexcept + -> ValueStore& = default; + +template +auto ValueStore::Resize(int32_t size, + ConstRefType default_value) -> void + requires(std::is_copy_constructible_v) +{ + if (size <= size_) { + return; + } + + auto [begin_chunk_index, begin_pos] = RawIndexToChunkIndices(size_); + // Use an inclusive range so that if `size` would be the next chunk, we + // don't try doing something with it. + auto [end_chunk_index, end_pos] = RawIndexToChunkIndices(size - 1); + chunks_.resize(end_chunk_index + 1); + + // If the begin and end chunks are the same, we only fill from begin to end. + if (begin_chunk_index == end_chunk_index) { + chunks_[begin_chunk_index].UninitializedFill(end_pos - begin_pos + 1, + default_value); + } else { + // Otherwise, we do partial fills on the begin and end chunk, and full + // fills on intermediate chunks. + chunks_[begin_chunk_index].UninitializedFill(Chunk::Capacity() - begin_pos, + default_value); + for (auto i = begin_chunk_index + 1; i < end_chunk_index; ++i) { + chunks_[i].UninitializedFill(Chunk::Capacity(), default_value); + } + chunks_[end_chunk_index].UninitializedFill(end_pos + 1, default_value); + } + + // Update size. + size_ = size; +} + +template +auto ValueStore::Chunk::UninitializedFill( + int32_t fill_count, + typename ValueStore::ConstRefType default_value) + -> void + requires(std::is_copy_constructible_v) +{ + CARBON_DCHECK(num_ + fill_count <= Capacity()); + std::uninitialized_fill_n(buf_ + num_, fill_count, default_value); + num_ += fill_count; +} + +template +auto ValueStore::OutputYaml() const + -> Yaml::OutputMapping { + return Yaml::OutputMapping([&](Yaml::OutputMapping::Map map) { + for (auto [id, value] : enumerate()) { + if constexpr (requires(llvm::raw_ostream& out) { out << value; }) { + map.Add(PrintToString(id), Yaml::OutputScalar(value)); + } else { + map.Add(PrintToString(id), Yaml::OutputScalar("")); + } + } + }); +} + +template +auto ValueStore::CollectMemUsage( + MemUsage& mem_usage, llvm::StringRef label) const -> void { + mem_usage.Add(label.str(), size_ * sizeof(ValueType), + Chunk::CapacityBytes * chunks_.size()); +} + +} // namespace Carbon + +#endif // CARBON_TOOLCHAIN_BASE_VALUE_STORE_IMPL_H_ diff --git a/toolchain/lex/BUILD b/toolchain/lex/BUILD index 10534f5a4e8f..4da6d167ac6f 100644 --- a/toolchain/lex/BUILD +++ b/toolchain/lex/BUILD @@ -257,6 +257,7 @@ cc_library( "//toolchain/base:index_base", "//toolchain/base:mem_usage", "//toolchain/base:shared_value_stores", + "//toolchain/base:value_store", "//toolchain/diagnostics:emitter", "//toolchain/source:source_buffer", "@llvm-project//llvm:Support", diff --git a/toolchain/lex/tokenized_buffer.cpp b/toolchain/lex/tokenized_buffer.cpp index a3479d4b66e0..b02edb49866e 100644 --- a/toolchain/lex/tokenized_buffer.cpp +++ b/toolchain/lex/tokenized_buffer.cpp @@ -16,6 +16,7 @@ #include "llvm/Support/Format.h" #include "llvm/Support/FormatVariadic.h" #include "toolchain/base/shared_value_stores.h" +#include "toolchain/base/value_store_impl.h" #include "toolchain/diagnostics/emitter.h" #include "toolchain/lex/character_set.h" #include "toolchain/lex/numeric_literal.h" @@ -449,3 +450,9 @@ auto TokenizedBuffer::OverlapsWithDumpSemIRRange( } } // namespace Carbon::Lex + +namespace Carbon { +template class ValueStore; +template class ValueStore; +template class ValueStore; +} // namespace Carbon diff --git a/toolchain/lex/tokenized_buffer.h b/toolchain/lex/tokenized_buffer.h index 8de771385253..152d44ed3080 100644 --- a/toolchain/lex/tokenized_buffer.h +++ b/toolchain/lex/tokenized_buffer.h @@ -383,4 +383,10 @@ inline auto TokenizedBuffer::AddToken(TokenInfo info) -> TokenIndex { } // namespace Carbon::Lex +namespace Carbon { +extern template class ValueStore; +extern template class ValueStore; +extern template class ValueStore; +} // namespace Carbon + #endif // CARBON_TOOLCHAIN_LEX_TOKENIZED_BUFFER_H_ diff --git a/toolchain/parse/tree.cpp b/toolchain/parse/tree.cpp index 266c51f8d45c..06495c87a8e2 100644 --- a/toolchain/parse/tree.cpp +++ b/toolchain/parse/tree.cpp @@ -8,6 +8,7 @@ #include "common/error.h" #include "llvm/ADT/Sequence.h" #include "llvm/ADT/SmallVector.h" +#include "toolchain/base/value_store_impl.h" #include "toolchain/lex/tokenized_buffer.h" #include "toolchain/parse/node_kind.h" #include "toolchain/parse/tree_and_subtrees.h" @@ -87,3 +88,8 @@ auto Tree::PostorderIterator::Print(llvm::raw_ostream& output) const -> void { } } // namespace Carbon::Parse + +namespace Carbon { +template class ValueStore; +} // namespace Carbon diff --git a/toolchain/parse/tree.h b/toolchain/parse/tree.h index 4c9510cf2d5d..b1c2ffdeedf4 100644 --- a/toolchain/parse/tree.h +++ b/toolchain/parse/tree.h @@ -349,4 +349,9 @@ struct Tree::ConvertTo> { } // namespace Carbon::Parse +namespace Carbon { +extern template class ValueStore; +} // namespace Carbon + #endif // CARBON_TOOLCHAIN_PARSE_TREE_H_ diff --git a/toolchain/sem_ir/BUILD b/toolchain/sem_ir/BUILD index 22e4e9bd9d66..773023e2c4a8 100644 --- a/toolchain/sem_ir/BUILD +++ b/toolchain/sem_ir/BUILD @@ -59,6 +59,7 @@ cc_library( "//common:ostream", "//common:raw_string_ostream", "//toolchain/base:canonical_value_store", + "//toolchain/base:value_store", "@llvm-project//clang:ast", ], ) @@ -82,11 +83,14 @@ cc_library( cc_library( name = "file", srcs = [ + "associated_constant.cpp", "builtin_function_kind.cpp", "class.cpp", "constant.cpp", "core_interface.cpp", + "cpp_global_var.cpp", "cpp_initializer_list.cpp", + "cpp_overload_set.cpp", "facet_type_info.cpp", "file.cpp", "function.cpp", @@ -94,12 +98,18 @@ cc_library( "impl.cpp", "import_ir.cpp", "inst.cpp", + "interface.cpp", "name.cpp", "name_scope.cpp", + "named_constraint.cpp", "pattern.cpp", + "require_impls.cpp", + "specific_interface.cpp", + "struct_type_field.cpp", "type.cpp", "type_info.cpp", "type_iterator.cpp", + "vtable.cpp", ], hdrs = [ "associated_constant.h", diff --git a/toolchain/sem_ir/associated_constant.cpp b/toolchain/sem_ir/associated_constant.cpp new file mode 100644 index 000000000000..2f0d2c6cc6fa --- /dev/null +++ b/toolchain/sem_ir/associated_constant.cpp @@ -0,0 +1,12 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include "toolchain/sem_ir/associated_constant.h" + +#include "toolchain/base/value_store_impl.h" + +namespace Carbon { +template class ValueStore>; +} // namespace Carbon diff --git a/toolchain/sem_ir/associated_constant.h b/toolchain/sem_ir/associated_constant.h index 1421631e91a2..eec01645e917 100644 --- a/toolchain/sem_ir/associated_constant.h +++ b/toolchain/sem_ir/associated_constant.h @@ -50,4 +50,10 @@ using AssociatedConstantStore = } // namespace Carbon::SemIR +namespace Carbon { +extern template class ValueStore>; +} // namespace Carbon + #endif // CARBON_TOOLCHAIN_SEM_IR_ASSOCIATED_CONSTANT_H_ diff --git a/toolchain/sem_ir/bundle.h b/toolchain/sem_ir/bundle.h index 74a7308ddb4f..cfd1b89fd97d 100644 --- a/toolchain/sem_ir/bundle.h +++ b/toolchain/sem_ir/bundle.h @@ -307,4 +307,9 @@ class BundleStore { } // namespace Carbon::SemIR +namespace Carbon { +extern template class BlockValueStore>; +} // namespace Carbon + #endif // CARBON_TOOLCHAIN_SEM_IR_BUNDLE_H_ diff --git a/toolchain/sem_ir/clang_decl.cpp b/toolchain/sem_ir/clang_decl.cpp index 8752e0740d57..097e65c672a7 100644 --- a/toolchain/sem_ir/clang_decl.cpp +++ b/toolchain/sem_ir/clang_decl.cpp @@ -8,6 +8,8 @@ #include "clang/AST/TextNodeDumper.h" #include "common/ostream.h" #include "common/raw_string_ostream.h" +#include "toolchain/base/canonical_value_store_impl.h" +#include "toolchain/base/value_store_impl.h" namespace Carbon::SemIR { @@ -107,3 +109,15 @@ auto ClangDeclStore::CollectMemUsage(MemUsage& mem_usage, } } // namespace Carbon::SemIR + +namespace Carbon { +template class CanonicalValueStore, SemIR::ClangDecl>; +template class ValueStore>; +template class CanonicalValueStore< + SemIR::ClangDeclSignatureId, SemIR::ClangDeclSignature, + Tag, SemIR::ClangDeclSignature>; +template class ValueStore>; +} // namespace Carbon diff --git a/toolchain/sem_ir/clang_decl.h b/toolchain/sem_ir/clang_decl.h index d9920ba47a74..07cf0c095a18 100644 --- a/toolchain/sem_ir/clang_decl.h +++ b/toolchain/sem_ir/clang_decl.h @@ -223,4 +223,18 @@ using ClangDeclSignatureStore = } // namespace Carbon::SemIR +namespace Carbon { +extern template class CanonicalValueStore< + SemIR::ClangDeclId, SemIR::ClangDeclKey, Tag, + SemIR::ClangDecl>; +extern template class ValueStore>; +extern template class CanonicalValueStore< + SemIR::ClangDeclSignatureId, SemIR::ClangDeclSignature, + Tag, SemIR::ClangDeclSignature>; +extern template class ValueStore>; +} // namespace Carbon + #endif // CARBON_TOOLCHAIN_SEM_IR_CLANG_DECL_H_ diff --git a/toolchain/sem_ir/class.cpp b/toolchain/sem_ir/class.cpp index 72acb30271ef..dfa0dc66bfd5 100644 --- a/toolchain/sem_ir/class.cpp +++ b/toolchain/sem_ir/class.cpp @@ -4,6 +4,7 @@ #include "toolchain/sem_ir/class.h" +#include "toolchain/base/value_store_impl.h" #include "toolchain/sem_ir/file.h" #include "toolchain/sem_ir/generic.h" #include "toolchain/sem_ir/ids.h" @@ -51,3 +52,7 @@ auto Class::GetObjectRepr(const File& file, SpecificId specific_id) const } } // namespace Carbon::SemIR + +namespace Carbon { +template class ValueStore>; +} // namespace Carbon diff --git a/toolchain/sem_ir/class.h b/toolchain/sem_ir/class.h index 6b0d13d54239..1c6b5b7fdb3e 100644 --- a/toolchain/sem_ir/class.h +++ b/toolchain/sem_ir/class.h @@ -135,4 +135,9 @@ using ClassStore = ValueStore>; } // namespace Carbon::SemIR +namespace Carbon { +extern template class ValueStore>; +} // namespace Carbon + #endif // CARBON_TOOLCHAIN_SEM_IR_CLASS_H_ diff --git a/toolchain/sem_ir/constant.cpp b/toolchain/sem_ir/constant.cpp index f0ca32332d39..866c55c00454 100644 --- a/toolchain/sem_ir/constant.cpp +++ b/toolchain/sem_ir/constant.cpp @@ -4,6 +4,7 @@ #include "toolchain/sem_ir/constant.h" +#include "toolchain/base/value_store_impl.h" #include "toolchain/sem_ir/file.h" namespace Carbon::SemIR { @@ -63,3 +64,10 @@ auto GetInstWithConstantValue(const File& file, ConstantId const_id) -> InstId { } } // namespace Carbon::SemIR + +namespace Carbon { +template class ValueStore>; +template class ValueStore>; +} // namespace Carbon diff --git a/toolchain/sem_ir/constant.h b/toolchain/sem_ir/constant.h index d520209fb479..b2579c315430 100644 --- a/toolchain/sem_ir/constant.h +++ b/toolchain/sem_ir/constant.h @@ -368,4 +368,12 @@ class ConstantStore { } // namespace Carbon::SemIR +namespace Carbon { +extern template class ValueStore>; +extern template class ValueStore>; +} // namespace Carbon + #endif // CARBON_TOOLCHAIN_SEM_IR_CONSTANT_H_ diff --git a/toolchain/sem_ir/cpp_global_var.cpp b/toolchain/sem_ir/cpp_global_var.cpp new file mode 100644 index 000000000000..b4738ab28011 --- /dev/null +++ b/toolchain/sem_ir/cpp_global_var.cpp @@ -0,0 +1,16 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include "toolchain/sem_ir/cpp_global_var.h" + +#include "toolchain/base/canonical_value_store_impl.h" +#include "toolchain/base/value_store_impl.h" + +namespace Carbon { +template class CanonicalValueStore, SemIR::CppGlobalVar>; +template class ValueStore>; +} // namespace Carbon diff --git a/toolchain/sem_ir/cpp_global_var.h b/toolchain/sem_ir/cpp_global_var.h index 586b176d8f0c..078db0a27261 100644 --- a/toolchain/sem_ir/cpp_global_var.h +++ b/toolchain/sem_ir/cpp_global_var.h @@ -54,4 +54,12 @@ using CppGlobalVarStore = CanonicalValueStore, + SemIR::CppGlobalVar>; +extern template class ValueStore>; +} // namespace Carbon + #endif // CARBON_TOOLCHAIN_SEM_IR_CPP_GLOBAL_VAR_H_ diff --git a/toolchain/sem_ir/cpp_overload_set.cpp b/toolchain/sem_ir/cpp_overload_set.cpp new file mode 100644 index 000000000000..6172f4e26ab0 --- /dev/null +++ b/toolchain/sem_ir/cpp_overload_set.cpp @@ -0,0 +1,12 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include "toolchain/sem_ir/cpp_overload_set.h" + +#include "toolchain/base/value_store_impl.h" + +namespace Carbon { +template class ValueStore>; +} // namespace Carbon diff --git a/toolchain/sem_ir/cpp_overload_set.h b/toolchain/sem_ir/cpp_overload_set.h index 30ded7b2df02..31716a3f4740 100644 --- a/toolchain/sem_ir/cpp_overload_set.h +++ b/toolchain/sem_ir/cpp_overload_set.h @@ -44,4 +44,9 @@ using CppOverloadSetStore = } // namespace Carbon::SemIR +namespace Carbon { +extern template class ValueStore>; +} // namespace Carbon + #endif // CARBON_TOOLCHAIN_SEM_IR_CPP_OVERLOAD_SET_H_ diff --git a/toolchain/sem_ir/facet_type_info.cpp b/toolchain/sem_ir/facet_type_info.cpp index 824594ffd72c..bf08efe9f770 100644 --- a/toolchain/sem_ir/facet_type_info.cpp +++ b/toolchain/sem_ir/facet_type_info.cpp @@ -6,7 +6,9 @@ #include +#include "toolchain/base/canonical_value_store_impl.h" #include "toolchain/base/kind_switch.h" +#include "toolchain/base/value_store_impl.h" #include "toolchain/sem_ir/file.h" #include "toolchain/sem_ir/ids.h" #include "toolchain/sem_ir/typed_insts.h" @@ -361,3 +363,15 @@ auto AddCanonicalWitnessesBlock(File& sem_ir, } } // namespace Carbon::SemIR + +namespace Carbon { +template class CanonicalValueStore>; +template class CanonicalValueStore< + SemIR::IdentifiedFacetTypeId, SemIR::IdentifiedFacetTypeKey, + Tag, SemIR::IdentifiedFacetType>; +template class ValueStore>; +template class ValueStore>; +} // namespace Carbon diff --git a/toolchain/sem_ir/facet_type_info.h b/toolchain/sem_ir/facet_type_info.h index 58d86701305b..96d2a0c86c6d 100644 --- a/toolchain/sem_ir/facet_type_info.h +++ b/toolchain/sem_ir/facet_type_info.h @@ -285,4 +285,17 @@ auto AddCanonicalWitnessesBlock(File& sem_ir, } // namespace Carbon::SemIR +namespace Carbon { +extern template class CanonicalValueStore< + SemIR::FacetTypeId, SemIR::FacetTypeInfo, Tag>; +extern template class CanonicalValueStore< + SemIR::IdentifiedFacetTypeId, SemIR::IdentifiedFacetTypeKey, + Tag, SemIR::IdentifiedFacetType>; +extern template class ValueStore>; +extern template class ValueStore>; +} // namespace Carbon + #endif // CARBON_TOOLCHAIN_SEM_IR_FACET_TYPE_INFO_H_ diff --git a/toolchain/sem_ir/file.cpp b/toolchain/sem_ir/file.cpp index 47460acd1d98..0318b516b5b0 100644 --- a/toolchain/sem_ir/file.cpp +++ b/toolchain/sem_ir/file.cpp @@ -11,8 +11,10 @@ #include "common/check.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" +#include "toolchain/base/block_value_store_impl.h" #include "toolchain/base/kind_switch.h" #include "toolchain/base/shared_value_stores.h" +#include "toolchain/base/value_store_impl.h" #include "toolchain/base/yaml.h" #include "toolchain/parse/node_ids.h" #include "toolchain/sem_ir/ids.h" @@ -220,3 +222,17 @@ auto File::set_cpp_file(std::unique_ptr cpp_file) -> void { } } // namespace Carbon::SemIR + +namespace Carbon { +template class ValueStore>; +template class ValueStore>; +template class ValueStore, + Tag>; +template class BlockValueStore>; +template class BlockValueStore>; +} // namespace Carbon diff --git a/toolchain/sem_ir/file.h b/toolchain/sem_ir/file.h index d14ac487d83b..026cece7d37f 100644 --- a/toolchain/sem_ir/file.h +++ b/toolchain/sem_ir/file.h @@ -450,4 +450,16 @@ class File : public Printable { } // namespace Carbon::SemIR +namespace Carbon { +extern template class ValueStore>; +extern template class ValueStore>; +extern template class ValueStore, + Tag>; +extern template class BlockValueStore>; +} // namespace Carbon + #endif // CARBON_TOOLCHAIN_SEM_IR_FILE_H_ diff --git a/toolchain/sem_ir/function.cpp b/toolchain/sem_ir/function.cpp index 317c985f22ce..b77643817ade 100644 --- a/toolchain/sem_ir/function.cpp +++ b/toolchain/sem_ir/function.cpp @@ -8,6 +8,7 @@ #include #include "toolchain/base/kind_switch.h" +#include "toolchain/base/value_store_impl.h" #include "toolchain/sem_ir/file.h" #include "toolchain/sem_ir/generic.h" #include "toolchain/sem_ir/ids.h" @@ -145,3 +146,8 @@ auto Function::GetDeclaredReturnForm(const File& file, } } // namespace Carbon::SemIR + +namespace Carbon { +template class ValueStore>; +} // namespace Carbon diff --git a/toolchain/sem_ir/function.h b/toolchain/sem_ir/function.h index 1c4cdc5c8a45..27a8a6dcf5b0 100644 --- a/toolchain/sem_ir/function.h +++ b/toolchain/sem_ir/function.h @@ -372,4 +372,9 @@ auto DecomposeVirtualFunction(const File& sem_ir, InstId fn_decl_id, } // namespace Carbon::SemIR +namespace Carbon { +extern template class ValueStore>; +} // namespace Carbon + #endif // CARBON_TOOLCHAIN_SEM_IR_FUNCTION_H_ diff --git a/toolchain/sem_ir/generic.cpp b/toolchain/sem_ir/generic.cpp index 6f40518dda7f..c1a882fe5334 100644 --- a/toolchain/sem_ir/generic.cpp +++ b/toolchain/sem_ir/generic.cpp @@ -4,6 +4,7 @@ #include "toolchain/sem_ir/generic.h" +#include "toolchain/base/value_store_impl.h" #include "toolchain/sem_ir/file.h" #include "toolchain/sem_ir/typed_insts.h" @@ -137,3 +138,10 @@ auto GetTypeOfInstInSpecific(const File& specific_ir, SpecificId specific_id, } } // namespace Carbon::SemIR + +namespace Carbon { +template class ValueStore>; +template class ValueStore>; +} // namespace Carbon diff --git a/toolchain/sem_ir/generic.h b/toolchain/sem_ir/generic.h index 4cb2975ea1c6..744bd40b8613 100644 --- a/toolchain/sem_ir/generic.h +++ b/toolchain/sem_ir/generic.h @@ -214,4 +214,11 @@ auto GetTypeOfInstInSpecific(const File& specific_ir, SpecificId specific_id, } // namespace Carbon::SemIR +namespace Carbon { +extern template class ValueStore>; +extern template class ValueStore>; +} // namespace Carbon + #endif // CARBON_TOOLCHAIN_SEM_IR_GENERIC_H_ diff --git a/toolchain/sem_ir/impl.cpp b/toolchain/sem_ir/impl.cpp index 79fbc6e68824..c04536322991 100644 --- a/toolchain/sem_ir/impl.cpp +++ b/toolchain/sem_ir/impl.cpp @@ -5,6 +5,7 @@ #include "toolchain/sem_ir/impl.h" #include "toolchain/base/kind_switch.h" +#include "toolchain/base/value_store_impl.h" #include "toolchain/sem_ir/facet_type_info.h" #include "toolchain/sem_ir/file.h" #include "toolchain/sem_ir/specific_interface.h" @@ -40,3 +41,7 @@ auto ImplStore::GetOrAddLookupBucket(const Impl& impl) -> LookupBucketRef { } } // namespace Carbon::SemIR + +namespace Carbon { +template class ValueStore>; +} // namespace Carbon diff --git a/toolchain/sem_ir/impl.h b/toolchain/sem_ir/impl.h index 92aa26818199..18f7ea12b1cc 100644 --- a/toolchain/sem_ir/impl.h +++ b/toolchain/sem_ir/impl.h @@ -229,4 +229,9 @@ inline constexpr ImplStore::ImplOrLookupBucketId } // namespace Carbon::SemIR +namespace Carbon { +extern template class ValueStore>; +} // namespace Carbon + #endif // CARBON_TOOLCHAIN_SEM_IR_IMPL_H_ diff --git a/toolchain/sem_ir/import_ir.cpp b/toolchain/sem_ir/import_ir.cpp index 84d33393f072..417bd80d4e48 100644 --- a/toolchain/sem_ir/import_ir.cpp +++ b/toolchain/sem_ir/import_ir.cpp @@ -6,6 +6,7 @@ #include +#include "toolchain/base/value_store_impl.h" #include "toolchain/sem_ir/file.h" namespace Carbon::SemIR { @@ -56,3 +57,9 @@ auto GetCanonicalFileAndInstId(const File* sem_ir, InstId inst_id) } } // namespace Carbon::SemIR + +namespace Carbon { +template class ValueStore>; +template class ValueStore; +} // namespace Carbon diff --git a/toolchain/sem_ir/import_ir.h b/toolchain/sem_ir/import_ir.h index 5846461a53d0..91aecc3fcf3e 100644 --- a/toolchain/sem_ir/import_ir.h +++ b/toolchain/sem_ir/import_ir.h @@ -83,4 +83,10 @@ auto GetCanonicalFileAndInstId(const File* sem_ir, InstId inst_id) } // namespace Carbon::SemIR +namespace Carbon { +extern template class ValueStore>; +extern template class ValueStore; +} // namespace Carbon + #endif // CARBON_TOOLCHAIN_SEM_IR_IMPORT_IR_H_ diff --git a/toolchain/sem_ir/inst.cpp b/toolchain/sem_ir/inst.cpp index 943e399b89ec..59beb9aeb4ad 100644 --- a/toolchain/sem_ir/inst.cpp +++ b/toolchain/sem_ir/inst.cpp @@ -6,6 +6,8 @@ #include +#include "toolchain/base/block_value_store_impl.h" +#include "toolchain/base/value_store_impl.h" #include "toolchain/sem_ir/file.h" namespace Carbon::SemIR { @@ -160,3 +162,11 @@ auto LocIdAndInst::RuntimeVerified(const File& file, LocId loc_id, Inst inst) } } // namespace Carbon::SemIR + +namespace Carbon { +template class ValueStore, + Tag>; +template class BlockValueStore>; +} // namespace Carbon diff --git a/toolchain/sem_ir/inst.h b/toolchain/sem_ir/inst.h index 19d42bf89fa4..5131328903ce 100644 --- a/toolchain/sem_ir/inst.h +++ b/toolchain/sem_ir/inst.h @@ -708,4 +708,12 @@ inline auto CarbonHashValue(const Inst& value, uint64_t seed) -> HashCode { } // namespace Carbon::SemIR +namespace Carbon { +extern template class ValueStore, + Tag>; +extern template class BlockValueStore>; +} // namespace Carbon + #endif // CARBON_TOOLCHAIN_SEM_IR_INST_H_ diff --git a/toolchain/sem_ir/interface.cpp b/toolchain/sem_ir/interface.cpp new file mode 100644 index 000000000000..6ab8807af45d --- /dev/null +++ b/toolchain/sem_ir/interface.cpp @@ -0,0 +1,12 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include "toolchain/sem_ir/interface.h" + +#include "toolchain/base/value_store_impl.h" + +namespace Carbon { +template class ValueStore>; +} // namespace Carbon diff --git a/toolchain/sem_ir/interface.h b/toolchain/sem_ir/interface.h index 8ebc4b6de8fb..5d9f4785065d 100644 --- a/toolchain/sem_ir/interface.h +++ b/toolchain/sem_ir/interface.h @@ -73,4 +73,9 @@ using InterfaceStore = ValueStore>; } // namespace Carbon::SemIR +namespace Carbon { +extern template class ValueStore>; +} // namespace Carbon + #endif // CARBON_TOOLCHAIN_SEM_IR_INTERFACE_H_ diff --git a/toolchain/sem_ir/name_scope.cpp b/toolchain/sem_ir/name_scope.cpp index 0dd8e17507aa..16cde114af89 100644 --- a/toolchain/sem_ir/name_scope.cpp +++ b/toolchain/sem_ir/name_scope.cpp @@ -7,6 +7,7 @@ #include #include +#include "toolchain/base/value_store_impl.h" #include "toolchain/sem_ir/file.h" namespace Carbon::SemIR { @@ -100,3 +101,8 @@ auto NameScopeStore::GetInstIfValid(NameScopeId scope_id) const } } // namespace Carbon::SemIR + +namespace Carbon { +template class ValueStore>; +} diff --git a/toolchain/sem_ir/named_constraint.cpp b/toolchain/sem_ir/named_constraint.cpp new file mode 100644 index 000000000000..63107661a934 --- /dev/null +++ b/toolchain/sem_ir/named_constraint.cpp @@ -0,0 +1,12 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include "toolchain/sem_ir/named_constraint.h" + +#include "toolchain/base/value_store_impl.h" + +namespace Carbon { +template class ValueStore>; +} // namespace Carbon diff --git a/toolchain/sem_ir/named_constraint.h b/toolchain/sem_ir/named_constraint.h index 834bf18f596d..94fbf112bfc8 100644 --- a/toolchain/sem_ir/named_constraint.h +++ b/toolchain/sem_ir/named_constraint.h @@ -64,4 +64,9 @@ using NamedConstraintStore = } // namespace Carbon::SemIR +namespace Carbon { +extern template class ValueStore>; +} // namespace Carbon + #endif // CARBON_TOOLCHAIN_SEM_IR_NAMED_CONSTRAINT_H_ diff --git a/toolchain/sem_ir/require_impls.cpp b/toolchain/sem_ir/require_impls.cpp new file mode 100644 index 000000000000..c1b0036e5db5 --- /dev/null +++ b/toolchain/sem_ir/require_impls.cpp @@ -0,0 +1,18 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include "toolchain/sem_ir/require_impls.h" + +#include "toolchain/base/block_value_store_impl.h" +#include "toolchain/base/value_store_impl.h" + +namespace Carbon { +template class ValueStore>; +template class ValueStore, + Tag>; +template class BlockValueStore>; +} // namespace Carbon diff --git a/toolchain/sem_ir/require_impls.h b/toolchain/sem_ir/require_impls.h index 4fd186ce6545..5a29c08e8e68 100644 --- a/toolchain/sem_ir/require_impls.h +++ b/toolchain/sem_ir/require_impls.h @@ -51,4 +51,14 @@ using RequireImplsBlockStore = } // namespace Carbon::SemIR +namespace Carbon { +extern template class ValueStore>; +extern template class ValueStore, + Tag>; +extern template class BlockValueStore< + SemIR::RequireImplsBlockId, SemIR::RequireImplsId, Tag>; +} // namespace Carbon + #endif // CARBON_TOOLCHAIN_SEM_IR_REQUIRE_IMPLS_H_ diff --git a/toolchain/sem_ir/specific_interface.cpp b/toolchain/sem_ir/specific_interface.cpp new file mode 100644 index 000000000000..2adb4bc01cb2 --- /dev/null +++ b/toolchain/sem_ir/specific_interface.cpp @@ -0,0 +1,16 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include "toolchain/sem_ir/specific_interface.h" + +#include "toolchain/base/canonical_value_store_impl.h" +#include "toolchain/base/value_store_impl.h" + +namespace Carbon { +template class CanonicalValueStore>; +template class ValueStore>; +} // namespace Carbon diff --git a/toolchain/sem_ir/specific_interface.h b/toolchain/sem_ir/specific_interface.h index b49ce76033c5..67bb5cd904f7 100644 --- a/toolchain/sem_ir/specific_interface.h +++ b/toolchain/sem_ir/specific_interface.h @@ -38,4 +38,13 @@ using SpecificInterfaceStore = } // namespace Carbon::SemIR +namespace Carbon { +extern template class CanonicalValueStore>; +extern template class ValueStore>; +} // namespace Carbon + #endif // CARBON_TOOLCHAIN_SEM_IR_SPECIFIC_INTERFACE_H_ diff --git a/toolchain/sem_ir/struct_type_field.cpp b/toolchain/sem_ir/struct_type_field.cpp new file mode 100644 index 000000000000..280288e22c3b --- /dev/null +++ b/toolchain/sem_ir/struct_type_field.cpp @@ -0,0 +1,16 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include "toolchain/sem_ir/struct_type_field.h" + +#include "toolchain/base/block_value_store_impl.h" +#include "toolchain/base/value_store_impl.h" + +namespace Carbon { +template class ValueStore, + Tag>; +template class BlockValueStore>; +} // namespace Carbon diff --git a/toolchain/sem_ir/struct_type_field.h b/toolchain/sem_ir/struct_type_field.h index 2ac1cca28f16..aa44797a8882 100644 --- a/toolchain/sem_ir/struct_type_field.h +++ b/toolchain/sem_ir/struct_type_field.h @@ -37,4 +37,12 @@ inline auto CarbonHashValue(const StructTypeField& value, uint64_t seed) } // namespace Carbon::SemIR +namespace Carbon { +extern template class ValueStore, + Tag>; +extern template class BlockValueStore< + SemIR::StructTypeFieldsId, SemIR::StructTypeField, Tag>; +} // namespace Carbon + #endif // CARBON_TOOLCHAIN_SEM_IR_STRUCT_TYPE_FIELD_H_ diff --git a/toolchain/sem_ir/vtable.cpp b/toolchain/sem_ir/vtable.cpp new file mode 100644 index 000000000000..5b24c9802457 --- /dev/null +++ b/toolchain/sem_ir/vtable.cpp @@ -0,0 +1,12 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include "toolchain/sem_ir/vtable.h" + +#include "toolchain/base/value_store_impl.h" + +namespace Carbon { +template class ValueStore>; +} // namespace Carbon diff --git a/toolchain/sem_ir/vtable.h b/toolchain/sem_ir/vtable.h index 5fc40c457e3c..f9211aa9af3b 100644 --- a/toolchain/sem_ir/vtable.h +++ b/toolchain/sem_ir/vtable.h @@ -40,4 +40,9 @@ using VtableStore = ValueStore>; } // namespace Carbon::SemIR +namespace Carbon { +extern template class ValueStore>; +} // namespace Carbon + #endif // CARBON_TOOLCHAIN_SEM_IR_VTABLE_H_