diff --git a/src/RISCv64Backend.cpp b/src/RISCv64Backend.cpp index 25012d4..ca68897 100644 --- a/src/RISCv64Backend.cpp +++ b/src/RISCv64Backend.cpp @@ -1049,6 +1049,7 @@ std::map> RISCv64CodeGen::liveness_analysis( std::map> 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> 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> 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(inst) << ")" << std::endl; @@ -1082,6 +1085,7 @@ std::map> RISCv64CodeGen::liveness_analysis( std::set current_live_out = live_out[inst]; std::set 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> RISCv64CodeGen::liveness_analysis( if (DEEPDEBUG) std::cerr << " 指令 (地址: " << static_cast(inst) << ") 定义了虚拟寄存器: " << value_vreg_map.at(inst) << std::endl; } - // StoreInst 的值可能被“杀死” - if (auto store = dynamic_cast(inst)) { - Value* stored_value = store->getValue(); - if (value_vreg_map.count(stored_value) && !dynamic_cast(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(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(operand)) { use_set.insert(value_vreg_map.at(operand)); if (DEEPDEBUG) std::cerr << " 指令 (地址: " << static_cast(inst) << ") 使用了虚拟寄存器: " << value_vreg_map.at(operand) << std::endl; } + // 如果是常量,确保其活跃性被记录 + if (auto constant = dynamic_cast(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(inst) << ") 的 use_set: " << print_set(use_set) << std::endl; if (DEEPDEBUG) std::cerr << " 指令 (地址: " << static_cast(inst) << ") 的 def_set: " << print_set(def_set) << std::endl; + // 计算新的 live_in std::set 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> RISCv64CodeGen::liveness_analysis( if (DEEPDEBUG) std::cerr << " 指令 (地址: " << static_cast(inst) << ") 计算出的 new_live_in: " << print_set(new_live_in) << std::endl; if (DEEPDEBUG) std::cerr << " 指令 (地址: " << static_cast(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 allocas_in_func; + // 收集函数中的所有 AllocaInst for (const auto& bb_ptr : func->getBasicBlocks()) { for (const auto& inst_ptr : bb_ptr->getInstructions()) { if (auto alloca = dynamic_cast(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(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> live_sets = liveness_analysis(func); @@ -1370,8 +1387,138 @@ RISCv64CodeGen::RegAllocResult RISCv64CodeGen::register_allocation(Function* fun // 构建干扰图 std::map> interference_graph = build_interference_graph(live_sets); - // 图着色 - color_graph(alloc_result.vreg_to_preg, interference_graph); + // 增强生命周期跟踪:记录每个虚拟寄存器的活跃范围 + std::map> 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(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(operand)) { + std::string vreg = value_vreg_map.at(operand); + vreg_lifetimes[vreg].second = inst; // 使用点更新生命周期结束 + } + } + } + } + + // 图着色,基于生命周期优化寄存器分配 + std::map& vreg_to_preg = alloc_result.vreg_to_preg; + vreg_to_preg.clear(); + + std::vector 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 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(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(pair.first)) { + return constant->isFloat(); + } + } + } + return false; + }; + + // 按活跃范围长度排序虚拟寄存器,优先分配长生命周期的寄存器 + std::vector> 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 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";