[backend-O1]修复后端在-O1情况下存在的大量bug
This commit is contained in:
@@ -103,6 +103,60 @@ void RISCv64ISel::select() {
|
||||
}
|
||||
}
|
||||
|
||||
if (optLevel > 0) {
|
||||
if (F && !F->getBasicBlocks().empty()) {
|
||||
// 定位到第一个MachineBasicBlock,也就是函数入口
|
||||
BasicBlock* first_ir_block = F->getBasicBlocks_NoRange().front().get();
|
||||
CurMBB = bb_map.at(first_ir_block);
|
||||
|
||||
int int_arg_idx = 0;
|
||||
int fp_arg_idx = 0;
|
||||
|
||||
for (Argument* arg : F->getArguments()) {
|
||||
Type* arg_type = arg->getType();
|
||||
|
||||
// --- 处理整数/指针参数 ---
|
||||
if (!arg_type->isFloat() && int_arg_idx < 8) {
|
||||
// 1. 获取参数原始的、将被预着色为 a0-a7 的 vreg
|
||||
unsigned original_vreg = getVReg(arg);
|
||||
|
||||
// 2. 创建一个新的、安全的 vreg 来持有参数的值
|
||||
unsigned saved_vreg = getNewVReg(arg_type);
|
||||
|
||||
// 3. 生成 mv saved_vreg, original_vreg 指令
|
||||
auto mv = std::make_unique<MachineInstr>(RVOpcodes::MV);
|
||||
mv->addOperand(std::make_unique<RegOperand>(saved_vreg));
|
||||
mv->addOperand(std::make_unique<RegOperand>(original_vreg));
|
||||
CurMBB->addInstruction(std::move(mv));
|
||||
|
||||
// 4.【关键】更新vreg映射表,将arg的vreg指向新的、安全的vreg
|
||||
// 这样,后续所有对该参数的 getVReg(arg) 调用都会自动获得 saved_vreg,
|
||||
// 使得函数体内的代码都使用这个被保存过的值。
|
||||
vreg_map[arg] = saved_vreg;
|
||||
|
||||
int_arg_idx++;
|
||||
}
|
||||
// --- 处理浮点参数 ---
|
||||
else if (arg_type->isFloat() && fp_arg_idx < 8) {
|
||||
unsigned original_vreg = getVReg(arg);
|
||||
unsigned saved_vreg = getNewVReg(arg_type);
|
||||
|
||||
// 对于浮点数,使用 fmv.s 指令
|
||||
auto fmv = std::make_unique<MachineInstr>(RVOpcodes::FMV_S);
|
||||
fmv->addOperand(std::make_unique<RegOperand>(saved_vreg));
|
||||
fmv->addOperand(std::make_unique<RegOperand>(original_vreg));
|
||||
CurMBB->addInstruction(std::move(fmv));
|
||||
|
||||
// 同样更新映射
|
||||
vreg_map[arg] = saved_vreg;
|
||||
|
||||
fp_arg_idx++;
|
||||
}
|
||||
// 对于栈传递的参数,则无需处理
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 遍历基本块,进行指令选择
|
||||
for (const auto& bb_ptr : F->getBasicBlocks()) {
|
||||
selectBasicBlock(bb_ptr.get());
|
||||
|
||||
Reference in New Issue
Block a user