perf(mir): 扩展缩放寻址到 EmitStatement Load 路径(ptr/float/int)

h-8 -58(-14.6%), sort -66(-10.7%), h-5 -35(-10.9%), crypto -43, shuffle -37
24 基线更新,此轮优化累计巨大收益。
lzk
lzkk 3 days ago
parent be3a5640ee
commit f65fe9fc20

@ -1390,28 +1390,73 @@ namespace mir
}
}
int addr = EmitPtrValue(load.GetPtr(), function, value_vregs,
scalar_slots, array_slots, block);
if (is_ptr)
{
int vreg = function.CreateVReg(VRegClass::Ptr);
block.Append(Opcode::LoadMem,
{Operand::VReg(vreg, VRegClass::Ptr), Operand::VReg(addr, VRegClass::Ptr)});
value_vregs[&load] = vreg;
}
else if (is_float)
// 缩放寻址GEP + Load → ldr [base, idx, uxtw #2]
bool scaled_load = false;
if (auto *gep = dynamic_cast<const ir::GetElementPtrInst *>(load.GetPtr()))
{
int vreg = function.CreateVReg(VRegClass::Float);
block.Append(Opcode::LoadMem,
{Operand::VReg(vreg, VRegClass::Float), Operand::VReg(addr, VRegClass::Ptr)});
value_vregs[&load] = vreg;
int idx_imm = 0;
if (!TryGetConstantInt(gep->GetIndex(), idx_imm))
{
scaled_load = true;
int base_addr = EmitPtrValue(gep->GetBasePtr(), function, value_vregs,
scalar_slots, array_slots, block);
int idx_vreg = EmitIntValue(gep->GetIndex(), function, value_vregs,
scalar_slots, array_slots, block);
if (is_ptr)
{
int vreg = function.CreateVReg(VRegClass::Ptr);
block.Append(Opcode::LoadMem,
{Operand::VReg(vreg, VRegClass::Ptr),
Operand::VReg(base_addr, VRegClass::Ptr),
Operand::VReg(idx_vreg, VRegClass::Int)});
value_vregs[&load] = vreg;
}
else if (is_float)
{
int vreg = function.CreateVReg(VRegClass::Float);
block.Append(Opcode::LoadMem,
{Operand::VReg(vreg, VRegClass::Float),
Operand::VReg(base_addr, VRegClass::Ptr),
Operand::VReg(idx_vreg, VRegClass::Int)});
value_vregs[&load] = vreg;
}
else
{
int vreg = function.CreateVReg(VRegClass::Int);
block.Append(Opcode::LoadMem,
{Operand::VReg(vreg, VRegClass::Int),
Operand::VReg(base_addr, VRegClass::Ptr),
Operand::VReg(idx_vreg, VRegClass::Int)});
value_vregs[&load] = vreg;
}
}
}
else
if (!scaled_load)
{
int vreg = function.CreateVReg(VRegClass::Int);
block.Append(Opcode::LoadMem,
{Operand::VReg(vreg, VRegClass::Int), Operand::VReg(addr, VRegClass::Ptr)});
value_vregs[&load] = vreg;
int addr = EmitPtrValue(load.GetPtr(), function, value_vregs,
scalar_slots, array_slots, block);
if (is_ptr)
{
int vreg = function.CreateVReg(VRegClass::Ptr);
block.Append(Opcode::LoadMem,
{Operand::VReg(vreg, VRegClass::Ptr), Operand::VReg(addr, VRegClass::Ptr)});
value_vregs[&load] = vreg;
}
else if (is_float)
{
int vreg = function.CreateVReg(VRegClass::Float);
block.Append(Opcode::LoadMem,
{Operand::VReg(vreg, VRegClass::Float), Operand::VReg(addr, VRegClass::Ptr)});
value_vregs[&load] = vreg;
}
else
{
int vreg = function.CreateVReg(VRegClass::Int);
block.Append(Opcode::LoadMem,
{Operand::VReg(vreg, VRegClass::Int), Operand::VReg(addr, VRegClass::Ptr)});
value_vregs[&load] = vreg;
}
}
return;
}

Loading…
Cancel
Save