Skip to content

Commit

Permalink
Update jit_brgemm_copy_b_emitter to spill only live regs
Browse files Browse the repository at this point in the history
  • Loading branch information
IvanNovoselov committed Jan 2, 2025
1 parent 6fa6b89 commit 33d52bf
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,10 @@ void jit_brgemm_copy_b_emitter::emit_impl(const std::vector<size_t>& in, const s
regs_to_spill.emplace(snippets::RegType::gpr, h->rbp.getIdx());
// Note: abi_param_1 is a default invalid value to check later that the aux reg was allocated properly
Xbyak::Reg64 aux_reg = abi_param1;
utils::init_memory_access_aux_gpr(mem_ptrs_idxs, m_memory_offsets, aux_gpr_idxs, regs_to_spill, aux_reg);
const bool is_dynamic_case =
std::any_of(m_memory_offsets.cbegin(), m_memory_offsets.cend(), ov::snippets::utils::is_dynamic_value<size_t>);
if (is_dynamic_case)
aux_reg = utils::init_memory_access_aux_gpr(mem_ptrs_idxs, aux_gpr_idxs, regs_to_spill);

EmitABIRegSpills spill(h);
spill.preamble(regs_to_spill);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,10 @@ void jit_brgemm_emitter::emit_call(const std::vector<size_t>& mem_ptrs_idxs) con
regs_to_spill.emplace(snippets::RegType::gpr, h->rbp.getIdx());
// Note: abi_param_1 is a default invalid value to check later that the aux reg was allocated properly
Xbyak::Reg64 aux_reg = abi_param1;
utils::init_memory_access_aux_gpr(mem_ptrs_idxs, m_memory_offsets, aux_gpr_idxs, regs_to_spill, aux_reg);
const bool is_dynamic_case =
std::any_of(m_memory_offsets.cbegin(), m_memory_offsets.cend(), ov::snippets::utils::is_dynamic_value<size_t>);
if (std::is_same<T, BrgemmAMXKernelExecutor>() || is_dynamic_case)
aux_reg = utils::init_memory_access_aux_gpr(mem_ptrs_idxs, aux_gpr_idxs, regs_to_spill);
EmitABIRegSpills spill(h);
spill.preamble(regs_to_spill);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ jit_reg_spill_begin_emitter::jit_reg_spill_begin_emitter(dnnl::impl::cpu::x64::j
const auto& reg_spill_node = ov::as_type_ptr<snippets::op::RegSpillBegin>(m_reg_spill_begin_expr->get_node());
OV_CPU_JIT_EMITTER_ASSERT(reg_spill_node, "expects RegSpillBegin expression");
m_num_spilled = reg_spill_node->get_regs_to_spill().size();
// todo: abstract registers were not mapped on physical onces at this point (Kernel emitter does that),
// so we have to declare reg_spiller mutable
m_abi_reg_spiller = std::make_shared<EmitABIRegSpills>(h);
in_out_type_ = emitter_in_out_map::gpr_to_gpr;
}
Expand Down
25 changes: 9 additions & 16 deletions src/plugins/intel_cpu/src/emitters/snippets/x64/utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,23 +59,16 @@ Xbyak::Reg64 get_aux_gpr(const std::vector<size_t>& used_gpr_idxs) {
OV_CPU_JIT_EMITTER_THROW("Failed to allocate aux GPR");
}

void init_memory_access_aux_gpr(const std::vector<size_t>& mem_ptr_reg_idxs,
const std::vector<size_t>& memory_offsets,
const std::vector<size_t>& aux_gpr_idxs,
std::set<snippets::Reg>& regs_to_spill,
Xbyak::Reg64& aux_reg) {
const bool is_dynamic_case =
std::any_of(memory_offsets.cbegin(), memory_offsets.cend(), ov::snippets::utils::is_dynamic_value<size_t>);
// Note: abi_param_1 is a default invalid value to check later that the aux reg was allocated properly
if (is_dynamic_case) {
if (!aux_gpr_idxs.empty()) {
aux_reg = Xbyak::Reg64(static_cast<int>(aux_gpr_idxs[0]));
} else {
aux_reg = ov::intel_cpu::utils::get_aux_gpr(mem_ptr_reg_idxs);
regs_to_spill.emplace(snippets::RegType::gpr, aux_reg.getIdx());
}
Xbyak::Reg64 init_memory_access_aux_gpr(const std::vector<size_t>& mem_ptr_reg_idxs,
const std::vector<size_t>& aux_gpr_idxs,
std::set<snippets::Reg>& regs_to_spill) {
if (!aux_gpr_idxs.empty()) {
return Xbyak::Reg64(static_cast<int>(aux_gpr_idxs[0]));
}
};
const auto aux_reg = ov::intel_cpu::utils::get_aux_gpr(mem_ptr_reg_idxs);
regs_to_spill.emplace(snippets::RegType::gpr, aux_reg.getIdx());
return aux_reg;
}

void push_ptr_with_runtime_offset_on_stack(dnnl::impl::cpu::x64::jit_generator* h,
size_t stack_offset,
Expand Down
15 changes: 5 additions & 10 deletions src/plugins/intel_cpu/src/emitters/snippets/x64/utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,20 +35,15 @@ size_t get_buffer_cluster_id(const ov::snippets::lowered::ExpressionPort& port);
Xbyak::Reg64 get_aux_gpr(const std::vector<size_t>& used_gpr_idxs);

/**
* @brief Initializes aux gpr register for dynamic memory access emitters. If any of the `memory_offsets` is dynamic,
* then try to assign `aux_reg` a register from `aux_gpr_idxs`. If `aux_gpr_idxs` is empty, then choose a register that
* is not in `mem_ptr_reg_idxs` and add it to `regs_to_spill`.
* @brief Returns aux gpr register for dynamic memory access emitters. Returns a register from `aux_gpr_idxs`.
* If it's empty, then choose a register that is not in `mem_ptr_reg_idxs` and add it to `regs_to_spill`.
* @param mem_ptr_reg_idxs register indexes reserved to store memory pointers in this emitter
* @param memory_offsets memory offsets, could be dynamic
* @param aux_gpr_idxs pool of available gp register indexes
* @param regs_to_spill set of live registers to be spilled before ABI call
* @param aux_reg auxiliary register that should be initialized
*/
void init_memory_access_aux_gpr(const std::vector<size_t>& mem_ptr_reg_idxs,
const std::vector<size_t>& memory_offsets,
const std::vector<size_t>& aux_gpr_idxs,
std::set<snippets::Reg>& regs_to_spill,
Xbyak::Reg64& aux_reg);
Xbyak::Reg64 init_memory_access_aux_gpr(const std::vector<size_t>& mem_ptr_reg_idxs,
const std::vector<size_t>& aux_gpr_idxs,
std::set<snippets::Reg>& regs_to_spill);

/**
* @brief Push data pointer on stack adding offset. The offset is taken from runtime params `abi_param1`
Expand Down

0 comments on commit 33d52bf

Please sign in to comment.