diff --git a/toolchain/base/BUILD b/toolchain/base/BUILD index 61eb65e7afcb..5b0c0fb1fd21 100644 --- a/toolchain/base/BUILD +++ b/toolchain/base/BUILD @@ -12,6 +12,7 @@ cc_library( name = "block_value_store", hdrs = ["block_value_store.h"], deps = [ + ":id_tag", ":mem_usage", ":value_store", ":yaml", @@ -88,6 +89,7 @@ cc_library( hdrs = ["id_tag.h"], deps = [ "//common:check", + "//common:ostream", "@llvm-project//llvm:Support", ], ) diff --git a/toolchain/base/block_value_store.h b/toolchain/base/block_value_store.h index 27d7969d2119..7f8d6e96b75e 100644 --- a/toolchain/base/block_value_store.h +++ b/toolchain/base/block_value_store.h @@ -10,6 +10,7 @@ #include "common/check.h" #include "common/set.h" #include "llvm/Support/Allocator.h" +#include "toolchain/base/id_tag.h" #include "toolchain/base/mem_usage.h" #include "toolchain/base/value_store.h" #include "toolchain/base/yaml.h" @@ -22,17 +23,21 @@ namespace Carbon::SemIR { // // BlockValueStore is used as-is, but there are also children that expose the // protected members for type-specific functionality. -template -class BlockValueStore : public Yaml::Printable> { +template +class BlockValueStore + : public Yaml::Printable> { public: using IdType = IdT; + using IdTagType = IdTag; using ElementType = ElementT; using RefType = llvm::MutableArrayRef; using ConstRefType = llvm::ArrayRef; explicit BlockValueStore(llvm::BumpPtrAllocator& allocator, - IdTag tag = IdTag()) - : allocator_(&allocator), values_(tag) { + IdTagType::TagIdType tag_id, + int32_t initial_reserved_ids = 0) + requires(!IdTagIsUntagged) + : allocator_(&allocator), values_(tag_id, initial_reserved_ids) { auto empty = RefType(); auto empty_val = canonical_blocks_.Insert( empty, [&] { return values_.Add(empty); }, KeyContext(this)); @@ -129,18 +134,18 @@ class BlockValueStore : public Yaml::Printable> { } // Allow children to have more complex value handling. - auto values() -> ValueStore& { return values_; } + auto values() -> ValueStore& { return values_; } private: class KeyContext; llvm::BumpPtrAllocator* allocator_; - ValueStore values_; + ValueStore values_; Set canonical_blocks_; }; -template -class BlockValueStore::KeyContext +template +class BlockValueStore::KeyContext : public TranslatingKeyContext { public: explicit KeyContext(const BlockValueStore* store) : store_(store) {} diff --git a/toolchain/base/canonical_value_store.h b/toolchain/base/canonical_value_store.h index 61531002adec..fb5c3976657a 100644 --- a/toolchain/base/canonical_value_store.h +++ b/toolchain/base/canonical_value_store.h @@ -22,10 +22,12 @@ 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. -template +template class CanonicalValueStore { public: using IdType = IdT; + using IdTagType = IdTag; using KeyType = std::remove_cvref_t; using ValueType = ValueStoreTypes::ValueType; using RefType = ValueStoreTypes::RefType; @@ -56,7 +58,7 @@ class CanonicalValueStore { } auto values() const [[clang::lifetimebound]] - -> ValueStore::Range { + -> ValueStore::Range { return values_.values(); } auto size() const -> size_t { return values_.size(); } @@ -71,7 +73,7 @@ class CanonicalValueStore { auto GetRawIndex(IdT id) const -> int32_t { return values_.GetRawIndex(id); } - auto GetIdTag() const -> IdTag { return values_.GetIdTag(); } + auto GetIdTag() const -> IdTagType { return values_.GetIdTag(); } private: class KeyContext; @@ -87,15 +89,15 @@ class CanonicalValueStore { return value.GetAsKey(); } - ValueStore values_; + ValueStore values_; Set set_; }; -template -class CanonicalValueStore::KeyContext +template +class CanonicalValueStore::KeyContext : public TranslatingKeyContext { public: - explicit KeyContext(const ValueStore* values) + explicit KeyContext(const ValueStore* values) : values_(values) {} // Note that it is safe to return a reference here as the underlying object's @@ -106,25 +108,28 @@ class CanonicalValueStore::KeyContext } private: - const ValueStore* values_; + const ValueStore* values_; }; -template -auto CanonicalValueStore::Add(ValueType value) -> IdT { +template +auto CanonicalValueStore::Add(ValueType value) + -> IdT { auto make_key = [&] { return IdT(values_.Add(std::move(value))); }; return set_.Insert(GetAsKey(value), make_key, KeyContext(&values_)).key(); } -template -auto CanonicalValueStore::Lookup(KeyType key) const -> IdT { +template +auto CanonicalValueStore::Lookup(KeyType key) const + -> IdT { if (auto result = set_.Lookup(key, KeyContext(&values_))) { return result.key(); } return IdT::None; } -template -auto CanonicalValueStore::Reserve(size_t size) -> void { +template +auto CanonicalValueStore::Reserve(size_t size) + -> void { // Compute the resulting new insert count using the size of values -- the // set doesn't have a fast to compute current size. if (size > values_.size()) { diff --git a/toolchain/base/fixed_size_value_store.h b/toolchain/base/fixed_size_value_store.h index 62a7c75268d4..bdf240050230 100644 --- a/toolchain/base/fixed_size_value_store.h +++ b/toolchain/base/fixed_size_value_store.h @@ -19,18 +19,32 @@ namespace Carbon { // A value store with a predetermined size. -template +template class FixedSizeValueStore { public: using IdType = IdT; + using IdTagType = IdTag; using ValueType = ValueStoreTypes::ValueType; using RefType = ValueStoreTypes::RefType; using ConstRefType = ValueStoreTypes::ConstRefType; // Makes a ValueStore of the specified size, but without initializing values. // Entries must be set before reading. + static auto MakeForOverwriteWithExplicitSize(size_t size, + IdTagType::TagIdType tag_id, + int32_t initial_reserved_ids = 0) + -> FixedSizeValueStore + requires(!IdTagIsUntagged) + { + FixedSizeValueStore store(IdTagType(tag_id, initial_reserved_ids)); + store.values_.resize_for_overwrite(size); + return store; + } + static auto MakeForOverwriteWithExplicitSize(size_t size) - -> FixedSizeValueStore { + -> FixedSizeValueStore + requires(IdTagIsUntagged) + { FixedSizeValueStore store; store.values_.resize_for_overwrite(size); return store; @@ -39,7 +53,8 @@ class FixedSizeValueStore { // Makes a ValueStore of the same size as a source `ValueStoreT`, but without // initializing values. Entries must be set before reading. template - requires std::same_as + requires(std::same_as && + !IdTagIsUntagged) static auto MakeForOverwrite(const ValueStoreT& size_source) -> FixedSizeValueStore { FixedSizeValueStore store(size_source.GetIdTag()); @@ -48,11 +63,21 @@ class FixedSizeValueStore { } // Makes a ValueStore of the specified size, initialized to a default. - static auto MakeWithExplicitSize(IdTag tag, size_t size, + static auto MakeWithExplicitSize(size_t size, IdTagType tag, ConstRefType default_value) - -> FixedSizeValueStore { + -> FixedSizeValueStore + requires(!IdTagIsUntagged) + { + FixedSizeValueStore store(tag); + store.values_.resize(size, default_value); + return store; + } + + static auto MakeWithExplicitSize(size_t size, ConstRefType default_value) + -> FixedSizeValueStore + requires(IdTagIsUntagged) + { FixedSizeValueStore store; - store.tag_ = tag; store.values_.resize(size, default_value); return store; } @@ -74,19 +99,29 @@ class FixedSizeValueStore { // the safest constructor to use, since it ensures everything's initialized to // a default, and verifies a matching `IdT` for the size. template - requires std::same_as + requires(std::same_as && + !IdTagIsUntagged && !IdTagIsUntagged) explicit FixedSizeValueStore(const ValueStoreT& size_source, ConstRefType default_value) : tag_(size_source.GetIdTag()) { values_.resize(size_source.size(), default_value); } - explicit FixedSizeValueStore(IdTag tag) : tag_(tag) {} + template + requires(std::same_as && + IdTagIsUntagged && IdTagIsUntagged) + explicit FixedSizeValueStore(const ValueStoreT& size_source, + ConstRefType default_value) { + values_.resize(size_source.size(), default_value); + } + + explicit FixedSizeValueStore(IdTagType tag) : tag_(tag) {} // Makes a ValueStore using a mapped range of `source`. The `factory_fn` // receives each enumerated entry for construction of `ValueType`. template - requires std::same_as + requires(std::same_as && + !IdTagIsUntagged && !IdTagIsUntagged) explicit FixedSizeValueStore( const ValueStoreT& source, llvm::function_ref< @@ -95,6 +130,16 @@ class FixedSizeValueStore { : values_(llvm::map_range(source.enumerate(), factory_fn)), tag_(GetIdTag(source)) {} + template + requires(std::same_as && + IdTagIsUntagged && IdTagIsUntagged) + explicit FixedSizeValueStore( + const ValueStoreT& source, + llvm::function_ref< + auto(IdT, typename ValueStoreT::ConstRefType)->ValueType> + factory_fn) + : values_(llvm::map_range(source.enumerate(), factory_fn)) {} + // Move-only. FixedSizeValueStore(FixedSizeValueStore&&) noexcept = default; auto operator=(FixedSizeValueStore&&) noexcept @@ -103,21 +148,21 @@ class FixedSizeValueStore { // Sets the value for an ID. auto Set(IdT id, ValueType value) -> void { CARBON_DCHECK(id.index >= 0, "{0}", id); - auto index = tag_.Remove(id.index); + auto index = tag_.Remove(id); values_[index] = value; } // Returns a mutable value for an ID. auto Get(IdT id) -> RefType { CARBON_DCHECK(id.index >= 0, "{0}", id); - auto index = tag_.Remove(id.index); + auto index = tag_.Remove(id); return values_[index]; } // Returns the value for an ID. auto Get(IdT id) const -> ConstRefType { CARBON_DCHECK(id.index >= 0, "{0}", id); - auto index = tag_.Remove(id.index); + auto index = tag_.Remove(id); return values_[index]; } @@ -146,7 +191,7 @@ class FixedSizeValueStore { // Storage for the `ValueT` objects, indexed by the id. llvm::SmallVector values_; - IdTag tag_; + IdTagType tag_; }; } // namespace Carbon diff --git a/toolchain/base/id_tag.h b/toolchain/base/id_tag.h index 712f1f188fb0..a8c84456ba52 100644 --- a/toolchain/base/id_tag.h +++ b/toolchain/base/id_tag.h @@ -10,17 +10,52 @@ #include #include "common/check.h" +#include "common/ostream.h" #include "llvm/Support/MathExtras.h" namespace Carbon { -// A tagged Id. It is used to add a tag into the unused bits of the id, in order -// to verify ids are used in the correct context. The tag should look like an -// Id, which is a non-negative number. -struct IdTag { - IdTag() = default; +// A sentinel type to construct an IdTag without tagging. +struct Untagged : Printable { + auto Print(llvm::raw_ostream& out) const -> void { out << ""; } +}; - explicit IdTag(int32_t tag, int32_t initial_reserved_ids) +// A wrapper type used as the template argument to IdTag, in order to mark the +// tag type as such. +template +struct Tag {}; + +template +struct GetTagIdType { + static_assert(false, "IdTag with TagT that is neither Untagged nor Tag"); +}; +template <> +struct GetTagIdType { + using TagIdType = Untagged; +}; +template +struct GetTagIdType> { + using TagIdType = TagIdT; +}; + +// Tests if an `IdTag` type is untagged. +template +concept IdTagIsUntagged = std::same_as; + +// A tagged Id. It is used to add a tag into the unused bits of the id, in order +// to verify ids are used in the correct context. The tag type must be `Tag` or +// `Untagged`. +template +struct IdTag { + using IdType = IdT; + using TagIdType = GetTagIdType::TagIdType; + + IdTag() + requires(IdTagIsUntagged) + = default; + + IdTag(TagIdType tag, int32_t initial_reserved_ids) + requires(!IdTagIsUntagged) : // Shift down by 1 to get out of the high bit to avoid using any // negative ids, since they have special uses. Shift down by another 1 // to free up the second highest bit for a marker to indicate whether @@ -28,43 +63,43 @@ struct IdTag { // index so it's not zero-based, to make it a bit less likely this // doesn't collide with anything else (though with the // second-highest-bit-tagging this might not be needed). - id_tag_(llvm::reverseBits((((tag + 1) << 1) | 1) << 1)), - initial_reserved_ids_(initial_reserved_ids) { - CARBON_CHECK( - tag != -1, - "IdTag should be default constructed if no tagging id is available."); - } + tag_(llvm::reverseBits((((tag.index + 1) << 1) | 1) << 1)), + initial_reserved_ids_(initial_reserved_ids) {} - auto Apply(int32_t index) const -> int32_t { + auto Apply(int32_t index) const -> IdT { CARBON_DCHECK(index >= 0, "{0}", index); if (index < initial_reserved_ids_) { - return index; + return IdT(index); } - // TODO: Assert that id_tag_ doesn't have the second highest bit set. - auto tagged_index = index ^ id_tag_; + // TODO: Assert that tag_ doesn't have the second highest bit set. + auto tagged_index = index ^ tag_; CARBON_DCHECK(tagged_index >= 0, "{0}", tagged_index); - return tagged_index; + return IdT(tagged_index); } - auto Remove(int32_t tagged_index) const -> int32_t { - CARBON_DCHECK(tagged_index >= 0, "{0}", tagged_index); - if (!HasTag(tagged_index)) { - CARBON_DCHECK(tagged_index < initial_reserved_ids_, + auto Remove(IdT id) const -> int32_t { + CARBON_DCHECK(id.index >= 0, "{0}", id); + if (!HasTag(id.index)) { + CARBON_DCHECK(id.index < initial_reserved_ids_, "This untagged index is outside the initial reserved ids " "and should have been tagged."); - return tagged_index; + return id.index; } - auto index = tagged_index ^ id_tag_; - CARBON_DCHECK(index >= initial_reserved_ids_, + auto untagged_index = id.index ^ tag_; + CARBON_DCHECK(untagged_index >= initial_reserved_ids_, "When removing tagging bits, found an index that " "shouldn't've been tagged in the first place."); - return index; + return untagged_index; } // Gets the value unique to this IdTag instance that is added to indices in // Apply, and removed in Remove. - auto GetContainerTag() const -> int32_t { - return (llvm::reverseBits(id_tag_) >> 2) - 1; + auto GetContainerTag() const -> TagIdType { + if constexpr (IdTagIsUntagged) { + return TagIdType(); + } else { + return TagIdType((llvm::reverseBits(tag_) >> 2) - 1); + } } // Returns whether `tagged_index` has an IdTag applied to it, from this IdTag @@ -73,56 +108,60 @@ struct IdTag { return (llvm::reverseBits(2) & tagged_index) != 0; } - template struct TagAndIndex { - int32_t tag; + TagIdType tag; int32_t index; }; - template - static auto DecomposeWithBestEffort(int32_t tagged_index) - -> TagAndIndex { - if (tagged_index < 0) { - // TODO: This should return TagT::None, but we need a fallback TagT other - // than `int32_t`. - return {TagT{-1}, tagged_index}; - } - if (!HasTag(tagged_index)) { - // TODO: This should return TagT::None, but we need a fallback TagT other - // than `int32_t`. - return {TagT{-1}, tagged_index}; - } - int length = 0; - int location = 0; - for (int i = 0; i != 32; ++i) { - int current_run = 0; - int location_of_current_run = i; - while (i != 32 && (tagged_index & (1 << i)) == 0) { - ++current_run; - ++i; + static auto DecomposeWithBestEffort(IdT id) -> TagAndIndex { + if constexpr (IdTagIsUntagged) { + return {TagIdType(), id.index}; + } else { + if (!id.has_value()) { + return {TagIdType::None, id.index}; } - if (current_run != 0) { - --i; + if (!HasTag(id.index)) { + return {TagIdType::None, id.index}; } - if (current_run > length) { - length = current_run; - location = location_of_current_run; + int length = 0; + int location = 0; + for (int i = 0; i != 32; ++i) { + int current_run = 0; + int location_of_current_run = i; + while (i != 32 && (id.index & (1 << i)) == 0) { + ++current_run; + ++i; + } + if (current_run != 0) { + --i; + } + if (current_run > length) { + length = current_run; + location = location_of_current_run; + } } + if (length < 8) { + return {TagIdType::None, id.index}; + } + auto index_mask = llvm::maskTrailingOnes(location); + auto tag = (llvm::reverseBits(id.index & ~index_mask) >> 2) - 1; + auto index = id.index & index_mask; + return {.tag = TagIdType(static_cast(tag)), + .index = static_cast(index)}; } - if (length < 8) { - // TODO: This should return TagT::None, but we need a fallback TagT other - // than `int32_t`. - return {TagT{-1}, tagged_index}; - } - auto index_mask = llvm::maskTrailingOnes(location); - auto tag = (llvm::reverseBits(tagged_index & ~index_mask) >> 2) - 1; - auto index = tagged_index & index_mask; - return {.tag = TagT{static_cast(tag)}, - .index = static_cast(index)}; + } + + // Converts an IdTag to be used for a different ID type. This is only valid + // when the id indices are interchangeable, as they will have the same tag and + // the same reserved ids. + template + requires(!IdTagIsUntagged) + auto ToEquivalentIdType() -> IdTag> { + return {GetContainerTag(), initial_reserved_ids_}; } private: - int32_t id_tag_ = 0; + int32_t tag_ = 0; int32_t initial_reserved_ids_ = std::numeric_limits::max(); }; diff --git a/toolchain/base/relational_value_store.h b/toolchain/base/relational_value_store.h index bbb7d8254d01..41b6bb530daa 100644 --- a/toolchain/base/relational_value_store.h +++ b/toolchain/base/relational_value_store.h @@ -35,6 +35,8 @@ template class RelationalValueStore { public: using RelatedIdType = RelatedStoreT::IdType; + using RelatedIdTagType = RelatedStoreT::IdTagType; + using RelatedTagIdType = RelatedIdTagType::TagIdType; using ValueType = ValueStoreTypes::ValueType; using ConstRefType = ValueStoreTypes::ConstRefType; @@ -50,7 +52,7 @@ class RelationalValueStore { CARBON_CHECK(!opt.has_value(), "Add with `related_id` that was already added to the store"); opt.emplace(std::move(value)); - return IdT(related_store_->GetIdTag().Apply(related_index)); + return IdT(related_store_->GetIdTag().Apply(related_index).index); } // Returns the ID of a value in the store if the `related_id` was previously @@ -64,7 +66,7 @@ class RelationalValueStore { if (!opt.has_value()) { return IdT::None; } - return IdT(related_store_->GetIdTag().Apply(related_index)); + return IdT(related_store_->GetIdTag().Apply(related_index).index); } // Returns a value for an ID. @@ -73,7 +75,8 @@ class RelationalValueStore { } private: - ValueStore> values_; + ValueStore, Tag> + values_; const RelatedStoreT* related_store_; }; diff --git a/toolchain/base/value_store.h b/toolchain/base/value_store.h index 6865c5979e2e..1810c7aeacc7 100644 --- a/toolchain/base/value_store.h +++ b/toolchain/base/value_store.h @@ -35,13 +35,14 @@ class ValueStoreNotPrintable {}; // A simple wrapper for accumulating values, providing IDs to later retrieve the // value. This does not do deduplication. -template +template class ValueStore : public std::conditional, ValueT>, - Yaml::Printable>, + Yaml::Printable>, Internal::ValueStoreNotPrintable> { public: using IdType = IdT; + using IdTagType = IdTag; using ValueType = ValueStoreTypes::ValueType; using RefType = ValueStoreTypes::RefType; using ConstRefType = ValueStoreTypes::ConstRefType; @@ -75,11 +76,21 @@ class ValueStore FlattenedRangeType flattened_range_; }; - ValueStore() = default; - explicit ValueStore(IdTag tag) : tag_(tag) {} - template - explicit ValueStore(Id id, int32_t initial_reserved_ids = 0) - : tag_(id.index, initial_reserved_ids) {} + // Default constructor, only valid when the IdTag's tag type is Untagged. + ValueStore() + requires(IdTagIsUntagged) + = default; + + // Construct a ValueStore sharing the IdTag from another ValueStore. Useful + // for when two ValueStores are sharing the same ID types. + explicit ValueStore(IdTagType tag) + requires(!IdTagIsUntagged) + : tag_(tag) {} + + // Construct a ValueStore with a given tag and set of untagged (reserved) ids. + explicit ValueStore(IdTagType::TagIdType id, int32_t initial_reserved_ids = 0) + requires(!IdTagIsUntagged) + : tag_(id, initial_reserved_ids) {} // Stores the value and returns an ID to reference it. auto Add(ValueType value) -> IdType { @@ -88,7 +99,7 @@ class ValueStore // tracking down issues easier. CARBON_DCHECK(size_ < std::numeric_limits::max(), "Id overflow"); - IdType id(tag_.Apply(size_)); + IdType id = tag_.Apply(size_); auto [chunk_index, pos] = RawIndexToChunkIndices(size_); ++size_; @@ -123,7 +134,7 @@ class ValueStore ConstRefType default_value [[clang::lifetimebound]]) const -> ConstRefType { CARBON_DCHECK(id.index >= 0, "{0}", id); - auto index = tag_.Remove(id.index); + auto index = tag_.Remove(id); if (index >= size_) { return default_value; } @@ -192,7 +203,7 @@ class ValueStore // Makes an iterable range over references to all values in the ValueStore. auto values() [[clang::lifetimebound]] -> auto { return llvm::map_range(llvm::seq(size_), [&](int32_t i) -> RefType { - return Get(IdType(tag_.Apply(i))); + return Get(tag_.Apply(i)); }); } auto values() const [[clang::lifetimebound]] -> Range { return Range(*this); } @@ -211,7 +222,7 @@ class ValueStore // `mapped_iterator` incorrectly infers the pointer type for `PointerProxy`. // NOLINTNEXTLINE(readability-const-return-type) auto index_to_id = [&](int32_t i) -> const std::pair { - IdType id(tag_.Apply(i)); + IdType id = tag_.Apply(i); return std::pair(id, Get(id)); }; // Because indices into `ValueStore` are all sequential values from 0, we @@ -219,10 +230,10 @@ class ValueStore return llvm::map_range(llvm::seq(size_), index_to_id); } - auto GetIdTag() const -> IdTag { return tag_; } + auto GetIdTag() const -> IdTagType { return tag_; } auto GetRawIndex(IdT id) const -> int32_t { CARBON_DCHECK(id.index >= 0, "{0}", index); - auto index = tag_.Remove(id.index); + auto index = tag_.Remove(id); #ifndef NDEBUG if (index >= size_) { // Attempt to decompose id.index to include extra detail in the check @@ -230,8 +241,7 @@ class ValueStore // // TODO: Teach ValueStore the type of the tag id with a template, then we // can print it with proper formatting instead of just as an integer. - auto [id_tag, id_untagged_index] = - IdTag::DecomposeWithBestEffort(id.index); + auto [id_tag, id_untagged_index] = IdTagType::DecomposeWithBestEffort(id); CARBON_DCHECK( index < size_, "Untagged index was outside of container range. Tagged index {0}. " @@ -390,7 +400,7 @@ class ValueStore // fits in an `int32_t`, which is checked in non-optimized builds in Add(). int32_t size_ = 0; - IdTag tag_; + IdTagType tag_; // Storage for the `ValueType` objects, indexed by the id. We use a vector of // chunks of `ValueType` instead of just a vector of `ValueType` so that diff --git a/toolchain/check/check_unit.cpp b/toolchain/check/check_unit.cpp index b4768d4b2041..412ea12cf8ac 100644 --- a/toolchain/check/check_unit.cpp +++ b/toolchain/check/check_unit.cpp @@ -169,9 +169,8 @@ auto CheckUnit::InitPackageScopeAndImports() -> void { auto CheckUnit::CollectDirectImports( llvm::SmallVector& results, - FixedSizeValueStore& ir_to_result_index, - SemIR::InstId import_decl_id, const PackageImports& imports, bool is_local) - -> void { + CheckIRIdToIntStore& ir_to_result_index, SemIR::InstId import_decl_id, + const PackageImports& imports, bool is_local) -> void { for (const auto& import : imports.imports) { const auto& direct_ir = *import.unit_info->unit->sem_ir; auto& index = ir_to_result_index.Get(direct_ir.check_ir_id()); @@ -198,9 +197,8 @@ auto CheckUnit::CollectTransitiveImports(SemIR::InstId import_decl_id, // Track whether an IR was imported in full, including `export import`. This // distinguishes from IRs that are indirectly added without all names being // exported to this IR. - auto ir_to_result_index = - FixedSizeValueStore::MakeWithExplicitSize( - IdTag(), unit_and_imports_->unit->total_ir_count, -1); + auto ir_to_result_index = CheckIRIdToIntStore::MakeWithExplicitSize( + unit_and_imports_->unit->total_ir_count, -1); // First add direct imports. This means that if an entity is imported both // directly and indirectly, the import path will reflect the direct import. diff --git a/toolchain/check/check_unit.h b/toolchain/check/check_unit.h index e3c4ed483e12..f9c6ec727312 100644 --- a/toolchain/check/check_unit.h +++ b/toolchain/check/check_unit.h @@ -134,15 +134,17 @@ class CheckUnit { auto Run() -> void; private: + using CheckIRIdToIntStore = FixedSizeValueStore; + // Add imports to the root block. auto InitPackageScopeAndImports() -> void; // Collects direct imports, for CollectTransitiveImports. - auto CollectDirectImports( - llvm::SmallVector& results, - FixedSizeValueStore& ir_to_result_index, - SemIR::InstId import_decl_id, const PackageImports& imports, - bool is_local) -> void; + auto CollectDirectImports(llvm::SmallVector& results, + CheckIRIdToIntStore& ir_to_result_index, + SemIR::InstId import_decl_id, + const PackageImports& imports, bool is_local) + -> void; // Collects transitive imports, handling deduplication. These will be unified // between local_imports and api_imports. diff --git a/toolchain/check/context.cpp b/toolchain/check/context.cpp index 60ecab399e20..2ea44663a898 100644 --- a/toolchain/check/context.cpp +++ b/toolchain/check/context.cpp @@ -32,9 +32,8 @@ Context::Context(DiagnosticEmitterBase* emitter, scope_stack_(sem_ir_), deferred_definition_worklist_(vlog_stream), vtable_stack_("vtable_stack_", *sem_ir, vlog_stream), - check_ir_map_(FixedSizeValueStore:: - MakeWithExplicitSize(IdTag(), total_ir_count_, - SemIR::ImportIRId::None)), + check_ir_map_(CheckIRToImpportIRStore::MakeWithExplicitSize( + total_ir_count_, SemIR::ImportIRId::None)), global_init_(this), region_stack_([this](SemIR::LocId loc_id, std::string label) { TODO(loc_id, label); diff --git a/toolchain/check/context.h b/toolchain/check/context.h index 4b20b70c7d0d..52ba28186b6b 100644 --- a/toolchain/check/context.h +++ b/toolchain/check/context.h @@ -158,10 +158,9 @@ class Context { auto exports() -> llvm::SmallVector& { return exports_; } - auto check_ir_map() - -> FixedSizeValueStore& { - return check_ir_map_; - } + using CheckIRToImpportIRStore = + FixedSizeValueStore; + auto check_ir_map() -> CheckIRToImpportIRStore& { return check_ir_map_; } auto import_ir_constant_values() -> llvm::SmallVector& { @@ -445,7 +444,7 @@ class Context { llvm::SmallVector exports_; // Maps CheckIRId to ImportIRId. - FixedSizeValueStore check_ir_map_; + CheckIRToImpportIRStore check_ir_map_; // Per-import constant values. These refer to the main IR and mainly serve as // a lookup table for quick access. diff --git a/toolchain/check/testdata/basics/raw_sem_ir/one_file.carbon b/toolchain/check/testdata/basics/raw_sem_ir/one_file.carbon index f5d134dea3ea..da3b0cbca6d8 100644 --- a/toolchain/check/testdata/basics/raw_sem_ir/one_file.carbon +++ b/toolchain/check/testdata/basics/raw_sem_ir/one_file.carbon @@ -378,18 +378,18 @@ fn Foo[T:! type](p: T*) -> (T*, ()) { // CHECK:STDOUT: value_repr: {kind: pointer, type: type(inst6000002C)} // CHECK:STDOUT: 'type(inst6000003D)': // CHECK:STDOUT: value_repr: {kind: none, type: type(inst60000025)} -// CHECK:STDOUT: 'type(symbolic_constant3)': -// CHECK:STDOUT: value_repr: {kind: copy, type: type(symbolic_constant3)} -// CHECK:STDOUT: 'type(symbolic_constantF)': -// CHECK:STDOUT: value_repr: {kind: copy, type: type(symbolic_constantF)} -// CHECK:STDOUT: 'type(symbolic_constant9)': -// CHECK:STDOUT: value_repr: {kind: pointer, type: type(symbolic_constantF)} +// CHECK:STDOUT: 'type(symbolic_constant60000003)': +// CHECK:STDOUT: value_repr: {kind: copy, type: type(symbolic_constant60000003)} +// CHECK:STDOUT: 'type(symbolic_constant6000000F)': +// CHECK:STDOUT: value_repr: {kind: copy, type: type(symbolic_constant6000000F)} +// CHECK:STDOUT: 'type(symbolic_constant60000009)': +// CHECK:STDOUT: value_repr: {kind: pointer, type: type(symbolic_constant6000000F)} // CHECK:STDOUT: 'type(inst(WitnessType))': // CHECK:STDOUT: value_repr: {kind: copy, type: type(inst(WitnessType))} -// CHECK:STDOUT: 'type(symbolic_constant4)': -// CHECK:STDOUT: value_repr: {kind: copy, type: type(symbolic_constant4)} -// CHECK:STDOUT: 'type(symbolic_constantA)': -// CHECK:STDOUT: value_repr: {kind: pointer, type: type(symbolic_constantF)} +// CHECK:STDOUT: 'type(symbolic_constant60000004)': +// CHECK:STDOUT: value_repr: {kind: copy, type: type(symbolic_constant60000004)} +// CHECK:STDOUT: 'type(symbolic_constant6000000A)': +// CHECK:STDOUT: value_repr: {kind: pointer, type: type(symbolic_constant6000000F)} // CHECK:STDOUT: 'type(inst(InstType))': // CHECK:STDOUT: value_repr: {kind: none, type: type(inst60000025)} // CHECK:STDOUT: 'type(inst6000004F)': @@ -420,11 +420,11 @@ fn Foo[T:! type](p: T*) -> (T*, ()) { // CHECK:STDOUT: inst6000001B: {kind: PointerType, arg0: inst6000001A, type: type(TypeType)} // CHECK:STDOUT: inst6000001C: {kind: PointerType, arg0: inst60000016, type: type(TypeType)} // CHECK:STDOUT: inst6000001D: {kind: PointerType, arg0: inst60000017, type: type(TypeType)} -// CHECK:STDOUT: inst6000001E: {kind: ValueBinding, arg0: entity_name60000002, arg1: inst60000038, type: type(symbolic_constant4)} +// CHECK:STDOUT: inst6000001E: {kind: ValueBinding, arg0: entity_name60000002, arg1: inst60000038, type: type(symbolic_constant60000004)} // CHECK:STDOUT: inst6000001F: {kind: PatternType, arg0: inst6000001C, type: type(TypeType)} -// CHECK:STDOUT: inst60000020: {kind: ValueBindingPattern, arg0: entity_name60000002, type: type(symbolic_constant6)} +// CHECK:STDOUT: inst60000020: {kind: ValueBindingPattern, arg0: entity_name60000002, type: type(symbolic_constant60000006)} // CHECK:STDOUT: inst60000021: {kind: PatternType, arg0: inst6000001D, type: type(TypeType)} -// CHECK:STDOUT: inst60000022: {kind: ValueParamPattern, arg0: inst60000020, arg1: call_param0, type: type(symbolic_constant6)} +// CHECK:STDOUT: inst60000022: {kind: ValueParamPattern, arg0: inst60000020, arg1: call_param0, type: type(symbolic_constant60000006)} // CHECK:STDOUT: inst60000023: {kind: NameRef, arg0: name1, arg1: inst60000015, type: type(TypeType)} // CHECK:STDOUT: inst60000024: {kind: PointerType, arg0: inst60000023, type: type(TypeType)} // CHECK:STDOUT: inst60000025: {kind: TupleType, arg0: inst_block_empty, type: type(TypeType)} @@ -443,13 +443,13 @@ fn Foo[T:! type](p: T*) -> (T*, ()) { // CHECK:STDOUT: inst60000032: {kind: InitForm, arg0: inst6000002E, arg1: call_param1, type: type(inst(FormType))} // CHECK:STDOUT: inst60000033: {kind: InitForm, arg0: inst60000030, arg1: call_param1, type: type(inst(FormType))} // CHECK:STDOUT: inst60000034: {kind: PatternType, arg0: inst6000002E, type: type(TypeType)} -// CHECK:STDOUT: inst60000035: {kind: ReturnSlotPattern, arg0: inst6000002F, type: type(symbolic_constantE)} +// CHECK:STDOUT: inst60000035: {kind: ReturnSlotPattern, arg0: inst6000002F, type: type(symbolic_constant6000000E)} // CHECK:STDOUT: inst60000036: {kind: PatternType, arg0: inst60000030, type: type(TypeType)} -// CHECK:STDOUT: inst60000037: {kind: OutParamPattern, arg0: inst60000035, arg1: call_param1, type: type(symbolic_constantE)} -// CHECK:STDOUT: inst60000038: {kind: ValueParam, arg0: call_param0, arg1: name2, type: type(symbolic_constant4)} +// CHECK:STDOUT: inst60000037: {kind: OutParamPattern, arg0: inst60000035, arg1: call_param1, type: type(symbolic_constant6000000E)} +// CHECK:STDOUT: inst60000038: {kind: ValueParam, arg0: call_param0, arg1: name2, type: type(symbolic_constant60000004)} // CHECK:STDOUT: inst60000039: {kind: SpliceBlock, arg0: inst_block60000006, arg1: inst6000001B, type: type(TypeType)} -// CHECK:STDOUT: inst6000003A: {kind: OutParam, arg0: call_param1, arg1: name(ReturnSlot), type: type(symbolic_constantA)} -// CHECK:STDOUT: inst6000003B: {kind: ReturnSlot, arg0: inst6000002E, arg1: inst6000003A, type: type(symbolic_constantA)} +// CHECK:STDOUT: inst6000003A: {kind: OutParam, arg0: call_param1, arg1: name(ReturnSlot), type: type(symbolic_constant6000000A)} +// CHECK:STDOUT: inst6000003B: {kind: ReturnSlot, arg0: inst6000002E, arg1: inst6000003A, type: type(symbolic_constant6000000A)} // CHECK:STDOUT: inst6000003C: {kind: FunctionDecl, arg0: function60000000, arg1: inst_block60000013, type: type(inst6000003D)} // CHECK:STDOUT: inst6000003D: {kind: FunctionType, arg0: function60000000, arg1: specific, type: type(TypeType)} // CHECK:STDOUT: inst6000003E: {kind: StructValue, arg0: inst_block_empty, type: type(inst6000003D)} @@ -461,11 +461,11 @@ fn Foo[T:! type](p: T*) -> (T*, ()) { // CHECK:STDOUT: inst60000044: {kind: RequireCompleteType, arg0: inst6000001C, type: type(inst(WitnessType))} // CHECK:STDOUT: inst60000045: {kind: RequireCompleteType, arg0: inst6000001D, type: type(inst(WitnessType))} // CHECK:STDOUT: inst60000046: {kind: RequireCompleteType, arg0: inst6000002E, type: type(inst(WitnessType))} -// CHECK:STDOUT: inst60000047: {kind: NameRef, arg0: name2, arg1: inst6000001E, type: type(symbolic_constant4)} +// CHECK:STDOUT: inst60000047: {kind: NameRef, arg0: name2, arg1: inst6000001E, type: type(symbolic_constant60000004)} // CHECK:STDOUT: inst60000048: {kind: TupleLiteral, arg0: inst_block_empty, type: type(inst60000025)} -// CHECK:STDOUT: inst60000049: {kind: TupleLiteral, arg0: inst_block60000019, type: type(symbolic_constantA)} +// CHECK:STDOUT: inst60000049: {kind: TupleLiteral, arg0: inst_block60000019, type: type(symbolic_constant6000000A)} // CHECK:STDOUT: inst6000004A: {kind: RequireCompleteType, arg0: inst6000002E, type: type(inst(WitnessType))} -// CHECK:STDOUT: inst6000004B: {kind: TupleAccess, arg0: inst6000003A, arg1: element0, type: type(symbolic_constant4)} +// CHECK:STDOUT: inst6000004B: {kind: TupleAccess, arg0: inst6000003A, arg1: element0, type: type(symbolic_constant60000004)} // CHECK:STDOUT: inst6000004C: {kind: RequireCompleteType, arg0: inst6000001C, type: type(inst(WitnessType))} // CHECK:STDOUT: inst6000004D: {kind: ImportRefLoaded, arg0: import_ir_inst0, arg1: entity_name60000003, type: type(TypeType)} // CHECK:STDOUT: inst6000004E: {kind: InterfaceDecl, arg0: interface60000000, arg1: inst_block_empty, type: type(TypeType)} @@ -757,60 +757,60 @@ fn Foo[T:! type](p: T*) -> (T*, ()) { // CHECK:STDOUT: inst6000016C: {kind: SpecificImplFunction, arg0: inst60000168, arg1: specific60000019, type: type(inst(SpecificFunctionType))} // CHECK:STDOUT: inst6000016D: {kind: BoundMethod, arg0: inst60000047, arg1: inst6000016A, type: type(inst(BoundMethodType))} // CHECK:STDOUT: inst6000016E: {kind: RequireCompleteType, arg0: inst6000001C, type: type(inst(WitnessType))} -// CHECK:STDOUT: inst6000016F: {kind: Call, arg0: inst6000016D, arg1: inst_block6000007F, type: type(symbolic_constant4)} -// CHECK:STDOUT: inst60000170: {kind: InitializeFrom, arg0: inst6000016F, arg1: inst6000004B, type: type(symbolic_constant4)} +// CHECK:STDOUT: inst6000016F: {kind: Call, arg0: inst6000016D, arg1: inst_block6000007F, type: type(symbolic_constant60000004)} +// CHECK:STDOUT: inst60000170: {kind: InitializeFrom, arg0: inst6000016F, arg1: inst6000004B, type: type(symbolic_constant60000004)} // CHECK:STDOUT: inst60000171: {kind: TupleAccess, arg0: inst6000003A, arg1: element1, type: type(inst60000025)} // CHECK:STDOUT: inst60000172: {kind: TupleInit, arg0: inst_block_empty, arg1: inst60000171, type: type(inst60000025)} // CHECK:STDOUT: inst60000173: {kind: Converted, arg0: inst60000048, arg1: inst60000172, type: type(inst60000025)} -// CHECK:STDOUT: inst60000174: {kind: TupleInit, arg0: inst_block60000080, arg1: inst6000003A, type: type(symbolic_constantA)} -// CHECK:STDOUT: inst60000175: {kind: Converted, arg0: inst60000049, arg1: inst60000174, type: type(symbolic_constantA)} +// CHECK:STDOUT: inst60000174: {kind: TupleInit, arg0: inst_block60000080, arg1: inst6000003A, type: type(symbolic_constant6000000A)} +// CHECK:STDOUT: inst60000175: {kind: Converted, arg0: inst60000049, arg1: inst60000174, type: type(symbolic_constant6000000A)} // CHECK:STDOUT: inst60000176: {kind: ReturnExpr, arg0: inst60000175, arg1: inst6000003A} // CHECK:STDOUT: constant_values: // CHECK:STDOUT: values: // CHECK:STDOUT: instF: concrete_constant(instF) // CHECK:STDOUT: inst60000011: concrete_constant(inst60000011) // CHECK:STDOUT: inst60000012: concrete_constant(inst60000012) -// CHECK:STDOUT: inst60000013: symbolic_constant0 -// CHECK:STDOUT: inst60000014: symbolic_constant0 -// CHECK:STDOUT: inst60000015: symbolic_constant2 -// CHECK:STDOUT: inst60000016: symbolic_constant1 -// CHECK:STDOUT: inst60000017: symbolic_constant2 +// CHECK:STDOUT: inst60000013: symbolic_constant60000000 +// CHECK:STDOUT: inst60000014: symbolic_constant60000000 +// CHECK:STDOUT: inst60000015: symbolic_constant60000002 +// CHECK:STDOUT: inst60000016: symbolic_constant60000001 +// CHECK:STDOUT: inst60000017: symbolic_constant60000002 // CHECK:STDOUT: inst60000018: concrete_constant(inst60000018) // CHECK:STDOUT: inst60000019: concrete_constant(inst60000019) -// CHECK:STDOUT: inst6000001A: symbolic_constant2 -// CHECK:STDOUT: inst6000001B: symbolic_constant4 -// CHECK:STDOUT: inst6000001C: symbolic_constant3 -// CHECK:STDOUT: inst6000001D: symbolic_constant4 -// CHECK:STDOUT: inst6000001F: symbolic_constant5 +// CHECK:STDOUT: inst6000001A: symbolic_constant60000002 +// CHECK:STDOUT: inst6000001B: symbolic_constant60000004 +// CHECK:STDOUT: inst6000001C: symbolic_constant60000003 +// CHECK:STDOUT: inst6000001D: symbolic_constant60000004 +// CHECK:STDOUT: inst6000001F: symbolic_constant60000005 // CHECK:STDOUT: inst60000020: concrete_constant(inst60000020) -// CHECK:STDOUT: inst60000021: symbolic_constant6 +// CHECK:STDOUT: inst60000021: symbolic_constant60000006 // CHECK:STDOUT: inst60000022: concrete_constant(inst60000022) -// CHECK:STDOUT: inst60000023: symbolic_constant2 -// CHECK:STDOUT: inst60000024: symbolic_constant4 +// CHECK:STDOUT: inst60000023: symbolic_constant60000002 +// CHECK:STDOUT: inst60000024: symbolic_constant60000004 // CHECK:STDOUT: inst60000025: concrete_constant(inst60000025) // CHECK:STDOUT: inst60000026: concrete_constant(inst60000027) // CHECK:STDOUT: inst60000027: concrete_constant(inst60000027) // CHECK:STDOUT: inst60000028: concrete_constant(inst60000028) -// CHECK:STDOUT: inst60000029: symbolic_constant8 -// CHECK:STDOUT: inst6000002A: symbolic_constant7 -// CHECK:STDOUT: inst6000002B: symbolic_constant8 +// CHECK:STDOUT: inst60000029: symbolic_constant60000008 +// CHECK:STDOUT: inst6000002A: symbolic_constant60000007 +// CHECK:STDOUT: inst6000002B: symbolic_constant60000008 // CHECK:STDOUT: inst6000002C: concrete_constant(inst6000002C) // CHECK:STDOUT: inst6000002D: concrete_constant(inst60000025) -// CHECK:STDOUT: inst6000002E: symbolic_constant9 -// CHECK:STDOUT: inst6000002F: symbolic_constantA -// CHECK:STDOUT: inst60000030: symbolic_constantA -// CHECK:STDOUT: inst60000031: symbolic_constantC -// CHECK:STDOUT: inst60000032: symbolic_constantB -// CHECK:STDOUT: inst60000033: symbolic_constantC -// CHECK:STDOUT: inst60000034: symbolic_constantD +// CHECK:STDOUT: inst6000002E: symbolic_constant60000009 +// CHECK:STDOUT: inst6000002F: symbolic_constant6000000A +// CHECK:STDOUT: inst60000030: symbolic_constant6000000A +// CHECK:STDOUT: inst60000031: symbolic_constant6000000C +// CHECK:STDOUT: inst60000032: symbolic_constant6000000B +// CHECK:STDOUT: inst60000033: symbolic_constant6000000C +// CHECK:STDOUT: inst60000034: symbolic_constant6000000D // CHECK:STDOUT: inst60000035: concrete_constant(inst60000035) -// CHECK:STDOUT: inst60000036: symbolic_constantE +// CHECK:STDOUT: inst60000036: symbolic_constant6000000E // CHECK:STDOUT: inst60000037: concrete_constant(inst60000037) -// CHECK:STDOUT: inst60000039: symbolic_constant4 +// CHECK:STDOUT: inst60000039: symbolic_constant60000004 // CHECK:STDOUT: inst6000003C: concrete_constant(inst6000003E) // CHECK:STDOUT: inst6000003D: concrete_constant(inst6000003D) // CHECK:STDOUT: inst6000003E: concrete_constant(inst6000003E) -// CHECK:STDOUT: inst6000003F: symbolic_constantF +// CHECK:STDOUT: inst6000003F: symbolic_constant6000000F // CHECK:STDOUT: inst60000040: symbolic_constant60000011 // CHECK:STDOUT: inst60000041: symbolic_constant60000010 // CHECK:STDOUT: inst60000042: symbolic_constant60000011 @@ -1112,22 +1112,22 @@ fn Foo[T:! type](p: T*) -> (T*, ()) { // CHECK:STDOUT: inst60000172: concrete_constant(inst60000027) // CHECK:STDOUT: inst60000173: concrete_constant(inst60000027) // CHECK:STDOUT: symbolic_constants: -// CHECK:STDOUT: symbolic_constant0: {inst: inst60000014, generic: generic, index: generic_inst, kind: self} -// CHECK:STDOUT: symbolic_constant1: {inst: inst60000016, generic: generic, index: generic_inst, kind: checked} -// CHECK:STDOUT: symbolic_constant2: {inst: inst60000016, generic: generic60000000, index: generic_inst_in_decl0, kind: checked} -// CHECK:STDOUT: symbolic_constant3: {inst: inst6000001C, generic: generic, index: generic_inst, kind: checked} -// CHECK:STDOUT: symbolic_constant4: {inst: inst6000001C, generic: generic60000000, index: generic_inst_in_decl1, kind: checked} -// CHECK:STDOUT: symbolic_constant5: {inst: inst6000001F, generic: generic, index: generic_inst, kind: checked} -// CHECK:STDOUT: symbolic_constant6: {inst: inst6000001F, generic: generic60000000, index: generic_inst_in_decl2, kind: checked} -// CHECK:STDOUT: symbolic_constant7: {inst: inst6000002A, generic: generic, index: generic_inst, kind: checked} -// CHECK:STDOUT: symbolic_constant8: {inst: inst6000002A, generic: generic60000000, index: generic_inst_in_decl3, kind: checked} -// CHECK:STDOUT: symbolic_constant9: {inst: inst6000002E, generic: generic, index: generic_inst, kind: checked} -// CHECK:STDOUT: symbolic_constantA: {inst: inst6000002E, generic: generic60000000, index: generic_inst_in_decl4, kind: checked} -// CHECK:STDOUT: symbolic_constantB: {inst: inst60000032, generic: generic, index: generic_inst, kind: checked} -// CHECK:STDOUT: symbolic_constantC: {inst: inst60000032, generic: generic60000000, index: generic_inst_in_decl5, kind: checked} -// CHECK:STDOUT: symbolic_constantD: {inst: inst60000034, generic: generic, index: generic_inst, kind: checked} -// CHECK:STDOUT: symbolic_constantE: {inst: inst60000034, generic: generic60000000, index: generic_inst_in_decl6, kind: checked} -// CHECK:STDOUT: symbolic_constantF: {inst: inst6000003F, generic: generic, index: generic_inst, kind: checked} +// CHECK:STDOUT: symbolic_constant60000000: {inst: inst60000014, generic: generic, index: generic_inst, kind: self} +// CHECK:STDOUT: symbolic_constant60000001: {inst: inst60000016, generic: generic, index: generic_inst, kind: checked} +// CHECK:STDOUT: symbolic_constant60000002: {inst: inst60000016, generic: generic60000000, index: generic_inst_in_decl0, kind: checked} +// CHECK:STDOUT: symbolic_constant60000003: {inst: inst6000001C, generic: generic, index: generic_inst, kind: checked} +// CHECK:STDOUT: symbolic_constant60000004: {inst: inst6000001C, generic: generic60000000, index: generic_inst_in_decl1, kind: checked} +// CHECK:STDOUT: symbolic_constant60000005: {inst: inst6000001F, generic: generic, index: generic_inst, kind: checked} +// CHECK:STDOUT: symbolic_constant60000006: {inst: inst6000001F, generic: generic60000000, index: generic_inst_in_decl2, kind: checked} +// CHECK:STDOUT: symbolic_constant60000007: {inst: inst6000002A, generic: generic, index: generic_inst, kind: checked} +// CHECK:STDOUT: symbolic_constant60000008: {inst: inst6000002A, generic: generic60000000, index: generic_inst_in_decl3, kind: checked} +// CHECK:STDOUT: symbolic_constant60000009: {inst: inst6000002E, generic: generic, index: generic_inst, kind: checked} +// CHECK:STDOUT: symbolic_constant6000000A: {inst: inst6000002E, generic: generic60000000, index: generic_inst_in_decl4, kind: checked} +// CHECK:STDOUT: symbolic_constant6000000B: {inst: inst60000032, generic: generic, index: generic_inst, kind: checked} +// CHECK:STDOUT: symbolic_constant6000000C: {inst: inst60000032, generic: generic60000000, index: generic_inst_in_decl5, kind: checked} +// CHECK:STDOUT: symbolic_constant6000000D: {inst: inst60000034, generic: generic, index: generic_inst, kind: checked} +// CHECK:STDOUT: symbolic_constant6000000E: {inst: inst60000034, generic: generic60000000, index: generic_inst_in_decl6, kind: checked} +// CHECK:STDOUT: symbolic_constant6000000F: {inst: inst6000003F, generic: generic, index: generic_inst, kind: checked} // CHECK:STDOUT: symbolic_constant60000010: {inst: inst60000041, generic: generic, index: generic_inst, kind: checked} // CHECK:STDOUT: symbolic_constant60000011: {inst: inst60000041, generic: generic60000000, index: generic_inst_in_def0, kind: checked} // CHECK:STDOUT: symbolic_constant60000012: {inst: inst60000044, generic: generic, index: generic_inst, kind: checked} diff --git a/toolchain/driver/compile_subcommand.cpp b/toolchain/driver/compile_subcommand.cpp index ad5cb6932564..3b45c30d323e 100644 --- a/toolchain/driver/compile_subcommand.cpp +++ b/toolchain/driver/compile_subcommand.cpp @@ -616,8 +616,8 @@ class MultiUnitCache { auto include_in_dumps() -> const IncludeInDumpsStore& { if (!include_in_dumps_) { - include_in_dumps_.emplace(IncludeInDumpsStore::MakeWithExplicitSize( - IdTag(), units_.size(), false)); + include_in_dumps_.emplace( + IncludeInDumpsStore::MakeWithExplicitSize(units_.size(), false)); for (const auto& [i, unit] : llvm::enumerate(units_)) { // If this is first accessed after lexing is complete, we need to apply // per-file includes. Otherwise, this is based only on the exclude @@ -637,8 +637,8 @@ class MultiUnitCache { auto tree_and_subtrees_getters() -> const TreeAndSubtreesGettersStore& { if (!tree_and_subtrees_getters_) { tree_and_subtrees_getters_.emplace( - TreeAndSubtreesGettersStore::MakeWithExplicitSize( - IdTag(), units_.size(), nullptr)); + TreeAndSubtreesGettersStore::MakeWithExplicitSize(units_.size(), + nullptr)); for (const auto& [i, unit] : llvm::enumerate(units_)) { if (unit->has_source()) { tree_and_subtrees_getters_->Set(SemIR::CheckIRId(i), diff --git a/toolchain/language_server/context.cpp b/toolchain/language_server/context.cpp index 635c8beb8fba..50c9ba0669f5 100644 --- a/toolchain/language_server/context.cpp +++ b/toolchain/language_server/context.cpp @@ -166,7 +166,7 @@ auto Context::File::SetText(Context& context, std::optional version, Check::CheckParseTreesOptions check_options; check_options.vlog_stream = context.vlog_stream(); auto getters = - Parse::GetTreeAndSubtreesStore::MakeWithExplicitSize(IdTag(), 1, getter); + Parse::GetTreeAndSubtreesStore::MakeWithExplicitSize(1, getter); auto clang_invocation = BuildClangInvocation(consumer, fs, context.installation(), diff --git a/toolchain/lower/file_context.cpp b/toolchain/lower/file_context.cpp index 9e2577ad2078..9466e364c1b3 100644 --- a/toolchain/lower/file_context.cpp +++ b/toolchain/lower/file_context.cpp @@ -51,11 +51,11 @@ FileContext::FileContext(Context& context, const SemIR::File& sem_ir, vlog_stream_(vlog_stream), functions_(LoweredFunctionStore::MakeForOverwrite(sem_ir.functions())), specific_functions_(sem_ir.specifics(), nullptr), - types_(LoweredTypeStore::MakeWithExplicitSize(sem_ir.insts().GetIdTag(), - sem_ir.insts().size(), - {nullptr, nullptr})), + types_(LoweredTypeStore::MakeWithExplicitSize( + sem_ir.constant_values().ConcreteStoreSize(), + sem_ir.constant_values().GetTypeIdTag(), {nullptr, nullptr})), constants_(LoweredConstantStore::MakeWithExplicitSize( - sem_ir.insts().GetIdTag(), sem_ir.insts().size(), nullptr)), + sem_ir.insts().size(), sem_ir.insts().GetIdTag(), nullptr)), lowered_specifics_(sem_ir.generics(), llvm::SmallVector()), coalescer_(vlog_stream_, sem_ir.specifics()), diff --git a/toolchain/lower/file_context.h b/toolchain/lower/file_context.h index 7b6c7de12a5b..87fb25cb180b 100644 --- a/toolchain/lower/file_context.h +++ b/toolchain/lower/file_context.h @@ -21,7 +21,8 @@ namespace Carbon::Lower { class FileContext { public: using LoweredConstantStore = - FixedSizeValueStore; + FixedSizeValueStore>; explicit FileContext(Context& context, const SemIR::File& sem_ir, const SemIR::InstNamer* inst_namer, @@ -249,14 +250,19 @@ class FileContext { // Maps callables to lowered functions. SemIR treats callables as the // canonical form of a function, so lowering needs to do the same. using LoweredFunctionStore = - FixedSizeValueStore; + FixedSizeValueStore>; LoweredFunctionStore functions_; // Maps specific callables to lowered functions. - FixedSizeValueStore specific_functions_; + FixedSizeValueStore> + specific_functions_; // Provides lowered versions of types. Entries are non-symbolic types. - using LoweredTypeStore = FixedSizeValueStore; + // + // TypeIds internally are concrete ConstantIds. + using LoweredTypeStore = + FixedSizeValueStore>; LoweredTypeStore types_; // Maps constants to their lowered values. Indexes are the `InstId` for @@ -269,13 +275,17 @@ class FileContext { // For a generic function, keep track of the specifics for which LLVM // function declarations were created. Those can be retrieved then from // `specific_functions_`. - FixedSizeValueStore> + FixedSizeValueStore, + Tag> lowered_specifics_; SpecificCoalescer coalescer_; - FixedSizeValueStore vtables_; - FixedSizeValueStore + FixedSizeValueStore> + vtables_; + FixedSizeValueStore> specific_vtables_; }; diff --git a/toolchain/lower/specific_coalescer.h b/toolchain/lower/specific_coalescer.h index 48ffdec55ad6..74bf4b2c39ea 100644 --- a/toolchain/lower/specific_coalescer.h +++ b/toolchain/lower/specific_coalescer.h @@ -16,9 +16,11 @@ class SpecificCoalescer { public: using LoweredSpecificsStore = FixedSizeValueStore>; + llvm::SmallVector, + Tag>; using LoweredLlvmFunctionStore = - FixedSizeValueStore; + FixedSizeValueStore>; // Describes a specific function's body fingerprint. struct SpecificFunctionFingerprint { @@ -128,11 +130,13 @@ class SpecificCoalescer { // For specifics that exist in lowered_specifics, a hash of their function // type information. - FixedSizeValueStore> + FixedSizeValueStore, + Tag> lowered_specifics_type_fingerprint_; // This is initialized and populated while lowering a specific. - FixedSizeValueStore + FixedSizeValueStore> lowered_specific_fingerprint_; // Equivalent specifics that have been found. For each specific, this points @@ -142,7 +146,8 @@ class SpecificCoalescer { // // Entries are initialized to `SpecificId::None`, which defines that there is // no other equivalent specific to this `SpecificId`. - FixedSizeValueStore + FixedSizeValueStore> equivalent_specifics_; // Non-equivalent specifics found. diff --git a/toolchain/sem_ir/associated_constant.h b/toolchain/sem_ir/associated_constant.h index 69c1b96882e6..8a8108b133b4 100644 --- a/toolchain/sem_ir/associated_constant.h +++ b/toolchain/sem_ir/associated_constant.h @@ -50,7 +50,7 @@ struct AssociatedConstant : public Printable { }; using AssociatedConstantStore = - ValueStore; + ValueStore>; } // namespace Carbon::SemIR diff --git a/toolchain/sem_ir/clang_decl.h b/toolchain/sem_ir/clang_decl.h index d7d0e75dee24..aaa4158a9a4b 100644 --- a/toolchain/sem_ir/clang_decl.h +++ b/toolchain/sem_ir/clang_decl.h @@ -96,7 +96,7 @@ struct ClangDecl : public Printable { // Use the AST node pointer directly when doing `Lookup` to find an ID. using ClangDeclStore = - CanonicalValueStore; + CanonicalValueStore, ClangDecl>; } // namespace Carbon::SemIR diff --git a/toolchain/sem_ir/class.h b/toolchain/sem_ir/class.h index c1e70732600e..641aee9b0132 100644 --- a/toolchain/sem_ir/class.h +++ b/toolchain/sem_ir/class.h @@ -116,7 +116,7 @@ struct Class : public EntityWithParamsBase, auto GetObjectRepr(const File& file, SpecificId specific_id) const -> TypeId; }; -using ClassStore = ValueStore; +using ClassStore = ValueStore>; } // namespace Carbon::SemIR diff --git a/toolchain/sem_ir/constant.h b/toolchain/sem_ir/constant.h index 91c49fe71cd2..54a5dd8f2ea0 100644 --- a/toolchain/sem_ir/constant.h +++ b/toolchain/sem_ir/constant.h @@ -116,12 +116,15 @@ class ConstantValueStore { // Constructs an unusable ConstantValueStore, only good as a placeholder (eg: // in C++ interop, where there's no foreign SemIR to reference) explicit ConstantValueStore(UnusableType /* tag */) - : default_(ConstantId::None), insts_(nullptr) {} + : default_(ConstantId::None), + values_(CheckIRId::None), + symbolic_constants_(CheckIRId::None), + insts_(nullptr) {} explicit ConstantValueStore(ConstantId default_value, const InstStore* insts) : default_(default_value), - values_((CARBON_CHECK(insts), insts->GetIdTag())), - symbolic_constants_(insts->GetIdTag()), + values_(insts->GetIdTag()), + symbolic_constants_(insts->GetIdTag().GetContainerTag()), insts_(insts) {} // Returns the constant value of the requested instruction, which is default_ @@ -247,6 +250,26 @@ class ConstantValueStore { }); } + // The tag used in ConstantIds for concrete constants. + using ConcreteIdTagType = IdTag>; + auto GetConcreteIdTag() const -> ConcreteIdTagType { + return values_.GetIdTag().ToEquivalentIdType(); + } + // The tag used for TypeId, which are concrete constants internally. + using TypeIdTagType = IdTag>; + auto GetTypeIdTag() const -> TypeIdTagType { + return values_.GetIdTag().ToEquivalentIdType(); + } + // The tag used in ConstantIds for symbolic constants. + using SymbolicIdTagType = + IdTag>; + auto GetSymbolicIdTag() const -> SymbolicIdTagType { + return symbolic_constants_.GetIdTag(); + } + + // The size of the value store for concrete constant values. + auto ConcreteStoreSize() const -> size_t { return values_.size(); } + private: const ConstantId default_; @@ -256,14 +279,15 @@ class ConstantValueStore { // // Set inline size to 0 because these will typically be too large for the // stack, while this does make File smaller. - ValueStore values_; + ValueStore> values_; // A mapping from a symbolic constant ID index to information about the // symbolic constant. For a concrete constant, the only information that we // track is the instruction ID, which is stored directly within the // `ConstantId`. For a symbolic constant, we also track information about // where the constant was used, which is stored here. - ValueStore symbolic_constants_; + ValueStore> + symbolic_constants_; const InstStore* insts_; }; diff --git a/toolchain/sem_ir/cpp_global_var.h b/toolchain/sem_ir/cpp_global_var.h index e7c597411b02..586b176d8f0c 100644 --- a/toolchain/sem_ir/cpp_global_var.h +++ b/toolchain/sem_ir/cpp_global_var.h @@ -49,8 +49,8 @@ struct CppGlobalVar : public Printable { }; // Use the name of a C++ global variable when doing `Lookup` to find an ID. -using CppGlobalVarStore = - CanonicalValueStore; +using CppGlobalVarStore = CanonicalValueStore, CppGlobalVar>; } // namespace Carbon::SemIR diff --git a/toolchain/sem_ir/cpp_overload_set.h b/toolchain/sem_ir/cpp_overload_set.h index ad532f82fb4f..30ded7b2df02 100644 --- a/toolchain/sem_ir/cpp_overload_set.h +++ b/toolchain/sem_ir/cpp_overload_set.h @@ -39,7 +39,8 @@ struct CppOverloadSet : public Printable { } }; -using CppOverloadSetStore = ValueStore; +using CppOverloadSetStore = + ValueStore>; } // namespace Carbon::SemIR diff --git a/toolchain/sem_ir/entity_name.h b/toolchain/sem_ir/entity_name.h index 404ce3da919a..1c62133e7e04 100644 --- a/toolchain/sem_ir/entity_name.h +++ b/toolchain/sem_ir/entity_name.h @@ -60,7 +60,8 @@ struct EntityName : public Printable { // Value store for EntityName. In addition to the regular ValueStore // functionality, this can provide optional canonical IDs for EntityNames. -struct EntityNameStore : public ValueStore { +struct EntityNameStore + : public ValueStore> { public: using ValueStore::ValueStore; diff --git a/toolchain/sem_ir/facet_type_info.h b/toolchain/sem_ir/facet_type_info.h index a8de9d549e39..2584780bbdbb 100644 --- a/toolchain/sem_ir/facet_type_info.h +++ b/toolchain/sem_ir/facet_type_info.h @@ -113,7 +113,8 @@ constexpr FacetTypeInfo::RewriteConstraint FacetTypeInfo::RewriteConstraint::None = {.lhs_id = InstId::None, .rhs_id = InstId::None}; -using FacetTypeInfoStore = CanonicalValueStore; +using FacetTypeInfoStore = + CanonicalValueStore>; struct IdentifiedFacetType { using RequiredInterface = SpecificInterface; diff --git a/toolchain/sem_ir/file.cpp b/toolchain/sem_ir/file.cpp index 823a4e38b50f..dac5d6d19a88 100644 --- a/toolchain/sem_ir/file.cpp +++ b/toolchain/sem_ir/file.cpp @@ -43,7 +43,7 @@ File::File(const Parse::Tree* parse_tree, CheckIRId check_ir_id, named_constraints_(check_ir_id), require_impls_(check_ir_id), // 1 reserved id for `RequireImplsBlockId::Empty`. - require_impls_blocks_(allocator_, IdTag(check_ir_id.index, 1)), + require_impls_blocks_(allocator_, check_ir_id, 1), associated_constants_(check_ir_id), facet_types_(check_ir_id), identified_facet_types_(&facet_types_), @@ -53,7 +53,7 @@ File::File(const Parse::Tree* parse_tree, CheckIRId check_ir_id, specifics_(check_ir_id), // The `2` prevents adding a tag for the global ids // `ImportIRId::{ApiForImpl,Cpp}`. - import_irs_(IdTag(check_ir_id.index, 2)), + import_irs_(check_ir_id, 2), clang_decls_(check_ir_id), // The `+1` prevents adding a tag to the global `NameSpace::PackageInstId` // instruction. It's not a "singleton" instruction, but it's a unique @@ -64,9 +64,9 @@ File::File(const Parse::Tree* parse_tree, CheckIRId check_ir_id, inst_blocks_(allocator_, check_ir_id), constants_(this), // 1 reserved id for `StructTypeFieldsId::Empty`. - struct_type_fields_(allocator_, IdTag(check_ir_id.index, 1)), + struct_type_fields_(allocator_, check_ir_id, 1), // 1 reserved id for `CustomLayoutId::Empty`. - custom_layouts_(allocator_, IdTag(check_ir_id.index, 1)), + custom_layouts_(allocator_, check_ir_id, 1), expr_regions_(check_ir_id), clang_source_locs_(check_ir_id) { // `type`, `form`, and the error type are both complete & concrete types. diff --git a/toolchain/sem_ir/file.h b/toolchain/sem_ir/file.h index 2630ee6e8807..e6a22d32a1b6 100644 --- a/toolchain/sem_ir/file.h +++ b/toolchain/sem_ir/file.h @@ -63,9 +63,10 @@ struct ExprRegion { InstId result_id; }; -using ExprRegionStore = ValueStore; +using ExprRegionStore = ValueStore>; -using CustomLayoutStore = BlockValueStore; +using CustomLayoutStore = + BlockValueStore>; // The semantic IR for a single file. class File : public Printable { @@ -264,7 +265,7 @@ class File : public Printable { auto expr_regions() const -> const ExprRegionStore& { return expr_regions_; } using ClangSourceLocStore = - ValueStore; + ValueStore>; auto clang_source_locs() -> ClangSourceLocStore& { return clang_source_locs_; } @@ -409,7 +410,7 @@ class File : public Printable { StructTypeFieldsStore struct_type_fields_; // Storage for custom layouts. - CustomLayoutStore custom_layouts_ = CustomLayoutStore(allocator_); + CustomLayoutStore custom_layouts_; // Descriptions of types used in this file. TypeStore types_ = TypeStore(this); diff --git a/toolchain/sem_ir/formatter.cpp b/toolchain/sem_ir/formatter.cpp index bab69523da00..126cafa10766 100644 --- a/toolchain/sem_ir/formatter.cpp +++ b/toolchain/sem_ir/formatter.cpp @@ -120,7 +120,7 @@ auto Formatter::Format() -> void { auto Formatter::ComputeNodeParents() -> void { CARBON_CHECK(!node_parents_); node_parents_ = NodeParentStore::MakeWithExplicitSize( - IdTag(), sem_ir_->parse_tree().size(), Parse::NodeId::None); + sem_ir_->parse_tree().size(), Parse::NodeId::None); for (auto n : sem_ir_->parse_tree().postorder()) { for (auto child : get_tree_and_subtrees_().children(n)) { node_parents_->Set(child, n); diff --git a/toolchain/sem_ir/formatter.h b/toolchain/sem_ir/formatter.h index bc259623d630..d0447a7db101 100644 --- a/toolchain/sem_ir/formatter.h +++ b/toolchain/sem_ir/formatter.h @@ -407,7 +407,7 @@ class Formatter { // Indexes of chunks of output that should be included when an instruction is // referenced, indexed by the instruction's index. - FixedSizeValueStore tentative_inst_chunks_; + FixedSizeValueStore> tentative_inst_chunks_; // Maps nodes to their parents. Only set when dump ranges are in use, because // the parents aren't used otherwise. diff --git a/toolchain/sem_ir/function.h b/toolchain/sem_ir/function.h index d4b552f9875b..79a0c7d55d43 100644 --- a/toolchain/sem_ir/function.h +++ b/toolchain/sem_ir/function.h @@ -213,7 +213,7 @@ struct Function : public EntityWithParamsBase, } }; -using FunctionStore = ValueStore; +using FunctionStore = ValueStore>; class File; diff --git a/toolchain/sem_ir/generic.cpp b/toolchain/sem_ir/generic.cpp index bff25fc47a7e..cd828a646c7b 100644 --- a/toolchain/sem_ir/generic.cpp +++ b/toolchain/sem_ir/generic.cpp @@ -19,8 +19,7 @@ class SpecificStore::KeyContext : public TranslatingKeyContext { friend auto operator==(const Key&, const Key&) -> bool = default; }; - explicit KeyContext(const ValueStore* specifics) - : specifics_(specifics) {} + explicit KeyContext(const ValueStore* specifics) : specifics_(specifics) {} auto TranslateKey(SpecificId id) const -> Key { const auto& specific = specifics_->Get(id); @@ -28,7 +27,7 @@ class SpecificStore::KeyContext : public TranslatingKeyContext { } private: - const ValueStore* specifics_; + const ValueStore* specifics_; }; auto SpecificStore::GetOrAdd(GenericId generic_id, InstBlockId args_id) diff --git a/toolchain/sem_ir/generic.h b/toolchain/sem_ir/generic.h index 3ce86474d9c6..a76fe30d9d90 100644 --- a/toolchain/sem_ir/generic.h +++ b/toolchain/sem_ir/generic.h @@ -53,7 +53,7 @@ struct Generic : public Printable { }; // Provides storage for generics. -class GenericStore : public ValueStore { +class GenericStore : public ValueStore> { public: using ValueStore::ValueStore; @@ -109,6 +109,7 @@ struct Specific : Printable { class SpecificStore : public Yaml::Printable { public: using IdType = SpecificId; + using ValueStore = ValueStore>; explicit SpecificStore(CheckIRId check_ir_id) : specifics_(check_ir_id) {} @@ -144,8 +145,7 @@ class SpecificStore : public Yaml::Printable { auto CollectMemUsage(MemUsage& mem_usage, llvm::StringRef label) const -> void; - auto values() const [[clang::lifetimebound]] - -> ValueStore::Range { + auto values() const [[clang::lifetimebound]] -> ValueStore::Range { return specifics_.values(); } auto size() const -> size_t { return specifics_.size(); } @@ -159,7 +159,7 @@ class SpecificStore : public Yaml::Printable { // Context for hashing keys. class KeyContext; - ValueStore specifics_; + ValueStore specifics_; Carbon::Set lookup_table_; }; diff --git a/toolchain/sem_ir/ids.h b/toolchain/sem_ir/ids.h index 403838ca6429..479ed0ca1ec9 100644 --- a/toolchain/sem_ir/ids.h +++ b/toolchain/sem_ir/ids.h @@ -173,6 +173,11 @@ class MetaInstId : public InstId { // constant instruction that defines the constant. Symbolic constants are an // index into a separate table of `SymbolicConstant`s maintained by the constant // value store. +// +// IdTags for ConstantIds are slightly complex, and you need to know if the +// constant is concrete or symbolic to know its tag: +// - Concrete ConstantIds use the tag of the store of InstIds. +// - Symbolic ConstantIds use the tag of the store of internal SymbolicIds. struct ConstantId : public IdBase { static constexpr llvm::StringLiteral Label = "constant"; diff --git a/toolchain/sem_ir/impl.h b/toolchain/sem_ir/impl.h index ffc4f80264e2..ada254edd9d2 100644 --- a/toolchain/sem_ir/impl.h +++ b/toolchain/sem_ir/impl.h @@ -202,7 +202,7 @@ class ImplStore { } auto values() const [[clang::lifetimebound]] - -> ValueStore::Range { + -> ValueStore>::Range { return values_.values(); } auto size() const -> size_t { return values_.size(); } @@ -212,7 +212,7 @@ class ImplStore { private: File& sem_ir_; - ValueStore values_; + ValueStore> values_; Map, ImplOrLookupBucketId> lookup_; // Buckets with at least 2 entries, which will be rare; see LookupBucketRef. llvm::SmallVector> lookup_buckets_; diff --git a/toolchain/sem_ir/import_ir.h b/toolchain/sem_ir/import_ir.h index 4494addb6ea1..5846461a53d0 100644 --- a/toolchain/sem_ir/import_ir.h +++ b/toolchain/sem_ir/import_ir.h @@ -26,7 +26,7 @@ struct ImportIR : public Printable { static_assert(sizeof(ImportIR) == 8 + sizeof(uintptr_t), "Unexpected size"); -using ImportIRStore = ValueStore; +using ImportIRStore = ValueStore>; // A reference to an instruction in an imported IR. Used for diagnostics with // LocId. For a `Cpp` import, points to a Clang source location. diff --git a/toolchain/sem_ir/inst.h b/toolchain/sem_ir/inst.h index 2cbe14d88928..899d8cab1a0e 100644 --- a/toolchain/sem_ir/inst.h +++ b/toolchain/sem_ir/inst.h @@ -459,6 +459,7 @@ struct LocIdAndInst { class InstStore { public: using IdType = InstId; + using IdTagType = IdTag>; explicit InstStore(File* file, int32_t reserved_inst_ids); @@ -658,7 +659,7 @@ class InstStore { } auto values() const [[clang::lifetimebound]] - -> ValueStore::Range { + -> ValueStore>::Range { return values_.values(); } auto size() const -> int { return values_.size(); } @@ -670,7 +671,7 @@ class InstStore { return values_.GetRawIndex(id); } - auto GetIdTag() const -> IdTag { return values_.GetIdTag(); } + auto GetIdTag() const -> IdTagType { return values_.GetIdTag(); } private: // Given a symbolic type, get the corresponding unattached type. @@ -687,19 +688,20 @@ class InstStore { File* file_; llvm::SmallVector loc_ids_; - ValueStore values_; + ValueStore> values_; }; // Adapts BlockValueStore for instruction blocks. -class InstBlockStore : public BlockValueStore { +class InstBlockStore + : public BlockValueStore> { public: - using BaseType = BlockValueStore; + using BaseType = BlockValueStore>; explicit InstBlockStore(llvm::BumpPtrAllocator& allocator, CheckIRId check_ir_id = CheckIRId::None) // 4 reserved ids for the // `InstBlockId::{Empty,Exports,Imports,GlobalInit}` global ids. - : BaseType(allocator, IdTag(check_ir_id.index, 4)) { + : BaseType(allocator, check_ir_id, 4) { auto exports_id = AddPlaceholder(); CARBON_CHECK(exports_id == InstBlockId::Exports); auto imports_id = AddPlaceholder(); diff --git a/toolchain/sem_ir/inst_fingerprinter.cpp b/toolchain/sem_ir/inst_fingerprinter.cpp index 657b4b97c69c..b8b9631310a7 100644 --- a/toolchain/sem_ir/inst_fingerprinter.cpp +++ b/toolchain/sem_ir/inst_fingerprinter.cpp @@ -25,7 +25,8 @@ namespace Carbon::SemIR { namespace { struct Worklist { - using FingerprintStore = FixedSizeValueStore; + using FingerprintStore = + FixedSizeValueStore>; using FilesFingerprintStores = FixedSizeValueStore; @@ -66,8 +67,8 @@ struct Worklist { auto SetFingerprint(const File* file, InstId inst_id, uint64_t fingerprint) { auto& store = fingerprints->Get(file->check_ir_id()); if (store.size() == 0) { - store = FixedSizeValueStore::MakeWithExplicitSize( - file->insts().GetIdTag(), file->insts().size(), 0); + store = FingerprintStore::MakeWithExplicitSize( + file->insts().size(), file->insts().GetIdTag(), 0); } store.Set(inst_id, fingerprint ? fingerprint : 1); } diff --git a/toolchain/sem_ir/inst_fingerprinter.h b/toolchain/sem_ir/inst_fingerprinter.h index f0ef5ef568ab..f20214b55bc7 100644 --- a/toolchain/sem_ir/inst_fingerprinter.h +++ b/toolchain/sem_ir/inst_fingerprinter.h @@ -18,7 +18,8 @@ class InstFingerprinter { explicit InstFingerprinter(int total_ir_count) : fingerprints_(FilesFingerprintStores::MakeWithExplicitSizeFrom( total_ir_count, [] { - return FingerprintStore::MakeForOverwriteWithExplicitSize(0); + return FingerprintStore::MakeForOverwriteWithExplicitSize( + 0, CheckIRId::None); })) {} // Gets or computes a fingerprint for the given instruction. @@ -43,7 +44,8 @@ class InstFingerprinter { // the `GetOrCompute` overload for `InstBlockId`s, and may save some work if // the same canonical inst block is used by multiple instructions, for example // as a specific argument list. - using FingerprintStore = FixedSizeValueStore; + using FingerprintStore = + FixedSizeValueStore>; using FilesFingerprintStores = FixedSizeValueStore; FilesFingerprintStores fingerprints_; diff --git a/toolchain/sem_ir/interface.h b/toolchain/sem_ir/interface.h index a635cb19d896..06891e55cf9d 100644 --- a/toolchain/sem_ir/interface.h +++ b/toolchain/sem_ir/interface.h @@ -52,7 +52,7 @@ struct Interface : public EntityWithParamsBase, } }; -using InterfaceStore = ValueStore; +using InterfaceStore = ValueStore>; } // namespace Carbon::SemIR diff --git a/toolchain/sem_ir/name_scope.cpp b/toolchain/sem_ir/name_scope.cpp index 42eeb215f2fd..0dd8e17507aa 100644 --- a/toolchain/sem_ir/name_scope.cpp +++ b/toolchain/sem_ir/name_scope.cpp @@ -14,7 +14,7 @@ namespace Carbon::SemIR { NameScopeStore::NameScopeStore(const File* file) // 1 reserved untagged id because the Package NameScope is used across // Files. - : file_(file), values_(IdTag(file->check_ir_id().index, 1)) {} + : file_(file), values_(file->check_ir_id(), 1) {} auto NameScope::Print(llvm::raw_ostream& out) const -> void { out << "{inst: " << inst_id_ << ", parent_scope: " << parent_scope_id_ diff --git a/toolchain/sem_ir/name_scope.h b/toolchain/sem_ir/name_scope.h index 1d621916cf44..b814e25dedb9 100644 --- a/toolchain/sem_ir/name_scope.h +++ b/toolchain/sem_ir/name_scope.h @@ -366,7 +366,7 @@ class NameScopeStore { private: const File* file_; - ValueStore values_; + ValueStore> values_; }; } // namespace Carbon::SemIR diff --git a/toolchain/sem_ir/named_constraint.h b/toolchain/sem_ir/named_constraint.h index 23f9e3f466b1..4639e7df8f81 100644 --- a/toolchain/sem_ir/named_constraint.h +++ b/toolchain/sem_ir/named_constraint.h @@ -49,7 +49,8 @@ struct NamedConstraint : public EntityWithParamsBase, } }; -using NamedConstraintStore = ValueStore; +using NamedConstraintStore = + ValueStore>; } // namespace Carbon::SemIR diff --git a/toolchain/sem_ir/require_impls.h b/toolchain/sem_ir/require_impls.h index de649f0f0457..4fd186ce6545 100644 --- a/toolchain/sem_ir/require_impls.h +++ b/toolchain/sem_ir/require_impls.h @@ -43,10 +43,11 @@ struct RequireImpls : Printable { } }; -using RequireImplsStore = ValueStore; +using RequireImplsStore = + ValueStore>; using RequireImplsBlockStore = - BlockValueStore; + BlockValueStore>; } // namespace Carbon::SemIR diff --git a/toolchain/sem_ir/specific_interface.h b/toolchain/sem_ir/specific_interface.h index 5fa5ee341fc0..ae10022e156b 100644 --- a/toolchain/sem_ir/specific_interface.h +++ b/toolchain/sem_ir/specific_interface.h @@ -27,7 +27,7 @@ inline constexpr SpecificInterface SpecificInterface::None = { .interface_id = InterfaceId::None, .specific_id = SpecificId::None}; using SpecificInterfaceStore = - CanonicalValueStore; + CanonicalValueStore>; } // namespace Carbon::SemIR diff --git a/toolchain/sem_ir/struct_type_field.h b/toolchain/sem_ir/struct_type_field.h index 709563cf5a6e..2ac1cca28f16 100644 --- a/toolchain/sem_ir/struct_type_field.h +++ b/toolchain/sem_ir/struct_type_field.h @@ -25,7 +25,7 @@ struct StructTypeField : Printable { }; using StructTypeFieldsStore = - BlockValueStore; + BlockValueStore>; // See common/hashing.h. Supports canonicalization of fields. inline auto CarbonHashValue(const StructTypeField& value, uint64_t seed) diff --git a/toolchain/sem_ir/vtable.h b/toolchain/sem_ir/vtable.h index 7011b18e13cf..96d99bb6f505 100644 --- a/toolchain/sem_ir/vtable.h +++ b/toolchain/sem_ir/vtable.h @@ -29,7 +29,7 @@ struct Vtable : public VtableFields, public Printable { } }; -using VtableStore = ValueStore; +using VtableStore = ValueStore>; } // namespace Carbon::SemIR