Explorar o código

Use a FixedSizeValueStore<CheckIRId> in Lower::Context (#6021)

Now that the total number of IRs is available from SemIR::File, we can
use FixedSizeValueStore to store/look up values mapped from a CheckIRId
instead of a Map, which is demonstrably faster (unsurprisingly, since
it's just a vector index). See #6019.

This replaces a Map with FixedSizeValueStore in Lower::Context for use
in `GetFileContext()`. This function is used in some places that can
become hot, such as `HandleInst()` and `GetType()`. In our current
lowering tests, there's no measurable performance change from this PR,
but based on #6019 we can expect to see one as the amount of
instructions being lowered increases. Using a FixedSizeValueStore when
possible is a better approach than a map, generally.
Dana Jansens hai 7 meses
pai
achega
b92e23962a
Modificáronse 2 ficheiros con 18 adicións e 9 borrados
  1. 14 8
      toolchain/lower/context.cpp
  2. 4 1
      toolchain/lower/context.h

+ 14 - 8
toolchain/lower/context.cpp

@@ -30,18 +30,21 @@ Context::Context(
               : nullptr),
       tree_and_subtrees_getters_(tree_and_subtrees_getters),
       vlog_stream_(vlog_stream),
-      total_ir_count_(total_ir_count) {}
+      total_ir_count_(total_ir_count),
+      file_contexts_(
+          FileContextStore::MakeForOverwriteWithExplicitSize(total_ir_count_)) {
+}
 
 auto Context::GetFileContext(const SemIR::File* file,
                              const SemIR::InstNamer* inst_namer)
     -> FileContext& {
-  auto insert_result = file_contexts_.Insert(file->check_ir_id(), [&] {
-    auto file_context =
+  auto& file_context = file_contexts_.Get(file->check_ir_id());
+  if (!file_context) {
+    file_context =
         std::make_unique<FileContext>(*this, *file, inst_namer, vlog_stream_);
     file_context->PrepareToLower();
-    return file_context;
-  });
-  return *insert_result.value();
+  }
+  return *file_context;
 }
 
 auto Context::LowerPendingDefinitions() -> void {
@@ -55,8 +58,11 @@ auto Context::LowerPendingDefinitions() -> void {
 auto Context::Finalize() && -> std::unique_ptr<llvm::Module> {
   LowerPendingDefinitions();
 
-  file_contexts_.ForEach(
-      [](auto, auto& file_context) { file_context->Finalize(); });
+  for (auto& file_context : file_contexts_.values()) {
+    if (file_context) {
+      file_context->Finalize();
+    }
+  }
 
   return std::move(llvm_module_);
 }

+ 4 - 1
toolchain/lower/context.h

@@ -13,6 +13,7 @@
 #include "llvm/IR/DIBuilder.h"
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/Module.h"
+#include "toolchain/base/fixed_size_value_store.h"
 #include "toolchain/parse/tree_and_subtrees.h"
 #include "toolchain/sem_ir/absolute_node_id.h"
 #include "toolchain/sem_ir/ids.h"
@@ -145,7 +146,9 @@ class Context {
   int total_ir_count_;
 
   // The `FileContext`s for each IR that is involved in this lowering action.
-  Map<SemIR::CheckIRId, std::unique_ptr<FileContext>> file_contexts_;
+  using FileContextStore =
+      FixedSizeValueStore<SemIR::CheckIRId, std::unique_ptr<FileContext>>;
+  FileContextStore file_contexts_;
 
   // Lowered version of the builtin type `type`.
   llvm::StructType* type_type_ = nullptr;