[backend-IRC]为虚拟寄存器与物理寄存器之间添加冲突
This commit is contained in:
@@ -124,29 +124,29 @@ void RISCv64RegAlloc::precolorByCallingConvention() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- 部分2:为CALL指令的返回值预着色 ---
|
// // --- 部分2:为CALL指令的返回值预着色 ---
|
||||||
for (auto& mbb : MFunc->getBlocks()) {
|
// for (auto& mbb : MFunc->getBlocks()) {
|
||||||
for (auto& instr : mbb->getInstructions()) {
|
// for (auto& instr : mbb->getInstructions()) {
|
||||||
if (instr->getOpcode() == RVOpcodes::CALL) {
|
// if (instr->getOpcode() == RVOpcodes::CALL) {
|
||||||
if (!instr->getOperands().empty() &&
|
// if (!instr->getOperands().empty() &&
|
||||||
instr->getOperands().front()->getKind() == MachineOperand::KIND_REG)
|
// instr->getOperands().front()->getKind() == MachineOperand::KIND_REG)
|
||||||
{
|
// {
|
||||||
auto reg_op = static_cast<RegOperand*>(instr->getOperands().front().get());
|
// auto reg_op = static_cast<RegOperand*>(instr->getOperands().front().get());
|
||||||
if (reg_op->isVirtual()) {
|
// if (reg_op->isVirtual()) {
|
||||||
unsigned ret_vreg = reg_op->getVRegNum();
|
// unsigned ret_vreg = reg_op->getVRegNum();
|
||||||
assert(vreg_to_value_map.count(ret_vreg) && "Return vreg not found!");
|
// assert(vreg_to_value_map.count(ret_vreg) && "Return vreg not found!");
|
||||||
Value* ret_val = vreg_to_value_map.at(ret_vreg);
|
// Value* ret_val = vreg_to_value_map.at(ret_vreg);
|
||||||
|
|
||||||
if (ret_val->getType()->isFloat()) {
|
// if (ret_val->getType()->isFloat()) {
|
||||||
color_map[ret_vreg] = PhysicalReg::F10; // fa0
|
// color_map[ret_vreg] = PhysicalReg::F10; // fa0
|
||||||
} else {
|
// } else {
|
||||||
color_map[ret_vreg] = PhysicalReg::A0; // a0
|
// color_map[ret_vreg] = PhysicalReg::A0; // a0
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
// 将所有预着色的vreg视为已着色节点
|
// 将所有预着色的vreg视为已着色节点
|
||||||
for(const auto& pair : color_map) {
|
for(const auto& pair : color_map) {
|
||||||
@@ -375,13 +375,17 @@ void RISCv64RegAlloc::build() {
|
|||||||
|
|
||||||
// --- 规则 1 & 2: Def 与 Live/Use 变量干扰 ---
|
// --- 规则 1 & 2: Def 与 Live/Use 变量干扰 ---
|
||||||
for (unsigned d : def) {
|
for (unsigned d : def) {
|
||||||
// [关键修正] Def必须是虚拟寄存器
|
// 新逻辑:对于指令定义的所有寄存器d(无论是虚拟寄存器还是像call指令那样
|
||||||
if (precolored.count(d)) continue;
|
// 隐式定义的物理寄存器),它都与该指令之后的所有活跃寄存器l冲突。
|
||||||
|
// addEdge函数内部会正确处理 vreg-vreg 和 vreg-preg 的情况,
|
||||||
|
// 并忽略 preg-preg 的情况。
|
||||||
for (unsigned l : live) {
|
for (unsigned l : live) {
|
||||||
addEdge(d, l);
|
addEdge(d, l);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 对于非传送指令, Def还和Use冲突。
|
||||||
|
// 这个逻辑主要用于确保在同一条指令内,例如 sub t0, t1, t0,
|
||||||
|
// 作为def的t0和作为use的t0被视为冲突。
|
||||||
if (!is_move) {
|
if (!is_move) {
|
||||||
for (unsigned u_op : use) {
|
for (unsigned u_op : use) {
|
||||||
addEdge(d, u_op);
|
addEdge(d, u_op);
|
||||||
@@ -961,6 +965,13 @@ void RISCv64RegAlloc::getInstrUseDef_Liveness(const MachineInstr* instr, VRegSet
|
|||||||
// 返回地址寄存器RA也被隐式定义
|
// 返回地址寄存器RA也被隐式定义
|
||||||
def.insert(offset + static_cast<unsigned>(PhysicalReg::RA));
|
def.insert(offset + static_cast<unsigned>(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) {
|
else if (opcode == RVOpcodes::RET) {
|
||||||
// 遵循调用约定,a0(整数/指针)和fa0(浮点)被隐式使用
|
// 遵循调用约定,a0(整数/指针)和fa0(浮点)被隐式使用
|
||||||
use.insert(offset + static_cast<unsigned>(PhysicalReg::A0));
|
use.insert(offset + static_cast<unsigned>(PhysicalReg::A0));
|
||||||
|
|||||||
Reference in New Issue
Block a user