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; } } }