Allow sharing of initialization functions across slots to limit code size growth. PiperOrigin-RevId: 734615591 Change-Id: I7b7d73c0e38e2b9f55013f79a33fce7bf71edb72
diff --git a/mpact/sim/decoder/BUILD b/mpact/sim/decoder/BUILD index 75511a5..536ba70 100644 --- a/mpact/sim/decoder/BUILD +++ b/mpact/sim/decoder/BUILD
@@ -117,6 +117,7 @@ ":antlr_parser_wrapper", ":decoder_error_listener", ":format_name", + "@com_google_absl//absl/base:no_destructor", "@com_google_absl//absl/container:btree", "@com_google_absl//absl/container:flat_hash_map", "@com_google_absl//absl/container:flat_hash_set",
diff --git a/mpact/sim/decoder/slot.cc b/mpact/sim/decoder/slot.cc index 63372ff..135539f 100644 --- a/mpact/sim/decoder/slot.cc +++ b/mpact/sim/decoder/slot.cc
@@ -26,7 +26,9 @@ #include <variant> #include <vector> +#include "absl/base/no_destructor.h" #include "absl/container/btree_set.h" +#include "absl/container/flat_hash_map.h" #include "absl/container/flat_hash_set.h" #include "absl/status/status.h" #include "absl/status/statusor.h" @@ -46,6 +48,15 @@ namespace machine_description { namespace instruction_set { +absl::NoDestructor<absl::flat_hash_map<std::string, std::string>> + Slot::operand_setter_name_map_; +absl::NoDestructor<absl::flat_hash_map<std::string, std::string>> + Slot::disasm_setter_name_map_; +absl::NoDestructor<absl::flat_hash_map<std::string, std::string>> + Slot::resource_setter_name_map_; +absl::NoDestructor<absl::flat_hash_map<std::string, std::string>> + Slot::attribute_setter_name_map_; + // This function translates the location specification into a set of '->' // references starting with 'inst->' to get to the operand that is implied. static absl::StatusOr<std::string> TranslateLocator( @@ -274,12 +285,12 @@ // instruction. If no such appropriate function exists, create one. std::string Slot::GenerateAttributeSetter(const Instruction *inst) { auto key = CreateAttributeLookupKey(inst); - auto iter = attribute_setter_name_map_.find(key); - if (iter == attribute_setter_name_map_.end()) { - auto index = attribute_setter_name_map_.size(); + auto iter = attribute_setter_name_map_->find(key); + if (iter == attribute_setter_name_map_->end()) { + auto index = attribute_setter_name_map_->size(); std::string func_name = absl::StrCat(pascal_name(), "Slot", "SetAttributes", index); - iter = attribute_setter_name_map_.emplace(key, func_name).first; + iter = attribute_setter_name_map_->emplace(key, func_name).first; absl::StrAppend(&setter_functions_, GenerateAttributeSetterFcn(func_name, inst)); } @@ -719,9 +730,9 @@ absl::StrAppend(&key, ":", CreateOperandLookupKey(inst->opcode())); std::string func_name = absl::StrCat( pascal_name(), "Slot", inst->opcode()->pascal_name(), "SetDisasm"); - auto iter = disasm_setter_name_map_.find(key); - if (iter == disasm_setter_name_map_.end()) { - iter = disasm_setter_name_map_.emplace(key, func_name).first; + auto iter = disasm_setter_name_map_->find(key); + if (iter == disasm_setter_name_map_->end()) { + iter = disasm_setter_name_map_->emplace(key, func_name).first; absl::StrAppend(&setter_functions_, GenerateDisasmSetterFcn(func_name, inst)); } @@ -849,12 +860,12 @@ absl::string_view encoding_type) { std::string key = CreateResourceKey(inst->resource_use_vec()); absl::StrAppend(&key, ":", CreateResourceKey(inst->resource_acquire_vec())); - auto iter = resource_setter_name_map_.find(key); - if (iter == resource_setter_name_map_.end()) { - auto index = resource_setter_name_map_.size(); + auto iter = resource_setter_name_map_->find(key); + if (iter == resource_setter_name_map_->end()) { + auto index = resource_setter_name_map_->size(); std::string func_name = absl::StrCat(pascal_name(), "Slot", "SetResources", index); - iter = resource_setter_name_map_.emplace(key, func_name).first; + iter = resource_setter_name_map_->emplace(key, func_name).first; absl::StrAppend(&setter_functions_, GenerateResourceSetterFcn(func_name, inst, encoding_type)); } @@ -1246,18 +1257,19 @@ inst = inst->child()) { // Construct operand getter lookup key. std::string key = CreateOperandLookupKey(inst->opcode()); - auto iter = operand_setter_name_map_.find(key); + auto iter = operand_setter_name_map_->find(key); // If the key is not found, create a new getter function, otherwise // reuse the existing one. - if (iter == operand_setter_name_map_.end()) { - auto index = operand_setter_name_map_.size(); + if (iter == operand_setter_name_map_->end()) { + auto index = operand_setter_name_map_->size(); std::string setter_name = absl::StrCat(class_name, "SetOperands", index); absl::StrAppend(&setter_functions_, GenerateOperandSetterFcn(setter_name, encoding_type, inst->opcode())); - iter = operand_setter_name_map_.insert(std::make_pair(key, setter_name)) - .first; + iter = + operand_setter_name_map_->insert(std::make_pair(key, setter_name)) + .first; } absl::StrAppend(&operands_str, sep, iter->second); if (inst->semfunc_code_string().empty()) {
diff --git a/mpact/sim/decoder/slot.h b/mpact/sim/decoder/slot.h index cc1df51..1f074d0 100644 --- a/mpact/sim/decoder/slot.h +++ b/mpact/sim/decoder/slot.h
@@ -20,6 +20,7 @@ #include <tuple> #include <vector> +#include "absl/base/no_destructor.h" #include "absl/container/btree_map.h" #include "absl/container/flat_hash_map.h" #include "absl/container/flat_hash_set.h" @@ -219,11 +220,16 @@ // Pointer to slot it inherits from. std::vector<BaseSlot> base_slots_; absl::flat_hash_set<const Slot *> predecessor_set_; - // Map from operand getter key to operand getter function name. - absl::flat_hash_map<std::string, std::string> operand_setter_name_map_; - absl::flat_hash_map<std::string, std::string> disasm_setter_name_map_; - absl::flat_hash_map<std::string, std::string> resource_setter_name_map_; - absl::flat_hash_map<std::string, std::string> attribute_setter_name_map_; + // Map from operand getter key to operand getter function name. These are + // static so that they can be shared across different slots. + static absl::NoDestructor<absl::flat_hash_map<std::string, std::string>> + operand_setter_name_map_; + static absl::NoDestructor<absl::flat_hash_map<std::string, std::string>> + disasm_setter_name_map_; + static absl::NoDestructor<absl::flat_hash_map<std::string, std::string>> + resource_setter_name_map_; + static absl::NoDestructor<absl::flat_hash_map<std::string, std::string>> + attribute_setter_name_map_; std::string setter_functions_; // Used to list the unique getters for the operands. absl::flat_hash_set<std::string> pred_operand_getters_;