deploy-20250820-3 #1
@@ -121,6 +121,8 @@ std::string RISCv64CodeGen::function_gen(Function* func) {
|
||||
// if (DEBUG) {
|
||||
// std::cout << ss_after_isel.str();
|
||||
// }
|
||||
// DEBUG = 0;
|
||||
// DEEPDEBUG = 0;
|
||||
// DEBUG = 1;
|
||||
// DEEPDEBUG = 1;
|
||||
if (DEBUG) {
|
||||
@@ -143,8 +145,8 @@ std::string RISCv64CodeGen::function_gen(Function* func) {
|
||||
// PreRA_Scheduler scheduler;
|
||||
// scheduler.runOnMachineFunction(mfunc.get());
|
||||
|
||||
DEBUG = 0;
|
||||
DEEPDEBUG = 0;
|
||||
// DEBUG = 0;
|
||||
// DEEPDEBUG = 0;
|
||||
// 阶段 3: 物理寄存器分配 (Register Allocation)
|
||||
RISCv64RegAlloc reg_alloc(mfunc.get());
|
||||
reg_alloc.run();
|
||||
|
||||
@@ -255,20 +255,20 @@ void RISCv64RegAlloc::build() {
|
||||
RISCv64AsmPrinter printer_inside_build(MFunc);
|
||||
printer_inside_build.setStream(std::cerr);
|
||||
|
||||
// 1. 收集所有待分配的(既非物理也非预着色)虚拟寄存器到 initial 集合
|
||||
for (const auto& mbb_ptr : MFunc->getBlocks()) {
|
||||
for (const auto& instr_ptr : mbb_ptr->getInstructions()) {
|
||||
const MachineInstr* instr = instr_ptr.get();
|
||||
VRegSet use, def;
|
||||
getInstrUseDef_Liveness(instr, use, def);
|
||||
|
||||
// 调试输出 use 和 def
|
||||
// 调试输出 use 和 def (保留您的调试逻辑)
|
||||
if (DEEPDEBUG) {
|
||||
std::cerr << "Instr:";
|
||||
printer_inside_build.printInstruction(instr_ptr.get(), true);
|
||||
// 修改 lambda 以捕获 this 指针,从而可以调用成员函数
|
||||
auto print_set = [this](const VRegSet& s, const std::string& name) {
|
||||
std::cerr << " " << name << ": { ";
|
||||
for(unsigned v : s) std::cerr << regIdToString(v) << " "; // 使用新函数
|
||||
for(unsigned v : s) std::cerr << regIdToString(v) << " ";
|
||||
std::cerr << "}\n";
|
||||
};
|
||||
print_set(def, "Def ");
|
||||
@@ -276,17 +276,26 @@ void RISCv64RegAlloc::build() {
|
||||
}
|
||||
|
||||
for (unsigned v : use) {
|
||||
if (!coloredNodes.count(v)) {
|
||||
if (!coloredNodes.count(v) && !precolored.count(v)) {
|
||||
initial.insert(v);
|
||||
} 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) {
|
||||
if (!coloredNodes.count(v)) {
|
||||
if (!coloredNodes.count(v) && !precolored.count(v)) {
|
||||
initial.insert(v);
|
||||
} 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) {
|
||||
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";
|
||||
}
|
||||
|
||||
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] = {};
|
||||
degree[vreg] = 0;
|
||||
moveList[vreg] = {};
|
||||
// alias[vreg] = vreg;
|
||||
}
|
||||
|
||||
// 3. 构建冲突图
|
||||
for (const auto& mbb_ptr : MFunc->getBlocks()) {
|
||||
if (DEEPDEBUG) std::cerr << "\n--- Building Graph for Basic Block: " << mbb_ptr->getName() << " ---\n";
|
||||
for (const auto& instr_ptr : mbb_ptr->getInstructions()) {
|
||||
@@ -313,8 +330,8 @@ void RISCv64RegAlloc::build() {
|
||||
getInstrUseDef_Liveness(instr, use, def);
|
||||
const VRegSet& live_out = live_out_map.at(instr);
|
||||
|
||||
// 保留您的指令级调试输出
|
||||
if (DEEPDEBUG) {
|
||||
// 使用临时的 AsmPrinter 打印当前指令,便于观察
|
||||
RISCv64AsmPrinter temp_printer(MFunc);
|
||||
temp_printer.setStream(std::cerr);
|
||||
std::cerr << "Instr: ";
|
||||
@@ -322,7 +339,7 @@ void RISCv64RegAlloc::build() {
|
||||
|
||||
auto print_set = [this](const VRegSet& s, const std::string& name) {
|
||||
std::cerr << " " << name << ": { ";
|
||||
for(unsigned v : s) std::cerr << regIdToString(v) << " "; // 使用新函数
|
||||
for(unsigned v : s) std::cerr << regIdToString(v) << " ";
|
||||
std::cerr << "}\n";
|
||||
};
|
||||
print_set(def, "Def ");
|
||||
@@ -333,46 +350,54 @@ void RISCv64RegAlloc::build() {
|
||||
|
||||
bool is_move = instr->getOpcode() == RVOpcodes::MV;
|
||||
|
||||
// 保留您处理 moveList 的逻辑
|
||||
if (is_move) {
|
||||
worklistMoves.insert(instr);
|
||||
VRegSet move_vregs;
|
||||
for(const auto& op : instr->getOperands()) {
|
||||
for(const auto& op : instr->getOperands()) {
|
||||
if (op->getKind() == MachineOperand::KIND_REG) {
|
||||
auto reg_op = static_cast<const RegOperand*>(op.get());
|
||||
if(reg_op->isVirtual()) move_vregs.insert(reg_op->getVRegNum());
|
||||
auto reg_op = static_cast<const RegOperand*>(op.get());
|
||||
if(reg_op->isVirtual()) move_vregs.insert(reg_op->getVRegNum());
|
||||
}
|
||||
}
|
||||
for (unsigned vreg : move_vregs) {
|
||||
// 使用 operator[] 是安全的,如果vreg不存在会默认构造
|
||||
moveList[vreg].insert(instr);
|
||||
}
|
||||
}
|
||||
|
||||
// --- 规则 1: Def 与 Live_Out 变量干扰 ---
|
||||
VRegSet live = live_out;
|
||||
if (is_move) {
|
||||
for (unsigned u : use) {
|
||||
live.erase(u);
|
||||
}
|
||||
}
|
||||
for (unsigned d : def) {
|
||||
for (unsigned l : live) {
|
||||
addEdge(d, l);
|
||||
for (unsigned u_op : use) {
|
||||
live.erase(u_op);
|
||||
}
|
||||
}
|
||||
|
||||
// --- [新增的关键逻辑] 规则 2: 对于非move指令,强制def和use互相干扰 ---
|
||||
// 这可以防止指令内部的源寄存器被目标寄存器错误地覆盖
|
||||
if (!is_move) {
|
||||
for (unsigned d : def) {
|
||||
for (unsigned u : use) {
|
||||
addEdge(d, u);
|
||||
// --- 规则 1 & 2: Def 与 Live/Use 变量干扰 ---
|
||||
for (unsigned d : def) {
|
||||
// [关键修正] Def必须是虚拟寄存器
|
||||
if (precolored.count(d)) continue;
|
||||
|
||||
for (unsigned l : live) {
|
||||
addEdge(d, l);
|
||||
}
|
||||
|
||||
if (!is_move) {
|
||||
for (unsigned u_op : use) {
|
||||
addEdge(d, u_op);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --- 规则 3: Live_Out 集合内部形成完全图 ---
|
||||
for (unsigned l1 : live_out) {
|
||||
for (unsigned l2 : live_out) {
|
||||
// --- 规则 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;
|
||||
|
||||
for (auto it2 = std::next(it1); it2 != live_out.end(); ++it2) {
|
||||
unsigned l2 = *it2;
|
||||
addEdge(l1, l2);
|
||||
}
|
||||
}
|
||||
@@ -552,6 +577,8 @@ void RISCv64RegAlloc::selectSpill() {
|
||||
|
||||
void RISCv64RegAlloc::assignColors() {
|
||||
if (DEEPDEBUG) std::cerr << "[AssignColors] Starting...\n";
|
||||
|
||||
// 步骤 1: 完整处理 selectStack
|
||||
while (!selectStack.empty()) {
|
||||
unsigned n = selectStack.back();
|
||||
selectStack.pop_back();
|
||||
@@ -559,12 +586,8 @@ void RISCv64RegAlloc::assignColors() {
|
||||
const auto& available_regs = is_fp ? allocable_fp_regs : allocable_int_regs;
|
||||
std::set<PhysicalReg> ok_colors(available_regs.begin(), available_regs.end());
|
||||
|
||||
// 遍历 n 的所有邻居 w
|
||||
for (unsigned w : adjList.at(n)) {
|
||||
unsigned w_alias = getAlias(w);
|
||||
|
||||
// [关键修正] 邻居 w 可能是一个已着色的虚拟寄存器,
|
||||
// 或者它本身就是一个物理寄存器。两种情况都要处理!
|
||||
bool is_colored_vreg = coloredNodes.count(w_alias);
|
||||
bool is_physical_reg = precolored.count(w_alias);
|
||||
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) {
|
||||
PhysicalReg neighbor_color;
|
||||
if (is_colored_vreg) {
|
||||
// 如果是已着色的vreg,从 color_map 获取它的颜色
|
||||
neighbor_color = color_map.at(w_alias);
|
||||
} else {
|
||||
// 如果是物理寄存器,它的ID就是它的颜色
|
||||
neighbor_color = static_cast<PhysicalReg>(w_alias - offset);
|
||||
}
|
||||
ok_colors.erase(neighbor_color);
|
||||
@@ -589,18 +610,28 @@ void RISCv64RegAlloc::assignColors() {
|
||||
PhysicalReg c = *ok_colors.begin();
|
||||
coloredNodes.insert(n);
|
||||
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) {
|
||||
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);
|
||||
if (DEEPDEBUG) std::cerr << " -> Coalesced " << regIdToString(n) << " gets color of alias " << regIdToString(root_alias) << ".\n";
|
||||
} else {
|
||||
if (DEEPDEBUG) std::cerr << " -> No color for alias of %vreg" << n << ". Spilling.\n";
|
||||
if (DEEPDEBUG) std::cerr << " -> Coalesced " << regIdToString(n) << " gets color of virtual alias " << regIdToString(root_alias) << ".\n";
|
||||
}
|
||||
// 情况 3: 别名是虚拟寄存器,但在步骤1中未能着色(即被溢出)
|
||||
else {
|
||||
if (DEEPDEBUG) std::cerr << " -> Alias " << regIdToString(root_alias) << " of %vreg" << n << " was spilled. Spilling.\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) {
|
||||
auto opcode = instr->getOpcode();
|
||||
const auto& operands = instr->getOperands();
|
||||
|
||||
// 映射表:指令操作码 -> {Def操作数索引列表, Use操作数索引列表}
|
||||
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::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}}},
|
||||
@@ -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::JALR, {{0}, {1}}}, {RVOpcodes::LI, {{0}, {}}}, {RVOpcodes::LA, {{0}, {}}},
|
||||
{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::FMUL_S, {{0}, {1, 2}}},
|
||||
{RVOpcodes::FDIV_S, {{0}, {1, 2}}}, {RVOpcodes::FEQ_S, {{0}, {1, 2}}}, {RVOpcodes::FLT_S, {{0}, {1, 2}}},
|
||||
{RVOpcodes::FLE_S, {{0}, {1, 2}}}, {RVOpcodes::FCVT_S_W, {{0}, {1}}}, {RVOpcodes::FCVT_W_S, {{0}, {1}}},
|
||||
{RVOpcodes::FMV_S, {{0}, {1}}}, {RVOpcodes::FMV_W_X, {{0}, {1}}}, {RVOpcodes::FMV_X_W, {{0}, {1}}},
|
||||
{RVOpcodes::FNEG_S, {{0}, {1}}}
|
||||
{RVOpcodes::FADD_S, {{0}, {1, 2}}}, {RVOpcodes::FSUB_S, {{0}, {1, 2}}},
|
||||
{RVOpcodes::FMUL_S, {{0}, {1, 2}}}, {RVOpcodes::FDIV_S, {{0}, {1, 2}}}, {RVOpcodes::FEQ_S, {{0}, {1, 2}}},
|
||||
{RVOpcodes::FLT_S, {{0}, {1, 2}}}, {RVOpcodes::FLE_S, {{0}, {1, 2}}}, {RVOpcodes::FCVT_S_W, {{0}, {1}}},
|
||||
{RVOpcodes::FCVT_W_S, {{0}, {1}}}, {RVOpcodes::FMV_S, {{0}, {1}}}, {RVOpcodes::FMV_W_X, {{0}, {1}}},
|
||||
{RVOpcodes::FMV_X_W, {{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);
|
||||
auto get_any_reg_id = [&](const MachineOperand* op) -> unsigned {
|
||||
if (op->getKind() == MachineOperand::KIND_REG) {
|
||||
@@ -843,39 +904,78 @@ void RISCv64RegAlloc::getInstrUseDef_Liveness(const MachineInstr* instr, VRegSet
|
||||
|
||||
if (op_info.count(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.second) if (idx < operands.size()) use.insert(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()));
|
||||
} else if (opcode == RVOpcodes::CALL) {
|
||||
if (!operands.empty() && operands[0]->getKind() == MachineOperand::KIND_REG) def.insert(get_any_reg_id(operands[0].get()));
|
||||
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()));
|
||||
for (auto preg : getCallerSavedIntRegs()) def.insert(static_cast<unsigned>(preg));
|
||||
for (auto preg : getCallerSavedFpRegs()) def.insert(static_cast<unsigned>(preg));
|
||||
def.insert(static_cast<unsigned>(PhysicalReg::RA));
|
||||
for (int idx : info.first) if (idx < operands.size()) {
|
||||
unsigned reg_id = get_any_reg_id(operands[idx].get());
|
||||
if (reg_id != (unsigned)-1) def.insert(reg_id);
|
||||
}
|
||||
for (int idx : info.second) if (idx < operands.size()) {
|
||||
unsigned reg_id = get_any_reg_id(operands[idx].get());
|
||||
if (reg_id != (unsigned)-1) use.insert(reg_id);
|
||||
}
|
||||
// 不要忘记内存操作数中的基址寄存器永远是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) {
|
||||
if (u == v) return;
|
||||
|
||||
// 关键修正:只为虚拟寄存器(非预着色)更新邻接表和度数
|
||||
// 如果 u 是虚拟寄存器
|
||||
if (!precolored.count(u)) {
|
||||
// 并且 u 和 v 之间还没有边
|
||||
if (adjList.at(u).find(v) == adjList.at(u).end()) {
|
||||
adjList.at(u).insert(v);
|
||||
degree.at(u)++;
|
||||
// 检查两个节点是否都是虚拟寄存器
|
||||
if (!precolored.count(u) && !precolored.count(v)) {
|
||||
// 只有当两个都是虚拟寄存器时,才为它们双方添加边和更新度数
|
||||
// 使用 operator[] 是安全的,如果键不存在,它会默认构造一个空的set
|
||||
if (adjList[u].find(v) == adjList[u].end()) {
|
||||
adjList[u].insert(v);
|
||||
adjList[v].insert(u);
|
||||
degree[u]++;
|
||||
degree[v]++;
|
||||
}
|
||||
}
|
||||
|
||||
// 对称地,如果 v 是虚拟寄存器
|
||||
if (!precolored.count(v)) {
|
||||
// 并且 v 和 u 之间还没有边
|
||||
if (adjList.at(v).find(u) == adjList.at(v).end()) {
|
||||
adjList.at(v).insert(u);
|
||||
degree.at(v)++;
|
||||
// 检查是否为 "虚拟-物理" 对
|
||||
else if (!precolored.count(u) && precolored.count(v)) {
|
||||
// u是虚拟寄存器,v是物理寄存器,只更新u的邻接表和度数
|
||||
if (adjList[u].find(v) == adjList[u].end()) {
|
||||
adjList[u].insert(v);
|
||||
degree[u]++;
|
||||
}
|
||||
}
|
||||
// 检查是否为 "物理-虚拟" 对
|
||||
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) {
|
||||
@@ -1112,10 +1212,13 @@ void RISCv64RegAlloc::combine(unsigned u, unsigned v) {
|
||||
addEdge(t, u);
|
||||
decrementDegree(t);
|
||||
}
|
||||
int K = isFPVReg(u) ? K_fp : K_int;
|
||||
if (degree.at(u) >= K && freezeWorklist.count(u)) {
|
||||
freezeWorklist.erase(u);
|
||||
spillWorklist.insert(u);
|
||||
|
||||
if (!precolored.count(u)) {
|
||||
int K = isFPVReg(u) ? K_fp : K_int;
|
||||
if (degree.at(u) >= K && freezeWorklist.count(u)) {
|
||||
freezeWorklist.erase(u);
|
||||
spillWorklist.insert(u);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user