[backend]修复了栈分配空间大小不考虑数组的错误

This commit is contained in:
Lixuanwang
2025-07-18 18:44:13 +08:00
parent 198c1974e3
commit 4bf4c98787

View File

@ -1049,6 +1049,7 @@ std::map<Instruction*, std::set<std::string>> RISCv64CodeGen::liveness_analysis(
std::map<Instruction*, std::set<std::string>> live_in, live_out;
bool changed = true;
// 初始化 live_in 和 live_out
for (const auto& bb : func->getBasicBlocks()) {
for (const auto& inst_ptr : bb->getInstructions()) {
live_in[inst_ptr.get()] = {};
@ -1062,6 +1063,7 @@ std::map<Instruction*, std::set<std::string>> RISCv64CodeGen::liveness_analysis(
iteration_count++;
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 (DEEPDEBUG) std::cerr << " 基本块: " << bb->getName() << std::endl;
@ -1074,6 +1076,7 @@ std::map<Instruction*, std::set<std::string>> RISCv64CodeGen::liveness_analysis(
}
}
// 逆序遍历指令
for (auto inst_it = bb->getInstructions().rbegin(); inst_it != bb->getInstructions().rend(); ++inst_it) {
auto inst = inst_it->get();
if (DEEPDEBUG) std::cerr << " 指令 (BB: " << bb->getName() << ", 地址: " << static_cast<void*>(inst) << ")" << std::endl;
@ -1082,6 +1085,7 @@ std::map<Instruction*, std::set<std::string>> RISCv64CodeGen::liveness_analysis(
std::set<std::string> current_live_out = live_out[inst];
std::set<std::string> new_live_out_calc;
// 计算 live_out
if (inst_it == bb->getInstructions().rbegin()) {
new_live_out_calc = live_out_for_bb_inst;
if (DEEPDEBUG) std::cerr << " 指令是基本块的最后一条指令live_out 取自后继基本块 live_in 的并集: " << print_set(new_live_out_calc) << std::endl;
@ -1100,34 +1104,26 @@ std::map<Instruction*, std::set<std::string>> RISCv64CodeGen::liveness_analysis(
if (DEEPDEBUG) std::cerr << " 指令 (地址: " << static_cast<void*>(inst) << ") 定义了虚拟寄存器: " << value_vreg_map.at(inst) << std::endl;
}
// StoreInst 的值可能被“杀死”
if (auto store = dynamic_cast<StoreInst*>(inst)) {
Value* stored_value = store->getValue();
if (value_vreg_map.count(stored_value) && !dynamic_cast<AllocaInst*>(stored_value)) {
bool is_unique_user = true;
if (!stored_value->getUses().empty()) {
is_unique_user = (stored_value->getUses().size() == 1 && stored_value->getUses().front()->getUser() == inst);
} else {
is_unique_user = false;
}
if (is_unique_user) {
def_set.insert(value_vreg_map.at(stored_value));
if (DEEPDEBUG) std::cerr << " Store 指令 (地址: " << static_cast<void*>(inst) << ") 将被存储的值 '" << value_vreg_map.at(stored_value) << "' 添加到 def_set (启发式)." << std::endl;
}
}
}
// 使用 (Use)
// 使用 (Use) - 增强对常量的处理
for (const auto& operand_use : inst->getOperands()) {
Value* operand = operand_use->getValue();
if (value_vreg_map.count(operand) && !dynamic_cast<AllocaInst*>(operand)) {
use_set.insert(value_vreg_map.at(operand));
if (DEEPDEBUG) std::cerr << " 指令 (地址: " << static_cast<void*>(inst) << ") 使用了虚拟寄存器: " << value_vreg_map.at(operand) << std::endl;
}
// 如果是常量,确保其活跃性被记录
if (auto constant = dynamic_cast<ConstantValue*>(operand)) {
if (value_vreg_map.count(constant)) {
use_set.insert(value_vreg_map.at(constant));
if (DEEPDEBUG) std::cerr << " 常量 (值: " << (constant->isInt() ? std::to_string(constant->getInt()) : std::to_string(constant->getFloat())) << ") 使用了虚拟寄存器: " << value_vreg_map.at(constant) << 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
std::set<std::string> new_live_in = use_set;
for (const auto& vreg : new_live_out_calc) {
if (def_set.find(vreg) == def_set.end()) {
@ -1138,6 +1134,7 @@ std::map<Instruction*, std::set<std::string>> RISCv64CodeGen::liveness_analysis(
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;
// 如果活跃性集合发生变化,更新并继续迭代
if (new_live_in != current_live_in || new_live_out_calc != current_live_out) {
live_in[inst] = new_live_in;
live_out[inst] = new_live_out_calc;
@ -1342,12 +1339,15 @@ RISCv64CodeGen::RegAllocResult RISCv64CodeGen::register_allocation(Function* fun
}
}
}
// 清空临时指令存储
temp_instructions_storage.clear();
}
RegAllocResult alloc_result;
int current_stack_offset = 0;
std::set<AllocaInst*> allocas_in_func;
// 收集函数中的所有 AllocaInst
for (const auto& bb_ptr : func->getBasicBlocks()) {
for (const auto& inst_ptr : bb_ptr->getInstructions()) {
if (auto alloca = dynamic_cast<AllocaInst*>(inst_ptr.get())) {
@ -1356,13 +1356,30 @@ RISCv64CodeGen::RegAllocResult RISCv64CodeGen::register_allocation(Function* fun
}
}
// 为每个 AllocaInst 计算栈空间并分配偏移量
for (auto alloca : allocas_in_func) {
int size = 4; // 假设 i32 或 float, 依旧是4字节
int total_size = 4; // 基本元素大小int 或 float
auto dims = alloca->getDims();
if (!dims.empty()) {
int num_elements = 1;
for (const auto& dim_use : dims) {
Value* dim_value = dim_use->getValue();
if (auto const_dim = dynamic_cast<ConstantValue*>(dim_value)) {
if (const_dim->isInt()) {
num_elements *= const_dim->getInt();
} else {
throw std::runtime_error("数组维度必须是整数");
}
} else {
throw std::runtime_error("数组维度必须是编译时常量");
}
}
total_size *= num_elements;
}
alloc_result.stack_map[alloca] = current_stack_offset;
current_stack_offset += size;
current_stack_offset += total_size;
}
// RV64 修改: 为保存的 ra 和 s0 (各8字节) 预留16字节空间
alloc_result.stack_size = current_stack_offset + 16;
alloc_result.stack_size = current_stack_offset + 16; // 为 ra 和 s0 预留16字节
// 活跃性分析
std::map<Instruction*, std::set<std::string>> live_sets = liveness_analysis(func);
@ -1370,8 +1387,138 @@ RISCv64CodeGen::RegAllocResult RISCv64CodeGen::register_allocation(Function* fun
// 构建干扰图
std::map<std::string, std::set<std::string>> interference_graph = build_interference_graph(live_sets);
// 图着色
color_graph(alloc_result.vreg_to_preg, interference_graph);
// 增强生命周期跟踪:记录每个虚拟寄存器的活跃范围
std::map<std::string, std::pair<Instruction*, Instruction*>> vreg_lifetimes; // <开始指令, 结束指令>
for (const auto& bb_ptr : func->getBasicBlocks()) {
for (const auto& inst_ptr : bb_ptr->getInstructions()) {
Instruction* inst = inst_ptr.get();
if (value_vreg_map.count(inst) && !dynamic_cast<AllocaInst*>(inst)) {
std::string vreg = value_vreg_map.at(inst);
if (vreg_lifetimes.find(vreg) == vreg_lifetimes.end()) {
vreg_lifetimes[vreg].first = inst; // 定义点作为生命周期开始
}
}
for (const auto& operand_use : inst->getOperands()) {
Value* operand = operand_use->getValue();
if (value_vreg_map.count(operand) && !dynamic_cast<AllocaInst*>(operand)) {
std::string vreg = value_vreg_map.at(operand);
vreg_lifetimes[vreg].second = inst; // 使用点更新生命周期结束
}
}
}
}
// 图着色,基于生命周期优化寄存器分配
std::map<std::string, PhysicalReg>& vreg_to_preg = alloc_result.vreg_to_preg;
vreg_to_preg.clear();
std::vector<PhysicalReg> int_regs = {
PhysicalReg::T0, PhysicalReg::T1, PhysicalReg::T2, PhysicalReg::T3,
PhysicalReg::T4, PhysicalReg::T5, PhysicalReg::T6,
PhysicalReg::A0, PhysicalReg::A1, PhysicalReg::A2, PhysicalReg::A3,
PhysicalReg::A4, PhysicalReg::A5, PhysicalReg::A6, PhysicalReg::A7,
PhysicalReg::S0, PhysicalReg::S1, PhysicalReg::S2, PhysicalReg::S3,
PhysicalReg::S4, PhysicalReg::S5, PhysicalReg::S6, PhysicalReg::S7,
PhysicalReg::S8, PhysicalReg::S9, PhysicalReg::S10, PhysicalReg::S11
};
std::vector<PhysicalReg> float_regs = {
PhysicalReg::F0, PhysicalReg::F1, PhysicalReg::F2, PhysicalReg::F3,
PhysicalReg::F4, PhysicalReg::F5, PhysicalReg::F6, PhysicalReg::F7,
PhysicalReg::F8, PhysicalReg::F9, PhysicalReg::F10, PhysicalReg::F11,
PhysicalReg::F12, PhysicalReg::F13, PhysicalReg::F14, PhysicalReg::F15,
PhysicalReg::F16, PhysicalReg::F17, PhysicalReg::F18, PhysicalReg::F19,
PhysicalReg::F20, PhysicalReg::F21, PhysicalReg::F22, PhysicalReg::F23,
PhysicalReg::F24, PhysicalReg::F25, PhysicalReg::F26, PhysicalReg::F27,
PhysicalReg::F28, PhysicalReg::F29, PhysicalReg::F30, PhysicalReg::F31
};
auto is_float_vreg = [&](const std::string& vreg) -> bool {
for (const auto& pair : value_vreg_map) {
if (pair.second == vreg) {
if (auto inst = dynamic_cast<Instruction*>(pair.first)) {
if (inst->isUnary()) {
switch (inst->getKind()) {
case Instruction::kFNeg:
case Instruction::kFNot:
case Instruction::kFtoI:
case Instruction::kItoF:
case Instruction::kBitFtoI:
case Instruction::kBitItoF:
return true;
default:
return inst->getType()->isFloat();
}
}
return inst->getType()->isFloat();
} else if (auto constant = dynamic_cast<ConstantValue*>(pair.first)) {
return constant->isFloat();
}
}
}
return false;
};
// 按活跃范围长度排序虚拟寄存器,优先分配长生命周期的寄存器
std::vector<std::pair<std::string, int>> vreg_priorities;
for (const auto& vreg_life : vreg_lifetimes) {
const std::string& vreg = vreg_life.first;
int lifetime_length = std::distance(
func->getBasicBlocks().begin(),
std::find_if(func->getBasicBlocks().begin(), func->getBasicBlocks().end(),
[&](const auto& bb) {
return std::find_if(bb->getInstructions().begin(), bb->getInstructions().end(),
[&](const auto& inst) { return inst.get() == vreg_life.second.second; }) != bb->getInstructions().end();
})) -
std::distance(
func->getBasicBlocks().begin(),
std::find_if(func->getBasicBlocks().begin(), func->getBasicBlocks().end(),
[&](const auto& bb) {
return std::find_if(bb->getInstructions().begin(), bb->getInstructions().end(),
[&](const auto& inst) { return inst.get() == vreg_life.second.first; }) != bb->getInstructions().end();
}));
vreg_priorities.push_back({vreg, lifetime_length});
}
std::sort(vreg_priorities.begin(), vreg_priorities.end(),
[](const auto& a, const auto& b) { return a.second > b.second; });
// 分配寄存器,考虑生命周期重叠
for (const auto& vreg_prio : vreg_priorities) {
const std::string& vreg = vreg_prio.first;
std::set<PhysicalReg> used_colors;
bool is_float = is_float_vreg(vreg);
// 检查干扰图和生命周期重叠
if (interference_graph.count(vreg)) {
for (const auto& neighbor_vreg : interference_graph.at(vreg)) {
if (vreg_to_preg.count(neighbor_vreg)) {
Instruction* neighbor_start = vreg_lifetimes[neighbor_vreg].first;
Instruction* neighbor_end = vreg_lifetimes[neighbor_vreg].second;
Instruction* current_start = vreg_lifetimes[vreg].first;
Instruction* current_end = vreg_lifetimes[vreg].second;
// 判断生命周期是否重叠
if (!(current_end < neighbor_start || current_start > neighbor_end)) {
used_colors.insert(vreg_to_preg.at(neighbor_vreg));
}
}
}
}
const auto& available_regs = is_float ? float_regs : int_regs;
bool colored = false;
for (PhysicalReg preg : available_regs) {
if (used_colors.find(preg) == used_colors.end()) {
vreg_to_preg[vreg] = preg;
colored = true;
break;
}
}
if (!colored) {
std::cerr << "警告: 无法为 " << vreg << " 分配" << (is_float ? "浮点" : "整数") << "寄存器,将溢出到栈。\n";
// 溢出处理逻辑待完善
}
}
if (DEBUG) {
std::cerr << "=== 寄存器分配结果 (vreg_to_preg) ===\n";