perf(mir): MIR 清扫——%2指令精简 + 算术select死代码消除

- %2快速路径:and+cmp+csneg ge(3指令)替代 negs+and+and+csneg mi(4指令)
- 穿透Inline中 icmp ne(zext(cmp),0) 冗余链,消除算术select的mov+cmp+cset冗余
- Madd折叠前移:Mul唯一用户是Add时跳过,由Add的Madd统一处理
- Div/Mod/And/Or常量提前处理,避免emit不消费的死MovImm

门禁:functional 99/100(95_float预存失败),h_functional 40/40
lzk
lzkk 2 days ago
parent f9bea1bf85
commit b3187edbbf

@ -192,6 +192,40 @@ static bool TryConvertIfElseToSelect(Function* func, Context& ctx) {
Value* cmp_val = br->GetCond();
// 穿透冗余链 icmp ne (zext(X), 0) → X
// IR 生成器将 condbr 条件包裹为 icmp ne (zext(原始比较), 0),消除它
if (auto* outer_cmp = dynamic_cast<BinaryInst*>(cmp_val))
{
if (outer_cmp->GetOpcode() == Opcode::Ne)
{
auto* rhs_c = dynamic_cast<ConstantInt*>(outer_cmp->GetRhs());
if (rhs_c && rhs_c->GetValue() == 0)
{
if (auto* zext = dynamic_cast<CastInst*>(outer_cmp->GetLhs()))
{
if (zext->GetOpcode() == Opcode::ZExt)
cmp_val = zext->GetOperandValue();
}
}
}
}
// 二次穿透(部分 IR 结构有两层包裹)
if (auto* outer_cmp = dynamic_cast<BinaryInst*>(cmp_val))
{
if (outer_cmp->GetOpcode() == Opcode::Ne)
{
auto* rhs_c = dynamic_cast<ConstantInt*>(outer_cmp->GetRhs());
if (rhs_c && rhs_c->GetValue() == 0)
{
if (auto* zext = dynamic_cast<CastInst*>(outer_cmp->GetLhs()))
{
if (zext->GetOpcode() == Opcode::ZExt)
cmp_val = zext->GetOperandValue();
}
}
}
}
// 移除 CondBr
entry->TakeInstruction(br);

@ -659,6 +659,69 @@ namespace mir
}
}
// Div/Mod/And/Or 常量提前处理——避免先 emit rhs 再发现不需要的死 MovImm
if (opcode == Opcode::DivRR || opcode == Opcode::ModRR ||
opcode == Opcode::AndRR || opcode == Opcode::OrRR)
{
if (auto *rhs_const = dynamic_cast<const ir::ConstantInt *>(bin->GetRhs()))
{
int val = rhs_const->GetValue();
// 提前处理 Div/Mod 的 1/-1 和 %2 情况,不 emit rhs
if (opcode == Opcode::DivRR && val == 1)
{
value_vregs[value] = lhs;
return lhs;
}
if (opcode == Opcode::DivRR && val == -1)
{
block.Append(Opcode::NegRR,
{Operand::VReg(dst, VRegClass::Int),
Operand::VReg(lhs, VRegClass::Int)});
value_vregs[value] = dst;
return dst;
}
// Mod by 2含正负and+cmp+csneg不 emit rhs
if (opcode == Opcode::ModRR && (val == 2 || val == -2))
{
int pos = function.CreateVReg(VRegClass::Int);
block.Append(Opcode::AndRR,
{Operand::VReg(pos, VRegClass::Int),
Operand::VReg(lhs, VRegClass::Int),
Operand::Imm(1)});
block.Append(Opcode::CmpImm,
{Operand::VReg(lhs, VRegClass::Int),
Operand::Imm(0)});
block.Append(Opcode::Csneg,
{Operand::VReg(dst, VRegClass::Int),
Operand::VReg(pos, VRegClass::Int),
Operand::VReg(pos, VRegClass::Int),
Operand::Imm(static_cast<int>(CondCode::GE))});
value_vregs[value] = dst;
return dst;
}
// And with constant → 直接嵌入立即数,不 emit rhs
if (opcode == Opcode::AndRR && val >= 0 && static_cast<unsigned int>(val) <= 4095)
{
block.Append(Opcode::AndRR,
{Operand::VReg(dst, VRegClass::Int),
Operand::VReg(lhs, VRegClass::Int),
Operand::Imm(val)});
value_vregs[value] = dst;
return dst;
}
// Or with constant → 直接嵌入立即数,不 emit rhs
if (opcode == Opcode::OrRR && val >= 0 && static_cast<unsigned int>(val) <= 4095)
{
block.Append(Opcode::OrRR,
{Operand::VReg(dst, VRegClass::Int),
Operand::VReg(lhs, VRegClass::Int),
Operand::Imm(val)});
value_vregs[value] = dst;
return dst;
}
}
}
int rhs = EmitIntValue(bin->GetRhs(), function, value_vregs,
scalar_slots, array_slots, block);
@ -806,8 +869,30 @@ namespace mir
int val = rhs_const->GetValue();
if (val > 0 && (val & (val - 1)) == 0)
{
// x % 2^n -> negs+and+and+csneg4 指令,含零值正确语义)
int mask = val - 1;
// x % 2 快速路径and+cmp+csneg ge3 指令)
// bit 0 在取反下不变,无需第二个 and
if (mask == 1)
{
int pos = function.CreateVReg(VRegClass::Int);
block.Append(Opcode::AndRR,
{Operand::VReg(pos, VRegClass::Int),
Operand::VReg(lhs, VRegClass::Int),
Operand::Imm(1)});
block.Append(Opcode::CmpImm,
{Operand::VReg(lhs, VRegClass::Int),
Operand::Imm(0)});
block.Append(Opcode::Csneg,
{Operand::VReg(dst, VRegClass::Int),
Operand::VReg(pos, VRegClass::Int),
Operand::VReg(pos, VRegClass::Int),
Operand::Imm(static_cast<int>(CondCode::GE))});
value_vregs[value] = dst;
return dst;
}
// x % 2^n (n>1) -> negs+and+and+csneg4 指令,含零值正确语义)
int neg = function.CreateVReg(VRegClass::Int);
int pos = function.CreateVReg(VRegClass::Int);
int neg_masked = function.CreateVReg(VRegClass::Int);
@ -847,8 +932,29 @@ namespace mir
}
if (val < 0 && (-val & (-val - 1)) == 0 && val != -1)
{
// x % -2^n -> 同 x % 2^nnegs+and+and+csneg
int mask = (-val) - 1;
// x % -2 快速路径and+cmp+csneg ge3 指令)
if (mask == 1)
{
int pos = function.CreateVReg(VRegClass::Int);
block.Append(Opcode::AndRR,
{Operand::VReg(pos, VRegClass::Int),
Operand::VReg(lhs, VRegClass::Int),
Operand::Imm(1)});
block.Append(Opcode::CmpImm,
{Operand::VReg(lhs, VRegClass::Int),
Operand::Imm(0)});
block.Append(Opcode::Csneg,
{Operand::VReg(dst, VRegClass::Int),
Operand::VReg(pos, VRegClass::Int),
Operand::VReg(pos, VRegClass::Int),
Operand::Imm(static_cast<int>(CondCode::GE))});
value_vregs[value] = dst;
return dst;
}
// x % -2^n (n>1) -> 同 x % 2^nnegs+and+and+csneg
int neg = function.CreateVReg(VRegClass::Int);
int pos = function.CreateVReg(VRegClass::Int);
int neg_masked = function.CreateVReg(VRegClass::Int);
@ -1839,9 +1945,27 @@ namespace mir
case ir::Opcode::GEP:
return;
case ir::Opcode::Mul:
{
auto &bin = static_cast<const ir::BinaryInst &>(inst);
if (IsFloatType(bin.GetType()))
{
EmitFloatValue(&bin, function, value_vregs, block);
return;
}
// 若 Mul 的唯一用户是 Add推迟到 Add 的 Madd 折叠处理
if (bin.GetUses().size() == 1)
{
auto *user = dynamic_cast<const ir::BinaryInst *>(bin.GetUses().begin()->GetUser());
if (user && user->GetOpcode() == ir::Opcode::Add)
return;
}
EmitIntValue(&bin, function, value_vregs, scalar_slots, array_slots, block);
return;
}
case ir::Opcode::Add:
case ir::Opcode::Sub:
case ir::Opcode::Mul:
case ir::Opcode::Div:
case ir::Opcode::Mod:
case ir::Opcode::And:

Loading…
Cancel
Save