Fixes issue with attributes for instructions with child instructions. PiperOrigin-RevId: 895900622 Change-Id: I006face376ecd28d39990449eb5aef2399dca010
diff --git a/mpact/sim/decoder/instruction.cc b/mpact/sim/decoder/instruction.cc index e784d8a..2d9ed19 100644 --- a/mpact/sim/decoder/instruction.cc +++ b/mpact/sim/decoder/instruction.cc
@@ -98,7 +98,7 @@ // Creating a derived instruction involves copying attributes and re-evaluating // any expressions that depend on any slot template instantiation values. absl::StatusOr<Instruction*> Instruction::CreateDerivedInstruction( - TemplateInstantiationArgs* args) const { + TemplateInstantiationArgs* args, Slot* new_slot) const { // First try to create a derived opcode object. Fail if it fails. auto op_result = slot_->instruction_set()->opcode_factory()->CreateDerivedOpcode(opcode(), @@ -139,6 +139,7 @@ for (auto const& [attr_name, expr_ptr] : attribute_map_) { auto result = expr_ptr->Evaluate(args); if (result.ok()) { + new_slot->AddAttributeName(attr_name); new_inst->AddInstructionAttribute(attr_name, result.value()); } else { delete new_inst; @@ -150,7 +151,7 @@ // Recursively hande child instructions. if (child() == nullptr) return new_inst; - auto result = child()->CreateDerivedInstruction(args); + auto result = child()->CreateDerivedInstruction(args, new_slot); if (result.ok()) { new_inst->AppendChild(result.value()); return new_inst;
diff --git a/mpact/sim/decoder/instruction.h b/mpact/sim/decoder/instruction.h index e2f6563..9f89586 100644 --- a/mpact/sim/decoder/instruction.h +++ b/mpact/sim/decoder/instruction.h
@@ -51,7 +51,7 @@ // evaluation of expressions within the instruction/opcode that rely on // template instantiation arguments. absl::StatusOr<Instruction*> CreateDerivedInstruction( - TemplateInstantiationArgs* args) const; + TemplateInstantiationArgs* args, Slot* new_slot) const; // Resources used and acquired/released. void AppendResourceUse(const ResourceReference* resource_ref); void AppendResourceAcquire(const ResourceReference* resource_ref);
diff --git a/mpact/sim/decoder/instruction_set_visitor.cc b/mpact/sim/decoder/instruction_set_visitor.cc index f70c5b3..d6a0b21 100644 --- a/mpact/sim/decoder/instruction_set_visitor.cc +++ b/mpact/sim/decoder/instruction_set_visitor.cc
@@ -1328,16 +1328,24 @@ if (inst != nullptr) { for (auto* child = inst; child != nullptr; child = child->child()) { for (auto& [name, expr] : attributes) { - child->AddInstructionAttribute(name, expr); + child->AddInstructionAttribute( + name, expr == nullptr ? nullptr : expr->DeepCopy()); } } // Ownership of expr objects transferred to opcode. + for (auto& [unused, expr] : attributes) { + delete expr; + } attributes.clear(); return; } // Attributes are default attributes for the current slot. for (auto& [name, expr] : attributes) { - slot->AddInstructionAttribute(name, expr); + slot->AddInstructionAttribute(name, + expr == nullptr ? nullptr : expr->DeepCopy()); + } + for (auto& [unused, expr] : attributes) { + delete expr; } attributes.clear(); }
diff --git a/mpact/sim/decoder/slot.cc b/mpact/sim/decoder/slot.cc index 0c786ef..0a8bd0e 100644 --- a/mpact/sim/decoder/slot.cc +++ b/mpact/sim/decoder/slot.cc
@@ -200,7 +200,7 @@ TemplateInstantiationArgs* args) { std::string name = inst->opcode()->name(); if (!instruction_map_.contains(name)) { - auto derived = inst->CreateDerivedInstruction(args); + auto derived = inst->CreateDerivedInstruction(args, this); if (derived.ok()) { if (!is_templated()) { @@ -256,9 +256,7 @@ int size = attribute_names_.size(); if (size > 0) { // Allocate the array and initialize to zero. - absl::StrAppend(&output, " int *attrs = new int[", size, - "];\n" - " *attrs = {"); + absl::StrAppend(&output, " int *attrs = new int[", size, "]{"); for (auto const& attribute_name : attribute_names_) { auto it = inst->attribute_map().find(attribute_name); if (it == inst->attribute_map().end()) {