From c8b2f63c934c3bdb4c38704610b4def51e9d65ed Mon Sep 17 00:00:00 2001 From: MerryMage Date: Tue, 23 Aug 2016 14:51:46 +0100 Subject: [PATCH] get_set_elimination_pass: Eliminate unnecessary gets/sets of extended registers --- src/backend_x64/reg_alloc.cpp | 4 ++- src/ir_opt/get_set_elimination_pass.cpp | 48 +++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/src/backend_x64/reg_alloc.cpp b/src/backend_x64/reg_alloc.cpp index 583cf174..82e32446 100644 --- a/src/backend_x64/reg_alloc.cpp +++ b/src/backend_x64/reg_alloc.cpp @@ -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 def_reg = DefRegister(def_inst, desired_locations); if (is_floating_point) { diff --git a/src/ir_opt/get_set_elimination_pass.cpp b/src/ir_opt/get_set_elimination_pass.cpp index 8db394a8..324da8ec 100644 --- a/src/ir_opt/get_set_elimination_pass.cpp +++ b/src/ir_opt/get_set_elimination_pass.cpp @@ -23,6 +23,8 @@ void GetSetElimination(IR::Block& block) { Iterator last_set_instruction; }; std::array reg_info; + std::array ext_reg_singles_info; + std::array ext_reg_doubles_info; RegisterInfo n_info; RegisterInfo z_info; RegisterInfo c_info; @@ -64,6 +66,52 @@ void GetSetElimination(IR::Block& block) { do_get(reg_info[reg_index], inst); 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: { do_set(n_info, inst->GetArg(0), inst); break;