get_set_elimination_pass: Eliminate unnecessary gets/sets of extended registers

This commit is contained in:
MerryMage 2016-08-23 14:51:46 +01:00
parent e0f9dead5d
commit c8b2f63c93
2 changed files with 51 additions and 1 deletions

View file

@ -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) {

View file

@ -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;