From 363b80973692b19b7231524378d4fa7e87ee9f7c Mon Sep 17 00:00:00 2001 From: lzkk <956449176@qq.com> Date: Tue, 26 May 2026 22:43:57 +0800 Subject: [PATCH] =?UTF-8?q?fix(mir):=20=E5=A4=A7=E6=A0=88=E5=B8=A7=20asm?= =?UTF-8?q?=20=E8=BE=93=E5=87=BA=20x13=20=E7=BC=93=E5=AD=98=E5=A4=B1?= =?UTF-8?q?=E6=95=88=20+=20=E5=8F=B6=E5=87=BD=E6=95=B0=E6=A0=88=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E5=81=8F=E7=A7=BB=E4=BF=AE=E5=A4=8D=20+=20IR=20?= =?UTF-8?q?=E6=95=B0=E7=BB=84=E5=88=9D=E5=A7=8B=E5=8C=96=E9=98=88=E5=80=BC?= =?UTF-8?q?=E9=99=8D=E4=BD=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - AsmPrinter: 大偏移量 movz/movk 路径中使用 x13 后失效帧基址缓存和 ADRP 缓存 - FrameLowering: 叶函数(仅保存 x29)栈参数偏移从 16 修正为 8 - IRGenDecl: 数组初始化阈值从 10000 降至 256,避免大数组 IR 膨胀导致后端超时 --- src/irgen/IRGenDecl.cpp | 5 +++-- src/mir/AsmPrinter.cpp | 10 ++++++---- src/mir/FrameLowering.cpp | 4 +++- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/irgen/IRGenDecl.cpp b/src/irgen/IRGenDecl.cpp index 3fa452e7..84266c4e 100644 --- a/src/irgen/IRGenDecl.cpp +++ b/src/irgen/IRGenDecl.cpp @@ -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(index)); auto* ptr = builder_.CreateGEP(slot, idx, module_.GetContext().NextTemp()); diff --git a/src/mir/AsmPrinter.cpp b/src/mir/AsmPrinter.cpp index ae06d87a..d9c089a8 100644 --- a/src/mir/AsmPrinter.cpp +++ b/src/mir/AsmPrinter.cpp @@ -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"; diff --git a/src/mir/FrameLowering.cpp b/src/mir/FrameLowering.cpp index 34422b00..efcbfd14 100644 --- a/src/mir/FrameLowering.cpp +++ b/src/mir/FrameLowering.cpp @@ -59,7 +59,9 @@ namespace mir { if (slot.is_callee_stack_arg) { - slot.offset = 16 + slot.offset; + // 叶函数仅保存 x29(8字节),非叶函数保存 x29+x30(16字节) + // 栈参数偏移需根据实际情况调整 + slot.offset = (function.HasCall() ? 16 : 8) + slot.offset; } } }