a32_get_set_elimination_pass: Ensure no use before rm def

This commit is contained in:
Merry 2023-01-19 20:48:07 +00:00
parent ba42318ab2
commit 7fb7352f55

View file

@ -3,7 +3,9 @@
* SPDX-License-Identifier: 0BSD * SPDX-License-Identifier: 0BSD
*/ */
#include <algorithm>
#include <array> #include <array>
#include <functional>
#include <mcl/assert.hpp> #include <mcl/assert.hpp>
#include <mcl/stdint.hpp> #include <mcl/stdint.hpp>
@ -39,16 +41,20 @@ void A32GetSetElimination(IR::Block& block, A32GetSetEliminationOptions) {
RegisterInfo c_flag; RegisterInfo c_flag;
RegisterInfo ge; RegisterInfo ge;
auto do_set = [&](RegisterInfo& info, IR::Value value, Iterator inst) { auto do_set = [&](RegisterInfo& info, IR::Value value, Iterator inst, std::initializer_list<std::reference_wrapper<RegisterInfo>> dependants = {}) {
if (info.has_value_request) { if (info.has_value_request) {
info.value_request->ReplaceUsesWith(value); info.value_request->ReplaceUsesWith(value);
} }
info.has_value_request = false; info.has_value_request = false;
if (info.set_not_required) { if (info.set_not_required && std::all_of(dependants.begin(), dependants.end(), [](auto d) { return !d.get().has_value_request; })) {
inst->Invalidate(); inst->Invalidate();
} }
info.set_not_required = true; info.set_not_required = true;
for (auto d : dependants) {
d.get() = {};
}
}; };
auto do_set_valueless = [&](ValuelessRegisterInfo& info, Iterator inst) { auto do_set_valueless = [&](ValuelessRegisterInfo& info, Iterator inst) {
@ -89,11 +95,14 @@ void A32GetSetElimination(IR::Block& block, A32GetSetEliminationOptions) {
case IR::Opcode::A32SetExtendedRegister32: { case IR::Opcode::A32SetExtendedRegister32: {
const A32::ExtReg reg = inst->GetArg(0).GetA32ExtRegRef(); const A32::ExtReg reg = inst->GetArg(0).GetA32ExtRegRef();
const size_t reg_index = A32::RegNumber(reg); const size_t reg_index = A32::RegNumber(reg);
do_set(ext_reg_singles_info[reg_index], inst->GetArg(1), inst); do_set(ext_reg_singles_info[reg_index],
inst->GetArg(1),
ext_reg_doubles_info[reg_index / 2] = {}; inst,
ext_reg_vector_double_info[reg_index / 2] = {}; {
ext_reg_vector_quad_info[reg_index / 4] = {}; ext_reg_doubles_info[reg_index / 2],
ext_reg_vector_double_info[reg_index / 2],
ext_reg_vector_quad_info[reg_index / 4],
});
break; break;
} }
case IR::Opcode::A32GetExtendedRegister32: { case IR::Opcode::A32GetExtendedRegister32: {
@ -105,12 +114,15 @@ void A32GetSetElimination(IR::Block& block, A32GetSetEliminationOptions) {
case IR::Opcode::A32SetExtendedRegister64: { case IR::Opcode::A32SetExtendedRegister64: {
const A32::ExtReg reg = inst->GetArg(0).GetA32ExtRegRef(); const A32::ExtReg reg = inst->GetArg(0).GetA32ExtRegRef();
const size_t reg_index = A32::RegNumber(reg); const size_t reg_index = A32::RegNumber(reg);
do_set(ext_reg_doubles_info[reg_index], inst->GetArg(1), inst); do_set(ext_reg_doubles_info[reg_index],
inst->GetArg(1),
ext_reg_singles_info[reg_index * 2 + 0] = {}; inst,
ext_reg_singles_info[reg_index * 2 + 1] = {}; {
ext_reg_vector_double_info[reg_index] = {}; ext_reg_singles_info[reg_index * 2 + 0],
ext_reg_vector_quad_info[reg_index / 2] = {}; ext_reg_singles_info[reg_index * 2 + 1],
ext_reg_vector_double_info[reg_index],
ext_reg_vector_quad_info[reg_index / 2],
});
break; break;
} }
case IR::Opcode::A32GetExtendedRegister64: { case IR::Opcode::A32GetExtendedRegister64: {
@ -123,25 +135,31 @@ void A32GetSetElimination(IR::Block& block, A32GetSetEliminationOptions) {
const A32::ExtReg reg = inst->GetArg(0).GetA32ExtRegRef(); const A32::ExtReg reg = inst->GetArg(0).GetA32ExtRegRef();
const size_t reg_index = A32::RegNumber(reg); const size_t reg_index = A32::RegNumber(reg);
if (A32::IsDoubleExtReg(reg)) { if (A32::IsDoubleExtReg(reg)) {
do_set(ext_reg_vector_double_info[reg_index], inst->GetArg(1), inst); do_set(ext_reg_vector_double_info[reg_index],
inst->GetArg(1),
ext_reg_singles_info[reg_index * 2 + 0] = {}; inst,
ext_reg_singles_info[reg_index * 2 + 1] = {}; {
ext_reg_doubles_info[reg_index] = {}; ext_reg_singles_info[reg_index * 2 + 0],
ext_reg_vector_quad_info[reg_index / 2] = {}; ext_reg_singles_info[reg_index * 2 + 1],
ext_reg_doubles_info[reg_index],
ext_reg_vector_quad_info[reg_index / 2],
});
} else { } else {
DEBUG_ASSERT(A32::IsQuadExtReg(reg)); DEBUG_ASSERT(A32::IsQuadExtReg(reg));
do_set(ext_reg_vector_quad_info[reg_index], inst->GetArg(1), inst); do_set(ext_reg_vector_quad_info[reg_index],
inst->GetArg(1),
ext_reg_singles_info[reg_index * 4 + 0] = {}; inst,
ext_reg_singles_info[reg_index * 4 + 1] = {}; {
ext_reg_singles_info[reg_index * 4 + 2] = {}; ext_reg_singles_info[reg_index * 4 + 0],
ext_reg_singles_info[reg_index * 4 + 3] = {}; ext_reg_singles_info[reg_index * 4 + 1],
ext_reg_doubles_info[reg_index * 2 + 0] = {}; ext_reg_singles_info[reg_index * 4 + 2],
ext_reg_doubles_info[reg_index * 2 + 1] = {}; ext_reg_singles_info[reg_index * 4 + 3],
ext_reg_vector_double_info[reg_index * 2 + 0] = {}; ext_reg_doubles_info[reg_index * 2 + 0],
ext_reg_vector_double_info[reg_index * 2 + 1] = {}; ext_reg_doubles_info[reg_index * 2 + 1],
ext_reg_vector_double_info[reg_index * 2 + 0],
ext_reg_vector_double_info[reg_index * 2 + 1],
});
} }
break; break;
} }