[backend]修复了引入常量重质化后全局常量加载指令的缺失问题

This commit is contained in:
Lixuanwang
2025-07-19 00:46:46 +08:00
parent 6ed5965b29
commit 6335abe806

View File

@@ -635,6 +635,14 @@ void RISCv64CodeGen::select_instructions(DAGNode* node, const RegAllocResult& al
} }
} else { } else {
std::string ptr_reg = get_preg_or_temp(ptr_node->result_vreg); std::string ptr_reg = get_preg_or_temp(ptr_node->result_vreg);
// [与STORE逻辑类似的修复] 如果是从一个全局地址加载先用la加载地址
if (ptr_node->kind == DAGNode::CONSTANT) {
if (auto global = dynamic_cast<GlobalValue*>(ptr_node->value)) {
ss_inst << "la " << ptr_reg << ", " << global->getName() << "\n\t";
}
}
ss_inst << "lw " << dest_reg << ", 0(" << ptr_reg << ")"; ss_inst << "lw " << dest_reg << ", 0(" << ptr_reg << ")";
} }
break; break;
@@ -660,18 +668,30 @@ void RISCv64CodeGen::select_instructions(DAGNode* node, const RegAllocResult& al
// 如果 STORE 的目标是浮点数,这里逻辑需要调整 // 如果 STORE 的目标是浮点数,这里逻辑需要调整
} }
} else if (auto global = dynamic_cast<GlobalValue*>(val_node->value)) { } else if (auto global = dynamic_cast<GlobalValue*>(val_node->value)) {
// 如果存储全局变量的地址 // 如果存储的值是另一个全局变量的地址
ss_inst << "la " << src_reg << ", " << global->getName() << "\n\t"; ss_inst << "la " << src_reg << ", " << global->getName() << "\n\t";
} }
} }
// [本次修复] 处理目标地址,并生成最终的存储指令
if (ptr_node->kind == DAGNode::ALLOCA_ADDR) { if (ptr_node->kind == DAGNode::ALLOCA_ADDR) {
// 情况1: 存储到栈上的局部变量
if (auto alloca_inst = dynamic_cast<AllocaInst*>(ptr_node->value)) { if (auto alloca_inst = dynamic_cast<AllocaInst*>(ptr_node->value)) {
int offset = alloc.stack_map.at(alloca_inst); int offset = alloc.stack_map.at(alloca_inst);
ss_inst << "sw " << src_reg << ", " << offset << "(s0)"; ss_inst << "sw " << src_reg << ", " << offset << "(s0)";
} }
} else { } else {
// 情况2: 存储到指针指向的地址 (可能是全局变量或已计算的地址)
std::string ptr_reg = get_preg_or_temp(ptr_node->result_vreg); std::string ptr_reg = get_preg_or_temp(ptr_node->result_vreg);
// 如果指针本身是一个全局变量的地址,需要先用 la 加载它
if (ptr_node->kind == DAGNode::CONSTANT) {
if (auto global = dynamic_cast<GlobalValue*>(ptr_node->value)) {
ss_inst << "la " << ptr_reg << ", " << global->getName() << "\n\t";
}
}
// 生成最终的存储指令
ss_inst << "sw " << src_reg << ", 0(" << ptr_reg << ")"; ss_inst << "sw " << src_reg << ", 0(" << ptr_reg << ")";
} }
break; break;
@@ -712,10 +732,12 @@ void RISCv64CodeGen::select_instructions(DAGNode* node, const RegAllocResult& al
std::string lhs_reg = get_preg_or_temp(lhs_node->result_vreg); std::string lhs_reg = get_preg_or_temp(lhs_node->result_vreg);
std::string rhs_reg = get_preg_or_temp(rhs_node->result_vreg); std::string rhs_reg = get_preg_or_temp(rhs_node->result_vreg);
// [V2 特性] 在生成二元运算指令前,检查操作数是否为常数,并按需加载 // [V2 特性] & [上次修复] 在生成二元运算指令前,检查操作数是否为常数(立即数或全局地址),并按需加载
if (lhs_node->kind == DAGNode::CONSTANT) { if (lhs_node->kind == DAGNode::CONSTANT) {
if (auto c = dynamic_cast<ConstantValue*>(lhs_node->value)) { if (auto c = dynamic_cast<ConstantValue*>(lhs_node->value)) {
ss_inst << "li " << lhs_reg << ", " << c->getInt() << "\n\t"; ss_inst << "li " << lhs_reg << ", " << c->getInt() << "\n\t";
} else if (auto g = dynamic_cast<GlobalValue*>(lhs_node->value)) {
ss_inst << "la " << lhs_reg << ", " << g->getName() << "\n\t";
} }
} }
if (rhs_node->kind == DAGNode::CONSTANT) { if (rhs_node->kind == DAGNode::CONSTANT) {
@@ -728,6 +750,8 @@ void RISCv64CodeGen::select_instructions(DAGNode* node, const RegAllocResult& al
} }
// 否则,正常加载 // 否则,正常加载
ss_inst << "li " << rhs_reg << ", " << c->getInt() << "\n\t"; ss_inst << "li " << rhs_reg << ", " << c->getInt() << "\n\t";
} else if (auto g = dynamic_cast<GlobalValue*>(rhs_node->value)) {
ss_inst << "la " << rhs_reg << ", " << g->getName() << "\n\t";
} }
} }
@@ -853,10 +877,12 @@ void RISCv64CodeGen::select_instructions(DAGNode* node, const RegAllocResult& al
if (!node->operands.empty() && node->operands[0]) { if (!node->operands.empty() && node->operands[0]) {
DAGNode* ret_val_node = node->operands[0]; DAGNode* ret_val_node = node->operands[0];
// [V2 特性] 如果返回值是常量,直接加载到 a0 // [V2 特性] & [上次修复] 如果返回值是常量(立即数或全局地址),直接加载到 a0
if (ret_val_node->kind == DAGNode::CONSTANT) { if (ret_val_node->kind == DAGNode::CONSTANT) {
if (auto c = dynamic_cast<ConstantValue*>(ret_val_node->value)) { if (auto c = dynamic_cast<ConstantValue*>(ret_val_node->value)) {
ss_inst << "li a0, " << c->getInt() << "\n"; ss_inst << "li a0, " << c->getInt() << "\n";
} else if (auto g = dynamic_cast<GlobalValue*>(ret_val_node->value)) {
ss_inst << "la a0, " << g->getName() << "\n";
} }
} else { } else {
std::string return_val_reg = get_preg_or_temp(ret_val_node->result_vreg); std::string return_val_reg = get_preg_or_temp(ret_val_node->result_vreg);