get_set_elimination_pass: Eliminate unnecessary gets/sets of extended registers
This commit is contained in:
parent
e0f9dead5d
commit
c8b2f63c93
2 changed files with 51 additions and 1 deletions
|
@ -119,7 +119,9 @@ Gen::X64Reg RegAlloc::UseDefRegister(IR::Inst* use_inst, IR::Inst* def_inst, Hos
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_floating_point = use_inst->GetType() == IR::Type::F32 || use_inst->GetType() == IR::Type::F64;
|
bool is_floating_point = HostLocIsXMM(*desired_locations.begin());
|
||||||
|
if (is_floating_point)
|
||||||
|
DEBUG_ASSERT(use_inst->GetType() == IR::Type::F32 || use_inst->GetType() == IR::Type::F64);
|
||||||
Gen::X64Reg use_reg = UseRegister(use_inst, is_floating_point ? any_xmm : any_gpr);
|
Gen::X64Reg use_reg = UseRegister(use_inst, is_floating_point ? any_xmm : any_gpr);
|
||||||
Gen::X64Reg def_reg = DefRegister(def_inst, desired_locations);
|
Gen::X64Reg def_reg = DefRegister(def_inst, desired_locations);
|
||||||
if (is_floating_point) {
|
if (is_floating_point) {
|
||||||
|
|
|
@ -23,6 +23,8 @@ void GetSetElimination(IR::Block& block) {
|
||||||
Iterator last_set_instruction;
|
Iterator last_set_instruction;
|
||||||
};
|
};
|
||||||
std::array<RegisterInfo, 15> reg_info;
|
std::array<RegisterInfo, 15> reg_info;
|
||||||
|
std::array<RegisterInfo, 32> ext_reg_singles_info;
|
||||||
|
std::array<RegisterInfo, 32> ext_reg_doubles_info;
|
||||||
RegisterInfo n_info;
|
RegisterInfo n_info;
|
||||||
RegisterInfo z_info;
|
RegisterInfo z_info;
|
||||||
RegisterInfo c_info;
|
RegisterInfo c_info;
|
||||||
|
@ -64,6 +66,52 @@ void GetSetElimination(IR::Block& block) {
|
||||||
do_get(reg_info[reg_index], inst);
|
do_get(reg_info[reg_index], inst);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case IR::Opcode::SetExtendedRegister32: {
|
||||||
|
Arm::ExtReg reg = inst->GetArg(0).GetExtRegRef();
|
||||||
|
size_t reg_index = Arm::RegNumber(reg);
|
||||||
|
do_set(ext_reg_singles_info[reg_index], inst->GetArg(1), inst);
|
||||||
|
|
||||||
|
size_t doubles_reg_index = reg_index / 2;
|
||||||
|
if (doubles_reg_index < ext_reg_doubles_info.size()) {
|
||||||
|
ext_reg_doubles_info[doubles_reg_index] = {};
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case IR::Opcode::GetExtendedRegister32: {
|
||||||
|
Arm::ExtReg reg = inst->GetArg(0).GetExtRegRef();
|
||||||
|
size_t reg_index = Arm::RegNumber(reg);
|
||||||
|
do_get(ext_reg_singles_info[reg_index], inst);
|
||||||
|
|
||||||
|
size_t doubles_reg_index = reg_index / 2;
|
||||||
|
if (doubles_reg_index < ext_reg_doubles_info.size()) {
|
||||||
|
ext_reg_doubles_info[doubles_reg_index] = {};
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case IR::Opcode::SetExtendedRegister64: {
|
||||||
|
Arm::ExtReg reg = inst->GetArg(0).GetExtRegRef();
|
||||||
|
size_t reg_index = Arm::RegNumber(reg);
|
||||||
|
do_set(ext_reg_doubles_info[reg_index], inst->GetArg(1), inst);
|
||||||
|
|
||||||
|
size_t singles_reg_index = reg_index * 2;
|
||||||
|
if (singles_reg_index < ext_reg_singles_info.size()) {
|
||||||
|
ext_reg_singles_info[singles_reg_index] = {};
|
||||||
|
ext_reg_singles_info[singles_reg_index+1] = {};
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case IR::Opcode::GetExtendedRegister64: {
|
||||||
|
Arm::ExtReg reg = inst->GetArg(0).GetExtRegRef();
|
||||||
|
size_t reg_index = Arm::RegNumber(reg);
|
||||||
|
do_get(ext_reg_doubles_info[reg_index], inst);
|
||||||
|
|
||||||
|
size_t singles_reg_index = reg_index * 2;
|
||||||
|
if (singles_reg_index < ext_reg_singles_info.size()) {
|
||||||
|
ext_reg_singles_info[singles_reg_index] = {};
|
||||||
|
ext_reg_singles_info[singles_reg_index+1] = {};
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case IR::Opcode::SetNFlag: {
|
case IR::Opcode::SetNFlag: {
|
||||||
do_set(n_info, inst->GetArg(0), inst);
|
do_set(n_info, inst->GetArg(0), inst);
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue