mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 15:10:12 +01:00
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:
+16
-3
@@ -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",
|
||||
|
||||
@@ -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_
|
||||
|
||||
@@ -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_
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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_
|
||||
|
||||
@@ -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
|
||||
@@ -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_
|
||||
|
||||
@@ -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_; }
|
||||
|
||||
|
||||
@@ -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_
|
||||
@@ -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",
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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_
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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_
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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
|
||||
@@ -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_
|
||||
|
||||
@@ -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_
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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_
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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_
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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_
|
||||
|
||||
@@ -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
|
||||
@@ -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_
|
||||
|
||||
@@ -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
|
||||
@@ -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_
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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_
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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_
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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_
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,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
|
||||
|
||||
@@ -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_
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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_
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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_
|
||||
|
||||
@@ -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
|
||||
@@ -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_
|
||||
|
||||
@@ -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>>;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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_
|
||||
|
||||
@@ -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
|
||||
@@ -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_
|
||||
|
||||
@@ -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
|
||||
@@ -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_
|
||||
|
||||
@@ -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
|
||||
@@ -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_
|
||||
|
||||
@@ -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
|
||||
@@ -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_
|
||||
|
||||
Reference in New Issue
Block a user