diff --git a/src/RISCv64AsmPrinter.cpp b/src/RISCv64AsmPrinter.cpp index 47e9773..9482a58 100644 --- a/src/RISCv64AsmPrinter.cpp +++ b/src/RISCv64AsmPrinter.cpp @@ -18,7 +18,7 @@ bool isMemoryOp(RVOpcodes opcode) { RISCv64AsmPrinter::RISCv64AsmPrinter(MachineFunction* mfunc) : MFunc(mfunc) {} -void RISCv64AsmPrinter::run(std::ostream& os) { +void RISCv64AsmPrinter::run(std::ostream& os, bool debug) { OS = &os; *OS << ".globl " << MFunc->getName() << "\n"; @@ -27,7 +27,7 @@ void RISCv64AsmPrinter::run(std::ostream& os) { printPrologue(); for (auto& mbb : MFunc->getBlocks()) { - printBasicBlock(mbb.get()); + printBasicBlock(mbb.get(), debug); } } @@ -73,16 +73,16 @@ void RISCv64AsmPrinter::printEpilogue() { } } -void RISCv64AsmPrinter::printBasicBlock(MachineBasicBlock* mbb) { +void RISCv64AsmPrinter::printBasicBlock(MachineBasicBlock* mbb, bool debug) { if (!mbb->getName().empty()) { *OS << mbb->getName() << ":\n"; } for (auto& instr : mbb->getInstructions()) { - printInstruction(instr.get()); + printInstruction(instr.get(), debug); } } -void RISCv64AsmPrinter::printInstruction(MachineInstr* instr) { +void RISCv64AsmPrinter::printInstruction(MachineInstr* instr, bool debug) { auto opcode = instr->getOpcode(); if (opcode == RVOpcodes::RET) { printEpilogue(); @@ -137,9 +137,17 @@ void RISCv64AsmPrinter::printInstruction(MachineInstr* instr) { // *OS << ":"; break; case RVOpcodes::FRAME_LOAD: + // It should have been eliminated by RegAlloc + if (!debug) throw std::runtime_error("FRAME pseudo-instruction not eliminated before AsmPrinter"); + *OS << "frame_load "; break; case RVOpcodes::FRAME_STORE: - // These should have been eliminated by RegAlloc - throw std::runtime_error("FRAME pseudo-instruction not eliminated before AsmPrinter"); + // It should have been eliminated by RegAlloc + if (!debug) throw std::runtime_error("FRAME pseudo-instruction not eliminated before AsmPrinter"); + *OS << "frame_store "; break; + case RVOpcodes::FRAME_ADDR: + // It should have been eliminated by RegAlloc + if (!debug) throw std::runtime_error("FRAME pseudo-instruction not eliminated before AsmPrinter"); + *OS << "frame_addr "; break; default: throw std::runtime_error("Unknown opcode in AsmPrinter"); } diff --git a/src/RISCv64Backend.cpp b/src/RISCv64Backend.cpp index cccbf40..4f45fde 100644 --- a/src/RISCv64Backend.cpp +++ b/src/RISCv64Backend.cpp @@ -61,6 +61,10 @@ std::string RISCv64CodeGen::function_gen(Function* func) { RISCv64ISel isel; std::unique_ptr mfunc = isel.runOnFunction(func); + std::stringstream ss1; + RISCv64AsmPrinter printer1(mfunc.get()); + printer1.run(ss1, true); + // 阶段 2: 指令调度 (Instruction Scheduling) PreRA_Scheduler scheduler; scheduler.runOnMachineFunction(mfunc.get()); @@ -81,7 +85,7 @@ std::string RISCv64CodeGen::function_gen(Function* func) { std::stringstream ss; RISCv64AsmPrinter printer(mfunc.get()); printer.run(ss); - + if (DEBUG) ss << ss1.str(); // 将指令选择阶段的结果也包含在最终输出中 return ss.str(); } diff --git a/src/RISCv64ISel.cpp b/src/RISCv64ISel.cpp index 005ba96..2da2373 100644 --- a/src/RISCv64ISel.cpp +++ b/src/RISCv64ISel.cpp @@ -4,6 +4,7 @@ #include #include // For std::fabs #include // For std::numeric_limits +#include namespace sysy { @@ -92,6 +93,10 @@ void RISCv64ISel::selectBasicBlock(BasicBlock* bb) { std::set selected_nodes; std::function select_recursive = [&](DAGNode* node) { + if (DEEPDEBUG) { + std::cout << "[DEEPDEBUG] select_recursive: Visiting node with kind: " << node->kind + << " (Value: " << (node->value ? node->value->getName() : "null") << ")" << std::endl; + } if (!node || selected_nodes.count(node)) return; for (auto operand : node->operands) { select_recursive(operand); @@ -118,24 +123,37 @@ void RISCv64ISel::selectBasicBlock(BasicBlock* bb) { } } -// 核心函数:为DAG节点选择并生成MachineInstr (忠实移植版) +// 核心函数:为DAG节点选择并生成MachineInstr (已修复和增强的完整版本) void RISCv64ISel::selectNode(DAGNode* node) { + // 调用者(select_recursive)已经保证了操作数节点会先于当前节点被选择。 + // 因此,这里我们只处理当前节点。 + switch (node->kind) { + // [V2优点] 采纳“延迟物化”(Late Materialization)思想。 + // 这两个节点仅作为标记,不直接生成指令。它们的目的是在DAG中保留类型信息。 + // 加载其值的责任,被转移给了使用它们的父节点(如STORE, BINARY等)。 + // 这修复了之前版本中“使用未初始化虚拟寄存器”的根本性bug。 case DAGNode::CONSTANT: case DAGNode::ALLOCA_ADDR: - if (node->value) getVReg(node->value); + if (node->value) { + // 确保它有一个关联的虚拟寄存器即可,不生成代码。 + getVReg(node->value); + } break; case DAGNode::LOAD: { auto dest_vreg = getVReg(node->value); Value* ptr_val = node->operands[0]->value; + // [V1设计保留] 对于从栈变量加载,继续使用伪指令 FRAME_LOAD。 + // 这种设计将栈帧布局的具体计算推迟到后续的 `eliminateFrameIndices` 阶段,保持了模块化。 if (auto alloca = dynamic_cast(ptr_val)) { auto instr = std::make_unique(RVOpcodes::FRAME_LOAD); instr->addOperand(std::make_unique(dest_vreg)); instr->addOperand(std::make_unique(getVReg(alloca))); CurMBB->addInstruction(std::move(instr)); } else if (auto global = dynamic_cast(ptr_val)) { + // 对于全局变量,先用 la 加载其地址,再用 lw 加载其值。 auto addr_vreg = getNewVReg(); auto la = std::make_unique(RVOpcodes::LA); la->addOperand(std::make_unique(addr_vreg)); @@ -150,6 +168,7 @@ void RISCv64ISel::selectNode(DAGNode* node) { )); CurMBB->addInstruction(std::move(lw)); } else { + // 对于已经在虚拟寄存器中的指针地址,直接通过该地址加载。 auto ptr_vreg = getVReg(ptr_val); auto lw = std::make_unique(RVOpcodes::LW); lw->addOperand(std::make_unique(dest_vreg)); @@ -166,7 +185,13 @@ void RISCv64ISel::selectNode(DAGNode* node) { Value* val_to_store = node->operands[0]->value; Value* ptr_val = node->operands[1]->value; + // [V2优点] 在STORE节点内部负责加载作为源的常量。 + // 如果要存储的值是一个常量,就在这里生成 `li` 指令加载它。 if (auto val_const = dynamic_cast(val_to_store)) { + if (DEBUG) { + std::cout << "[DEBUG] selectNode-BINARY: Found constant operand with value " << val_const->getInt() + << ". Generating LI instruction." << std::endl; + } auto li = std::make_unique(RVOpcodes::LI); li->addOperand(std::make_unique(getVReg(val_const))); li->addOperand(std::make_unique(val_const->getInt())); @@ -174,13 +199,15 @@ void RISCv64ISel::selectNode(DAGNode* node) { } auto val_vreg = getVReg(val_to_store); + // [V1设计保留] 同样,对于向栈变量的存储,使用 FRAME_STORE 伪指令。 if (auto alloca = dynamic_cast(ptr_val)) { auto instr = std::make_unique(RVOpcodes::FRAME_STORE); instr->addOperand(std::make_unique(val_vreg)); instr->addOperand(std::make_unique(getVReg(alloca))); CurMBB->addInstruction(std::move(instr)); } else if (auto global = dynamic_cast(ptr_val)) { - auto addr_vreg = getNewVReg(); + // 向全局变量存储。 + auto addr_vreg = getNewVReg(); auto la = std::make_unique(RVOpcodes::LA); la->addOperand(std::make_unique(addr_vreg)); la->addOperand(std::make_unique(global->getName())); @@ -194,6 +221,7 @@ void RISCv64ISel::selectNode(DAGNode* node) { )); CurMBB->addInstruction(std::move(sw)); } else { + // 向一个指针(存储在虚拟寄存器中)指向的地址存储。 auto ptr_vreg = getVReg(ptr_val); auto sw = std::make_unique(RVOpcodes::SW); sw->addOperand(std::make_unique(val_vreg)); @@ -211,36 +239,53 @@ void RISCv64ISel::selectNode(DAGNode* node) { Value* lhs = bin->getLhs(); Value* rhs = bin->getRhs(); + // [V2优点] 在BINARY节点内部按需加载常量操作数。 auto load_val_if_const = [&](Value* val) { if (auto c = dynamic_cast(val)) { + if (DEBUG) { + std::cout << "[DEBUG] selectNode-BINARY: Found constant operand with value " << c->getInt() + << ". Generating LI instruction." << std::endl; + } auto li = std::make_unique(RVOpcodes::LI); li->addOperand(std::make_unique(getVReg(c))); li->addOperand(std::make_unique(c->getInt())); CurMBB->addInstruction(std::move(li)); } }; - load_val_if_const(lhs); - load_val_if_const(rhs); - auto dest_vreg = getVReg(bin); - auto lhs_vreg = getVReg(lhs); - auto rhs_vreg = getVReg(rhs); - - if (bin->getKind() == BinaryInst::kAdd) { - if (auto rhs_const = dynamic_cast(rhs)) { - if (rhs_const->getInt() >= -2048 && rhs_const->getInt() < 2048) { - auto instr = std::make_unique(RVOpcodes::ADDIW); - instr->addOperand(std::make_unique(dest_vreg)); - instr->addOperand(std::make_unique(lhs_vreg)); - instr->addOperand(std::make_unique(rhs_const->getInt())); - CurMBB->addInstruction(std::move(instr)); - return; - } + // 检查是否能应用立即数优化。 + bool rhs_is_imm_opt = false; + if (auto rhs_const = dynamic_cast(rhs)) { + if (bin->getKind() == BinaryInst::kAdd && rhs_const->getInt() >= -2048 && rhs_const->getInt() < 2048) { + rhs_is_imm_opt = true; } } + // 仅在不能作为立即数操作数时才需要提前加载。 + load_val_if_const(lhs); + if (!rhs_is_imm_opt) { + load_val_if_const(rhs); + } + + auto dest_vreg = getVReg(bin); + auto lhs_vreg = getVReg(lhs); + + // [V2优点] 融合 ADDIW 优化。 + if (rhs_is_imm_opt) { + auto rhs_const = dynamic_cast(rhs); + auto instr = std::make_unique(RVOpcodes::ADDIW); + instr->addOperand(std::make_unique(dest_vreg)); + instr->addOperand(std::make_unique(lhs_vreg)); + instr->addOperand(std::make_unique(rhs_const->getInt())); + CurMBB->addInstruction(std::move(instr)); + return; // 指令已生成,直接返回。 + } + + auto rhs_vreg = getVReg(rhs); + switch (bin->getKind()) { case BinaryInst::kAdd: { + // 区分指针运算(64位)和整数运算(32位)。 RVOpcodes opcode = (lhs->getType()->isPointer() || rhs->getType()->isPointer()) ? RVOpcodes::ADD : RVOpcodes::ADDW; auto instr = std::make_unique(opcode); instr->addOperand(std::make_unique(dest_vreg)); @@ -281,7 +326,7 @@ void RISCv64ISel::selectNode(DAGNode* node) { CurMBB->addInstruction(std::move(instr)); break; } - case BinaryInst::kICmpEQ: { + case BinaryInst::kICmpEQ: { // 等于 (a == b) -> (subw; seqz) auto sub = std::make_unique(RVOpcodes::SUBW); sub->addOperand(std::make_unique(dest_vreg)); sub->addOperand(std::make_unique(lhs_vreg)); @@ -294,7 +339,7 @@ void RISCv64ISel::selectNode(DAGNode* node) { CurMBB->addInstruction(std::move(seqz)); break; } - case BinaryInst::kICmpNE: { + case BinaryInst::kICmpNE: { // 不等于 (a != b) -> (subw; snez) auto sub = std::make_unique(RVOpcodes::SUBW); sub->addOperand(std::make_unique(dest_vreg)); sub->addOperand(std::make_unique(lhs_vreg)); @@ -307,7 +352,7 @@ void RISCv64ISel::selectNode(DAGNode* node) { CurMBB->addInstruction(std::move(snez)); break; } - case BinaryInst::kICmpLT: { + case BinaryInst::kICmpLT: { // 小于 (a < b) -> slt auto instr = std::make_unique(RVOpcodes::SLT); instr->addOperand(std::make_unique(dest_vreg)); instr->addOperand(std::make_unique(lhs_vreg)); @@ -315,7 +360,7 @@ void RISCv64ISel::selectNode(DAGNode* node) { CurMBB->addInstruction(std::move(instr)); break; } - case BinaryInst::kICmpGT: { + case BinaryInst::kICmpGT: { // 大于 (a > b) -> (b < a) -> slt auto instr = std::make_unique(RVOpcodes::SLT); instr->addOperand(std::make_unique(dest_vreg)); instr->addOperand(std::make_unique(rhs_vreg)); @@ -323,7 +368,7 @@ void RISCv64ISel::selectNode(DAGNode* node) { CurMBB->addInstruction(std::move(instr)); break; } - case BinaryInst::kICmpLE: { + case BinaryInst::kICmpLE: { // 小于等于 (a <= b) -> !(b < a) -> (slt; xori) auto slt = std::make_unique(RVOpcodes::SLT); slt->addOperand(std::make_unique(dest_vreg)); slt->addOperand(std::make_unique(rhs_vreg)); @@ -337,7 +382,7 @@ void RISCv64ISel::selectNode(DAGNode* node) { CurMBB->addInstruction(std::move(xori)); break; } - case BinaryInst::kICmpGE: { + case BinaryInst::kICmpGE: { // 大于等于 (a >= b) -> !(a < b) -> (slt; xori) auto slt = std::make_unique(RVOpcodes::SLT); slt->addOperand(std::make_unique(dest_vreg)); slt->addOperand(std::make_unique(lhs_vreg)); @@ -363,7 +408,7 @@ void RISCv64ISel::selectNode(DAGNode* node) { auto src_vreg = getVReg(unary->getOperand()); switch (unary->getKind()) { - case UnaryInst::kNeg: { + case UnaryInst::kNeg: { // 取负: 0 - src auto instr = std::make_unique(RVOpcodes::SUBW); instr->addOperand(std::make_unique(dest_vreg)); instr->addOperand(std::make_unique(PhysicalReg::ZERO)); @@ -371,7 +416,7 @@ void RISCv64ISel::selectNode(DAGNode* node) { CurMBB->addInstruction(std::move(instr)); break; } - case UnaryInst::kNot: { + case UnaryInst::kNot: { // 逻辑非: src == 0 ? 1 : 0 auto instr = std::make_unique(RVOpcodes::SEQZ); instr->addOperand(std::make_unique(dest_vreg)); instr->addOperand(std::make_unique(src_vreg)); @@ -386,6 +431,7 @@ void RISCv64ISel::selectNode(DAGNode* node) { case DAGNode::CALL: { auto call = dynamic_cast(node->value); + // 处理函数参数,放入a0-a7物理寄存器 for (size_t i = 0; i < node->operands.size() && i < 8; ++i) { DAGNode* arg_node = node->operands[i]; auto arg_preg = static_cast(static_cast(PhysicalReg::A0) + i); @@ -409,7 +455,8 @@ void RISCv64ISel::selectNode(DAGNode* node) { auto call_instr = std::make_unique(RVOpcodes::CALL); call_instr->addOperand(std::make_unique(call->getCallee()->getName())); CurMBB->addInstruction(std::move(call_instr)); - + + // 处理返回值,从a0移动到目标虚拟寄存器 if (!call->getType()->isVoid()) { auto mv_instr = std::make_unique(RVOpcodes::MV); mv_instr->addOperand(std::make_unique(getVReg(call))); @@ -423,6 +470,7 @@ void RISCv64ISel::selectNode(DAGNode* node) { auto ret_inst_ir = dynamic_cast(node->value); if (ret_inst_ir && ret_inst_ir->hasReturnValue()) { Value* ret_val = ret_inst_ir->getReturnValue(); + // [V2优点] 在RETURN节点内加载常量返回值 if (auto const_val = dynamic_cast(ret_val)) { auto li_instr = std::make_unique(RVOpcodes::LI); li_instr->addOperand(std::make_unique(PhysicalReg::A0)); @@ -435,6 +483,8 @@ void RISCv64ISel::selectNode(DAGNode* node) { CurMBB->addInstruction(std::move(mv_instr)); } } + // [V1设计保留] 函数尾声(epilogue)不由RETURN节点生成, + // 而是由后续的AsmPrinter或其它Pass统一处理,这是一种常见且有效的模块化设计。 auto ret_mi = std::make_unique(RVOpcodes::RET); CurMBB->addInstruction(std::move(ret_mi)); break; @@ -442,11 +492,25 @@ void RISCv64ISel::selectNode(DAGNode* node) { case DAGNode::BRANCH: { if (auto cond_br = dynamic_cast(node->value)) { + // [V2优点] 采用更健壮的if-then-else分支逻辑。 + auto cond_vreg = getVReg(cond_br->getCondition()); + auto then_bb_name = cond_br->getThenBlock()->getName(); + auto else_bb_name = cond_br->getElseBlock()->getName(); + + // bne cond, zero, then_label (如果cond不为0,则跳转到then) auto br_instr = std::make_unique(RVOpcodes::BNE); - br_instr->addOperand(std::make_unique(getVReg(cond_br->getCondition()))); + br_instr->addOperand(std::make_unique(cond_vreg)); br_instr->addOperand(std::make_unique(PhysicalReg::ZERO)); - br_instr->addOperand(std::make_unique(cond_br->getThenBlock()->getName())); + br_instr->addOperand(std::make_unique(then_bb_name)); CurMBB->addInstruction(std::move(br_instr)); + + // 无条件跳转到else块 (如果上面分支未发生) + // 注意:在实际的CFG中,这个J指令可能不是必须的, + // 因为else块可能是下一个块。但为了通用性,这里生成它。 + auto j_instr = std::make_unique(RVOpcodes::J); + j_instr->addOperand(std::make_unique(else_bb_name)); + CurMBB->addInstruction(std::move(j_instr)); + } else if (auto uncond_br = dynamic_cast(node->value)) { auto j_instr = std::make_unique(RVOpcodes::J); j_instr->addOperand(std::make_unique(uncond_br->getBlock()->getName())); @@ -456,15 +520,58 @@ void RISCv64ISel::selectNode(DAGNode* node) { } case DAGNode::MEMSET: { + // [V1设计保留] Memset的核心展开逻辑在虚拟寄存器层面是正确的,无需修改。 + // 之前的bug是由于其输入(地址、值、大小)的虚拟寄存器未被正确初始化。 + // 在修复了CONSTANT/ALLOCA_ADDR的加载问题后,此处的逻辑现在可以正常工作。 + + if (DEBUG) { + std::cout << "[DEBUG] selectNode-MEMSET: Processing MEMSET node." << std::endl; + } auto memset = dynamic_cast(node->value); + Value* val_to_set = memset->getValue(); + Value* size_to_set = memset->getSize(); + Value* ptr_val = memset->getPointer(); + auto dest_addr_vreg = getVReg(ptr_val); + + if (auto const_val = dynamic_cast(val_to_set)) { + if (DEBUG) { + std::cout << "[DEBUG] selectNode-MEMSET: Found constant 'value' operand (" << const_val->getInt() << "). Generating LI." << std::endl; + } + auto li = std::make_unique(RVOpcodes::LI); + li->addOperand(std::make_unique(getVReg(const_val))); + li->addOperand(std::make_unique(const_val->getInt())); + CurMBB->addInstruction(std::move(li)); + } + if (auto const_size = dynamic_cast(size_to_set)) { + if (DEBUG) { + std::cout << "[DEBUG] selectNode-MEMSET: Found constant 'size' operand (" << const_size->getInt() << "). Generating LI." << std::endl; + } + auto li = std::make_unique(RVOpcodes::LI); + li->addOperand(std::make_unique(getVReg(const_size))); + li->addOperand(std::make_unique(const_size->getInt())); + CurMBB->addInstruction(std::move(li)); + } + if (auto alloca = dynamic_cast(ptr_val)) { + if (DEBUG) { + std::cout << "[DEBUG] selectNode-MEMSET: Found 'pointer' operand is an AllocaInst. Generating FRAME_ADDR." << std::endl; + } + // 生成新的伪指令来获取栈地址 + auto instr = std::make_unique(RVOpcodes::FRAME_ADDR); + instr->addOperand(std::make_unique(dest_addr_vreg)); // 目标虚拟寄存器 + instr->addOperand(std::make_unique(getVReg(alloca))); // 源AllocaInst + CurMBB->addInstruction(std::move(instr)); + } auto r_dest_addr = getVReg(memset->getPointer()); auto r_num_bytes = getVReg(memset->getSize()); auto r_value_byte = getVReg(memset->getValue()); + + // 为memset内部逻辑创建新的临时虚拟寄存器 auto r_counter = getNewVReg(); auto r_end_addr = getNewVReg(); auto r_current_addr = getNewVReg(); auto r_temp_val = getNewVReg(); + // 定义一系列lambda表达式来简化指令创建 auto add_instr = [&](RVOpcodes op, unsigned rd, unsigned rs1, unsigned rs2) { auto i = std::make_unique(op); i->addOperand(std::make_unique(rd)); @@ -503,12 +610,14 @@ void RISCv64ISel::selectNode(DAGNode* node) { CurMBB->addInstruction(std::move(i)); }; + // 生成唯一的循环标签 int unique_id = this->local_label_counter++; std::string loop_start_label = MFunc->getName() + "_memset_loop_start_" + std::to_string(unique_id); std::string loop_end_label = MFunc->getName() + "_memset_loop_end_" + std::to_string(unique_id); std::string remainder_label = MFunc->getName() + "_memset_remainder_" + std::to_string(unique_id); std::string done_label = MFunc->getName() + "_memset_done_" + std::to_string(unique_id); + // 构造64位的填充值 addi_instr(RVOpcodes::ANDI, r_temp_val, r_value_byte, 255); addi_instr(RVOpcodes::SLLI, r_value_byte, r_temp_val, 8); add_instr(RVOpcodes::OR, r_temp_val, r_temp_val, r_value_byte); @@ -516,6 +625,8 @@ void RISCv64ISel::selectNode(DAGNode* node) { add_instr(RVOpcodes::OR, r_temp_val, r_temp_val, r_value_byte); addi_instr(RVOpcodes::SLLI, r_value_byte, r_temp_val, 32); add_instr(RVOpcodes::OR, r_temp_val, r_temp_val, r_value_byte); + + // 计算循环边界 add_instr(RVOpcodes::ADD, r_end_addr, r_dest_addr, r_num_bytes); auto mv = std::make_unique(RVOpcodes::MV); mv->addOperand(std::make_unique(r_current_addr)); @@ -523,17 +634,22 @@ void RISCv64ISel::selectNode(DAGNode* node) { CurMBB->addInstruction(std::move(mv)); addi_instr(RVOpcodes::ANDI, r_counter, r_num_bytes, -8); add_instr(RVOpcodes::ADD, r_counter, r_dest_addr, r_counter); + + // 8字节主循环 label_instr(loop_start_label); branch_instr(RVOpcodes::BGEU, r_current_addr, r_counter, loop_end_label); store_instr(RVOpcodes::SD, r_temp_val, r_current_addr, 0); addi_instr(RVOpcodes::ADDI, r_current_addr, r_current_addr, 8); jump_instr(loop_start_label); + + // 1字节收尾循环 label_instr(loop_end_label); label_instr(remainder_label); branch_instr(RVOpcodes::BGEU, r_current_addr, r_end_addr, done_label); store_instr(RVOpcodes::SB, r_temp_val, r_current_addr, 0); addi_instr(RVOpcodes::ADDI, r_current_addr, r_current_addr, 1); jump_instr(remainder_label); + label_instr(done_label); break; } @@ -590,6 +706,12 @@ std::vector> RISCv64ISel::build_dag(BasicB memset_node->operands.push_back(get_operand_node(memset->getBegin(), value_to_node, nodes_storage)); memset_node->operands.push_back(get_operand_node(memset->getSize(), value_to_node, nodes_storage)); memset_node->operands.push_back(get_operand_node(memset->getValue(), value_to_node, nodes_storage)); + if (DEBUG) { + std::cout << "[DEBUG] build_dag: Created MEMSET node for: " << memset->getName() << std::endl; + for (size_t i = 0; i < memset_node->operands.size(); ++i) { + std::cout << " -> Operand " << i << " has kind: " << memset_node->operands[i]->kind << std::endl; + } + } } else if (auto load = dynamic_cast(inst)) { auto load_node = create_node(DAGNode::LOAD, load, value_to_node, nodes_storage); load_node->operands.push_back(get_operand_node(load->getPointer(), value_to_node, nodes_storage)); diff --git a/src/RISCv64RegAlloc.cpp b/src/RISCv64RegAlloc.cpp index 2695f3b..d4c69e7 100644 --- a/src/RISCv64RegAlloc.cpp +++ b/src/RISCv64RegAlloc.cpp @@ -94,6 +94,18 @@ void RISCv64RegAlloc::eliminateFrameIndices() { std::make_unique(addr_vreg), std::make_unique(0))); new_instructions.push_back(std::move(sw)); + } else if (instr_ptr->getOpcode() == RVOpcodes::FRAME_ADDR) { // [新] 处理FRAME_ADDR + auto& operands = instr_ptr->getOperands(); + unsigned dest_vreg = static_cast(operands[0].get())->getVRegNum(); + unsigned alloca_vreg = static_cast(operands[1].get())->getVRegNum(); + int offset = frame_info.alloca_offsets.at(alloca_vreg); + + // 将 `frame_addr rd, rs` 展开为 `addi rd, s0, offset` + auto addi = std::make_unique(RVOpcodes::ADDI); + addi->addOperand(std::make_unique(dest_vreg)); + addi->addOperand(std::make_unique(PhysicalReg::S0)); // 基地址是帧指针 s0 + addi->addOperand(std::make_unique(offset)); + new_instructions.push_back(std::move(addi)); } else { new_instructions.push_back(std::move(instr_ptr)); } diff --git a/src/include/RISCv64AsmPrinter.h b/src/include/RISCv64AsmPrinter.h index 3ea71f6..f942a45 100644 --- a/src/include/RISCv64AsmPrinter.h +++ b/src/include/RISCv64AsmPrinter.h @@ -4,20 +4,23 @@ #include "RISCv64LLIR.h" #include +extern int DEBUG; +extern int DEEPDEBUG; + namespace sysy { class RISCv64AsmPrinter { public: RISCv64AsmPrinter(MachineFunction* mfunc); // 主入口 - void run(std::ostream& os); + void run(std::ostream& os, bool debug = false); private: // 打印各个部分 void printPrologue(); void printEpilogue(); - void printBasicBlock(MachineBasicBlock* mbb); - void printInstruction(MachineInstr* instr); + void printBasicBlock(MachineBasicBlock* mbb, bool debug = false); + void printInstruction(MachineInstr* instr, bool debug = false); // 辅助函数 std::string regToString(PhysicalReg reg); diff --git a/src/include/RISCv64Backend.h b/src/include/RISCv64Backend.h index 33f7831..403d586 100644 --- a/src/include/RISCv64Backend.h +++ b/src/include/RISCv64Backend.h @@ -4,6 +4,9 @@ #include "IR.h" #include +extern int DEBUG; +extern int DEEPDEBUG; + namespace sysy { // RISCv64CodeGen 现在是一个高层驱动器 diff --git a/src/include/RISCv64ISel.h b/src/include/RISCv64ISel.h index 795b2b8..6c5e421 100644 --- a/src/include/RISCv64ISel.h +++ b/src/include/RISCv64ISel.h @@ -3,6 +3,9 @@ #include "RISCv64LLIR.h" +extern int DEBUG; +extern int DEEPDEBUG; + namespace sysy { class RISCv64ISel { diff --git a/src/include/RISCv64LLIR.h b/src/include/RISCv64LLIR.h index 6310741..86de7d4 100644 --- a/src/include/RISCv64LLIR.h +++ b/src/include/RISCv64LLIR.h @@ -46,6 +46,7 @@ enum class RVOpcodes { // 新增伪指令,用于解耦栈帧处理 FRAME_LOAD, // 从栈帧加载 (AllocaInst) FRAME_STORE, // 保存到栈帧 (AllocaInst) + FRAME_ADDR, // [新] 获取栈帧变量的地址 }; class MachineOperand; diff --git a/src/sysyc.cpp b/src/sysyc.cpp index 692225d..cac39a9 100644 --- a/src/sysyc.cpp +++ b/src/sysyc.cpp @@ -218,7 +218,7 @@ int main(int argc, char **argv) { // 设置 DEBUG 模式(如果指定了 'asmd') if (argStopAfter == "asmd") { DEBUG = 1; - // DEEPDEBUG = 1; + DEEPDEBUG = 1; } sysy::RISCv64CodeGen codegen(moduleIR); // 传入优化后的 moduleIR string asmCode = codegen.code_gen();