[backend]修复了引入常量重质化后全局常量加载指令的缺失问题
This commit is contained in:
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user