diff --git a/toolchain/base/fixed_size_value_store.h b/toolchain/base/fixed_size_value_store.h index 638811dd21f4..e750ea54576f 100644 --- a/toolchain/base/fixed_size_value_store.h +++ b/toolchain/base/fixed_size_value_store.h @@ -5,6 +5,9 @@ #ifndef CARBON_TOOLCHAIN_BASE_FIXED_SIZE_VALUE_STORE_H_ #define CARBON_TOOLCHAIN_BASE_FIXED_SIZE_VALUE_STORE_H_ +#include +#include + #include "common/check.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" @@ -51,6 +54,19 @@ class FixedSizeValueStore { return store; } + // Makes a ValueStore of the specified size, initialized to values returned + // from a callback. This allows initializing non-copyable values. + static auto MakeWithExplicitSizeFrom( + size_t size, llvm::function_refValueT> callable) + -> FixedSizeValueStore { + FixedSizeValueStore store; + store.values_.reserve(size); + for (auto _ : llvm::seq(size)) { + store.values_.push_back(callable()); + } + return store; + } + // Makes a ValueStore of the same size as a source `ValueStoreT`. This is // the safest constructor to use, since it ensures everything's initialized to // a default, and verifies a matching `IdT` for the size. diff --git a/toolchain/check/check.cpp b/toolchain/check/check.cpp index d90477684270..1c1d4749a489 100644 --- a/toolchain/check/check.cpp +++ b/toolchain/check/check.cpp @@ -332,7 +332,7 @@ static auto BuildApiMapAndDiagnosePackaging( // Handles printing of formatted SemIR. static auto MaybeDumpFormattedSemIR( - const SemIR::File& sem_ir, + const SemIR::File& sem_ir, int total_ir_count, Parse::GetTreeAndSubtreesFn tree_and_subtrees_getter, bool include_in_dumps, const CheckParseTreesOptions& options) -> void { bool dump = options.dump_stream && include_in_dumps; @@ -351,7 +351,7 @@ static auto MaybeDumpFormattedSemIR( options.dump_sem_ir_ranges != CheckParseTreesOptions::DumpSemIRRanges::Ignore && tokens.has_dump_sem_ir_ranges(); - SemIR::Formatter formatter(&sem_ir, tree_and_subtrees_getter, + SemIR::Formatter formatter(&sem_ir, total_ir_count, tree_and_subtrees_getter, options.include_in_dumps, use_dump_sem_ir_ranges); formatter.Format(); if (options.vlog_stream) { @@ -387,7 +387,8 @@ static auto MaybeDumpSemIR( } MaybeDumpFormattedSemIR( - *unit.sem_ir, tree_and_subtrees_getters.Get(unit.sem_ir->check_ir_id()), + *unit.sem_ir, units.size(), + tree_and_subtrees_getters.Get(unit.sem_ir->check_ir_id()), include_in_dumps, options); } } diff --git a/toolchain/check/check.h b/toolchain/check/check.h index 5eeb270414ad..ce157e63f8ed 100644 --- a/toolchain/check/check.h +++ b/toolchain/check/check.h @@ -27,6 +27,8 @@ struct Unit { // The unit's SemIR, provided as empty and filled in by CheckParseTrees. SemIR::File* sem_ir; + // The total number of files. + int total_ir_count; // Storage for the unit's Clang AST. The unique_ptr should start empty, and // can be assigned as part of checking. diff --git a/toolchain/check/check_unit.cpp b/toolchain/check/check_unit.cpp index 05314e6b7054..32f1436934f3 100644 --- a/toolchain/check/check_unit.cpp +++ b/toolchain/check/check_unit.cpp @@ -63,15 +63,15 @@ CheckUnit::CheckUnit( : unit_and_imports_(unit_and_imports), tree_and_subtrees_getter_(tree_and_subtrees_getters->Get( unit_and_imports->unit->sem_ir->check_ir_id())), - total_ir_count_(tree_and_subtrees_getters->size()), fs_(std::move(fs)), clang_invocation_(std::move(clang_invocation)), emitter_(&unit_and_imports_->err_tracker, tree_and_subtrees_getters, unit_and_imports_->unit->sem_ir), context_(&emitter_, tree_and_subtrees_getter_, unit_and_imports_->unit->sem_ir, - GetImportedIRCount(unit_and_imports), total_ir_count_, - gen_implicit_type_impls, vlog_stream) {} + GetImportedIRCount(unit_and_imports), + unit_and_imports_->unit->total_ir_count, gen_implicit_type_impls, + vlog_stream) {} auto CheckUnit::Run() -> void { Timings::ScopedTiming timing(unit_and_imports_->unit->timings, "check"); @@ -195,7 +195,7 @@ auto CheckUnit::CollectTransitiveImports(SemIR::InstId import_decl_id, // exported to this IR. auto ir_to_result_index = FixedSizeValueStore::MakeWithExplicitSize( - total_ir_count_, -1); + 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 d4e75499f98a..84d3c7698a96 100644 --- a/toolchain/check/check_unit.h +++ b/toolchain/check/check_unit.h @@ -187,8 +187,6 @@ class CheckUnit { UnitAndImports* unit_and_imports_; Parse::GetTreeAndSubtreesFn tree_and_subtrees_getter_; - // The number of IRs being checked in total. - int total_ir_count_; llvm::IntrusiveRefCntPtr fs_; std::shared_ptr clang_invocation_; diff --git a/toolchain/check/context.cpp b/toolchain/check/context.cpp index e440e46cbee9..89773f8ba651 100644 --- a/toolchain/check/context.cpp +++ b/toolchain/check/context.cpp @@ -20,6 +20,7 @@ Context::Context(DiagnosticEmitterBase* emitter, : emitter_(emitter), tree_and_subtrees_getter_(tree_and_subtrees_getter), sem_ir_(sem_ir), + total_ir_count_(total_ir_count), gen_implicit_type_impls_(gen_implicit_type_impls), vlog_stream_(vlog_stream), node_stack_(sem_ir->parse_tree(), vlog_stream), @@ -33,7 +34,7 @@ Context::Context(DiagnosticEmitterBase* emitter, vtable_stack_("vtable_stack_", *sem_ir, vlog_stream), check_ir_map_( FixedSizeValueStore:: - MakeWithExplicitSize(total_ir_count, SemIR::ImportIRId::None)), + 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 9f957514ea74..6127d1b8f4d6 100644 --- a/toolchain/check/context.h +++ b/toolchain/check/context.h @@ -313,6 +313,8 @@ class Context { // The SemIR::File being added to. SemIR::File* sem_ir_; + // The total number of files. + int total_ir_count_; // Whether to generate standard `impl`s for types, such as `Core.Destroy`; see // `CheckParseTreesOptions`. diff --git a/toolchain/driver/compile_subcommand.cpp b/toolchain/driver/compile_subcommand.cpp index 572efa8d4ec6..edf78a481054 100644 --- a/toolchain/driver/compile_subcommand.cpp +++ b/toolchain/driver/compile_subcommand.cpp @@ -436,8 +436,8 @@ class MultiUnitCache; class CompilationUnit { public: // `driver_env`, `options`, and `consumer` must be non-null. - explicit CompilationUnit(SemIR::CheckIRId check_ir_id, DriverEnv* driver_env, - const CompileOptions* options, + explicit CompilationUnit(SemIR::CheckIRId check_ir_id, int total_ir_count, + DriverEnv* driver_env, const CompileOptions* options, Diagnostics::Consumer* consumer, llvm::StringRef input_filename); @@ -499,6 +499,8 @@ class CompilationUnit { // The index of the unit amongst all units. SemIR::CheckIRId check_ir_id_; + // The number of units in total. + int total_ir_count_; DriverEnv* driver_env_; const CompileOptions* options_; @@ -619,11 +621,12 @@ class MultiUnitCache { } // namespace CompilationUnit::CompilationUnit(SemIR::CheckIRId check_ir_id, - DriverEnv* driver_env, + int total_ir_count, DriverEnv* driver_env, const CompileOptions* options, Diagnostics::Consumer* consumer, llvm::StringRef input_filename) : check_ir_id_(check_ir_id), + total_ir_count_(total_ir_count), driver_env_(driver_env), options_(options), input_filename_(input_filename), @@ -724,6 +727,7 @@ auto CompilationUnit::GetCheckUnit() -> Check::Unit { .value_stores = &value_stores_, .timings = timings_ ? &*timings_ : nullptr, .sem_ir = &*sem_ir_, + .total_ir_count = total_ir_count_, .clang_ast_unit = &clang_ast_unit_}; } @@ -757,7 +761,7 @@ auto CompilationUnit::RunLower() -> void { } module_ = Lower::LowerToLLVM(*llvm_context_, driver_env_->fs, cache_->tree_and_subtrees_getters(), *sem_ir_, - options); + total_ir_count_, options); }); } @@ -955,16 +959,18 @@ auto CompileSubcommand::Run(DriverEnv& driver_env) -> DriverResult { // Prepare CompilationUnits before building scope exit handlers. llvm::SmallVector> units; + int total_unit_count = prelude.size() + options_.input_filenames.size(); int unit_index = -1; auto unit_builder = [&](llvm::StringRef filename) { ++unit_index; - return std::make_unique(SemIR::CheckIRId(unit_index), - &driver_env, &options_, - &driver_env.consumer, filename); + return std::make_unique( + SemIR::CheckIRId(unit_index), total_unit_count, &driver_env, &options_, + &driver_env.consumer, filename); }; llvm::append_range(units, llvm::map_range(prelude, unit_builder)); llvm::append_range(units, llvm::map_range(options_.input_filenames, unit_builder)); + CARBON_CHECK(units.size() == static_cast(total_unit_count)); // Add the cache to all units. This must be done after all units are created. MultiUnitCache cache(&options_, units); diff --git a/toolchain/language_server/context.cpp b/toolchain/language_server/context.cpp index 8fe65f74d9a2..78db9c9f767e 100644 --- a/toolchain/language_server/context.cpp +++ b/toolchain/language_server/context.cpp @@ -154,6 +154,7 @@ auto Context::File::SetText(Context& context, std::optional version, .value_stores = value_stores_.get(), .timings = nullptr, .sem_ir = &sem_ir, + .total_ir_count = 1, .clang_ast_unit = &clang_ast_unt}}}; auto getter = [this]() -> const Parse::TreeAndSubtrees& { @@ -163,7 +164,7 @@ auto Context::File::SetText(Context& context, std::optional version, llvm::IntrusiveRefCntPtr fs = llvm::vfs::getRealFileSystem(); - // TODO: Include the prelude. + // TODO: Include the prelude. Make sure `total_ir_count` includes the files. Check::CheckParseTreesOptions check_options; check_options.vlog_stream = context.vlog_stream(); auto getters = diff --git a/toolchain/lower/context.cpp b/toolchain/lower/context.cpp index b1ef08b596c2..9cc29c2e93e7 100644 --- a/toolchain/lower/context.cpp +++ b/toolchain/lower/context.cpp @@ -18,7 +18,8 @@ Context::Context( llvm::LLVMContext* llvm_context, llvm::IntrusiveRefCntPtr fs, bool want_debug_info, const Parse::GetTreeAndSubtreesStore* tree_and_subtrees_getters, - llvm::StringRef module_name, llvm::raw_ostream* vlog_stream) + llvm::StringRef module_name, int total_ir_count, + llvm::raw_ostream* vlog_stream) : llvm_context_(llvm_context), llvm_module_(std::make_unique(module_name, *llvm_context)), file_system_(std::move(fs)), @@ -28,7 +29,8 @@ Context::Context( ? BuildDICompileUnit(module_name, *llvm_module_, di_builder_) : nullptr), tree_and_subtrees_getters_(tree_and_subtrees_getters), - vlog_stream_(vlog_stream) {} + vlog_stream_(vlog_stream), + total_ir_count_(total_ir_count) {} auto Context::GetFileContext(const SemIR::File* file, const SemIR::InstNamer* inst_namer) diff --git a/toolchain/lower/context.h b/toolchain/lower/context.h index 84fa7108d124..d3afbaf4fb92 100644 --- a/toolchain/lower/context.h +++ b/toolchain/lower/context.h @@ -47,7 +47,8 @@ class Context { llvm::LLVMContext* llvm_context, llvm::IntrusiveRefCntPtr fs, bool want_debug_info, const Parse::GetTreeAndSubtreesStore* tree_and_subtrees_getters, - llvm::StringRef module_name, llvm::raw_ostream* vlog_stream); + llvm::StringRef module_name, int total_ir_count, + llvm::raw_ostream* vlog_stream); // Gets or creates the `FileContext` for a given SemIR file. If an // `inst_namer` is specified the first time this is called for a file, it will @@ -100,6 +101,7 @@ class Context { auto tree_and_subtrees_getters() -> const Parse::GetTreeAndSubtreesStore& { return *tree_and_subtrees_getters_; } + auto total_ir_count() -> int { return total_ir_count_; } auto printf_int_format_string() -> llvm::Value* { return printf_int_format_string_; @@ -139,6 +141,9 @@ class Context { // The optional vlog stream. llvm::raw_ostream* vlog_stream_; + // The total number of files. + int total_ir_count_; + // The `FileContext`s for each IR that is involved in this lowering action. Map> file_contexts_; diff --git a/toolchain/lower/lower.cpp b/toolchain/lower/lower.cpp index 47f0d076ee7d..ace02fad8d14 100644 --- a/toolchain/lower/lower.cpp +++ b/toolchain/lower/lower.cpp @@ -18,15 +18,15 @@ auto LowerToLLVM( llvm::LLVMContext& llvm_context, llvm::IntrusiveRefCntPtr fs, const Parse::GetTreeAndSubtreesStore& tree_and_subtrees_getters, - const SemIR::File& sem_ir, const LowerToLLVMOptions& options) - -> std::unique_ptr { + const SemIR::File& sem_ir, int total_ir_count, + const LowerToLLVMOptions& options) -> std::unique_ptr { Context context(&llvm_context, std::move(fs), options.want_debug_info, - &tree_and_subtrees_getters, sem_ir.filename(), + &tree_and_subtrees_getters, sem_ir.filename(), total_ir_count, options.vlog_stream); // TODO: Consider disabling instruction naming by default if we're not // producing textual LLVM IR. - SemIR::InstNamer inst_namer(&sem_ir); + SemIR::InstNamer inst_namer(&sem_ir, total_ir_count); context.GetFileContext(&sem_ir, &inst_namer).LowerDefinitions(); std::unique_ptr module = std::move(context).Finalize(); diff --git a/toolchain/lower/lower.h b/toolchain/lower/lower.h index 5485afb1e098..189820df87ab 100644 --- a/toolchain/lower/lower.h +++ b/toolchain/lower/lower.h @@ -36,8 +36,8 @@ auto LowerToLLVM( llvm::LLVMContext& llvm_context, llvm::IntrusiveRefCntPtr fs, const Parse::GetTreeAndSubtreesStore& tree_and_subtrees_getters, - const SemIR::File& sem_ir, const LowerToLLVMOptions& options) - -> std::unique_ptr; + const SemIR::File& sem_ir, int total_ir_count, + const LowerToLLVMOptions& options) -> std::unique_ptr; } // namespace Carbon::Lower diff --git a/toolchain/lower/mangler.h b/toolchain/lower/mangler.h index c2932dfecc79..2cd809a1e8a9 100644 --- a/toolchain/lower/mangler.h +++ b/toolchain/lower/mangler.h @@ -22,7 +22,9 @@ class Mangler { public: // Initialize a new Mangler instance for mangling entities within the // specified `FileContext`. - explicit Mangler(FileContext& file_context) : file_context_(file_context) {} + explicit Mangler(FileContext& file_context) + : file_context_(file_context), + fingerprinter_(file_context_.context().total_ir_count()) {} // Produce a deterministically unique mangled name for the function specified // by `function_id` and `specific_id`. diff --git a/toolchain/sem_ir/BUILD b/toolchain/sem_ir/BUILD index 962ebe8ed572..94665f62ec99 100644 --- a/toolchain/sem_ir/BUILD +++ b/toolchain/sem_ir/BUILD @@ -172,6 +172,7 @@ cc_library( "//common:ostream", "//common:raw_string_ostream", "//common:type_enum", + "//toolchain/base:fixed_size_value_store", "//toolchain/base:kind_switch", "//toolchain/base:shared_value_stores", "//toolchain/base:value_ids", diff --git a/toolchain/sem_ir/formatter.cpp b/toolchain/sem_ir/formatter.cpp index de7afd6ceee3..102ad9a0dac5 100644 --- a/toolchain/sem_ir/formatter.cpp +++ b/toolchain/sem_ir/formatter.cpp @@ -35,11 +35,12 @@ namespace Carbon::SemIR { Formatter::Formatter( - const File* sem_ir, Parse::GetTreeAndSubtreesFn get_tree_and_subtrees, + const File* sem_ir, int total_ir_count, + Parse::GetTreeAndSubtreesFn get_tree_and_subtrees, const FixedSizeValueStore* include_ir_in_dumps, bool use_dump_sem_ir_ranges) : sem_ir_(sem_ir), - inst_namer_(sem_ir_), + inst_namer_(sem_ir_, total_ir_count), get_tree_and_subtrees_(get_tree_and_subtrees), include_ir_in_dumps_(include_ir_in_dumps), use_dump_sem_ir_ranges_(use_dump_sem_ir_ranges), diff --git a/toolchain/sem_ir/formatter.h b/toolchain/sem_ir/formatter.h index c9bd6df76b0a..bbb22c302b10 100644 --- a/toolchain/sem_ir/formatter.h +++ b/toolchain/sem_ir/formatter.h @@ -21,7 +21,8 @@ class Formatter { public: // sem_ir and include_ir_in_dumps must be non-null. explicit Formatter( - const File* sem_ir, Parse::GetTreeAndSubtreesFn get_tree_and_subtrees, + const File* sem_ir, int total_ir_count, + Parse::GetTreeAndSubtreesFn get_tree_and_subtrees, const FixedSizeValueStore* include_ir_in_dumps, bool use_dump_sem_ir_ranges); diff --git a/toolchain/sem_ir/inst_fingerprinter.cpp b/toolchain/sem_ir/inst_fingerprinter.cpp index 41e87e54acd6..e94d51c6e1fa 100644 --- a/toolchain/sem_ir/inst_fingerprinter.cpp +++ b/toolchain/sem_ir/inst_fingerprinter.cpp @@ -13,6 +13,7 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StableHashing.h" +#include "toolchain/base/fixed_size_value_store.h" #include "toolchain/base/value_ids.h" #include "toolchain/sem_ir/entity_with_params_base.h" #include "toolchain/sem_ir/ids.h" @@ -22,6 +23,10 @@ namespace Carbon::SemIR { namespace { struct Worklist { + using FingerprintStore = FixedSizeValueStore; + using FilesFingerprintStores = + FixedSizeValueStore; + // The file containing the instruction we're currently processing. const File* sem_ir = nullptr; // The instructions we need to compute fingerprints for. @@ -34,11 +39,31 @@ struct Worklist { llvm::SmallVector contents = {}; // Known cached instruction fingerprints. Each item in `todo` will be added to // the cache if not already present. - Map, uint64_t>* fingerprints; + FilesFingerprintStores* fingerprints; // Finish fingerprinting and compute the fingerprint. auto Finish() -> uint64_t { return llvm::stable_hash_combine(contents); } + // Gets the known fingerprint from the cache, or returns 0. + auto GetFingerprint(const File* file, InstId inst_id) -> uint64_t { + auto& store = fingerprints->Get(file->check_ir_id()); + if (store.size() == 0) { + return 0; + } + return store.Get(inst_id); + } + + // Sets the fingerprint for an instruction in the cache. Since 0 is used to + // indicate empty, we map 0 to another fixed value. + 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().size(), 0); + } + store.Set(inst_id, fingerprint ? fingerprint : 1); + } + // Add an invalid marker to the contents. This is used when the entity // contains a `None` ID. This uses an arbitrary fixed value that is assumed // to be unlikely to collide with a valid value. @@ -96,11 +121,11 @@ struct Worklist { AddInvalid(); return; } - if (auto lookup = fingerprints->Lookup(std::pair(file, inner_id))) { - contents.push_back(lookup.value()); - } else { - todo.push_back({file, inner_id}); + if (auto fingerprint = GetFingerprint(file, inner_id)) { + contents.push_back(fingerprint); + return; } + todo.push_back({file, inner_id}); } auto Add(InstId inner_id) -> void { AddInFile(sem_ir, inner_id); } @@ -406,11 +431,10 @@ struct Worklist { // If we already have a fingerprint for this instruction, we have nothing // to do. Just pop it from `todo`. - if (auto lookup = - fingerprints->Lookup(std::pair(next_sem_ir, next_inst_id))) { + if (auto fingerprint = GetFingerprint(next_sem_ir, next_inst_id)) { todo.pop_back(); if (todo.empty()) { - return lookup.value(); + return fingerprint; } continue; } @@ -438,7 +462,7 @@ struct Worklist { // we can compute its fingerprint once we've finished the work we added. if (todo.size() == init_size) { uint64_t fingerprint = Finish(); - fingerprints->Insert(std::pair(next_sem_ir, next_inst_id), fingerprint); + SetFingerprint(next_sem_ir, next_inst_id, fingerprint); todo.pop_back(); if (todo.empty()) { return fingerprint; diff --git a/toolchain/sem_ir/inst_fingerprinter.h b/toolchain/sem_ir/inst_fingerprinter.h index f8fef9a81623..c2670fed1f15 100644 --- a/toolchain/sem_ir/inst_fingerprinter.h +++ b/toolchain/sem_ir/inst_fingerprinter.h @@ -5,6 +5,7 @@ #ifndef CARBON_TOOLCHAIN_SEM_IR_INST_FINGERPRINTER_H_ #define CARBON_TOOLCHAIN_SEM_IR_INST_FINGERPRINTER_H_ +#include "toolchain/base/fixed_size_value_store.h" #include "toolchain/sem_ir/file.h" #include "toolchain/sem_ir/ids.h" @@ -14,6 +15,12 @@ namespace Carbon::SemIR { // stable across compilations and across minor changes to the compiler. class InstFingerprinter { public: + explicit InstFingerprinter(int total_ir_count) + : fingerprints_(FilesFingerprintStores::MakeWithExplicitSizeFrom( + total_ir_count, [] { + return FingerprintStore::MakeForOverwriteWithExplicitSize(0); + })) {} + // Gets or computes a fingerprint for the given instruction. auto GetOrCompute(const File* file, InstId inst_id) -> uint64_t; @@ -32,7 +39,10 @@ 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. - Map, uint64_t> fingerprints_; + using FingerprintStore = FixedSizeValueStore; + using FilesFingerprintStores = + FixedSizeValueStore; + FilesFingerprintStores fingerprints_; }; } // namespace Carbon::SemIR diff --git a/toolchain/sem_ir/inst_namer.cpp b/toolchain/sem_ir/inst_namer.cpp index b5bb35cddf3e..774db1d66d3f 100644 --- a/toolchain/sem_ir/inst_namer.cpp +++ b/toolchain/sem_ir/inst_namer.cpp @@ -78,7 +78,8 @@ class InstNamer::NamingContext { Inst inst_; }; -InstNamer::InstNamer(const File* sem_ir) : sem_ir_(sem_ir) { +InstNamer::InstNamer(const File* sem_ir, int total_ir_count) + : sem_ir_(sem_ir), fingerprinter_(total_ir_count) { insts_.resize(sem_ir->insts().size(), {ScopeId::None, Namespace::Name()}); labels_.resize(sem_ir->inst_blocks().size()); scopes_.resize(GetScopeIdOffset(ScopeIdTypeEnum::None)); @@ -644,7 +645,7 @@ auto InstNamer::NamingContext::AddInstName(std::string name) -> void { loc_id_or_fingerprint = LocId(inst_id_); } auto scoped_name = inst_namer_->GetScopeInfo(scope_id_).insts.AllocateName( - *inst_namer_, loc_id_or_fingerprint, name); + *inst_namer_, loc_id_or_fingerprint, std::move(name)); inst_namer_->insts_[inst_id_.index] = {scope_id_, scoped_name}; } else { CARBON_CHECK(old_scope_id == scope_id_, diff --git a/toolchain/sem_ir/inst_namer.h b/toolchain/sem_ir/inst_namer.h index 04846605b1c9..7e7c8828b13e 100644 --- a/toolchain/sem_ir/inst_namer.h +++ b/toolchain/sem_ir/inst_namer.h @@ -43,7 +43,7 @@ class InstNamer { // Construct the instruction namer, and assign names to all instructions in // the provided file. - explicit InstNamer(const File* sem_ir); + explicit InstNamer(const File* sem_ir, int total_ir_count); // Returns the scope ID corresponding to an ID of a function, class, or // interface.