[backend-IRC]基本构建了IRC
This commit is contained in:
@@ -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();
|
||||||
|
|||||||
@@ -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 集合内部形成完全图 ---
|
// --- 规则 3: Live_Out 集合内部的【虚拟寄存器】形成完全图 ---
|
||||||
for (unsigned l1 : live_out) {
|
// [优化与修正] 使用更高效的遍历,避免重复调用 addEdge(A,B) 和 addEdge(B,A)
|
||||||
for (unsigned l2 : live_out) {
|
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);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user