fix(mir): 大栈帧 asm 输出 x13 缓存失效 + 叶函数栈参数偏移修复 + IR 数组初始化阈值降低

- AsmPrinter: 大偏移量 movz/movk 路径中使用 x13 后失效帧基址缓存和 ADRP 缓存
- FrameLowering: 叶函数(仅保存 x29)栈参数偏移从 16 修正为 8
- IRGenDecl: 数组初始化阈值从 10000 降至 256,避免大数组 IR 膨胀导致后端超时
lzk
lzkk 7 days ago
parent 120d7197d8
commit 363b809736

@ -661,8 +661,9 @@ std::any IRGenImpl::visitVarDef(SysYParser::VarDefContext* ctx) {
throw std::runtime_error(FormatError("irgen", "数组初始化元素过多"));
}
// 对于小数组(<=10000元素直接生成完整初始化
if (total_extent <= 10000) {
// 对于小数组(<=256元素直接生成完整初始化
// 超过 256 元素用循环零初始化 + 非零元素单独赋值,避免 IR 膨胀导致后端超时
if (total_extent <= 256) {
for (size_t index = 0; index < total_extent; ++index) {
auto* idx = builder_.CreateConstInt(static_cast<int>(index));
auto* ptr = builder_.CreateGEP(slot, idx, module_.GetContext().NextTemp());

@ -314,8 +314,9 @@ namespace mir
if (offset > 12285)
{
if (target_xreg != PrinterScratchXReg())
InvalidateAdrpCache();
// 使用 x13 作为立即数暂存,必须失效帧基址和 ADRP 缓存
InvalidateAdrpCache();
InvalidateFrameBase();
os << " movz x13, #" << (offset & 0xFFFF) << "\n";
if ((offset >> 16) != 0)
os << " movk x13, #" << ((offset >> 16) & 0xFFFF) << ", lsl #16\n";
@ -326,8 +327,9 @@ namespace mir
if (offset < -12285)
{
int abs_off = -offset;
if (target_xreg != PrinterScratchXReg())
InvalidateAdrpCache();
// 使用 x13 作为立即数暂存,必须失效帧基址和 ADRP 缓存
InvalidateAdrpCache();
InvalidateFrameBase();
os << " movz x13, #" << (abs_off & 0xFFFF) << "\n";
if ((abs_off >> 16) != 0)
os << " movk x13, #" << ((abs_off >> 16) & 0xFFFF) << ", lsl #16\n";

@ -59,7 +59,9 @@ namespace mir
{
if (slot.is_callee_stack_arg)
{
slot.offset = 16 + slot.offset;
// 叶函数仅保存 x298字节非叶函数保存 x29+x3016字节
// 栈参数偏移需根据实际情况调整
slot.offset = (function.HasCall() ? 16 : 8) + slot.offset;
}
}
}

Loading…
Cancel
Save