Switch the ValueStore-related templates to use explicit instantiation (#7116)

As part of this, move functions that seem reasonable to make out-of-line
to a separate `_impl.h` header file that is only included where the
explicit instantiation _definition_ is provided.

By using explicit instantiation we can make these templates behave more
like non-template classes in terms of supporting out-of-line definitions
that don't need to be compiled by every translation unit. The set of
eventual instantiations here is fundamentally known, and there tend to
be headers that define a canonical "leaf" type where it makes sense to
trigger the explicit instantiation.

Where we already had a `.cpp` file to put the explicit instantiation
definition, use it. But in some places we didn't have such a `.cpp` file
so this PR adds those.

This also requires that we have precise constraints on APIs that _can't_
be instantiated for specific argument types, as now we don't do this
lazily.

Combined, this appears to reduce the sum of object file sizes in the
`check` directory by almost 40% (122mb -> 74mb) in my measurement.

My actual goal was to improve compile times, but so far I don't have a
great methodology for measuring these... But the object file size
reduction seems to confirm this is a net win and likely represents a
non-trivial improvement in compile time.

Assisted-by: Antigravity with Gemini
This commit is contained in:
Chandler Carruth
2026-05-14 08:29:17 +00:00
committed by GitHub
parent c9d8b59bbd
commit d010d52f37
58 changed files with 802 additions and 116 deletions
+16 -3
View File
@@ -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",
+21 -41
View File
@@ -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 <typename IdT, typename ElementT, typename TagIdT = Untagged>
class BlockValueStore
: public Yaml::Printable<BlockValueStore<IdT, ElementT, TagIdT>> {
@@ -36,15 +46,11 @@ class BlockValueStore
explicit BlockValueStore(llvm::BumpPtrAllocator& allocator,
IdTagType::TagIdType tag_id,
int32_t initial_reserved_ids = 0)
requires(!IdTagIsUntagged<IdTagType>)
: 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<IdTagType>);
~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<ElementType>);
auto storage = static_cast<ElementType*>(
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<IdT, RefType, TagIdT>& { return values_; }
@@ -166,6 +146,6 @@ class BlockValueStore<IdT, ElementT, TagIdT>::KeyContext
const BlockValueStore* store_;
};
} // namespace Carbon::SemIR
} // namespace Carbon
#endif // CARBON_TOOLCHAIN_BASE_BLOCK_VALUE_STORE_H_
+88
View File
@@ -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 <typename IdT, typename ElementT, typename TagIdT>
BlockValueStore<IdT, ElementT, TagIdT>::BlockValueStore(
llvm::BumpPtrAllocator& allocator, IdTagType::TagIdType tag_id,
int32_t initial_reserved_ids)
requires(!IdTagIsUntagged<IdTagType>)
: 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 <typename IdT, typename ElementT, typename TagIdT>
BlockValueStore<IdT, ElementT, TagIdT>::~BlockValueStore() = default;
template <typename IdT, typename ElementT, typename TagIdT>
BlockValueStore<IdT, ElementT, TagIdT>::BlockValueStore(
BlockValueStore&&) noexcept = default;
template <typename IdT, typename ElementT, typename TagIdT>
auto BlockValueStore<IdT, ElementT, TagIdT>::operator=(
BlockValueStore&&) noexcept -> BlockValueStore& = default;
template <typename IdT, typename ElementT, typename TagIdT>
auto BlockValueStore<IdT, ElementT, TagIdT>::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("<unprintable>"));
}
}
}));
}
});
}
template <typename IdT, typename ElementT, typename TagIdT>
auto BlockValueStore<IdT, ElementT, TagIdT>::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 <typename IdT, typename ElementT, typename TagIdT>
auto BlockValueStore<IdT, ElementT, TagIdT>::AllocateCopy(ConstRefType data)
-> RefType {
auto result = AllocateUninitialized(data.size());
std::uninitialized_copy(data.begin(), data.end(), result.begin());
return result;
}
template <typename IdT, typename ElementT, typename TagIdT>
auto BlockValueStore<IdT, ElementT, TagIdT>::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<ElementType>);
auto storage = static_cast<ElementType*>(
allocator_->Allocate(size * sizeof(ElementType), alignof(ElementType)));
return RefType(storage, size);
}
} // namespace Carbon
#endif // CARBON_TOOLCHAIN_BASE_BLOCK_VALUE_STORE_IMPL_H_
+44 -16
View File
@@ -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 <typename IdT, typename KeyT, typename TagIdT = Untagged,
typename ValueT = KeyT>
class CanonicalValueStore {
@@ -33,10 +44,15 @@ class CanonicalValueStore {
using RefType = ValueStoreTypes<ValueT>::RefType;
using ConstRefType = ValueStoreTypes<ValueT>::ConstRefType;
CanonicalValueStore() = default;
template <typename Id>
explicit CanonicalValueStore(Id id, int32_t initial_reserved_ids = 0)
: values_(id, initial_reserved_ids) {}
CanonicalValueStore()
requires(IdTagIsUntagged<IdTag<IdT, TagIdT>>);
explicit CanonicalValueStore(IdTagType::TagIdType id,
int32_t initial_reserved_ids = 0)
requires(!IdTagIsUntagged<IdTag<IdT, TagIdT>>);
~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<IdT, ValueType, TagIdT>::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<IdT, KeyT, TagIdT, ValueT>::KeyContext
const ValueStore<IdT, ValueType, TagIdT>* 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 <typename IdT, typename KeyT, typename TagIdT, typename ValueT>
auto CanonicalValueStore<IdT, KeyT, TagIdT, ValueT>::Add(ValueType value)
inline auto CanonicalValueStore<IdT, KeyT, TagIdT, ValueT>::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 <typename IdT, typename KeyT, typename TagIdT, typename ValueT>
auto CanonicalValueStore<IdT, KeyT, TagIdT, ValueT>::Lookup(KeyType key) const
-> IdT {
inline auto CanonicalValueStore<IdT, KeyT, TagIdT, ValueT>::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 <typename IdT, typename KeyT, typename TagIdT, typename ValueT>
auto CanonicalValueStore<IdT, KeyT, TagIdT, ValueT>::Reserve(size_t size)
inline auto CanonicalValueStore<IdT, KeyT, TagIdT, ValueT>::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.
@@ -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 <typename IdT, typename KeyT, typename TagIdT, typename ValueT>
CanonicalValueStore<IdT, KeyT, TagIdT, ValueT>::CanonicalValueStore()
requires(IdTagIsUntagged<IdTag<IdT, TagIdT>>)
= default;
template <typename IdT, typename KeyT, typename TagIdT, typename ValueT>
CanonicalValueStore<IdT, KeyT, TagIdT, ValueT>::CanonicalValueStore(
typename IdTagType::TagIdType id, int32_t initial_reserved_ids)
requires(!IdTagIsUntagged<IdTag<IdT, TagIdT>>)
: values_(id, initial_reserved_ids) {}
template <typename IdT, typename KeyT, typename TagIdT, typename ValueT>
CanonicalValueStore<IdT, KeyT, TagIdT, ValueT>::~CanonicalValueStore() =
default;
template <typename IdT, typename KeyT, typename TagIdT, typename ValueT>
CanonicalValueStore<IdT, KeyT, TagIdT, ValueT>::CanonicalValueStore(
CanonicalValueStore&&) noexcept = default;
template <typename IdT, typename KeyT, typename TagIdT, typename ValueT>
auto CanonicalValueStore<IdT, KeyT, TagIdT, ValueT>::operator=(
CanonicalValueStore&&) noexcept -> CanonicalValueStore& = default;
template <typename IdT, typename KeyT, typename TagIdT, typename ValueT>
auto CanonicalValueStore<IdT, KeyT, TagIdT, ValueT>::OutputYaml() const
-> Yaml::OutputMapping {
return values_.OutputYaml();
}
template <typename IdT, typename KeyT, typename TagIdT, typename ValueT>
auto CanonicalValueStore<IdT, KeyT, TagIdT, ValueT>::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_
@@ -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 {
+6
View File
@@ -7,6 +7,9 @@
#include <algorithm>
#include <string>
#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<IntStore::APIntId, llvm::APInt>;
template class ValueStore<IntStore::APIntId, llvm::APInt>;
} // namespace Carbon
+3
View File
@@ -432,6 +432,9 @@ class IntStore {
inline constexpr IntStore::APIntId IntStore::APIntId::None(
IntId::None.AsIndex());
extern template class CanonicalValueStore<IntStore::APIntId, llvm::APInt>;
extern template class ValueStore<IntStore::APIntId, llvm::APInt>;
} // namespace Carbon
#endif // CARBON_TOOLCHAIN_BASE_INT_H_
+20
View File
@@ -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<FloatId, llvm::APFloat>;
template class CanonicalValueStore<IdentifierId, llvm::StringRef>;
template class CanonicalValueStore<StringLiteralValueId, llvm::StringRef>;
template class ValueStore<FloatId, llvm::APFloat>;
template class ValueStore<IdentifierId, llvm::StringRef>;
template class ValueStore<RealId, Real>;
template class ValueStore<StringLiteralValueId, llvm::StringRef>;
} // namespace Carbon
+9
View File
@@ -87,6 +87,15 @@ class SharedValueStores : public Yaml::Printable<SharedValueStores> {
StringLiteralStore string_literals_;
};
extern template class CanonicalValueStore<FloatId, llvm::APFloat>;
extern template class CanonicalValueStore<IdentifierId, llvm::StringRef>;
extern template class CanonicalValueStore<StringLiteralValueId,
llvm::StringRef>;
extern template class ValueStore<FloatId, llvm::APFloat>;
extern template class ValueStore<IdentifierId, llvm::StringRef>;
extern template class ValueStore<RealId, Real>;
extern template class ValueStore<StringLiteralValueId, llvm::StringRef>;
} // namespace Carbon
#endif // CARBON_TOOLCHAIN_BASE_SHARED_VALUE_STORES_H_
+25 -56
View File
@@ -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 <typename IdT, typename ValueT, typename TagIdT = Untagged>
class ValueStore
: public std::conditional<std::is_base_of_v<Printable<ValueT>, 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<IdTagType>)
= default;
requires(IdTagIsUntagged<IdTagType>);
// 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<IdTagType>)
: tag_(tag) {}
requires(!IdTagIsUntagged<IdTagType>);
// 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<IdTagType>)
: tag_(id, initial_reserved_ids) {}
requires(!IdTagIsUntagged<IdTagType>);
~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<ValueT>);
// 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<ValueT>);
auto size() const -> int32_t { return num_; }
+108
View File
@@ -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 <typename IdT, typename ValueT, typename TagIdT>
ValueStore<IdT, ValueT, TagIdT>::ValueStore()
requires(IdTagIsUntagged<IdTagType>)
= default;
template <typename IdT, typename ValueT, typename TagIdT>
ValueStore<IdT, ValueT, TagIdT>::ValueStore(IdTagType tag)
requires(!IdTagIsUntagged<IdTagType>)
: tag_(tag) {}
template <typename IdT, typename ValueT, typename TagIdT>
ValueStore<IdT, ValueT, TagIdT>::ValueStore(
typename ValueStore<IdT, ValueT, TagIdT>::IdTagType::TagIdType id,
int32_t initial_reserved_ids)
requires(!IdTagIsUntagged<IdTagType>)
: tag_(id, initial_reserved_ids) {}
template <typename IdT, typename ValueT, typename TagIdT>
ValueStore<IdT, ValueT, TagIdT>::~ValueStore() = default;
template <typename IdT, typename ValueT, typename TagIdT>
ValueStore<IdT, ValueT, TagIdT>::ValueStore(ValueStore&&) noexcept = default;
template <typename IdT, typename ValueT, typename TagIdT>
auto ValueStore<IdT, ValueT, TagIdT>::operator=(ValueStore&&) noexcept
-> ValueStore& = default;
template <typename IdT, typename ValueT, typename TagIdT>
auto ValueStore<IdT, ValueT, TagIdT>::Resize(int32_t size,
ConstRefType default_value) -> void
requires(std::is_copy_constructible_v<ValueT>)
{
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 <typename IdT, typename ValueT, typename TagIdT>
auto ValueStore<IdT, ValueT, TagIdT>::Chunk::UninitializedFill(
int32_t fill_count,
typename ValueStore<IdT, ValueT, TagIdT>::ConstRefType default_value)
-> void
requires(std::is_copy_constructible_v<ValueT>)
{
CARBON_DCHECK(num_ + fill_count <= Capacity());
std::uninitialized_fill_n(buf_ + num_, fill_count, default_value);
num_ += fill_count;
}
template <typename IdT, typename ValueT, typename TagIdT>
auto ValueStore<IdT, ValueT, TagIdT>::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("<unprintable>"));
}
}
});
}
template <typename IdT, typename ValueT, typename TagIdT>
auto ValueStore<IdT, ValueT, TagIdT>::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_
+1
View File
@@ -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",
+7
View File
@@ -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<Lex::TokenIndex, Lex::TokenInfo>;
template class ValueStore<Lex::LineIndex, Lex::LineInfo>;
template class ValueStore<Lex::CommentIndex, Lex::CommentData>;
} // namespace Carbon
+6
View File
@@ -383,4 +383,10 @@ inline auto TokenizedBuffer::AddToken(TokenInfo info) -> TokenIndex {
} // namespace Carbon::Lex
namespace Carbon {
extern template class ValueStore<Lex::TokenIndex, Lex::TokenInfo>;
extern template class ValueStore<Lex::LineIndex, Lex::LineInfo>;
extern template class ValueStore<Lex::CommentIndex, Lex::CommentData>;
} // namespace Carbon
#endif // CARBON_TOOLCHAIN_LEX_TOKENIZED_BUFFER_H_
+6
View File
@@ -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<Parse::DeferredDefinitionIndex,
Parse::DeferredDefinition>;
} // namespace Carbon
+5
View File
@@ -349,4 +349,9 @@ struct Tree::ConvertTo<NodeIdOneOf<T...>> {
} // namespace Carbon::Parse
namespace Carbon {
extern template class ValueStore<Parse::DeferredDefinitionIndex,
Parse::DeferredDefinition>;
} // namespace Carbon
#endif // CARBON_TOOLCHAIN_PARSE_TREE_H_
+10
View File
@@ -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",
+12
View File
@@ -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<SemIR::AssociatedConstantId,
SemIR::AssociatedConstant, Tag<SemIR::CheckIRId>>;
} // namespace Carbon
+6
View File
@@ -50,4 +50,10 @@ using AssociatedConstantStore =
} // namespace Carbon::SemIR
namespace Carbon {
extern template class ValueStore<SemIR::AssociatedConstantId,
SemIR::AssociatedConstant,
Tag<SemIR::CheckIRId>>;
} // namespace Carbon
#endif // CARBON_TOOLCHAIN_SEM_IR_ASSOCIATED_CONSTANT_H_
+5
View File
@@ -307,4 +307,9 @@ class BundleStore {
} // namespace Carbon::SemIR
namespace Carbon {
extern template class BlockValueStore<SemIR::RawBundleId, SemIR::AnyRawId,
Tag<SemIR::CheckIRId>>;
} // namespace Carbon
#endif // CARBON_TOOLCHAIN_SEM_IR_BUNDLE_H_
+14
View File
@@ -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::ClangDeclId, SemIR::ClangDeclKey,
Tag<SemIR::CheckIRId>, SemIR::ClangDecl>;
template class ValueStore<SemIR::ClangDeclId, SemIR::ClangDecl,
Tag<SemIR::CheckIRId>>;
template class CanonicalValueStore<
SemIR::ClangDeclSignatureId, SemIR::ClangDeclSignature,
Tag<SemIR::CheckIRId>, SemIR::ClangDeclSignature>;
template class ValueStore<SemIR::ClangDeclSignatureId,
SemIR::ClangDeclSignature, Tag<SemIR::CheckIRId>>;
} // namespace Carbon
+14
View File
@@ -223,4 +223,18 @@ using ClangDeclSignatureStore =
} // namespace Carbon::SemIR
namespace Carbon {
extern template class CanonicalValueStore<
SemIR::ClangDeclId, SemIR::ClangDeclKey, Tag<SemIR::CheckIRId>,
SemIR::ClangDecl>;
extern template class ValueStore<SemIR::ClangDeclId, SemIR::ClangDecl,
Tag<SemIR::CheckIRId>>;
extern template class CanonicalValueStore<
SemIR::ClangDeclSignatureId, SemIR::ClangDeclSignature,
Tag<SemIR::CheckIRId>, SemIR::ClangDeclSignature>;
extern template class ValueStore<SemIR::ClangDeclSignatureId,
SemIR::ClangDeclSignature,
Tag<SemIR::CheckIRId>>;
} // namespace Carbon
#endif // CARBON_TOOLCHAIN_SEM_IR_CLANG_DECL_H_
+5
View File
@@ -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<SemIR::ClassId, SemIR::Class, Tag<SemIR::CheckIRId>>;
} // namespace Carbon
+5
View File
@@ -135,4 +135,9 @@ using ClassStore = ValueStore<ClassId, Class, Tag<CheckIRId>>;
} // namespace Carbon::SemIR
namespace Carbon {
extern template class ValueStore<SemIR::ClassId, SemIR::Class,
Tag<SemIR::CheckIRId>>;
} // namespace Carbon
#endif // CARBON_TOOLCHAIN_SEM_IR_CLASS_H_
+8
View File
@@ -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<SemIR::InstId, SemIR::ConstantId,
Tag<SemIR::CheckIRId>>;
template class ValueStore<SemIR::ConstantId::SymbolicId,
SemIR::SymbolicConstant, Tag<SemIR::CheckIRId>>;
} // namespace Carbon
+8
View File
@@ -368,4 +368,12 @@ class ConstantStore {
} // namespace Carbon::SemIR
namespace Carbon {
extern template class ValueStore<SemIR::InstId, SemIR::ConstantId,
Tag<SemIR::CheckIRId>>;
extern template class ValueStore<SemIR::ConstantId::SymbolicId,
SemIR::SymbolicConstant,
Tag<SemIR::CheckIRId>>;
} // namespace Carbon
#endif // CARBON_TOOLCHAIN_SEM_IR_CONSTANT_H_
+16
View File
@@ -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::CppGlobalVarId,
SemIR::CppGlobalVarKey,
Tag<SemIR::CheckIRId>, SemIR::CppGlobalVar>;
template class ValueStore<SemIR::CppGlobalVarId, SemIR::CppGlobalVar,
Tag<SemIR::CheckIRId>>;
} // namespace Carbon
+8
View File
@@ -54,4 +54,12 @@ using CppGlobalVarStore = CanonicalValueStore<CppGlobalVarId, CppGlobalVarKey,
} // namespace Carbon::SemIR
namespace Carbon {
extern template class CanonicalValueStore<
SemIR::CppGlobalVarId, SemIR::CppGlobalVarKey, Tag<SemIR::CheckIRId>,
SemIR::CppGlobalVar>;
extern template class ValueStore<SemIR::CppGlobalVarId, SemIR::CppGlobalVar,
Tag<SemIR::CheckIRId>>;
} // namespace Carbon
#endif // CARBON_TOOLCHAIN_SEM_IR_CPP_GLOBAL_VAR_H_
+12
View File
@@ -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<SemIR::CppOverloadSetId, SemIR::CppOverloadSet,
Tag<SemIR::CheckIRId>>;
} // namespace Carbon
+5
View File
@@ -44,4 +44,9 @@ using CppOverloadSetStore =
} // namespace Carbon::SemIR
namespace Carbon {
extern template class ValueStore<SemIR::CppOverloadSetId, SemIR::CppOverloadSet,
Tag<SemIR::CheckIRId>>;
} // namespace Carbon
#endif // CARBON_TOOLCHAIN_SEM_IR_CPP_OVERLOAD_SET_H_
+14
View File
@@ -6,7 +6,9 @@
#include <tuple>
#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<SemIR::FacetTypeId, SemIR::FacetTypeInfo,
Tag<SemIR::CheckIRId>>;
template class CanonicalValueStore<
SemIR::IdentifiedFacetTypeId, SemIR::IdentifiedFacetTypeKey,
Tag<SemIR::CheckIRId>, SemIR::IdentifiedFacetType>;
template class ValueStore<SemIR::FacetTypeId, SemIR::FacetTypeInfo,
Tag<SemIR::CheckIRId>>;
template class ValueStore<SemIR::IdentifiedFacetTypeId,
SemIR::IdentifiedFacetType, Tag<SemIR::CheckIRId>>;
} // namespace Carbon
+13
View File
@@ -285,4 +285,17 @@ auto AddCanonicalWitnessesBlock(File& sem_ir,
} // namespace Carbon::SemIR
namespace Carbon {
extern template class CanonicalValueStore<
SemIR::FacetTypeId, SemIR::FacetTypeInfo, Tag<SemIR::CheckIRId>>;
extern template class CanonicalValueStore<
SemIR::IdentifiedFacetTypeId, SemIR::IdentifiedFacetTypeKey,
Tag<SemIR::CheckIRId>, SemIR::IdentifiedFacetType>;
extern template class ValueStore<SemIR::FacetTypeId, SemIR::FacetTypeInfo,
Tag<SemIR::CheckIRId>>;
extern template class ValueStore<SemIR::IdentifiedFacetTypeId,
SemIR::IdentifiedFacetType,
Tag<SemIR::CheckIRId>>;
} // namespace Carbon
#endif // CARBON_TOOLCHAIN_SEM_IR_FACET_TYPE_INFO_H_
+16
View File
@@ -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<SemIR::CppFile> cpp_file) -> void {
}
} // namespace Carbon::SemIR
namespace Carbon {
template class ValueStore<SemIR::ExprRegionId, SemIR::ExprRegion,
Tag<SemIR::CheckIRId>>;
template class ValueStore<SemIR::ClangSourceLocId, clang::SourceLocation,
Tag<SemIR::CheckIRId>>;
template class ValueStore<SemIR::CustomLayoutId,
llvm::MutableArrayRef<SemIR::ObjectSize>,
Tag<SemIR::CheckIRId>>;
template class BlockValueStore<SemIR::CustomLayoutId, SemIR::ObjectSize,
Tag<SemIR::CheckIRId>>;
template class BlockValueStore<SemIR::RawBundleId, SemIR::AnyRawId,
Tag<SemIR::CheckIRId>>;
} // namespace Carbon
+12
View File
@@ -450,4 +450,16 @@ class File : public Printable<File> {
} // namespace Carbon::SemIR
namespace Carbon {
extern template class ValueStore<SemIR::ExprRegionId, SemIR::ExprRegion,
Tag<SemIR::CheckIRId>>;
extern template class ValueStore<SemIR::ClangSourceLocId, clang::SourceLocation,
Tag<SemIR::CheckIRId>>;
extern template class ValueStore<SemIR::CustomLayoutId,
llvm::MutableArrayRef<SemIR::ObjectSize>,
Tag<SemIR::CheckIRId>>;
extern template class BlockValueStore<SemIR::CustomLayoutId, SemIR::ObjectSize,
Tag<SemIR::CheckIRId>>;
} // namespace Carbon
#endif // CARBON_TOOLCHAIN_SEM_IR_FILE_H_
+6
View File
@@ -8,6 +8,7 @@
#include <variant>
#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<SemIR::FunctionId, SemIR::Function,
Tag<SemIR::CheckIRId>>;
} // namespace Carbon
+5
View File
@@ -372,4 +372,9 @@ auto DecomposeVirtualFunction(const File& sem_ir, InstId fn_decl_id,
} // namespace Carbon::SemIR
namespace Carbon {
extern template class ValueStore<SemIR::FunctionId, SemIR::Function,
Tag<SemIR::CheckIRId>>;
} // namespace Carbon
#endif // CARBON_TOOLCHAIN_SEM_IR_FUNCTION_H_
+8
View File
@@ -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<SemIR::GenericId, SemIR::Generic,
Tag<SemIR::CheckIRId>>;
template class ValueStore<SemIR::SpecificId, SemIR::Specific,
Tag<SemIR::CheckIRId>>;
} // namespace Carbon
+7
View File
@@ -214,4 +214,11 @@ auto GetTypeOfInstInSpecific(const File& specific_ir, SpecificId specific_id,
} // namespace Carbon::SemIR
namespace Carbon {
extern template class ValueStore<SemIR::GenericId, SemIR::Generic,
Tag<SemIR::CheckIRId>>;
extern template class ValueStore<SemIR::SpecificId, SemIR::Specific,
Tag<SemIR::CheckIRId>>;
} // namespace Carbon
#endif // CARBON_TOOLCHAIN_SEM_IR_GENERIC_H_
+5
View File
@@ -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<SemIR::ImplId, SemIR::Impl, Tag<SemIR::CheckIRId>>;
} // namespace Carbon
+5
View File
@@ -229,4 +229,9 @@ inline constexpr ImplStore::ImplOrLookupBucketId
} // namespace Carbon::SemIR
namespace Carbon {
extern template class ValueStore<SemIR::ImplId, SemIR::Impl,
Tag<SemIR::CheckIRId>>;
} // namespace Carbon
#endif // CARBON_TOOLCHAIN_SEM_IR_IMPL_H_
+7
View File
@@ -6,6 +6,7 @@
#include <utility>
#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<SemIR::ImportIRId, SemIR::ImportIR,
Tag<SemIR::CheckIRId>>;
template class ValueStore<SemIR::ImportIRInstId, SemIR::ImportIRInst>;
} // namespace Carbon
+6
View File
@@ -83,4 +83,10 @@ auto GetCanonicalFileAndInstId(const File* sem_ir, InstId inst_id)
} // namespace Carbon::SemIR
namespace Carbon {
extern template class ValueStore<SemIR::ImportIRId, SemIR::ImportIR,
Tag<SemIR::CheckIRId>>;
extern template class ValueStore<SemIR::ImportIRInstId, SemIR::ImportIRInst>;
} // namespace Carbon
#endif // CARBON_TOOLCHAIN_SEM_IR_IMPORT_IR_H_
+10
View File
@@ -6,6 +6,8 @@
#include <utility>
#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<SemIR::InstBlockId,
llvm::MutableArrayRef<SemIR::InstId>,
Tag<SemIR::CheckIRId>>;
template class BlockValueStore<SemIR::InstBlockId, SemIR::InstId,
Tag<SemIR::CheckIRId>>;
} // namespace Carbon
+8
View File
@@ -708,4 +708,12 @@ inline auto CarbonHashValue(const Inst& value, uint64_t seed) -> HashCode {
} // namespace Carbon::SemIR
namespace Carbon {
extern template class ValueStore<SemIR::InstBlockId,
llvm::MutableArrayRef<SemIR::InstId>,
Tag<SemIR::CheckIRId>>;
extern template class BlockValueStore<SemIR::InstBlockId, SemIR::InstId,
Tag<SemIR::CheckIRId>>;
} // namespace Carbon
#endif // CARBON_TOOLCHAIN_SEM_IR_INST_H_
+12
View File
@@ -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<SemIR::InterfaceId, SemIR::Interface,
Tag<SemIR::CheckIRId>>;
} // namespace Carbon
+5
View File
@@ -73,4 +73,9 @@ using InterfaceStore = ValueStore<InterfaceId, Interface, Tag<CheckIRId>>;
} // namespace Carbon::SemIR
namespace Carbon {
extern template class ValueStore<SemIR::InterfaceId, SemIR::Interface,
Tag<SemIR::CheckIRId>>;
} // namespace Carbon
#endif // CARBON_TOOLCHAIN_SEM_IR_INTERFACE_H_
+6
View File
@@ -7,6 +7,7 @@
#include <optional>
#include <utility>
#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<SemIR::NameScopeId, SemIR::NameScope,
Tag<SemIR::CheckIRId>>;
}
+12
View File
@@ -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<SemIR::NamedConstraintId, SemIR::NamedConstraint,
Tag<SemIR::CheckIRId>>;
} // namespace Carbon
+5
View File
@@ -64,4 +64,9 @@ using NamedConstraintStore =
} // namespace Carbon::SemIR
namespace Carbon {
extern template class ValueStore<SemIR::NamedConstraintId,
SemIR::NamedConstraint, Tag<SemIR::CheckIRId>>;
} // namespace Carbon
#endif // CARBON_TOOLCHAIN_SEM_IR_NAMED_CONSTRAINT_H_
+18
View File
@@ -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<SemIR::RequireImplsId, SemIR::RequireImpls,
Tag<SemIR::CheckIRId>>;
template class ValueStore<SemIR::RequireImplsBlockId,
llvm::MutableArrayRef<SemIR::RequireImplsId>,
Tag<SemIR::CheckIRId>>;
template class BlockValueStore<SemIR::RequireImplsBlockId,
SemIR::RequireImplsId, Tag<SemIR::CheckIRId>>;
} // namespace Carbon
+10
View File
@@ -51,4 +51,14 @@ using RequireImplsBlockStore =
} // namespace Carbon::SemIR
namespace Carbon {
extern template class ValueStore<SemIR::RequireImplsId, SemIR::RequireImpls,
Tag<SemIR::CheckIRId>>;
extern template class ValueStore<SemIR::RequireImplsBlockId,
llvm::MutableArrayRef<SemIR::RequireImplsId>,
Tag<SemIR::CheckIRId>>;
extern template class BlockValueStore<
SemIR::RequireImplsBlockId, SemIR::RequireImplsId, Tag<SemIR::CheckIRId>>;
} // namespace Carbon
#endif // CARBON_TOOLCHAIN_SEM_IR_REQUIRE_IMPLS_H_
+16
View File
@@ -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<SemIR::SpecificInterfaceId,
SemIR::SpecificInterface,
Tag<SemIR::CheckIRId>>;
template class ValueStore<SemIR::SpecificInterfaceId, SemIR::SpecificInterface,
Tag<SemIR::CheckIRId>>;
} // namespace Carbon
+9
View File
@@ -38,4 +38,13 @@ using SpecificInterfaceStore =
} // namespace Carbon::SemIR
namespace Carbon {
extern template class CanonicalValueStore<SemIR::SpecificInterfaceId,
SemIR::SpecificInterface,
Tag<SemIR::CheckIRId>>;
extern template class ValueStore<SemIR::SpecificInterfaceId,
SemIR::SpecificInterface,
Tag<SemIR::CheckIRId>>;
} // namespace Carbon
#endif // CARBON_TOOLCHAIN_SEM_IR_SPECIFIC_INTERFACE_H_
+16
View File
@@ -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<SemIR::StructTypeFieldsId,
llvm::MutableArrayRef<SemIR::StructTypeField>,
Tag<SemIR::CheckIRId>>;
template class BlockValueStore<SemIR::StructTypeFieldsId,
SemIR::StructTypeField, Tag<SemIR::CheckIRId>>;
} // namespace Carbon
+8
View File
@@ -37,4 +37,12 @@ inline auto CarbonHashValue(const StructTypeField& value, uint64_t seed)
} // namespace Carbon::SemIR
namespace Carbon {
extern template class ValueStore<SemIR::StructTypeFieldsId,
llvm::MutableArrayRef<SemIR::StructTypeField>,
Tag<SemIR::CheckIRId>>;
extern template class BlockValueStore<
SemIR::StructTypeFieldsId, SemIR::StructTypeField, Tag<SemIR::CheckIRId>>;
} // namespace Carbon
#endif // CARBON_TOOLCHAIN_SEM_IR_STRUCT_TYPE_FIELD_H_
+12
View File
@@ -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<SemIR::VtableId, SemIR::Vtable,
Tag<SemIR::CheckIRId>>;
} // namespace Carbon
+5
View File
@@ -40,4 +40,9 @@ using VtableStore = ValueStore<VtableId, Vtable, Tag<CheckIRId>>;
} // namespace Carbon::SemIR
namespace Carbon {
extern template class ValueStore<SemIR::VtableId, SemIR::Vtable,
Tag<SemIR::CheckIRId>>;
} // namespace Carbon
#endif // CARBON_TOOLCHAIN_SEM_IR_VTABLE_H_