[backend-IRC]基本构建了IRC

This commit is contained in:
Lixuanwang
2025-08-01 04:44:13 +08:00
parent f387aecc03
commit 873dbf64d0
2 changed files with 186 additions and 81 deletions

View File

@@ -121,6 +121,8 @@ std::string RISCv64CodeGen::function_gen(Function* func) {
// if (DEBUG) { // if (DEBUG) {
// std::cout << ss_after_isel.str(); // std::cout << ss_after_isel.str();
// } // }
// DEBUG = 0;
// DEEPDEBUG = 0;
// DEBUG = 1; // DEBUG = 1;
// DEEPDEBUG = 1; // DEEPDEBUG = 1;
if (DEBUG) { if (DEBUG) {
@@ -143,8 +145,8 @@ std::string RISCv64CodeGen::function_gen(Function* func) {
// PreRA_Scheduler scheduler; // PreRA_Scheduler scheduler;
// scheduler.runOnMachineFunction(mfunc.get()); // scheduler.runOnMachineFunction(mfunc.get());
DEBUG = 0; // DEBUG = 0;
DEEPDEBUG = 0; // DEEPDEBUG = 0;
// 阶段 3: 物理寄存器分配 (Register Allocation) // 阶段 3: 物理寄存器分配 (Register Allocation)
RISCv64RegAlloc reg_alloc(mfunc.get()); RISCv64RegAlloc reg_alloc(mfunc.get());
reg_alloc.run(); reg_alloc.run();

View File

@@ -255,20 +255,20 @@ void RISCv64RegAlloc::build() {
RISCv64AsmPrinter printer_inside_build(MFunc); RISCv64AsmPrinter printer_inside_build(MFunc);
printer_inside_build.setStream(std::cerr); printer_inside_build.setStream(std::cerr);
// 1. 收集所有待分配的(既非物理也非预着色)虚拟寄存器到 initial 集合
for (const auto& mbb_ptr : MFunc->getBlocks()) { for (const auto& mbb_ptr : MFunc->getBlocks()) {
for (const auto& instr_ptr : mbb_ptr->getInstructions()) { for (const auto& instr_ptr : mbb_ptr->getInstructions()) {
const MachineInstr* instr = instr_ptr.get(); const MachineInstr* instr = instr_ptr.get();
VRegSet use, def; VRegSet use, def;
getInstrUseDef_Liveness(instr, use, def); getInstrUseDef_Liveness(instr, use, def);
// 调试输出 use 和 def // 调试输出 use 和 def (保留您的调试逻辑)
if (DEEPDEBUG) { if (DEEPDEBUG) {
std::cerr << "Instr:"; std::cerr << "Instr:";
printer_inside_build.printInstruction(instr_ptr.get(), true); printer_inside_build.printInstruction(instr_ptr.get(), true);
// 修改 lambda 以捕获 this 指针,从而可以调用成员函数
auto print_set = [this](const VRegSet& s, const std::string& name) { auto print_set = [this](const VRegSet& s, const std::string& name) {
std::cerr << " " << name << ": { "; std::cerr << " " << name << ": { ";
for(unsigned v : s) std::cerr << regIdToString(v) << " "; // 使用新函数 for(unsigned v : s) std::cerr << regIdToString(v) << " ";
std::cerr << "}\n"; std::cerr << "}\n";
}; };
print_set(def, "Def "); print_set(def, "Def ");
@@ -276,17 +276,26 @@ void RISCv64RegAlloc::build() {
} }
for (unsigned v : use) { for (unsigned v : use) {
if (!coloredNodes.count(v)) { if (!coloredNodes.count(v) && !precolored.count(v)) {
initial.insert(v); initial.insert(v);
} else if (DEEPDEBUG) { } else if (DEEPDEBUG) {
std::cerr << "Skipping %vreg" << v << " because it is in coloredNodes.\n"; // 这里的调试信息可以更精确
if (precolored.count(v)) {
std::cerr << "Skipping " << regIdToString(v) << " because it is a physical register.\n";
} else {
std::cerr << "Skipping " << regIdToString(v) << " because it is a pre-colored virtual register.\n";
}
} }
} }
for (unsigned v : def) { for (unsigned v : def) {
if (!coloredNodes.count(v)) { if (!coloredNodes.count(v) && !precolored.count(v)) {
initial.insert(v); initial.insert(v);
} else if (DEEPDEBUG) { } else if (DEEPDEBUG) {
std::cerr << "Skipping %vreg" << v << " because it is in coloredNodes.\n"; if (precolored.count(v)) {
std::cerr << "Skipping " << regIdToString(v) << " because it is a physical register.\n";
} else {
std::cerr << "Skipping " << regIdToString(v) << " because it is a pre-colored virtual register.\n";
}
} }
} }
} }
@@ -294,17 +303,25 @@ void RISCv64RegAlloc::build() {
if (DEEPDEBUG) { if (DEEPDEBUG) {
std::cerr << "Initial set after build: { "; std::cerr << "Initial set after build: { ";
for (unsigned v : initial) std::cerr << "%vreg" << v << " "; for (unsigned v : initial) std::cerr << regIdToString(v) << " ";
std::cerr << "}\n"; std::cerr << "}\n";
} }
for(unsigned vreg : initial) { // 2. 为所有参与图构建的虚拟寄存器initial + coloredNodes初始化数据结构
VRegSet all_participating_vregs = initial;
all_participating_vregs.insert(coloredNodes.begin(), coloredNodes.end());
for (unsigned vreg : all_participating_vregs) {
// 物理寄存器ID不应作为key此检查是安全的双重保障
const unsigned offset = static_cast<unsigned>(PhysicalReg::PHYS_REG_START_ID);
if (vreg >= offset) {
continue;
}
adjList[vreg] = {}; adjList[vreg] = {};
degree[vreg] = 0; degree[vreg] = 0;
moveList[vreg] = {};
// alias[vreg] = vreg;
} }
// 3. 构建冲突图
for (const auto& mbb_ptr : MFunc->getBlocks()) { for (const auto& mbb_ptr : MFunc->getBlocks()) {
if (DEEPDEBUG) std::cerr << "\n--- Building Graph for Basic Block: " << mbb_ptr->getName() << " ---\n"; if (DEEPDEBUG) std::cerr << "\n--- Building Graph for Basic Block: " << mbb_ptr->getName() << " ---\n";
for (const auto& instr_ptr : mbb_ptr->getInstructions()) { for (const auto& instr_ptr : mbb_ptr->getInstructions()) {
@@ -313,8 +330,8 @@ void RISCv64RegAlloc::build() {
getInstrUseDef_Liveness(instr, use, def); getInstrUseDef_Liveness(instr, use, def);
const VRegSet& live_out = live_out_map.at(instr); const VRegSet& live_out = live_out_map.at(instr);
// 保留您的指令级调试输出
if (DEEPDEBUG) { if (DEEPDEBUG) {
// 使用临时的 AsmPrinter 打印当前指令,便于观察
RISCv64AsmPrinter temp_printer(MFunc); RISCv64AsmPrinter temp_printer(MFunc);
temp_printer.setStream(std::cerr); temp_printer.setStream(std::cerr);
std::cerr << "Instr: "; std::cerr << "Instr: ";
@@ -322,7 +339,7 @@ void RISCv64RegAlloc::build() {
auto print_set = [this](const VRegSet& s, const std::string& name) { auto print_set = [this](const VRegSet& s, const std::string& name) {
std::cerr << " " << name << ": { "; std::cerr << " " << name << ": { ";
for(unsigned v : s) std::cerr << regIdToString(v) << " "; // 使用新函数 for(unsigned v : s) std::cerr << regIdToString(v) << " ";
std::cerr << "}\n"; std::cerr << "}\n";
}; };
print_set(def, "Def "); print_set(def, "Def ");
@@ -333,46 +350,54 @@ void RISCv64RegAlloc::build() {
bool is_move = instr->getOpcode() == RVOpcodes::MV; bool is_move = instr->getOpcode() == RVOpcodes::MV;
// 保留您处理 moveList 的逻辑
if (is_move) { if (is_move) {
worklistMoves.insert(instr); worklistMoves.insert(instr);
VRegSet move_vregs; VRegSet move_vregs;
for(const auto& op : instr->getOperands()) { for(const auto& op : instr->getOperands()) {
if (op->getKind() == MachineOperand::KIND_REG) { if (op->getKind() == MachineOperand::KIND_REG) {
auto reg_op = static_cast<const RegOperand*>(op.get()); auto reg_op = static_cast<const RegOperand*>(op.get());
if(reg_op->isVirtual()) move_vregs.insert(reg_op->getVRegNum()); if(reg_op->isVirtual()) move_vregs.insert(reg_op->getVRegNum());
} }
} }
for (unsigned vreg : move_vregs) { for (unsigned vreg : move_vregs) {
// 使用 operator[] 是安全的如果vreg不存在会默认构造
moveList[vreg].insert(instr); moveList[vreg].insert(instr);
} }
} }
// --- 规则 1: Def 与 Live_Out 变量干扰 ---
VRegSet live = live_out; VRegSet live = live_out;
if (is_move) { if (is_move) {
for (unsigned u : use) { for (unsigned u_op : use) {
live.erase(u); live.erase(u_op);
}
}
for (unsigned d : def) {
for (unsigned l : live) {
addEdge(d, l);
} }
} }
// --- [新增的关键逻辑] 规则 2: 对于非move指令强制def和use互相干扰 --- // --- 规则 1 & 2: Def 与 Live/Use 变量干扰 ---
// 这可以防止指令内部的源寄存器被目标寄存器错误地覆盖 for (unsigned d : def) {
if (!is_move) { // [关键修正] Def必须是虚拟寄存器
for (unsigned d : def) { if (precolored.count(d)) continue;
for (unsigned u : use) {
addEdge(d, u); for (unsigned l : live) {
addEdge(d, l);
}
if (!is_move) {
for (unsigned u_op : use) {
addEdge(d, u_op);
} }
} }
} }
// --- 规则 3: Live_Out 集合内部的【虚拟寄存器】形成完全图 ---
// [优化与修正] 使用更高效的遍历,避免重复调用 addEdge(A,B) 和 addEdge(B,A)
for (auto it1 = live_out.begin(); it1 != live_out.end(); ++it1) {
unsigned l1 = *it1;
// [关键修正] 只为虚拟寄存器 l1 添加边
if (precolored.count(l1)) continue;
// --- 规则 3: Live_Out 集合内部形成完全图 --- for (auto it2 = std::next(it1); it2 != live_out.end(); ++it2) {
for (unsigned l1 : live_out) { unsigned l2 = *it2;
for (unsigned l2 : live_out) {
addEdge(l1, l2); addEdge(l1, l2);
} }
} }
@@ -552,6 +577,8 @@ void RISCv64RegAlloc::selectSpill() {
void RISCv64RegAlloc::assignColors() { void RISCv64RegAlloc::assignColors() {
if (DEEPDEBUG) std::cerr << "[AssignColors] Starting...\n"; if (DEEPDEBUG) std::cerr << "[AssignColors] Starting...\n";
// 步骤 1: 完整处理 selectStack
while (!selectStack.empty()) { while (!selectStack.empty()) {
unsigned n = selectStack.back(); unsigned n = selectStack.back();
selectStack.pop_back(); selectStack.pop_back();
@@ -559,12 +586,8 @@ void RISCv64RegAlloc::assignColors() {
const auto& available_regs = is_fp ? allocable_fp_regs : allocable_int_regs; const auto& available_regs = is_fp ? allocable_fp_regs : allocable_int_regs;
std::set<PhysicalReg> ok_colors(available_regs.begin(), available_regs.end()); std::set<PhysicalReg> ok_colors(available_regs.begin(), available_regs.end());
// 遍历 n 的所有邻居 w
for (unsigned w : adjList.at(n)) { for (unsigned w : adjList.at(n)) {
unsigned w_alias = getAlias(w); unsigned w_alias = getAlias(w);
// [关键修正] 邻居 w 可能是一个已着色的虚拟寄存器,
// 或者它本身就是一个物理寄存器。两种情况都要处理!
bool is_colored_vreg = coloredNodes.count(w_alias); bool is_colored_vreg = coloredNodes.count(w_alias);
bool is_physical_reg = precolored.count(w_alias); bool is_physical_reg = precolored.count(w_alias);
const unsigned offset = static_cast<unsigned>(PhysicalReg::PHYS_REG_START_ID); const unsigned offset = static_cast<unsigned>(PhysicalReg::PHYS_REG_START_ID);
@@ -572,10 +595,8 @@ void RISCv64RegAlloc::assignColors() {
if (is_colored_vreg || is_physical_reg) { if (is_colored_vreg || is_physical_reg) {
PhysicalReg neighbor_color; PhysicalReg neighbor_color;
if (is_colored_vreg) { if (is_colored_vreg) {
// 如果是已着色的vreg从 color_map 获取它的颜色
neighbor_color = color_map.at(w_alias); neighbor_color = color_map.at(w_alias);
} else { } else {
// 如果是物理寄存器它的ID就是它的颜色
neighbor_color = static_cast<PhysicalReg>(w_alias - offset); neighbor_color = static_cast<PhysicalReg>(w_alias - offset);
} }
ok_colors.erase(neighbor_color); ok_colors.erase(neighbor_color);
@@ -589,18 +610,28 @@ void RISCv64RegAlloc::assignColors() {
PhysicalReg c = *ok_colors.begin(); PhysicalReg c = *ok_colors.begin();
coloredNodes.insert(n); coloredNodes.insert(n);
color_map[n] = c; color_map[n] = c;
if (DEEPDEBUG) std::cerr << " -> Colored %vreg" << n << " with " << regToString(c) << " (ID: " << static_cast<int>(c) << ").\n"; if (DEEPDEBUG) std::cerr << " -> Colored %vreg" << n << " with " << regToString(c) << ".\n";
} }
} }
// 为合并的节点上色(这部分逻辑是正确的) // 步骤 2: 独立、完整地处理 coalescedNodes
for (unsigned n : coalescedNodes) { for (unsigned n : coalescedNodes) {
unsigned root_alias = getAlias(n); unsigned root_alias = getAlias(n);
if (color_map.count(root_alias)) {
// 情况 1: 别名是物理寄存器,直接获得该颜色
if (precolored.count(root_alias)) {
const unsigned offset = static_cast<unsigned>(PhysicalReg::PHYS_REG_START_ID);
color_map[n] = static_cast<PhysicalReg>(root_alias - offset);
if (DEEPDEBUG) std::cerr << " -> Coalesced " << regIdToString(n) << " gets color from physical alias " << regIdToString(root_alias) << ".\n";
}
// 情况 2: 别名是虚拟寄存器且在步骤1中已被成功着色
else if (color_map.count(root_alias)) {
color_map[n] = color_map.at(root_alias); color_map[n] = color_map.at(root_alias);
if (DEEPDEBUG) std::cerr << " -> Coalesced " << regIdToString(n) << " gets color of alias " << regIdToString(root_alias) << ".\n"; if (DEEPDEBUG) std::cerr << " -> Coalesced " << regIdToString(n) << " gets color of virtual alias " << regIdToString(root_alias) << ".\n";
} else { }
if (DEEPDEBUG) std::cerr << " -> No color for alias of %vreg" << n << ". Spilling.\n"; // 情况 3: 别名是虚拟寄存器但在步骤1中未能着色即被溢出
else {
if (DEEPDEBUG) std::cerr << " -> Alias " << regIdToString(root_alias) << " of %vreg" << n << " was spilled. Spilling.\n";
spilledNodes.insert(n); spilledNodes.insert(n);
} }
} }
@@ -798,14 +829,16 @@ void RISCv64RegAlloc::getInstrUseDef(const MachineInstr* instr, VRegSet& use, VR
} }
/** /**
* @brief [新增] 获取一条指令完整的、包含物理寄存器的Use/Def集合 * @brief [已修复] 获取一条指令完整的、包含物理寄存器的Use/Def集合
* 这个新函数将专门服务于活跃性分析。 * 这个新函数将专门服务于活跃性分析。
*/ */
void RISCv64RegAlloc::getInstrUseDef_Liveness(const MachineInstr* instr, VRegSet& use, VRegSet& def) { void RISCv64RegAlloc::getInstrUseDef_Liveness(const MachineInstr* instr, VRegSet& use, VRegSet& def) {
auto opcode = instr->getOpcode(); auto opcode = instr->getOpcode();
const auto& operands = instr->getOperands(); const auto& operands = instr->getOperands();
// 映射表:指令操作码 -> {Def操作数索引列表, Use操作数索引列表}
static const std::map<RVOpcodes, std::pair<std::vector<int>, std::vector<int>>> op_info = { static const std::map<RVOpcodes, std::pair<std::vector<int>, std::vector<int>>> op_info = {
// ===== 已有指令定义 (保留) =====
{RVOpcodes::ADD, {{0}, {1, 2}}}, {RVOpcodes::SUB, {{0}, {1, 2}}}, {RVOpcodes::MUL, {{0}, {1, 2}}}, {RVOpcodes::ADD, {{0}, {1, 2}}}, {RVOpcodes::SUB, {{0}, {1, 2}}}, {RVOpcodes::MUL, {{0}, {1, 2}}},
{RVOpcodes::DIV, {{0}, {1, 2}}}, {RVOpcodes::REM, {{0}, {1, 2}}}, {RVOpcodes::ADDW, {{0}, {1, 2}}}, {RVOpcodes::DIV, {{0}, {1, 2}}}, {RVOpcodes::REM, {{0}, {1, 2}}}, {RVOpcodes::ADDW, {{0}, {1, 2}}},
{RVOpcodes::SUBW, {{0}, {1, 2}}}, {RVOpcodes::MULW, {{0}, {1, 2}}}, {RVOpcodes::DIVW, {{0}, {1, 2}}}, {RVOpcodes::SUBW, {{0}, {1, 2}}}, {RVOpcodes::MULW, {{0}, {1, 2}}}, {RVOpcodes::DIVW, {{0}, {1, 2}}},
@@ -820,14 +853,42 @@ void RISCv64RegAlloc::getInstrUseDef_Liveness(const MachineInstr* instr, VRegSet
{RVOpcodes::BNE, {{}, {0, 1}}}, {RVOpcodes::BLT, {{}, {0, 1}}}, {RVOpcodes::BGE, {{}, {0, 1}}}, {RVOpcodes::BNE, {{}, {0, 1}}}, {RVOpcodes::BLT, {{}, {0, 1}}}, {RVOpcodes::BGE, {{}, {0, 1}}},
{RVOpcodes::JALR, {{0}, {1}}}, {RVOpcodes::LI, {{0}, {}}}, {RVOpcodes::LA, {{0}, {}}}, {RVOpcodes::JALR, {{0}, {1}}}, {RVOpcodes::LI, {{0}, {}}}, {RVOpcodes::LA, {{0}, {}}},
{RVOpcodes::MV, {{0}, {1}}}, {RVOpcodes::SEQZ, {{0}, {1}}}, {RVOpcodes::SNEZ, {{0}, {1}}}, {RVOpcodes::MV, {{0}, {1}}}, {RVOpcodes::SEQZ, {{0}, {1}}}, {RVOpcodes::SNEZ, {{0}, {1}}},
{RVOpcodes::RET, {{}, {static_cast<int>(PhysicalReg::A0), static_cast<int>(PhysicalReg::F10)}}}, {RVOpcodes::FADD_S, {{0}, {1, 2}}}, {RVOpcodes::FSUB_S, {{0}, {1, 2}}},
{RVOpcodes::FADD_S, {{0}, {1, 2}}}, {RVOpcodes::FSUB_S, {{0}, {1, 2}}}, {RVOpcodes::FMUL_S, {{0}, {1, 2}}}, {RVOpcodes::FMUL_S, {{0}, {1, 2}}}, {RVOpcodes::FDIV_S, {{0}, {1, 2}}}, {RVOpcodes::FEQ_S, {{0}, {1, 2}}},
{RVOpcodes::FDIV_S, {{0}, {1, 2}}}, {RVOpcodes::FEQ_S, {{0}, {1, 2}}}, {RVOpcodes::FLT_S, {{0}, {1, 2}}}, {RVOpcodes::FLT_S, {{0}, {1, 2}}}, {RVOpcodes::FLE_S, {{0}, {1, 2}}}, {RVOpcodes::FCVT_S_W, {{0}, {1}}},
{RVOpcodes::FLE_S, {{0}, {1, 2}}}, {RVOpcodes::FCVT_S_W, {{0}, {1}}}, {RVOpcodes::FCVT_W_S, {{0}, {1}}}, {RVOpcodes::FCVT_W_S, {{0}, {1}}}, {RVOpcodes::FMV_S, {{0}, {1}}}, {RVOpcodes::FMV_W_X, {{0}, {1}}},
{RVOpcodes::FMV_S, {{0}, {1}}}, {RVOpcodes::FMV_W_X, {{0}, {1}}}, {RVOpcodes::FMV_X_W, {{0}, {1}}}, {RVOpcodes::FMV_X_W, {{0}, {1}}}, {RVOpcodes::FNEG_S, {{0}, {1}}},
{RVOpcodes::FNEG_S, {{0}, {1}}}
// ===== 新增的指令定义开始 =====
// --- 逻辑指令 ---
{RVOpcodes::XOR, {{0}, {1, 2}}},
{RVOpcodes::OR, {{0}, {1, 2}}},
{RVOpcodes::AND, {{0}, {1, 2}}},
{RVOpcodes::ORI, {{0}, {1}}},
{RVOpcodes::ANDI, {{0}, {1}}},
// --- 移位指令 ---
{RVOpcodes::SLL, {{0}, {1, 2}}}, {RVOpcodes::SLLI, {{0}, {1}}},
{RVOpcodes::SLLW, {{0}, {1, 2}}}, {RVOpcodes::SLLIW, {{0}, {1}}},
{RVOpcodes::SRL, {{0}, {1, 2}}}, {RVOpcodes::SRLI, {{0}, {1}}},
{RVOpcodes::SRLW, {{0}, {1, 2}}}, {RVOpcodes::SRLIW, {{0}, {1}}},
{RVOpcodes::SRA, {{0}, {1, 2}}}, {RVOpcodes::SRAI, {{0}, {1}}},
{RVOpcodes::SRAW, {{0}, {1, 2}}}, {RVOpcodes::SRAIW, {{0}, {1}}},
// --- 控制流指令 (补全) ---
{RVOpcodes::BLTU, {{}, {0, 1}}},
{RVOpcodes::BGEU, {{}, {0, 1}}},
// J 没有寄存器操作数JAL 由CALL指令类似的特殊逻辑处理
// --- 伪指令 (补全) ---
{RVOpcodes::NEG, {{0}, {1}}},
{RVOpcodes::NEGW, {{0}, {1}}},
// ===== 新增的指令定义结束 =====
}; };
// 该lambda表达式用于获取操作数的寄存器ID虚拟或物理逻辑正确保持不变
const unsigned offset = static_cast<unsigned>(PhysicalReg::PHYS_REG_START_ID); const unsigned offset = static_cast<unsigned>(PhysicalReg::PHYS_REG_START_ID);
auto get_any_reg_id = [&](const MachineOperand* op) -> unsigned { auto get_any_reg_id = [&](const MachineOperand* op) -> unsigned {
if (op->getKind() == MachineOperand::KIND_REG) { if (op->getKind() == MachineOperand::KIND_REG) {
@@ -843,39 +904,78 @@ void RISCv64RegAlloc::getInstrUseDef_Liveness(const MachineInstr* instr, VRegSet
if (op_info.count(opcode)) { if (op_info.count(opcode)) {
const auto& info = op_info.at(opcode); const auto& info = op_info.at(opcode);
for (int idx : info.first) if (idx < operands.size()) def.insert(get_any_reg_id(operands[idx].get())); for (int idx : info.first) if (idx < operands.size()) {
for (int idx : info.second) if (idx < operands.size()) use.insert(get_any_reg_id(operands[idx].get())); unsigned reg_id = get_any_reg_id(operands[idx].get());
for (const auto& op : operands) if (op->getKind() == MachineOperand::KIND_MEM) use.insert(get_any_reg_id(op.get())); if (reg_id != (unsigned)-1) def.insert(reg_id);
} else if (opcode == RVOpcodes::CALL) { }
if (!operands.empty() && operands[0]->getKind() == MachineOperand::KIND_REG) def.insert(get_any_reg_id(operands[0].get())); for (int idx : info.second) if (idx < operands.size()) {
for (size_t i = 1; i < operands.size(); ++i) if (operands[i]->getKind() == MachineOperand::KIND_REG) use.insert(get_any_reg_id(operands[i].get())); unsigned reg_id = get_any_reg_id(operands[idx].get());
for (auto preg : getCallerSavedIntRegs()) def.insert(static_cast<unsigned>(preg)); if (reg_id != (unsigned)-1) use.insert(reg_id);
for (auto preg : getCallerSavedFpRegs()) def.insert(static_cast<unsigned>(preg)); }
def.insert(static_cast<unsigned>(PhysicalReg::RA)); // 不要忘记内存操作数中的基址寄存器永远是use
for (const auto& op : operands) {
if (op->getKind() == MachineOperand::KIND_MEM) {
unsigned reg_id = get_any_reg_id(op.get());
if (reg_id != (unsigned)-1) use.insert(reg_id);
}
}
}
// CALL 和 RET 的特殊处理逻辑,保持不变
else if (opcode == RVOpcodes::CALL) {
// 返回值是Def
if (!operands.empty() && operands[0]->getKind() == MachineOperand::KIND_REG) {
def.insert(get_any_reg_id(operands[0].get()));
}
// 函数名后的所有寄存器参数都是Use
for (size_t i = 1; i < operands.size(); ++i) {
if (operands[i]->getKind() == MachineOperand::KIND_REG) {
use.insert(get_any_reg_id(operands[i].get()));
}
}
// 所有调用者保存寄存器(caller-saved)被隐式定义(因为它们的值被破坏了)
for (auto preg : getCallerSavedIntRegs()) def.insert(offset + static_cast<unsigned>(preg));
for (auto preg : getCallerSavedFpRegs()) def.insert(offset + static_cast<unsigned>(preg));
// 返回地址寄存器RA也被隐式定义
def.insert(offset + static_cast<unsigned>(PhysicalReg::RA));
}
else if (opcode == RVOpcodes::RET) {
// 遵循调用约定a0(整数/指针)和fa0(浮点)被隐式使用
use.insert(offset + static_cast<unsigned>(PhysicalReg::A0));
use.insert(offset + static_cast<unsigned>(PhysicalReg::F10)); // F10 is fa0
} }
} }
void RISCv64RegAlloc::addEdge(unsigned u, unsigned v) { void RISCv64RegAlloc::addEdge(unsigned u, unsigned v) {
if (u == v) return; if (u == v) return;
// 关键修正:只为虚拟寄存器(非预着色)更新邻接表和度数 // 检查两个节点是否都是虚拟寄存器
// 如果 u 是虚拟寄存器 if (!precolored.count(u) && !precolored.count(v)) {
if (!precolored.count(u)) { // 只有当两个都是虚拟寄存器时,才为它们双方添加边和更新度数
// 并且 u 和 v 之间还没有边 // 使用 operator[] 是安全的如果键不存在它会默认构造一个空的set
if (adjList.at(u).find(v) == adjList.at(u).end()) { if (adjList[u].find(v) == adjList[u].end()) {
adjList.at(u).insert(v); adjList[u].insert(v);
degree.at(u)++; adjList[v].insert(u);
degree[u]++;
degree[v]++;
} }
} }
// 检查是否为 "虚拟-物理" 对
// 对称地,如果 v 是虚拟寄存器 else if (!precolored.count(u) && precolored.count(v)) {
if (!precolored.count(v)) { // u是虚拟寄存器v是物理寄存器只更新u的邻接表和度数
// 并且 v 和 u 之间还没有边 if (adjList[u].find(v) == adjList[u].end()) {
if (adjList.at(v).find(u) == adjList.at(v).end()) { adjList[u].insert(v);
adjList.at(v).insert(u); degree[u]++;
degree.at(v)++;
} }
} }
// 检查是否为 "物理-虚拟" 对
else if (precolored.count(u) && !precolored.count(v)) {
// u是物理寄存器v是虚拟寄存器只更新v的邻接表和度数
if (adjList[v].find(u) == adjList[v].end()) {
adjList[v].insert(u);
degree[v]++;
}
}
// 如果两个都是物理寄存器,则什么都不做,直接返回。
} }
RISCv64RegAlloc::VRegSet RISCv64RegAlloc::adjacent(unsigned n) { RISCv64RegAlloc::VRegSet RISCv64RegAlloc::adjacent(unsigned n) {
@@ -1112,10 +1212,13 @@ void RISCv64RegAlloc::combine(unsigned u, unsigned v) {
addEdge(t, u); addEdge(t, u);
decrementDegree(t); decrementDegree(t);
} }
int K = isFPVReg(u) ? K_fp : K_int;
if (degree.at(u) >= K && freezeWorklist.count(u)) { if (!precolored.count(u)) {
freezeWorklist.erase(u); int K = isFPVReg(u) ? K_fp : K_int;
spillWorklist.insert(u); if (degree.at(u) >= K && freezeWorklist.count(u)) {
freezeWorklist.erase(u);
spillWorklist.insert(u);
}
} }
} }