[backend]修复了一个栈管理问题
This commit is contained in:
@@ -165,10 +165,6 @@ void RISCv64RegAlloc::handleCallingConvention() {
|
||||
*/
|
||||
void RISCv64RegAlloc::eliminateFrameIndices() {
|
||||
StackFrameInfo& frame_info = MFunc->getFrameInfo();
|
||||
// 初始偏移量,为保存ra和s0留出空间。
|
||||
// 假设序言是 addi sp, sp, -stack_size; sd ra, stack_size-8(sp); sd s0, stack_size-16(sp);
|
||||
int current_offset = 16;
|
||||
|
||||
Function* F = MFunc->getFunc();
|
||||
RISCv64ISel* isel = MFunc->getISel();
|
||||
|
||||
@@ -190,12 +186,15 @@ void RISCv64RegAlloc::eliminateFrameIndices() {
|
||||
}
|
||||
}
|
||||
|
||||
// 处理局部变量
|
||||
// 遍历AllocaInst来计算局部变量所需的总空间
|
||||
// [关键修改] 为局部变量分配空间时,起始点必须考虑为ra, s0以及所有callee-saved寄存器预留的空间。
|
||||
// 布局顺序为: [s0/ra, 16字节] -> [callee-saved, callee_saved_size字节] -> [局部变量...]
|
||||
int local_var_offset = 16 + frame_info.callee_saved_size;
|
||||
int locals_start_offset = local_var_offset; // 记录局部变量区域的起始点,用于计算总大小
|
||||
|
||||
// 处理局部变量 (AllocaInst)
|
||||
for (auto& bb : F->getBasicBlocks()) {
|
||||
for (auto& inst : bb->getInstructions()) {
|
||||
if (auto alloca = dynamic_cast<AllocaInst*>(inst.get())) {
|
||||
// 获取Alloca指令指向的类型 (例如 alloca i32* 中,获取 i32)
|
||||
Type* allocated_type = alloca->getType()->as<PointerType>()->getBaseType();
|
||||
int size = getTypeSizeInBytes(allocated_type);
|
||||
|
||||
@@ -203,14 +202,17 @@ void RISCv64RegAlloc::eliminateFrameIndices() {
|
||||
size = (size + 7) & ~7;
|
||||
if (size == 0) size = 8; // 至少分配8字节
|
||||
|
||||
current_offset += size;
|
||||
local_var_offset += size;
|
||||
unsigned alloca_vreg = isel->getVReg(alloca);
|
||||
// 局部变量使用相对于s0的负向偏移
|
||||
frame_info.alloca_offsets[alloca_vreg] = -current_offset;
|
||||
frame_info.alloca_offsets[alloca_vreg] = -local_var_offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
frame_info.locals_size = current_offset;
|
||||
|
||||
// [修复] 正确计算并设置locals_size
|
||||
// 它只应该包含由AllocaInst分配的局部变量的总大小。
|
||||
frame_info.locals_size = local_var_offset - locals_start_offset;
|
||||
|
||||
// 遍历所有机器指令,将伪指令展开为真实指令
|
||||
for (auto& mbb : MFunc->getBlocks()) {
|
||||
|
||||
Reference in New Issue
Block a user