From 57fe17dc21f42e2f85406805b7208f207952b167 Mon Sep 17 00:00:00 2001 From: Lixuanwang Date: Fri, 1 Aug 2025 21:20:04 +0800 Subject: [PATCH] =?UTF-8?q?[backend-IRC]=E4=B8=BA=E8=99=9A=E6=8B=9F?= =?UTF-8?q?=E5=AF=84=E5=AD=98=E5=99=A8=E4=B8=8E=E7=89=A9=E7=90=86=E5=AF=84?= =?UTF-8?q?=E5=AD=98=E5=99=A8=E4=B9=8B=E9=97=B4=E6=B7=BB=E5=8A=A0=E5=86=B2?= =?UTF-8?q?=E7=AA=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/RISCv64/RISCv64RegAlloc.cpp | 61 +++++++++++++++---------- 1 file changed, 36 insertions(+), 25 deletions(-) diff --git a/src/backend/RISCv64/RISCv64RegAlloc.cpp b/src/backend/RISCv64/RISCv64RegAlloc.cpp index 5216594..3eed7dd 100644 --- a/src/backend/RISCv64/RISCv64RegAlloc.cpp +++ b/src/backend/RISCv64/RISCv64RegAlloc.cpp @@ -124,29 +124,29 @@ void RISCv64RegAlloc::precolorByCallingConvention() { } } - // --- 部分2:为CALL指令的返回值预着色 --- - for (auto& mbb : MFunc->getBlocks()) { - for (auto& instr : mbb->getInstructions()) { - if (instr->getOpcode() == RVOpcodes::CALL) { - if (!instr->getOperands().empty() && - instr->getOperands().front()->getKind() == MachineOperand::KIND_REG) - { - auto reg_op = static_cast(instr->getOperands().front().get()); - if (reg_op->isVirtual()) { - unsigned ret_vreg = reg_op->getVRegNum(); - assert(vreg_to_value_map.count(ret_vreg) && "Return vreg not found!"); - Value* ret_val = vreg_to_value_map.at(ret_vreg); + // // --- 部分2:为CALL指令的返回值预着色 --- + // for (auto& mbb : MFunc->getBlocks()) { + // for (auto& instr : mbb->getInstructions()) { + // if (instr->getOpcode() == RVOpcodes::CALL) { + // if (!instr->getOperands().empty() && + // instr->getOperands().front()->getKind() == MachineOperand::KIND_REG) + // { + // auto reg_op = static_cast(instr->getOperands().front().get()); + // if (reg_op->isVirtual()) { + // unsigned ret_vreg = reg_op->getVRegNum(); + // assert(vreg_to_value_map.count(ret_vreg) && "Return vreg not found!"); + // Value* ret_val = vreg_to_value_map.at(ret_vreg); - if (ret_val->getType()->isFloat()) { - color_map[ret_vreg] = PhysicalReg::F10; // fa0 - } else { - color_map[ret_vreg] = PhysicalReg::A0; // a0 - } - } - } - } - } - } + // if (ret_val->getType()->isFloat()) { + // color_map[ret_vreg] = PhysicalReg::F10; // fa0 + // } else { + // color_map[ret_vreg] = PhysicalReg::A0; // a0 + // } + // } + // } + // } + // } + // } // 将所有预着色的vreg视为已着色节点 for(const auto& pair : color_map) { @@ -375,13 +375,17 @@ void RISCv64RegAlloc::build() { // --- 规则 1 & 2: Def 与 Live/Use 变量干扰 --- for (unsigned d : def) { - // [关键修正] Def必须是虚拟寄存器 - if (precolored.count(d)) continue; - + // 新逻辑:对于指令定义的所有寄存器d(无论是虚拟寄存器还是像call指令那样 + // 隐式定义的物理寄存器),它都与该指令之后的所有活跃寄存器l冲突。 + // addEdge函数内部会正确处理 vreg-vreg 和 vreg-preg 的情况, + // 并忽略 preg-preg 的情况。 for (unsigned l : live) { addEdge(d, l); } + // 对于非传送指令, Def还和Use冲突。 + // 这个逻辑主要用于确保在同一条指令内,例如 sub t0, t1, t0, + // 作为def的t0和作为use的t0被视为冲突。 if (!is_move) { for (unsigned u_op : use) { addEdge(d, u_op); @@ -961,6 +965,13 @@ void RISCv64RegAlloc::getInstrUseDef_Liveness(const MachineInstr* instr, VRegSet // 返回地址寄存器RA也被隐式定义 def.insert(offset + static_cast(PhysicalReg::RA)); } + else if (opcode == RVOpcodes::JALR) { + // JALR rd, rs1, imm. Def: rd, Use: rs1. + // 同时也隐式定义了ra(x1),但通常rd就是ra。为精确,我们只处理显式操作数。 + // 旧版本逻辑:def.insert(ra); first_reg_is_def = false; -> 这是不精确的 + def.insert(get_any_reg_id(operands[0].get())); + use.insert(get_any_reg_id(operands[1].get())); + } else if (opcode == RVOpcodes::RET) { // 遵循调用约定,a0(整数/指针)和fa0(浮点)被隐式使用 use.insert(offset + static_cast(PhysicalReg::A0));