diff --git a/src/RISCv32Backend.cpp b/src/RISCv32Backend.cpp index 271d2c8..c7760e1 100644 --- a/src/RISCv32Backend.cpp +++ b/src/RISCv32Backend.cpp @@ -6,7 +6,7 @@ #include #include // For std::function -#define DEBUG 1 // 开启DEBUG以便查看新输出 +#define DEBUG 0 namespace sysy { // 可用于分配的通用寄存器 @@ -266,7 +266,6 @@ std::vector> RISCv32CodeGen::build_dag( // 为产生结果的值分配虚拟寄存器 // 注意:这里的vreg分配是在每个块中独立进行的,但寄存器分配器是在函数级别运行的 // 我们在寄存器分配前,已经为整个函数的所有value预分配了vreg - // 此处的逻辑应完全依赖于 register_allocation 阶段已经建立的 value_vreg_map // 并且 AllocaInst 不应在此处获取 result_vreg,因为它不映射到物理寄存器。 if (val && value_vreg_map.count(val) && !dynamic_cast(val)) { // 排除 AllocaInst node->result_vreg = value_vreg_map.at(val); @@ -711,8 +710,7 @@ void RISCv32CodeGen::select_instructions(DAGNode* node, const RegAllocResult& al // 如果有返回值,将其移动到 a0 if (!node->operands.empty() && node->operands[0]) { std::string return_val_reg = get_preg_or_temp(node->operands[0]->result_vreg); - // 对于返回值,直接将最终结果移动到 a0 - // 确保 load 的结果最终进入 a0,避免不必要的 t0 中转 + // 对于返回值,直接将最终结果移动到 a0,避免不必要的 t0 中转 ss_inst << "mv a0, " << return_val_reg << "\n"; } @@ -735,7 +733,7 @@ void RISCv32CodeGen::select_instructions(DAGNode* node, const RegAllocResult& al if (node->operands.empty() || !node->operands[0]) break; std::string cond_reg = get_preg_or_temp(node->operands[0]->result_vreg); std::string then_block = br->getThenBlock()->getName(); - std::string else_block = br->getElseBlock()->getName(); + std::string else_block = br->getName(); // 修复空标签问题 if (then_block.empty()) { @@ -762,7 +760,7 @@ void RISCv32CodeGen::select_instructions(DAGNode* node, const RegAllocResult& al break; } default: - // 对于不直接映射到指令的节点 (例如 `alloca` 本身,其地址由其地址节点处理) + // 对于不直接映射到指令的节点 (例如 `alloc` 本身,其地址由其地址节点处理) // 或未处理的指令类型,将 inst 留空。 break; } @@ -855,12 +853,12 @@ std::map> RISCv32CodeGen::liveness_analysis( while (changed) { changed = false; iteration_count++; - std::cout << "\n--- 活跃性分析迭代: " << iteration_count << " ---" << std::endl; + if (DEBUG) std::cerr << "\n--- 活跃性分析迭代: " << iteration_count << " ---" << std::endl; // 逆序遍历基本块 for (auto it = func->getBasicBlocks_NoRange().rbegin(); it != func->getBasicBlocks_NoRange().rend(); ++it) { auto bb = it->get(); - std::cout << " 基本块: " << bb->getName() << std::endl; // 打印基本块名称 + if (DEBUG) std::cerr << " 基本块: " << bb->getName() << std::endl; // 打印基本块名称 // 在基本块内逆序遍历指令 // live_out_for_bb_inst 是当前基本块的 live_out 集合,用于计算该基本块中第一条指令的 live_out @@ -877,7 +875,7 @@ std::map> RISCv32CodeGen::liveness_analysis( for (auto inst_it = bb->getInstructions().rbegin(); inst_it != bb->getInstructions().rend(); ++inst_it) { auto inst = inst_it->get(); // 打印指令,使用其父基本块的名称和指令地址作为唯一标识符 - std::cout << " 指令 (BB: " << bb->getName() << ", 地址: " << static_cast(inst) << ")" << std::endl; + if (DEBUG) std::cerr << " 指令 (BB: " << bb->getName() << ", 地址: " << static_cast(inst) << ")" << std::endl; std::set current_live_in = live_in[inst]; std::set current_live_out = live_out[inst]; // 用于比较的旧 live_out @@ -888,12 +886,12 @@ std::map> RISCv32CodeGen::liveness_analysis( // 那么它的 live_out 就是该基本块的 live_out,即其所有后继基本块的 live_in 的并集 if (inst_it == bb->getInstructions().rbegin()) { new_live_out_calc = live_out_for_bb_inst; - std::cout << " 指令是基本块的最后一条指令,live_out 取自后继基本块 live_in 的并集: " << print_set(new_live_out_calc) << std::endl; + if (DEBUG) 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()]; - std::cout << " 指令不是基本块的最后一条,其 live_out 是其后继指令 live_in: " << print_set(new_live_out_calc) << std::endl; + if (DEBUG) std::cerr << " 指令不是基本块的最后一条,其 live_out 是其后继指令 live_in: " << print_set(new_live_out_calc) << std::endl; } @@ -906,7 +904,7 @@ std::map> RISCv32CodeGen::liveness_analysis( if (!inst->getType()->isVoid() && !dynamic_cast(inst) && !dynamic_cast(inst) && !dynamic_cast(inst) && !dynamic_cast(inst) && !dynamic_cast(inst) && value_vreg_map.count(inst)) { def_set.insert(value_vreg_map.at(inst)); - std::cout << " 指令 (地址: " << static_cast(inst) << ") 定义了虚拟寄存器: " << value_vreg_map.at(inst) << std::endl; + if (DEBUG) std::cerr << " 指令 (地址: " << static_cast(inst) << ") 定义了虚拟寄存器: " << value_vreg_map.at(inst) << std::endl; } // *** 针对 StoreInst 的新逻辑来“杀死”被存储值的虚拟寄存器 *** @@ -935,12 +933,12 @@ std::map> RISCv32CodeGen::liveness_analysis( if (is_unique_user) { def_set.insert(value_vreg_map.at(stored_value)); - std::cout << " Store 指令 (地址: " << static_cast(inst) << ") 将被存储的值 '" << value_vreg_map.at(stored_value) << "' 添加到 def_set (启发式)." << std::endl; + if (DEBUG) std::cerr << " Store 指令 (地址: " << static_cast(inst) << ") 将被存储的值 '" << value_vreg_map.at(stored_value) << "' 添加到 def_set (启发式)." << std::endl; } else { - std::cout << " Store 指令 (地址: " << static_cast(inst) << ") 存储的值 '" << value_vreg_map.at(stored_value) << "' 有其他用途或不是唯一用途,未添加到 def_set。" << std::endl; + if (DEBUG) std::cerr << " Store 指令 (地址: " << static_cast(inst) << ") 存储的值 '" << value_vreg_map.at(stored_value) << "' 有其他用途或不是唯一用途,未添加到 def_set。" << std::endl; } } else if (dynamic_cast(stored_value)) { - std::cout << " Store 指令存储的是 AllocaInst 地址,不处理其虚拟寄存器定义。" << std::endl; + if (DEBUG) std::cerr << " Store 指令存储的是 AllocaInst 地址,不处理其虚拟寄存器定义。" << std::endl; } } // *** 结束新逻辑 *** @@ -953,17 +951,17 @@ std::map> RISCv32CodeGen::liveness_analysis( // 并且确保 operand 已经在 value_vreg_map 中有对应的虚拟寄存器。 if (value_vreg_map.count(operand) && !dynamic_cast(operand)) { use_set.insert(value_vreg_map.at(operand)); - std::cout << " 指令 (地址: " << static_cast(inst) << ") 使用了虚拟寄存器: " << value_vreg_map.at(operand) << std::endl; + if (DEBUG) std::cerr << " 指令 (地址: " << static_cast(inst) << ") 使用了虚拟寄存器: " << value_vreg_map.at(operand) << std::endl; } else if (dynamic_cast(operand)) { - std::cout << " 指令 (地址: " << static_cast(inst) << ") 操作数是 AllocaInst 地址,不添加到 use_set。" << std::endl; + if (DEBUG) std::cerr << " 指令 (地址: " << static_cast(inst) << ") 操作数是 AllocaInst 地址,不添加到 use_set。" << std::endl; } else { // 对于常量,它们没有虚拟寄存器,也不应该被添加到use_set // 也可以是其他没有对应虚拟寄存器(例如函数名)的值。 - std::cout << " 指令 (地址: " << static_cast(inst) << ") 操作数没有对应的虚拟寄存器,或不是需要寄存器的值。" << std::endl; + if (DEBUG) std::cerr << " 指令 (地址: " << static_cast(inst) << ") 操作数没有对应的虚拟寄存器,或不是需要寄存器的值。" << std::endl; } } - std::cout << " 指令 (地址: " << static_cast(inst) << ") 的 use_set: " << print_set(use_set) << std::endl; - std::cout << " 指令 (地址: " << static_cast(inst) << ") 的 def_set: " << print_set(def_set) << std::endl; + if (DEBUG) std::cerr << " 指令 (地址: " << static_cast(inst) << ") 的 use_set: " << print_set(use_set) << std::endl; + if (DEBUG) std::cerr << " 指令 (地址: " << static_cast(inst) << ") 的 def_set: " << print_set(def_set) << std::endl; // 计算新的 live_in = use U (new_live_out_calc - def) @@ -974,8 +972,8 @@ std::map> RISCv32CodeGen::liveness_analysis( } } - std::cout << " 指令 (地址: " << static_cast(inst) << ") 计算出的 new_live_in: " << print_set(new_live_in) << std::endl; - std::cout << " 指令 (地址: " << static_cast(inst) << ") 当前 live_in: " << print_set(current_live_in) << ", 当前 live_out: " << print_set(current_live_out) << std::endl; + if (DEBUG) std::cerr << " 指令 (地址: " << static_cast(inst) << ") 计算出的 new_live_in: " << print_set(new_live_in) << std::endl; + if (DEBUG) std::cerr << " 指令 (地址: " << static_cast(inst) << ") 当前 live_in: " << print_set(current_live_in) << ", 当前 live_out: " << print_set(current_live_out) << std::endl; // 检查收敛 @@ -983,9 +981,9 @@ std::map> RISCv32CodeGen::liveness_analysis( live_in[inst] = new_live_in; live_out[inst] = new_live_out_calc; // 更新 live_out changed = true; - std::cout << " 指令 (地址: " << static_cast(inst) << ") 活跃性集合发生变化,更新并继续迭代." << std::endl; + if (DEBUG) std::cerr << " 指令 (地址: " << static_cast(inst) << ") 活跃性集合发生变化,更新并继续迭代." << std::endl; } else { - std::cout << " 指令 (地址: " << static_cast(inst) << ") 活跃性集合未发生变化." << std::endl; + if (DEBUG) std::cerr << " 指令 (地址: " << static_cast(inst) << ") 活跃性集合未发生变化." << std::endl; } } } @@ -1162,52 +1160,53 @@ RISCv32CodeGen::RegAllocResult RISCv32CodeGen::register_allocation(Function* fun // 如果一个vreg没有被着色,get_preg_or_temp会回退到t0,这对于简单情况可能够用。 // 打印寄存器分配结果 (调试用) - std::cerr << "=== 寄存器分配结果 (vreg_to_preg) ===\n"; - for (const auto& pair : alloc_result.vreg_to_preg) { - std::cerr << " " << pair.first << " -> " << reg_to_string(pair.second) << "\n"; - } - std::cerr << "=== 寄存器分配结果结束 ===\n\n"; + if (DEBUG) { + std::cerr << "=== 寄存器分配结果 (vreg_to_preg) ===\n"; + for (const auto& pair : alloc_result.vreg_to_preg) { + std::cerr << " " << pair.first << " -> " << reg_to_string(pair.second) << "\n"; + } + std::cerr << "=== 寄存器分配结果结束 ===\n\n"; - // 打印活跃性分析结果 (调试用) - std::cerr << "=== 活跃性分析结果 (live_in sets) ===\n"; - for (const auto& bb_ptr : func->getBasicBlocks()) { - std::cerr << "Basic Block: " << bb_ptr->getName() << "\n"; - for (const auto& inst_ptr : bb_ptr->getInstructions()) { - std::cerr << " Inst: " << inst_ptr->getKindString(); - if (!inst_ptr->getName().empty()) { - std::cerr << "(" << inst_ptr->getName() << ")"; - } - if (value_vreg_map.count(inst_ptr.get())) { - std::cerr << " (Def vreg: " << value_vreg_map.at(inst_ptr.get()) << ")"; - } - std::cerr << " (Live In: {"; - bool first = true; - if (live_sets.count(inst_ptr.get())) { - for (const auto& vreg : live_sets.at(inst_ptr.get())) { - if (!first) std::cerr << ", "; - std::cerr << vreg; - first = false; + // 打印活跃性分析结果 (调试用) + std::cerr << "=== 活跃性分析结果 (live_in sets) ===\n"; + for (const auto& bb_ptr : func->getBasicBlocks()) { + std::cerr << "Basic Block: " << bb_ptr->getName() << "\n"; + for (const auto& inst_ptr : bb_ptr->getInstructions()) { + std::cerr << " Inst: " << inst_ptr->getKindString(); + if (!inst_ptr->getName().empty()) { + std::cerr << "(" << inst_ptr->getName() << ")"; } + if (value_vreg_map.count(inst_ptr.get())) { + std::cerr << " (Def vreg: " << value_vreg_map.at(inst_ptr.get()) << ")"; + } + std::cerr << " (Live In: {"; + bool first = true; + if (live_sets.count(inst_ptr.get())) { + for (const auto& vreg : live_sets.at(inst_ptr.get())) { + if (!first) std::cerr << ", "; + std::cerr << vreg; + first = false; + } + } + std::cerr << "})\n"; } - std::cerr << "})\n"; } - } - std::cerr << "=== 活跃性分析结果结束 ===\n\n"; + std::cerr << "=== 活跃性分析结果结束 ===\n\n"; - // 打印干扰图 (调试用) - std::cerr << "=== 干扰图 ===\n"; - for (const auto& pair : interference_graph) { - std::cerr << " " << pair.first << ": {"; - bool first = true; - for (const auto& neighbor : pair.second) { - if (!first) std::cerr << ", "; - std::cerr << neighbor; - first = false; + // 打印干扰图 (调试用) + std::cerr << "=== 干扰图 ===\n"; + for (const auto& pair : interference_graph) { + std::cerr << " " << pair.first << ": {"; + bool first = true; + for (const auto& neighbor : pair.second) { + if (!first) std::cerr << ", "; + std::cerr << neighbor; + first = false; + } + std::cerr << "}\n"; } - std::cerr << "}\n"; + std::cerr << "=== 干扰图结束 ===\n\n"; } - std::cerr << "=== 干扰图结束 ===\n\n"; - return alloc_result; }