diff --git a/src/backend/RISCv64/RISCv64SimpleRegAlloc.cpp b/src/backend/RISCv64/RISCv64SimpleRegAlloc.cpp index 9608b31..7438d2a 100644 --- a/src/backend/RISCv64/RISCv64SimpleRegAlloc.cpp +++ b/src/backend/RISCv64/RISCv64SimpleRegAlloc.cpp @@ -17,7 +17,7 @@ RISCv64SimpleRegAlloc::RISCv64SimpleRegAlloc(MachineFunction* mfunc) : MFunc(mfu // T5 被大立即数传送逻辑保留 // T2, T3, T4 被本分配器保留为专用的溢出/临时寄存器 allocable_int_regs = { - PhysicalReg::T0, PhysicalReg::T1, /* T2,T3,T4,T5 reserved */ PhysicalReg::T6, + PhysicalReg::T0, PhysicalReg::T1, /* T2,T3,T4,T5,T6 reserved */ PhysicalReg::A0, PhysicalReg::A1, PhysicalReg::A2, PhysicalReg::A3, PhysicalReg::A4, PhysicalReg::A5, PhysicalReg::A6, PhysicalReg::A7, PhysicalReg::S1, PhysicalReg::S2, PhysicalReg::S3, PhysicalReg::S4, PhysicalReg::S5, PhysicalReg::S6, PhysicalReg::S7, PhysicalReg::S8, PhysicalReg::S9, PhysicalReg::S10, PhysicalReg::S11, @@ -221,27 +221,6 @@ void RISCv64SimpleRegAlloc::handleCallingConvention() { int_arg_idx++; } } - - // --- 2. 为CALL指令的返回值预着色 --- - for (auto& mbb : MFunc->getBlocks()) { - for (auto& instr : mbb->getInstructions()) { - if (instr->getOpcode() == RVOpcodes::CALL && !instr->getOperands().empty()) { - auto& first_op = instr->getOperands().front(); - if (first_op->getKind() == MachineOperand::KIND_REG) { - auto reg_op = static_cast(first_op.get()); - if (reg_op->isVirtual()) { - unsigned ret_vreg = reg_op->getVRegNum(); - auto [type, size] = getTypeAndSize(ret_vreg); - if (type == Type::kFloat) { - color_map[ret_vreg] = PhysicalReg::F10; // fa0 - } else { - color_map[ret_vreg] = PhysicalReg::A0; // a0 - } - } - } - } - } - } } void RISCv64SimpleRegAlloc::analyzeLiveness() { @@ -511,15 +490,13 @@ void RISCv64SimpleRegAlloc::rewriteFunction() { } frame_info.spill_size = -(current_offset - frame_info.locals_end_offset); - // 步骤 2: 遍历所有指令,对CALL指令和普通指令进行分别处理 + // 步骤 2: 遍历所有指令,对CALL指令做简化处理 for (auto& mbb : MFunc->getBlocks()) { std::vector> new_instructions; for (auto& instr_ptr : mbb->getInstructions()) { if (instr_ptr->getOpcode() != RVOpcodes::CALL) { - // --- 对于非CALL的普通指令,此逻辑已是正确的 --- - // (此部分代码与上一版相同,保持不变) - std::vector int_spill_pool = {PhysicalReg::T2, PhysicalReg::T3, PhysicalReg::T4, PhysicalReg::T5, PhysicalReg::T6}; + std::vector int_spill_pool = {PhysicalReg::T2, PhysicalReg::T3, PhysicalReg::T4, /*PhysicalReg::T5,*/ PhysicalReg::T6}; std::vector fp_spill_pool = {PhysicalReg::F0, PhysicalReg::F1, PhysicalReg::F2, PhysicalReg::F3}; std::map vreg_to_preg_map_for_this_instr; LiveSet use, def; @@ -600,102 +577,36 @@ void RISCv64SimpleRegAlloc::rewriteFunction() { } } } else { - // --- 对于CALL指令,使用修正后的、完全区分类型的序列化逻辑 --- + // --- 对于CALL指令,只处理其自身和返回值,不再处理参数 --- const PhysicalReg INT_TEMP_REG = PhysicalReg::T6; const PhysicalReg FP_TEMP_REG = PhysicalReg::F7; - auto& operands = instr_ptr->getOperands(); - int int_arg_idx = 0; - int fp_arg_idx = 0; - bool label_found = false; - - for (const auto& op : operands) { - if (op->getKind() == MachineOperand::KIND_LABEL) { - label_found = true; - continue; - } - if (!label_found) continue; - - unsigned vreg = static_cast(op.get())->getVRegNum(); - auto [type, size] = getTypeAndSize(vreg); - PhysicalReg source_reg; - - if (spilled_vregs.count(vreg)) { - PhysicalReg temp_reg = (type == Type::kFloat) ? FP_TEMP_REG : INT_TEMP_REG; - source_reg = temp_reg; - - // --- FIX 1: Correctly choose LW/LD/FLW based on type --- - RVOpcodes load_op = (type == Type::kFloat) ? RVOpcodes::FLW : ((type == Type::kPointer) ? RVOpcodes::LD : RVOpcodes::LW); - auto load = std::make_unique(load_op); - load->addOperand(std::make_unique(temp_reg)); - load->addOperand(std::make_unique( - std::make_unique(PhysicalReg::S0), - std::make_unique(frame_info.spill_offsets.at(vreg)) - )); - new_instructions.push_back(std::move(load)); - } else { - source_reg = color_map.at(vreg); - } - - if (type == Type::kFloat) { - if (fp_arg_idx < 8) { - auto fmv = std::make_unique(RVOpcodes::FMV_S); - fmv->addOperand(std::make_unique(static_cast(static_cast(PhysicalReg::F10) + fp_arg_idx))); - fmv->addOperand(std::make_unique(source_reg)); - new_instructions.push_back(std::move(fmv)); - } else { - auto store = std::make_unique(RVOpcodes::FSW); - store->addOperand(std::make_unique(source_reg)); - store->addOperand(std::make_unique( - std::make_unique(PhysicalReg::SP), - std::make_unique((int_arg_idx - 8) * 8 + (fp_arg_idx - 8) * 4) // Simplified offset - )); - new_instructions.push_back(std::move(store)); - } - fp_arg_idx++; - } else { - if (int_arg_idx < 8) { - auto mv = std::make_unique(RVOpcodes::MV); - mv->addOperand(std::make_unique(static_cast(static_cast(PhysicalReg::A0) + int_arg_idx))); - mv->addOperand(std::make_unique(source_reg)); - new_instructions.push_back(std::move(mv)); - } else { - // --- FIX 2: Correctly choose SW/SD based on type --- - RVOpcodes store_op = (type == Type::kPointer) ? RVOpcodes::SD : RVOpcodes::SW; - auto store = std::make_unique(store_op); - store->addOperand(std::make_unique(source_reg)); - store->addOperand(std::make_unique( - std::make_unique(PhysicalReg::SP), - std::make_unique((int_arg_idx - 8) * 8) // Simplified offset - )); - new_instructions.push_back(std::move(store)); - } - int_arg_idx++; - } - } - + // 1. 克隆CALL指令本身,只保留标签操作数 auto new_call = std::make_unique(RVOpcodes::CALL); - for(const auto& op : operands) { - if(op->getKind() == MachineOperand::KIND_LABEL) { + for (const auto& op : instr_ptr->getOperands()) { + if (op->getKind() == MachineOperand::KIND_LABEL) { new_call->addOperand(std::make_unique(*static_cast(op.get()))); - break; + // 注意:只添加第一个标签,防止ISel的错误导致多个标签 + break; } } new_instructions.push_back(std::move(new_call)); - if(operands.front()->getKind() == MachineOperand::KIND_REG) { + // 2. 只处理返回值(def)的溢出和移动 + auto& operands = instr_ptr->getOperands(); + if (!operands.empty() && operands.front()->getKind() == MachineOperand::KIND_REG) { unsigned def_vreg = static_cast(operands.front().get())->getVRegNum(); auto [type, size] = getTypeAndSize(def_vreg); - PhysicalReg result_reg = type == Type::kFloat ? PhysicalReg::F10 : PhysicalReg::A0; + PhysicalReg result_reg_abi = type == Type::kFloat ? PhysicalReg::F10 : PhysicalReg::A0; - if(spilled_vregs.count(def_vreg)) { + if (spilled_vregs.count(def_vreg)) { + // 返回值被溢出:a0/fa0 -> temp -> 溢出槽 PhysicalReg temp_reg = type == Type::kFloat ? FP_TEMP_REG : INT_TEMP_REG; - // --- FIX 3: Correctly choose SW/SD based on type for storing return value --- RVOpcodes store_op = (type == Type::kFloat) ? RVOpcodes::FSW : ((type == Type::kPointer) ? RVOpcodes::SD : RVOpcodes::SW); auto mv_from_abi = std::make_unique(type == Type::kFloat ? RVOpcodes::FMV_S : RVOpcodes::MV); mv_from_abi->addOperand(std::make_unique(temp_reg)); - mv_from_abi->addOperand(std::make_unique(result_reg)); + mv_from_abi->addOperand(std::make_unique(result_reg_abi)); new_instructions.push_back(std::move(mv_from_abi)); auto store = std::make_unique(store_op); @@ -706,9 +617,10 @@ void RISCv64SimpleRegAlloc::rewriteFunction() { )); new_instructions.push_back(std::move(store)); } else { + // 返回值未溢出:a0/fa0 -> 已着色的物理寄存器 auto mv_to_dest = std::make_unique(type == Type::kFloat ? RVOpcodes::FMV_S : RVOpcodes::MV); mv_to_dest->addOperand(std::make_unique(color_map.at(def_vreg))); - mv_to_dest->addOperand(std::make_unique(result_reg)); + mv_to_dest->addOperand(std::make_unique(result_reg_abi)); new_instructions.push_back(std::move(mv_to_dest)); } }