better opt
This commit is contained in:
parent
448e6343e7
commit
f6fcadcabe
|
|
@ -511,8 +511,8 @@ static void A64GetSetElimination(IR::Block& block) {
|
|||
struct RegisterInfo {
|
||||
IR::Value register_value;
|
||||
TrackingType tracking_type;
|
||||
bool set_instruction_present = false;
|
||||
Iterator last_set_instruction;
|
||||
bool set_instruction_present = false;
|
||||
};
|
||||
std::array<RegisterInfo, 31> reg_info;
|
||||
std::array<RegisterInfo, 32> vec_info;
|
||||
|
|
@ -524,26 +524,25 @@ static void A64GetSetElimination(IR::Block& block) {
|
|||
info.last_set_instruction->Invalidate();
|
||||
block.Instructions().erase(info.last_set_instruction);
|
||||
}
|
||||
|
||||
info.register_value = value;
|
||||
info.tracking_type = tracking_type;
|
||||
info.set_instruction_present = true;
|
||||
info.last_set_instruction = set_inst;
|
||||
};
|
||||
const auto do_get = [](RegisterInfo& info, Iterator get_inst, TrackingType tracking_type) {
|
||||
// A sequence like
|
||||
// SetX r1 -> GetW r1, is just reading off the lowest 32-bits of the register
|
||||
auto const is_lower_32 = tracking_type == TrackingType::W
|
||||
&& info.tracking_type == TrackingType::X;
|
||||
const auto do_get = [&block](RegisterInfo& info, Iterator get_inst, TrackingType tracking_type) {
|
||||
if (!info.register_value.IsEmpty() && info.tracking_type == tracking_type) {
|
||||
get_inst->ReplaceUsesWith(info.register_value);
|
||||
} else if (!info.register_value.IsEmpty() && is_lower_32) {
|
||||
} else if (!info.register_value.IsEmpty()
|
||||
&& tracking_type == TrackingType::W
|
||||
&& info.tracking_type == TrackingType::X) {
|
||||
// A sequence like
|
||||
// SetX r1 -> GetW r1, is just reading off the lowest 32-bits of the register
|
||||
if (info.register_value.IsImmediate()) {
|
||||
ReplaceUsesWith(*get_inst, true, u32(info.register_value.GetImmediateAsU64() & 0xffff'ffff));
|
||||
ReplaceUsesWith(*get_inst, true, u32(info.register_value.GetImmediateAsU64()));
|
||||
} else {
|
||||
info = {};
|
||||
info.register_value = IR::Value(&*get_inst);
|
||||
info.tracking_type = tracking_type;
|
||||
A64::IREmitter ir{block};
|
||||
ir.SetInsertionPointBefore(&*get_inst);
|
||||
get_inst->ReplaceUsesWith(ir.LeastSignificantWord(IR::U64{info.register_value}));
|
||||
}
|
||||
} else {
|
||||
info = {};
|
||||
|
|
@ -556,27 +555,27 @@ static void A64GetSetElimination(IR::Block& block) {
|
|||
switch (opcode) {
|
||||
case IR::Opcode::A64GetW: {
|
||||
const size_t index = A64::RegNumber(inst->GetArg(0).GetA64RegRef());
|
||||
do_get(reg_info.at(index), inst, TrackingType::W);
|
||||
do_get(reg_info[index], inst, TrackingType::W);
|
||||
break;
|
||||
}
|
||||
case IR::Opcode::A64GetX: {
|
||||
const size_t index = A64::RegNumber(inst->GetArg(0).GetA64RegRef());
|
||||
do_get(reg_info.at(index), inst, TrackingType::X);
|
||||
do_get(reg_info[index], inst, TrackingType::X);
|
||||
break;
|
||||
}
|
||||
case IR::Opcode::A64GetS: {
|
||||
const size_t index = A64::VecNumber(inst->GetArg(0).GetA64VecRef());
|
||||
do_get(vec_info.at(index), inst, TrackingType::S);
|
||||
do_get(vec_info[index], inst, TrackingType::S);
|
||||
break;
|
||||
}
|
||||
case IR::Opcode::A64GetD: {
|
||||
const size_t index = A64::VecNumber(inst->GetArg(0).GetA64VecRef());
|
||||
do_get(vec_info.at(index), inst, TrackingType::D);
|
||||
do_get(vec_info[index], inst, TrackingType::D);
|
||||
break;
|
||||
}
|
||||
case IR::Opcode::A64GetQ: {
|
||||
const size_t index = A64::VecNumber(inst->GetArg(0).GetA64VecRef());
|
||||
do_get(vec_info.at(index), inst, TrackingType::Q);
|
||||
do_get(vec_info[index], inst, TrackingType::Q);
|
||||
break;
|
||||
}
|
||||
case IR::Opcode::A64GetSP: {
|
||||
|
|
@ -589,27 +588,27 @@ static void A64GetSetElimination(IR::Block& block) {
|
|||
}
|
||||
case IR::Opcode::A64SetW: {
|
||||
const size_t index = A64::RegNumber(inst->GetArg(0).GetA64RegRef());
|
||||
do_set(reg_info.at(index), inst->GetArg(1), inst, TrackingType::W);
|
||||
do_set(reg_info[index], inst->GetArg(1), inst, TrackingType::W);
|
||||
break;
|
||||
}
|
||||
case IR::Opcode::A64SetX: {
|
||||
const size_t index = A64::RegNumber(inst->GetArg(0).GetA64RegRef());
|
||||
do_set(reg_info.at(index), inst->GetArg(1), inst, TrackingType::X);
|
||||
do_set(reg_info[index], inst->GetArg(1), inst, TrackingType::X);
|
||||
break;
|
||||
}
|
||||
case IR::Opcode::A64SetS: {
|
||||
const size_t index = A64::VecNumber(inst->GetArg(0).GetA64VecRef());
|
||||
do_set(vec_info.at(index), inst->GetArg(1), inst, TrackingType::S);
|
||||
do_set(vec_info[index], inst->GetArg(1), inst, TrackingType::S);
|
||||
break;
|
||||
}
|
||||
case IR::Opcode::A64SetD: {
|
||||
const size_t index = A64::VecNumber(inst->GetArg(0).GetA64VecRef());
|
||||
do_set(vec_info.at(index), inst->GetArg(1), inst, TrackingType::D);
|
||||
do_set(vec_info[index], inst->GetArg(1), inst, TrackingType::D);
|
||||
break;
|
||||
}
|
||||
case IR::Opcode::A64SetQ: {
|
||||
const size_t index = A64::VecNumber(inst->GetArg(0).GetA64VecRef());
|
||||
do_set(vec_info.at(index), inst->GetArg(1), inst, TrackingType::Q);
|
||||
do_set(vec_info[index], inst->GetArg(1), inst, TrackingType::Q);
|
||||
break;
|
||||
}
|
||||
case IR::Opcode::A64SetSP: {
|
||||
|
|
|
|||
Loading…
Reference in New Issue