[backend] fixed bugs of deadcode elimation

This commit is contained in:
Lixuanwang
2025-06-25 18:56:08 +08:00
parent 019cb6dc0d
commit d06c5efae1

View File

@ -1,16 +1,16 @@
#include "RISCv64Backend.h" // 修改头文件名 #include "RISCv64Backend.h"
#include <sstream> #include <sstream>
#include <algorithm> #include <algorithm>
#include <stdexcept> #include <stdexcept>
#include <regex> #include <regex>
#include <iomanip> #include <iomanip>
#include <functional> // For std::function #include <functional>
#define DEBUG 1 #define DEBUG 1
#define DEEPDEBUG 0 #define DEEPDEBUG 0
namespace sysy { namespace sysy {
// 可用于分配的寄存器(整数和浮点) // 可用于分配的寄存器
const std::vector<RISCv64CodeGen::PhysicalReg> RISCv64CodeGen::allocable_regs = { const std::vector<RISCv64CodeGen::PhysicalReg> RISCv64CodeGen::allocable_regs = {
// 整数寄存器 // 整数寄存器
PhysicalReg::T0, PhysicalReg::T1, PhysicalReg::T2, PhysicalReg::T3, PhysicalReg::T0, PhysicalReg::T1, PhysicalReg::T2, PhysicalReg::T3,
@ -111,7 +111,6 @@ std::string RISCv64CodeGen::code_gen() {
} }
// 模块级代码生成 (处理全局变量和函数) // 模块级代码生成 (处理全局变量和函数)
// 注意:由于 int 和 float 仍然是32位.word 的使用是正确的。
std::string RISCv64CodeGen::module_gen() { std::string RISCv64CodeGen::module_gen() {
std::stringstream ss; std::stringstream ss;
bool has_globals = !module->getGlobals().empty(); bool has_globals = !module->getGlobals().empty();
@ -173,7 +172,6 @@ std::string RISCv64CodeGen::function_gen(Function* func) {
ss << " mv s0, sp\n"; // 设置新的帧指针 ss << " mv s0, sp\n"; // 设置新的帧指针
} }
// *** 新增的逻辑:处理传入的函数参数 ***
// 将传入的寄存器参数 (a0-a7 / f10-f17) 保存到对应的栈槽 (AllocaInst)。 // 将传入的寄存器参数 (a0-a7 / f10-f17) 保存到对应的栈槽 (AllocaInst)。
// RV64中a0-a7是64位寄存器但我们传入的int/float是32位。 // RV64中a0-a7是64位寄存器但我们传入的int/float是32位。
// 使用 sw/fsw 会正确地存储低32位这是正确的行为。 // 使用 sw/fsw 会正确地存储低32位这是正确的行为。
@ -227,7 +225,7 @@ std::string RISCv64CodeGen::function_gen(Function* func) {
} }
// 基本块代码生成 (无修改) // 基本块代码生成
std::string RISCv64CodeGen::basicBlock_gen(BasicBlock* bb, const RegAllocResult& alloc, int block_idx) { std::string RISCv64CodeGen::basicBlock_gen(BasicBlock* bb, const RegAllocResult& alloc, int block_idx) {
std::stringstream ss; std::stringstream ss;
@ -241,15 +239,8 @@ std::string RISCv64CodeGen::basicBlock_gen(BasicBlock* bb, const RegAllocResult&
else { else {
ss << bb_name << ":\n"; // 基本块标签 ss << bb_name << ":\n"; // 基本块标签
} }
// !!! 重要的修改:此处不再清除 value_vreg_map 和 vreg_counter。
// !!! 这些映射在 function_gen -> register_allocation 阶段为整个函数建立。
// value_vreg_map.clear(); // 移除此行
// vreg_counter = 0; // 移除此行
// 构建当前基本块的 DAG // 构建当前基本块的 DAG
// 注意DAGNode 的唯一性在当前函数范围内是重要的,
// 所以 build_dag 应该返回一个完整的 DAG 节点列表,而不是每次都创建新的。
// 为了简化,这里仍然按块构建,但需要注意跨块值的使用。
auto dag_nodes_for_bb = build_dag(bb); auto dag_nodes_for_bb = build_dag(bb);
if (DEBUG) if (DEBUG)
print_dag(dag_nodes_for_bb, bb_name); // 打印 DAG 调试信息 print_dag(dag_nodes_for_bb, bb_name); // 打印 DAG 调试信息
@ -413,8 +404,10 @@ std::vector<std::unique_ptr<RISCv64CodeGen::DAGNode>> RISCv64CodeGen::build_dag(
val_node->users.push_back(store_node); val_node->users.push_back(store_node);
ptr_node->users.push_back(store_node); ptr_node->users.push_back(store_node);
// !!! 新增:处理 StoreInst 的 indices if (store->getNumIndices())
if (DEBUG) std::cerr << "处理 StoreInst 的 indices: " << store->getNumIndices() << "\n"; // 调试输出
for (int i = 0; i < store->getNumIndices(); ++i) { for (int i = 0; i < store->getNumIndices(); ++i) {
if (DEBUG) std::cerr << "处理 StoreInst 的 indices: " << i << "\n"; // 调试输出
Value* index_ir = store->getIndex(i); Value* index_ir = store->getIndex(i);
DAGNode* index_node = get_operand_node(index_ir, value_to_node, nodes_storage); // 传递参数 DAGNode* index_node = get_operand_node(index_ir, value_to_node, nodes_storage); // 传递参数
store_node->operands.push_back(index_node); store_node->operands.push_back(index_node);
@ -430,7 +423,6 @@ std::vector<std::unique_ptr<RISCv64CodeGen::DAGNode>> RISCv64CodeGen::build_dag(
load_node->operands.push_back(ptr_node); load_node->operands.push_back(ptr_node);
ptr_node->users.push_back(load_node); ptr_node->users.push_back(load_node);
// !!! 新增:处理 LoadInst 的 indices
for (int i = 0; i < load->getNumIndices(); ++i) { for (int i = 0; i < load->getNumIndices(); ++i) {
Value* index_ir = load->getIndex(i); Value* index_ir = load->getIndex(i);
DAGNode* index_node = get_operand_node(index_ir, value_to_node, nodes_storage); // 传递参数 DAGNode* index_node = get_operand_node(index_ir, value_to_node, nodes_storage); // 传递参数
@ -443,7 +435,6 @@ std::vector<std::unique_ptr<RISCv64CodeGen::DAGNode>> RISCv64CodeGen::build_dag(
} else if (auto bin = dynamic_cast<BinaryInst*>(inst)) { } else if (auto bin = dynamic_cast<BinaryInst*>(inst)) {
if (value_to_node.count(bin)) continue; // CSE if (value_to_node.count(bin)) continue; // CSE
// --- 关键修改:识别 SUB 0, X 或 FSUB 0.0, X 模式为 NEG ---
if (bin->getKind() == BinaryInst::kSub || bin->getKind() == BinaryInst::kFSub) { if (bin->getKind() == BinaryInst::kSub || bin->getKind() == BinaryInst::kFSub) {
Value* lhs_ir = bin->getLhs(); Value* lhs_ir = bin->getLhs();
if (auto const_lhs = dynamic_cast<ConstantValue*>(lhs_ir)) { if (auto const_lhs = dynamic_cast<ConstantValue*>(lhs_ir)) {
@ -468,14 +459,9 @@ std::vector<std::unique_ptr<RISCv64CodeGen::DAGNode>> RISCv64CodeGen::build_dag(
} }
} }
} }
// --- 结束关键修改 ---
// 常规二进制操作 // 常规二进制操作
auto bin_node = create_node(DAGNode::BINARY, bin, value_to_node, nodes_storage); // 传递参数 auto bin_node = create_node(DAGNode::BINARY, bin, value_to_node, nodes_storage); // 传递参数
// !!! 移除 lambda 版本的 get_operand_node现在调用成员函数版本 !!!
// auto get_operand_node = [&](Value* operand_ir) -> DAGNode* { ... };
DAGNode* lhs_node = get_operand_node(bin->getLhs(), value_to_node, nodes_storage); // 传递参数 DAGNode* lhs_node = get_operand_node(bin->getLhs(), value_to_node, nodes_storage); // 传递参数
DAGNode* rhs_node = get_operand_node(bin->getRhs(), value_to_node, nodes_storage); // 传递参数 DAGNode* rhs_node = get_operand_node(bin->getRhs(), value_to_node, nodes_storage); // 传递参数
@ -483,6 +469,7 @@ std::vector<std::unique_ptr<RISCv64CodeGen::DAGNode>> RISCv64CodeGen::build_dag(
bin_node->operands.push_back(rhs_node); bin_node->operands.push_back(rhs_node);
lhs_node->users.push_back(bin_node); lhs_node->users.push_back(bin_node);
rhs_node->users.push_back(bin_node); rhs_node->users.push_back(bin_node);
} else if (auto un_inst = dynamic_cast<UnaryInst*>(inst)) { } else if (auto un_inst = dynamic_cast<UnaryInst*>(inst)) {
if (value_to_node.count(un_inst)) continue; if (value_to_node.count(un_inst)) continue;
@ -493,11 +480,10 @@ std::vector<std::unique_ptr<RISCv64CodeGen::DAGNode>> RISCv64CodeGen::build_dag(
unary_node->operands.push_back(operand_node); unary_node->operands.push_back(operand_node);
operand_node->users.push_back(unary_node); operand_node->users.push_back(unary_node);
} else if (auto call = dynamic_cast<CallInst*>(inst)) { } else if (auto call = dynamic_cast<CallInst*>(inst)) {
if (value_to_node.count(call)) continue; if (value_to_node.count(call)) continue;
auto call_node = create_node(DAGNode::CALL, call, value_to_node, nodes_storage); // 传递参数 auto call_node = create_node(DAGNode::CALL, call, value_to_node, nodes_storage); // 传递参数
for (auto arg : call->getArguments()) { for (auto arg : call->getArguments()) {
auto arg_val_ir = arg->getValue(); auto arg_val_ir = arg->getValue();
DAGNode* arg_node = get_operand_node(arg_val_ir, value_to_node, nodes_storage); // 传递参数 DAGNode* arg_node = get_operand_node(arg_val_ir, value_to_node, nodes_storage); // 传递参数
@ -505,6 +491,7 @@ std::vector<std::unique_ptr<RISCv64CodeGen::DAGNode>> RISCv64CodeGen::build_dag(
arg_node->users.push_back(call_node); arg_node->users.push_back(call_node);
} }
} else if (auto ret = dynamic_cast<ReturnInst*>(inst)) { } else if (auto ret = dynamic_cast<ReturnInst*>(inst)) {
std::cout << "处理 RETURN 指令: " << ret->getName() << "\n"; // 调试输出
auto ret_node = create_node(DAGNode::RETURN, ret, value_to_node, nodes_storage); // 传递参数 auto ret_node = create_node(DAGNode::RETURN, ret, value_to_node, nodes_storage); // 传递参数
if (ret->hasReturnValue()) { if (ret->hasReturnValue()) {
auto val_ir = ret->getReturnValue(); auto val_ir = ret->getReturnValue();
@ -528,11 +515,10 @@ std::vector<std::unique_ptr<RISCv64CodeGen::DAGNode>> RISCv64CodeGen::build_dag(
br_node->inst = "j " + uncond_br->getBlock()->getName(); br_node->inst = "j " + uncond_br->getBlock()->getName();
} }
} }
return nodes_storage; return nodes_storage;
} }
// 打印 DAG (保持不变) // 打印 DAG
void RISCv64CodeGen::print_dag(const std::vector<std::unique_ptr<DAGNode>>& dag, const std::string& bb_name) { void RISCv64CodeGen::print_dag(const std::vector<std::unique_ptr<DAGNode>>& dag, const std::string& bb_name) {
std::cerr << "=== DAG for Basic Block: " << bb_name << " ===\n"; std::cerr << "=== DAG for Basic Block: " << bb_name << " ===\n";
std::set<DAGNode*> visited; std::set<DAGNode*> visited;
@ -584,7 +570,6 @@ void RISCv64CodeGen::print_dag(const std::vector<std::unique_ptr<DAGNode>>& dag,
} }
visited.insert(node); visited.insert(node);
if (!node->operands.empty()) { if (!node->operands.empty()) {
std::cerr << current_indent << " 操作数:\n"; std::cerr << current_indent << " 操作数:\n";
for (auto operand : node->operands) { for (auto operand : node->operands) {
@ -609,7 +594,6 @@ void RISCv64CodeGen::print_dag(const std::vector<std::unique_ptr<DAGNode>>& dag,
std::cerr << "=== DAG 结束 ===\n\n"; std::cerr << "=== DAG 结束 ===\n\n";
} }
// 指令选择 // 指令选择
void RISCv64CodeGen::select_instructions(DAGNode* node, const RegAllocResult& alloc) { void RISCv64CodeGen::select_instructions(DAGNode* node, const RegAllocResult& alloc) {
if (!node) return; if (!node) return;
@ -906,10 +890,6 @@ void RISCv64CodeGen::emit_instructions(DAGNode* node, std::stringstream& ss, con
// 处理虚拟寄存器替换和溢出/加载逻辑 // 处理虚拟寄存器替换和溢出/加载逻辑
std::string processed_line = line; std::string processed_line = line;
// 注意:这里的替换逻辑比较脆弱,因为 select_instructions 已经直接生成了物理寄存器名
// 在一个更健壮的系统中select_instructions 会生成带vreg的指令而这里会进行替换
// 当前的实现下,这个替换逻辑大部分时间是空操作,但为了安全保留
// 替换结果虚拟寄存器 (如果此行中存在) // 替换结果虚拟寄存器 (如果此行中存在)
if (!node->result_vreg.empty() && alloc.vreg_to_preg.count(node->result_vreg)) { if (!node->result_vreg.empty() && alloc.vreg_to_preg.count(node->result_vreg)) {
std::string preg = reg_to_string(alloc.vreg_to_preg.at(node->result_vreg)); std::string preg = reg_to_string(alloc.vreg_to_preg.at(node->result_vreg));
@ -1083,7 +1063,7 @@ std::map<std::string, std::set<std::string>> RISCv64CodeGen::build_interference_
} }
} }
} }
// --- 新增修复逻辑:处理指令内部操作数之间的干扰 ---
// 对于 store 指令,要存储的值和目标地址指针是同时活跃的,必须互相干扰。 // 对于 store 指令,要存储的值和目标地址指针是同时活跃的,必须互相干扰。
if (auto store = dynamic_cast<StoreInst*>(inst)) { if (auto store = dynamic_cast<StoreInst*>(inst)) {
Value* val_operand = store->getValue(); Value* val_operand = store->getValue();