[midend][backend]修复了全局常量数组的访问错误

This commit is contained in:
Lixuanwang
2025-07-30 18:23:56 +08:00
parent 38bee5d5ac
commit 48b0aec6c3
2 changed files with 40 additions and 13 deletions

View File

@ -16,7 +16,7 @@ std::string RISCv64CodeGen::code_gen() {
std::string RISCv64CodeGen::module_gen() {
std::stringstream ss;
// --- [新逻辑] 步骤1将全局变量分为.data和.bss两组 ---
// --- 步骤1将全局变量(GlobalValue)分为.data和.bss两组 ---
std::vector<GlobalValue*> data_globals;
std::vector<GlobalValue*> bss_globals;
@ -26,7 +26,6 @@ std::string RISCv64CodeGen::module_gen() {
// 判断是否为大型零初始化数组,以便放入.bss段
bool is_large_zero_array = false;
// 规则初始化列表只有一项且该项是值为0的整数且数量大于一个阈值例如16
if (init_values.getValues().size() == 1) {
if (auto const_val = dynamic_cast<ConstantValue*>(init_values.getValues()[0])) {
if (const_val->isInt() && const_val->getInt() == 0 && init_values.getNumbers()[0] > 16) {
@ -42,33 +41,56 @@ std::string RISCv64CodeGen::module_gen() {
}
}
// --- [新逻辑] 步骤2生成 .bss 段的代码 ---
// --- 步骤2生成 .bss 段的代码 (这部分不变) ---
if (!bss_globals.empty()) {
ss << ".bss\n"; // 切换到 .bss 段
ss << ".bss\n";
for (GlobalValue* global : bss_globals) {
// 获取数组总大小(元素个数 * 元素大小)
// 在SysY中我们假设元素都是4字节int或float
unsigned count = global->getInitValues().getNumbers()[0];
unsigned total_size = count * 4;
unsigned total_size = count * 4; // 假设元素都是4字节
ss << " .align 3\n"; // 8字节对齐 (2^3)
ss << " .align 3\n";
ss << ".globl " << global->getName() << "\n";
ss << ".type " << global->getName() << ", @object\n";
ss << ".size " << global->getName() << ", " << total_size << "\n";
ss << global->getName() << ":\n";
// 使用 .space 指令来预留指定大小的零填充空间
ss << " .space " << total_size << "\n";
}
}
// --- [旧逻辑保留] 步骤3生成 .data 段的代码 ---
if (!data_globals.empty()) {
ss << ".data\n"; // 切换到 .data 段
// --- [修改] 步骤3生成 .data 段的代码 ---
// 我们需要检查 data_globals 和 常量列表是否都为空
if (!data_globals.empty() || !module->getConsts().empty()) {
ss << ".data\n";
// a. 先处理普通的全局变量 (GlobalValue)
for (GlobalValue* global : data_globals) {
ss << ".globl " << global->getName() << "\n";
ss << global->getName() << ":\n";
const auto& init_values = global->getInitValues();
// 使用您原有的逻辑来处理显式初始化的值
for (size_t i = 0; i < init_values.getValues().size(); ++i) {
auto val = init_values.getValues()[i];
auto count = init_values.getNumbers()[i];
if (auto constant = dynamic_cast<ConstantValue*>(val)) {
for (unsigned j = 0; j < count; ++j) {
if (constant->isInt()) {
ss << " .word " << constant->getInt() << "\n";
} else {
float f = constant->getFloat();
uint32_t float_bits = *(uint32_t*)&f;
ss << " .word " << float_bits << "\n";
}
}
}
}
}
// b. [新增] 再处理全局常量 (ConstantVariable)
for (const auto& const_ptr : module->getConsts()) {
ConstantVariable* cnst = const_ptr.get();
ss << ".globl " << cnst->getName() << "\n";
ss << cnst->getName() << ":\n";
const auto& init_values = cnst->getInitValues();
// 这部分逻辑和处理 GlobalValue 完全相同
for (size_t i = 0; i < init_values.getValues().size(); ++i) {
auto val = init_values.getValues()[i];
auto count = init_values.getNumbers()[i];

View File

@ -862,6 +862,11 @@ void RISCv64ISel::selectNode(DAGNode* node) {
la_instr->addOperand(std::make_unique<RegOperand>(current_addr_vreg));
la_instr->addOperand(std::make_unique<LabelOperand>(global_base->getName()));
CurMBB->addInstruction(std::move(la_instr));
} else if (auto const_global_base = dynamic_cast<ConstantVariable*>(base_ptr_node->value)) {
auto la_instr = std::make_unique<MachineInstr>(RVOpcodes::LA);
la_instr->addOperand(std::make_unique<RegOperand>(current_addr_vreg));
la_instr->addOperand(std::make_unique<LabelOperand>(const_global_base->getName()));
CurMBB->addInstruction(std::move(la_instr));
} else {
auto base_vreg = getVReg(base_ptr_node->value);
auto mv = std::make_unique<MachineInstr>(RVOpcodes::MV);