[backend] introduced float instrs and regs
This commit is contained in:
@@ -6,7 +6,8 @@
|
||||
#include <iomanip>
|
||||
#include <functional> // For std::function
|
||||
|
||||
#define DEBUG 0
|
||||
#define DEBUG 1
|
||||
#define DEEPDEBUG 0
|
||||
namespace sysy {
|
||||
|
||||
// 可用于分配的通用寄存器
|
||||
@@ -854,12 +855,12 @@ std::map<Instruction*, std::set<std::string>> RISCv32CodeGen::liveness_analysis(
|
||||
while (changed) {
|
||||
changed = false;
|
||||
iteration_count++;
|
||||
if (DEBUG) std::cerr << "\n--- 活跃性分析迭代: " << iteration_count << " ---" << std::endl;
|
||||
if (DEEPDEBUG) std::cerr << "\n--- 活跃性分析迭代: " << iteration_count << " ---" << std::endl;
|
||||
|
||||
// 逆序遍历基本块
|
||||
for (auto it = func->getBasicBlocks_NoRange().rbegin(); it != func->getBasicBlocks_NoRange().rend(); ++it) {
|
||||
auto bb = it->get();
|
||||
if (DEBUG) std::cerr << " 基本块: " << bb->getName() << std::endl; // 打印基本块名称
|
||||
if (DEEPDEBUG) std::cerr << " 基本块: " << bb->getName() << std::endl; // 打印基本块名称
|
||||
|
||||
// 在基本块内逆序遍历指令
|
||||
// live_out_for_bb_inst 是当前基本块的 live_out 集合,用于计算该基本块中第一条指令的 live_out
|
||||
@@ -876,7 +877,7 @@ std::map<Instruction*, std::set<std::string>> RISCv32CodeGen::liveness_analysis(
|
||||
for (auto inst_it = bb->getInstructions().rbegin(); inst_it != bb->getInstructions().rend(); ++inst_it) {
|
||||
auto inst = inst_it->get();
|
||||
// 打印指令,使用其父基本块的名称和指令地址作为唯一标识符
|
||||
if (DEBUG) std::cerr << " 指令 (BB: " << bb->getName() << ", 地址: " << static_cast<void*>(inst) << ")" << std::endl;
|
||||
if (DEEPDEBUG) std::cerr << " 指令 (BB: " << bb->getName() << ", 地址: " << static_cast<void*>(inst) << ")" << std::endl;
|
||||
|
||||
std::set<std::string> current_live_in = live_in[inst];
|
||||
std::set<std::string> current_live_out = live_out[inst]; // 用于比较的旧 live_out
|
||||
@@ -887,12 +888,12 @@ std::map<Instruction*, std::set<std::string>> RISCv32CodeGen::liveness_analysis(
|
||||
// 那么它的 live_out 就是该基本块的 live_out,即其所有后继基本块的 live_in 的并集
|
||||
if (inst_it == bb->getInstructions().rbegin()) {
|
||||
new_live_out_calc = live_out_for_bb_inst;
|
||||
if (DEBUG) std::cerr << " 指令是基本块的最后一条指令,live_out 取自后继基本块 live_in 的并集: " << print_set(new_live_out_calc) << std::endl;
|
||||
if (DEEPDEBUG) std::cerr << " 指令是基本块的最后一条指令,live_out 取自后继基本块 live_in 的并集: " << print_set(new_live_out_calc) << std::endl;
|
||||
} else {
|
||||
// 如果不是基本块的最后一条指令,则其 live_out 是其后继指令的 live_in
|
||||
auto prev_inst_it = std::prev(inst_it); // std::prev 获取正向的下一条指令
|
||||
new_live_out_calc = live_in[prev_inst_it->get()];
|
||||
if (DEBUG) std::cerr << " 指令不是基本块的最后一条,其 live_out 是其后继指令 live_in: " << print_set(new_live_out_calc) << std::endl;
|
||||
if (DEEPDEBUG) std::cerr << " 指令不是基本块的最后一条,其 live_out 是其后继指令 live_in: " << print_set(new_live_out_calc) << std::endl;
|
||||
}
|
||||
|
||||
|
||||
@@ -905,7 +906,7 @@ std::map<Instruction*, std::set<std::string>> RISCv32CodeGen::liveness_analysis(
|
||||
if (!inst->getType()->isVoid() && !dynamic_cast<AllocaInst*>(inst) && !dynamic_cast<StoreInst*>(inst) &&
|
||||
!dynamic_cast<ReturnInst*>(inst) && !dynamic_cast<CondBrInst*>(inst) && !dynamic_cast<UncondBrInst*>(inst) && value_vreg_map.count(inst)) {
|
||||
def_set.insert(value_vreg_map.at(inst));
|
||||
if (DEBUG) std::cerr << " 指令 (地址: " << static_cast<void*>(inst) << ") 定义了虚拟寄存器: " << value_vreg_map.at(inst) << std::endl;
|
||||
if (DEEPDEBUG) std::cerr << " 指令 (地址: " << static_cast<void*>(inst) << ") 定义了虚拟寄存器: " << value_vreg_map.at(inst) << std::endl;
|
||||
}
|
||||
|
||||
// *** 针对 StoreInst 的新逻辑来“杀死”被存储值的虚拟寄存器 ***
|
||||
@@ -934,12 +935,12 @@ std::map<Instruction*, std::set<std::string>> RISCv32CodeGen::liveness_analysis(
|
||||
|
||||
if (is_unique_user) {
|
||||
def_set.insert(value_vreg_map.at(stored_value));
|
||||
if (DEBUG) std::cerr << " Store 指令 (地址: " << static_cast<void*>(inst) << ") 将被存储的值 '" << value_vreg_map.at(stored_value) << "' 添加到 def_set (启发式)." << std::endl;
|
||||
if (DEEPDEBUG) std::cerr << " Store 指令 (地址: " << static_cast<void*>(inst) << ") 将被存储的值 '" << value_vreg_map.at(stored_value) << "' 添加到 def_set (启发式)." << std::endl;
|
||||
} else {
|
||||
if (DEBUG) std::cerr << " Store 指令 (地址: " << static_cast<void*>(inst) << ") 存储的值 '" << value_vreg_map.at(stored_value) << "' 有其他用途或不是唯一用途,未添加到 def_set。" << std::endl;
|
||||
if (DEEPDEBUG) std::cerr << " Store 指令 (地址: " << static_cast<void*>(inst) << ") 存储的值 '" << value_vreg_map.at(stored_value) << "' 有其他用途或不是唯一用途,未添加到 def_set。" << std::endl;
|
||||
}
|
||||
} else if (dynamic_cast<AllocaInst*>(stored_value)) {
|
||||
if (DEBUG) std::cerr << " Store 指令存储的是 AllocaInst 地址,不处理其虚拟寄存器定义。" << std::endl;
|
||||
if (DEEPDEBUG) std::cerr << " Store 指令存储的是 AllocaInst 地址,不处理其虚拟寄存器定义。" << std::endl;
|
||||
}
|
||||
}
|
||||
// *** 结束新逻辑 ***
|
||||
@@ -952,17 +953,17 @@ std::map<Instruction*, std::set<std::string>> RISCv32CodeGen::liveness_analysis(
|
||||
// 并且确保 operand 已经在 value_vreg_map 中有对应的虚拟寄存器。
|
||||
if (value_vreg_map.count(operand) && !dynamic_cast<AllocaInst*>(operand)) {
|
||||
use_set.insert(value_vreg_map.at(operand));
|
||||
if (DEBUG) std::cerr << " 指令 (地址: " << static_cast<void*>(inst) << ") 使用了虚拟寄存器: " << value_vreg_map.at(operand) << std::endl;
|
||||
if (DEEPDEBUG) std::cerr << " 指令 (地址: " << static_cast<void*>(inst) << ") 使用了虚拟寄存器: " << value_vreg_map.at(operand) << std::endl;
|
||||
} else if (dynamic_cast<AllocaInst*>(operand)) {
|
||||
if (DEBUG) std::cerr << " 指令 (地址: " << static_cast<void*>(inst) << ") 操作数是 AllocaInst 地址,不添加到 use_set。" << std::endl;
|
||||
if (DEEPDEBUG) std::cerr << " 指令 (地址: " << static_cast<void*>(inst) << ") 操作数是 AllocaInst 地址,不添加到 use_set。" << std::endl;
|
||||
} else {
|
||||
// 对于常量,它们没有虚拟寄存器,也不应该被添加到use_set
|
||||
// 也可以是其他没有对应虚拟寄存器(例如函数名)的值。
|
||||
if (DEBUG) std::cerr << " 指令 (地址: " << static_cast<void*>(inst) << ") 操作数没有对应的虚拟寄存器,或不是需要寄存器的值。" << std::endl;
|
||||
if (DEEPDEBUG) std::cerr << " 指令 (地址: " << static_cast<void*>(inst) << ") 操作数没有对应的虚拟寄存器,或不是需要寄存器的值。" << std::endl;
|
||||
}
|
||||
}
|
||||
if (DEBUG) std::cerr << " 指令 (地址: " << static_cast<void*>(inst) << ") 的 use_set: " << print_set(use_set) << std::endl;
|
||||
if (DEBUG) std::cerr << " 指令 (地址: " << static_cast<void*>(inst) << ") 的 def_set: " << print_set(def_set) << std::endl;
|
||||
if (DEEPDEBUG) std::cerr << " 指令 (地址: " << static_cast<void*>(inst) << ") 的 use_set: " << print_set(use_set) << std::endl;
|
||||
if (DEEPDEBUG) std::cerr << " 指令 (地址: " << static_cast<void*>(inst) << ") 的 def_set: " << print_set(def_set) << std::endl;
|
||||
|
||||
|
||||
// 计算新的 live_in = use U (new_live_out_calc - def)
|
||||
@@ -973,8 +974,8 @@ std::map<Instruction*, std::set<std::string>> RISCv32CodeGen::liveness_analysis(
|
||||
}
|
||||
}
|
||||
|
||||
if (DEBUG) std::cerr << " 指令 (地址: " << static_cast<void*>(inst) << ") 计算出的 new_live_in: " << print_set(new_live_in) << std::endl;
|
||||
if (DEBUG) std::cerr << " 指令 (地址: " << static_cast<void*>(inst) << ") 当前 live_in: " << print_set(current_live_in) << ", 当前 live_out: " << print_set(current_live_out) << std::endl;
|
||||
if (DEEPDEBUG) std::cerr << " 指令 (地址: " << static_cast<void*>(inst) << ") 计算出的 new_live_in: " << print_set(new_live_in) << std::endl;
|
||||
if (DEEPDEBUG) std::cerr << " 指令 (地址: " << static_cast<void*>(inst) << ") 当前 live_in: " << print_set(current_live_in) << ", 当前 live_out: " << print_set(current_live_out) << std::endl;
|
||||
|
||||
|
||||
// 检查收敛
|
||||
@@ -982,9 +983,9 @@ std::map<Instruction*, std::set<std::string>> RISCv32CodeGen::liveness_analysis(
|
||||
live_in[inst] = new_live_in;
|
||||
live_out[inst] = new_live_out_calc; // 更新 live_out
|
||||
changed = true;
|
||||
if (DEBUG) std::cerr << " 指令 (地址: " << static_cast<void*>(inst) << ") 活跃性集合发生变化,更新并继续迭代." << std::endl;
|
||||
if (DEEPDEBUG) std::cerr << " 指令 (地址: " << static_cast<void*>(inst) << ") 活跃性集合发生变化,更新并继续迭代." << std::endl;
|
||||
} else {
|
||||
if (DEBUG) std::cerr << " 指令 (地址: " << static_cast<void*>(inst) << ") 活跃性集合未发生变化." << std::endl;
|
||||
if (DEEPDEBUG) std::cerr << " 指令 (地址: " << static_cast<void*>(inst) << ") 活跃性集合未发生变化." << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,12 +15,13 @@ namespace sysy {
|
||||
class RISCv32CodeGen {
|
||||
public:
|
||||
enum class PhysicalReg {
|
||||
ZERO, RA, SP, GP, TP, T0, T1, T2, S0, S1, A0, A1, A2, A3, A4, A5, A6, A7, S2, S3, S4, S5, S6, S7, S8, S9, S10, S11, T3, T4, T5, T6
|
||||
ZERO, RA, SP, GP, TP, T0, T1, T2, S0, S1, A0, A1, A2, A3, A4, A5, A6, A7, S2, S3, S4, S5, S6, S7, S8, S9, S10, S11, T3, T4, T5, T6,
|
||||
F0, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, F14, F15,F16, F17, F18, F19, F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F30, F31
|
||||
};
|
||||
|
||||
// Move DAGNode and RegAllocResult to public section
|
||||
struct DAGNode {
|
||||
enum NodeKind { CONSTANT, LOAD, STORE, BINARY, CALL, RETURN, BRANCH, ALLOCA_ADDR }; // Added ALLOCA_ADDR
|
||||
enum NodeKind { CONSTANT, LOAD, STORE, BINARY, CALL, RETURN, BRANCH, ALLOCA_ADDR, UNARY };
|
||||
NodeKind kind;
|
||||
Value* value = nullptr; // For IR Value
|
||||
std::string inst; // Generated RISC-V instruction(s) for this node
|
||||
@@ -40,6 +41,7 @@ public:
|
||||
case RETURN: return "RETURN";
|
||||
case BRANCH: return "BRANCH";
|
||||
case ALLOCA_ADDR: return "ALLOCA_ADDR";
|
||||
case UNARY: return "UNARY";
|
||||
default: return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user