From 33388496d5a7327e433322da9d2e338bea8b72b2 Mon Sep 17 00:00:00 2001 From: CGH0S7 <776459475@qq.com> Date: Tue, 19 Aug 2025 22:42:30 +0800 Subject: [PATCH] =?UTF-8?q?[backend-O1]RISCv64ISel=E5=AF=B9-O1=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E4=B8=93=E9=97=A8=E7=9A=84=E5=A4=84=E7=90=86=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/RISCv64/RISCv64ISel.cpp | 101 ++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) diff --git a/src/backend/RISCv64/RISCv64ISel.cpp b/src/backend/RISCv64/RISCv64ISel.cpp index 22ccc22..9fccba6 100644 --- a/src/backend/RISCv64/RISCv64ISel.cpp +++ b/src/backend/RISCv64/RISCv64ISel.cpp @@ -1311,6 +1311,7 @@ void RISCv64ISel::selectNode(DAGNode* node) { auto gep = dynamic_cast(node->value); auto result_vreg = getVReg(gep); + if (optLevel == 0) { // --- Step 1: 获取基地址 (此部分逻辑正确,保持不变) --- auto base_ptr_node = node->operands[0]; auto current_addr_vreg = getNewVReg(gep->getType()); @@ -1417,6 +1418,106 @@ void RISCv64ISel::selectNode(DAGNode* node) { final_mv->addOperand(std::make_unique(current_addr_vreg)); CurMBB->addInstruction(std::move(final_mv)); break; + } else { + // 对于-O1时的处理逻辑 + // --- Step 1: 获取基地址 --- + auto base_ptr_node = node->operands[0]; + auto base_ptr_val = base_ptr_node->value; + + // last_step_addr_vreg 保存上一步计算的结果。 + // 它首先被初始化为GEP的初始基地址。 + unsigned last_step_addr_vreg; + + if (auto alloca_base = dynamic_cast(base_ptr_val)) { + last_step_addr_vreg = getNewVReg(gep->getType()); + auto frame_addr_instr = std::make_unique(RVOpcodes::FRAME_ADDR); + frame_addr_instr->addOperand(std::make_unique(last_step_addr_vreg)); + frame_addr_instr->addOperand(std::make_unique(getVReg(alloca_base))); + CurMBB->addInstruction(std::move(frame_addr_instr)); + } else if (auto global_base = dynamic_cast(base_ptr_val)) { + last_step_addr_vreg = getNewVReg(gep->getType()); + auto la_instr = std::make_unique(RVOpcodes::LA); + la_instr->addOperand(std::make_unique(last_step_addr_vreg)); + la_instr->addOperand(std::make_unique(global_base->getName())); + CurMBB->addInstruction(std::move(la_instr)); + } else { + // 对于函数参数或来自其他指令的指针,直接获取其vreg。 + // 这个vreg必须被保护,不能在计算中被修改。 + last_step_addr_vreg = getVReg(base_ptr_val); + } + + // --- Step 2: 遵循LLVM GEP语义迭代计算地址 --- + Type* current_type = gep->getBasePointer()->getType()->as()->getBaseType(); + + for (size_t i = 0; i < gep->getNumIndices(); ++i) { + Value* indexValue = gep->getIndex(i); + unsigned stride = getTypeSizeInBytes(current_type); + + if (stride != 0) { + // --- 为当前索引和步长生成偏移计算指令 --- + auto offset_vreg = getNewVReg(Type::getIntType()); + + unsigned index_vreg; + if (auto const_index = dynamic_cast(indexValue)) { + index_vreg = getNewVReg(Type::getIntType()); + auto li = std::make_unique(RVOpcodes::LI); + li->addOperand(std::make_unique(index_vreg)); + li->addOperand(std::make_unique(const_index->getInt())); + CurMBB->addInstruction(std::move(li)); + } else { + index_vreg = getVReg(indexValue); + } + + if (stride == 1) { + auto mv = std::make_unique(RVOpcodes::MV); + mv->addOperand(std::make_unique(offset_vreg)); + mv->addOperand(std::make_unique(index_vreg)); + CurMBB->addInstruction(std::move(mv)); + } else { + auto size_vreg = getNewVReg(Type::getIntType()); + auto li_size = std::make_unique(RVOpcodes::LI); + li_size->addOperand(std::make_unique(size_vreg)); + li_size->addOperand(std::make_unique(stride)); + CurMBB->addInstruction(std::move(li_size)); + + auto mul = std::make_unique(RVOpcodes::MULW); + mul->addOperand(std::make_unique(offset_vreg)); + mul->addOperand(std::make_unique(index_vreg)); + mul->addOperand(std::make_unique(size_vreg)); + CurMBB->addInstruction(std::move(mul)); + } + + // --- 关键修复点 --- + // 创建一个新的vreg来保存本次加法的结果。 + unsigned current_step_addr_vreg = getNewVReg(gep->getType()); + + // 执行 add current_step, last_step, offset + // 这确保了 last_step_addr_vreg (输入) 永远不会被直接修改。 + auto add = std::make_unique(RVOpcodes::ADD); + add->addOperand(std::make_unique(current_step_addr_vreg)); + add->addOperand(std::make_unique(last_step_addr_vreg)); + add->addOperand(std::make_unique(offset_vreg)); + CurMBB->addInstruction(std::move(add)); + + // 本次的结果成为下一次计算的输入。 + last_step_addr_vreg = current_step_addr_vreg; + } + + // --- 为下一次迭代更新类型 --- + if (auto array_type = current_type->as()) { + current_type = array_type->getElementType(); + } else if (auto ptr_type = current_type->as()) { + current_type = ptr_type->getBaseType(); + } + } + + // --- Step 3: 将最终计算出的地址存入GEP的目标虚拟寄存器 --- + auto final_mv = std::make_unique(RVOpcodes::MV); + final_mv->addOperand(std::make_unique(result_vreg)); + final_mv->addOperand(std::make_unique(last_step_addr_vreg)); + CurMBB->addInstruction(std::move(final_mv)); + break; + } } default: