#include "RISCv64Backend.h"
#include <sstream>
#include <algorithm>
#include <stdexcept>
#include <regex>
#include <iomanip>
#include <functional>

namespace sysy {    

// 可用于分配的寄存器
const std::vector<RISCv64CodeGen::PhysicalReg> RISCv64CodeGen::allocable_regs = {
    // 整数寄存器
    PhysicalReg::T0, PhysicalReg::T1, PhysicalReg::T2, PhysicalReg::T3,
    PhysicalReg::T4, PhysicalReg::T5, PhysicalReg::T6,
    PhysicalReg::A0, PhysicalReg::A1, PhysicalReg::A2, PhysicalReg::A3,
    PhysicalReg::A4, PhysicalReg::A5, PhysicalReg::A6, PhysicalReg::A7,
    PhysicalReg::S0, PhysicalReg::S1, PhysicalReg::S2, PhysicalReg::S3,
    PhysicalReg::S4, PhysicalReg::S5, PhysicalReg::S6, PhysicalReg::S7,
    PhysicalReg::S8, PhysicalReg::S9, PhysicalReg::S10, PhysicalReg::S11,
    // 浮点寄存器
    PhysicalReg::F0, PhysicalReg::F1, PhysicalReg::F2, PhysicalReg::F3,
    PhysicalReg::F4, PhysicalReg::F5, PhysicalReg::F6, PhysicalReg::F7,
    PhysicalReg::F8, PhysicalReg::F9, PhysicalReg::F10, PhysicalReg::F11,
    PhysicalReg::F12, PhysicalReg::F13, PhysicalReg::F14, PhysicalReg::F15,
    PhysicalReg::F16, PhysicalReg::F17, PhysicalReg::F18, PhysicalReg::F19,
    PhysicalReg::F20, PhysicalReg::F21, PhysicalReg::F22, PhysicalReg::F23,
    PhysicalReg::F24, PhysicalReg::F25, PhysicalReg::F26, PhysicalReg::F27,
    PhysicalReg::F28, PhysicalReg::F29, PhysicalReg::F30, PhysicalReg::F31
};

// 将物理寄存器枚举转换为字符串
std::string RISCv64CodeGen::reg_to_string(PhysicalReg reg) {
    switch (reg) {
        case PhysicalReg::ZERO: return "x0";
        case PhysicalReg::RA:   return "ra";
        case PhysicalReg::SP:   return "sp";
        case PhysicalReg::GP:   return "gp";
        case PhysicalReg::TP:   return "tp";
        case PhysicalReg::T0:   return "t0";
        case PhysicalReg::T1:   return "t1";
        case PhysicalReg::T2:   return "t2";
        case PhysicalReg::S0:   return "s0";
        case PhysicalReg::S1:   return "s1";
        case PhysicalReg::A0:   return "a0";
        case PhysicalReg::A1:   return "a1";
        case PhysicalReg::A2:   return "a2";
        case PhysicalReg::A3:   return "a3";
        case PhysicalReg::A4:   return "a4";
        case PhysicalReg::A5:   return "a5";
        case PhysicalReg::A6:   return "a6";
        case PhysicalReg::A7:   return "a7";
        case PhysicalReg::S2:   return "s2";
        case PhysicalReg::S3:   return "s3";
        case PhysicalReg::S4:   return "s4";
        case PhysicalReg::S5:   return "s5";
        case PhysicalReg::S6:   return "s6";
        case PhysicalReg::S7:   return "s7";
        case PhysicalReg::S8:   return "s8";
        case PhysicalReg::S9:   return "s9";
        case PhysicalReg::S10:  return "s10";
        case PhysicalReg::S11:  return "s11";
        case PhysicalReg::T3:   return "t3";
        case PhysicalReg::T4:   return "t4";
        case PhysicalReg::T5:   return "t5";
        case PhysicalReg::T6:   return "t6";
        // 浮点寄存器
        case PhysicalReg::F0:   return "f0";
        case PhysicalReg::F1:   return "f1";
        case PhysicalReg::F2:   return "f2";
        case PhysicalReg::F3:   return "f3";
        case PhysicalReg::F4:   return "f4";
        case PhysicalReg::F5:   return "f5";
        case PhysicalReg::F6:   return "f6";
        case PhysicalReg::F7:   return "f7";
        case PhysicalReg::F8:   return "f8";
        case PhysicalReg::F9:   return "f9";
        case PhysicalReg::F10:  return "f10";
        case PhysicalReg::F11:  return "f11";
        case PhysicalReg::F12:  return "f12";
        case PhysicalReg::F13:  return "f13";
        case PhysicalReg::F14:  return "f14";
        case PhysicalReg::F15:  return "f15";
        case PhysicalReg::F16:  return "f16";
        case PhysicalReg::F17:  return "f17";
        case PhysicalReg::F18:  return "f18";
        case PhysicalReg::F19:  return "f19";
        case PhysicalReg::F20:  return "f20";
        case PhysicalReg::F21:  return "f21";
        case PhysicalReg::F22:  return "f22";
        case PhysicalReg::F23:  return "f23";
        case PhysicalReg::F24:  return "f24";
        case PhysicalReg::F25:  return "f25";
        case PhysicalReg::F26:  return "f26";
        case PhysicalReg::F27:  return "f27";
        case PhysicalReg::F28:  return "f28";
        case PhysicalReg::F29:  return "f29";
        case PhysicalReg::F30:  return "f30";
        case PhysicalReg::F31:  return "f31";
        default: return "UNKNOWN_REG";
    }
}

// 总体代码生成入口
std::string RISCv64CodeGen::code_gen() {
    std::stringstream ss;
    ss << module_gen();
    return ss.str();
}

// 模块级代码生成 (处理全局变量和函数)
std::string RISCv64CodeGen::module_gen() {
    std::stringstream ss;
    bool has_globals = !module->getGlobals().empty();
    if (has_globals) {
        ss << ".data\n"; // 数据段
        for (const auto& global : module->getGlobals()) {
            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"; // 整数常量 (32位)
                        } else {
                            float f = constant->getFloat();
                            uint32_t float_bits = *(uint32_t*)&f;
                            ss << "    .word " << float_bits << "\n"; // 浮点常量 (32位)
                        }
                    }
                }
            }
        }
    }
    if (!module->getFunctions().empty()) {
        ss << ".text\n"; // 代码段
        for (const auto& func : module->getFunctions()) {
            ss << function_gen(func.second.get());
        }
    }
    return ss.str();
}

// 函数级代码生成
std::string RISCv64CodeGen::function_gen(Function* func) {
    std::stringstream ss;
    ss << ".globl " << func->getName() << "\n"; // 声明函数为全局符号
    ss << func->getName() << ":\n"; // 函数入口标签

    RegAllocResult alloc_result = register_allocation(func);
    int stack_size = alloc_result.stack_size;

    // 函数序言 (Prologue)
    // RV64: ra 和 s0 都是64位（8字节）寄存器
    // 保存 ra 和 s0, 调整栈指针
    // s0 指向当前帧的底部（分配局部变量/溢出空间后的 sp）
    // 确保栈大小 16 字节对齐
    int aligned_stack_size = (stack_size + 15) & ~15;

    // 只有当需要栈空间时才生成序言
    if (aligned_stack_size > 0) {
        ss << "    addi sp, sp, -" << aligned_stack_size << "\n"; // 调整栈指针
        // RV64 修改: 使用 sd (store doubleword) 保存 8 字节的 ra 和 s0
        // 同时更新偏移量，为每个寄存器保留8字节
        ss << "    sd ra, " << (aligned_stack_size - 8) << "(sp)\n"; // 保存返回地址 (8字节)
        ss << "    sd s0, " << (aligned_stack_size - 16) << "(sp)\n"; // 保存帧指针 (8字节)
        ss << "    mv s0, sp\n"; // 设置新的帧指针
    }

    // 将传入的寄存器参数 (a0-a7 / f10-f17) 保存到对应的栈槽 (AllocaInst)。
    // RV64中，a0-a7是64位寄存器，但我们传入的int/float是32位。
    // 使用 sw/fsw 会正确地存储低32位，这是正确的行为。
    int arg_idx = 0;
    BasicBlock* entry_bb = func->getEntryBlock(); // 获取函数的入口基本块

    if (entry_bb) { // 确保入口基本块存在
        for (AllocaInst* alloca_for_param : entry_bb->getArguments()) {
            if (arg_idx >= 8) {
                std::cerr << "警告: 函数 '" << func->getName() << "' 的参数 (索引 " << arg_idx << ") 数量超过了 RISC-V 寄存器传递限制 (8个参数)。\n"
                          << "       这些参数目前未通过栈正确处理，可能导致错误。\n";
                break;
            }

            if (alloc_result.stack_map.count(alloca_for_param)) {
                int offset = alloc_result.stack_map.at(alloca_for_param);
                Type* allocated_type = alloca_for_param->getType()->as<PointerType>()->getBaseType();

                if (allocated_type->isInt()) {
                    PhysicalReg arg_reg = static_cast<PhysicalReg>(static_cast<int>(PhysicalReg::A0) + arg_idx);
                    std::string arg_reg_str = reg_to_string(arg_reg);
                    // 使用 sw 保存 int (32位) 参数，这是正确的
                    ss << "    sw " << arg_reg_str << ", " << offset << "(s0)\n";
                } else if (allocated_type->isFloat()) {
                    PhysicalReg farg_reg = static_cast<PhysicalReg>(static_cast<int>(PhysicalReg::F10) + arg_idx);
                    std::string farg_reg_str = reg_to_string(farg_reg);
                     // 使用 fsw 保存 float (32位) 参数，这是正确的
                    ss << "    fsw " << farg_reg_str << ", " << offset << "(s0)\n";
                } else {
                    throw std::runtime_error("Unsupported function argument type encountered during parameter saving to stack.");
                }
            } else {
                std::cerr << "警告: 函数参数对应的 AllocaInst '" 
                          << (alloca_for_param->getName().empty() ? "anonymous" : alloca_for_param->getName()) 
                          << "' 没有在栈映射中找到。这可能导致后续代码生成错误。\n";
            }
            arg_idx++;
        }
    } else {
        std::cerr << "错误: 函数 '" << func->getName() << "' 没有入口基本块。\n";
    }

    // 生成每个基本块的代码
    int block_idx = 0; 
    for (const auto& bb : func->getBasicBlocks()) {
        ss << basicBlock_gen(bb.get(), alloc_result, block_idx++);
    }

    // 函数尾声 (Epilogue) 由 RETURN DAGNode 的指令选择处理
    return ss.str();
}


// 基本块代码生成
std::string RISCv64CodeGen::basicBlock_gen(BasicBlock* bb, const RegAllocResult& alloc, int block_idx) {
    std::stringstream ss;

    std::string bb_name = bb->getName();
    if (bb_name.empty()) {
        bb_name = ENTRY_BLOCK_PSEUDO_NAME + std::to_string(block_idx);
        if (block_idx == 0) {
            bb_name = "entry";
        }
    }
    else {
        ss << bb_name << ":\n"; // 基本块标签
    }
    if (DEBUG) std::cerr << "=== 生成基本块: " << bb_name << " ===\n";

    // 构建当前基本块的 DAG
    auto dag_nodes_for_bb = build_dag(bb);
    if (DEBUG)
        print_dag(dag_nodes_for_bb, bb_name); // 打印 DAG 调试信息

    // 存储最终生成的指令
    std::set<DAGNode*> emitted_nodes; // 跟踪已发射的节点，防止重复
    std::vector<std::string> ordered_insts; // 用于收集指令并按序排列

    // 在 DAG 中遍历并生成指令。由于 select_instructions 可能会递归地为操作数选择指令，
    // 并且 emit_instructions 也会递归地发射，我们需要一个机制来确保指令的正确顺序和唯一性。
    // 最简单的方法是逆拓扑序遍历所有节点，确保其操作数先被处理。
    // 但是目前的 DAG 构建方式可能不支持直接的拓扑排序，
    // 我们将依赖 emit_instructions 的递归特性来处理依赖。

    // 遍历 DAG 的根节点（没有用户的节点，或者 Store/Return/Branch 节点）
    // 从这些节点开始递归发射指令。
    // NOTE: 这种发射方式可能不总是产生最优的代码顺序，但可以确保依赖关系。
    for (auto it = dag_nodes_for_bb.rbegin(); it != dag_nodes_for_bb.rend(); ++it) {
        DAGNode* node = it->get();
        // 只有那些没有用户（或者代表副作用，如STORE, RETURN, BRANCH）的节点才需要作为发射的“根”
        // 否则，它们会被其用户节点递归地发射
        // 然而，为了确保所有指令都被发射，我们通常从所有节点（或者至少是副作用节点）开始发射
        // 并且利用 emitted_nodes 集合防止重复
        // 这里简化为对所有 DAG 节点进行一次 select_instructions 和 emit_instructions 调用。
        // emit_instructions 会通过递归处理其操作数来保证依赖顺序。
        select_instructions(node, alloc); // 为当前节点选择指令
    }

    // 收集所有指令到一个临时的 vector 中，然后进行排序
    // 注意：这里的发射逻辑需要重新设计，目前的 emit_instructions 是直接添加到 std::vector<std::string>& insts 中
    // 并且期望是按顺序添加的，这在递归时难以保证。
    // 更好的方法是让 emit_instructions 直接输出到 stringstream，并控制递归顺序。
    // 但是为了最小化改动，我们先保持 emit_instructions 的现有签名，
    // 然后在它内部处理指令的收集和去重。

    // 重新设计 emit_instructions 的调用方式
    // 这里的思路是，每个 DAGNode 都存储了自己及其依赖（如果未被其他节点引用）的指令。
    // 最终，我们遍历 BasicBlock 中的所有原始 IR 指令，找到它们对应的 DAGNode，然后发射。
    // 这是因为 IR 指令的顺序决定了代码的逻辑顺序。

    // 遍历 IR 指令，并找到对应的 DAGNode 进行发射
    // 由于 build_dag 是从 IR 指令顺序构建的，我们应该按照 IR 指令的顺序来发射。
    emitted_nodes.clear(); // 再次清空已发射节点集合
    // 临时存储每个 IR 指令对应的 DAGNode，因为 DAGNode 列表是平铺的
    std::map<Instruction*, DAGNode*> inst_to_dag_node;
    for (const auto& dag_node_ptr : dag_nodes_for_bb) {
        if (dag_node_ptr->value && dynamic_cast<Instruction*>(dag_node_ptr->value)) {
            inst_to_dag_node[dynamic_cast<Instruction*>(dag_node_ptr->value)] = dag_node_ptr.get();
        }
    }

    for (const auto& inst_ptr : bb->getInstructions()) {
        DAGNode* node_to_emit = nullptr;
        // 查找当前 IR 指令在 DAG 中对应的节点。
        // 注意：不是所有 IR 指令都会直接映射到一个“根”DAGNode (例如，某些值可能只作为操作数存在)
        // 但终结符（如 Branch, Return）和 Store 指令总是重要的。
        // 对于 load/binary 等，我们应该在 build_dag 中确保它们有一个结果 vreg，并被后续指令使用。
        // 如果一个 IR 指令是某个 DAGNode 的 value，那么我们就发射那个 DAGNode。
        if (inst_to_dag_node.count(inst_ptr.get())) {
            node_to_emit = inst_to_dag_node.at(inst_ptr.get());
        }

        if (node_to_emit) {
            // 注意：select_instructions 已经在上面统一调用过，这里只需要 emit。
            // 但如果 select_instructions 没有递归地为所有依赖选择指令，这里可能需要重新考虑。
            // 为了简化，我们假定 select_instructions 在第一次被调用时（通常在 emit 之前）已经递归地为所有操作数选择了指令。

            // 直接将指令添加到 ss 中，而不是通过 vector 中转
            emit_instructions(node_to_emit, ss, alloc, emitted_nodes);
        }
    }

    return ss.str();
}

// 辅助函数，用于创建 DAGNode 并管理其所有权
sysy::RISCv64CodeGen::DAGNode* sysy::RISCv64CodeGen::create_node(
    DAGNode::NodeKind kind,
    Value* val,
    std::map<Value*, DAGNode*>& value_to_node, // 需要外部传入
    std::vector<std::unique_ptr<DAGNode>>& nodes_storage // 需要外部传入
) {
    // 优化：如果一个值已经有节点并且它不是控制流/存储/Alloca地址/一元操作，则重用它 (CSE)
    // 对于 AllocaInst，我们想创建一个代表其地址的节点，但不一定直接为 AllocaInst 本身分配虚拟寄存器。
    if (val && value_to_node.count(val) && kind != DAGNode::STORE && kind != DAGNode::RETURN && kind != DAGNode::BRANCH && kind != DAGNode::ALLOCA_ADDR && kind != DAGNode::UNARY) {
        return value_to_node[val];
    }

    auto node = std::make_unique<DAGNode>(kind);
    node->value = val;

    // 为产生结果的值分配虚拟寄存器
    if (val && value_vreg_map.count(val) && !dynamic_cast<AllocaInst*>(val)) { // 排除 AllocaInst
        node->result_vreg = value_vreg_map.at(val);
    }
    
    DAGNode* raw_node_ptr = node.get();
    nodes_storage.push_back(std::move(node)); // 存储 unique_ptr

    // 仅当 IR Value 表示一个计算值时，才将其映射到创建的 DAGNode
    // 且它应该已经在 register_allocation 中被分配了 vreg
    if (val && value_vreg_map.count(val) && kind != DAGNode::STORE && kind != DAGNode::RETURN && kind != DAGNode::BRANCH && !dynamic_cast<AllocaInst*>(val)) {
        value_to_node[val] = raw_node_ptr;
    }
    return raw_node_ptr;
}


// 辅助函数：获取值的 DAG 节点。
// 如果 value 已经映射到 DAG 节点，则直接返回。
// 如果是常量，则创建 CONSTANT 节点。
// 如果是 AllocaInst，则创建 ALLOCA_ADDR 节点。
// 否则，假定需要通过 LOAD 获取该值。
sysy::RISCv64CodeGen::DAGNode* sysy::RISCv64CodeGen::get_operand_node(
    Value* val_ir,
    std::map<Value*, DAGNode*>& value_to_node, // 接受 value_to_node
    std::vector<std::unique_ptr<DAGNode>>& nodes_storage // 接受 nodes_storage
) {
    if (value_to_node.count(val_ir)) {
        return value_to_node[val_ir];
    } else if (auto constant = dynamic_cast<ConstantValue*>(val_ir)) {
        return create_node(DAGNode::CONSTANT, constant, value_to_node, nodes_storage); // 调用成员函数版 create_node
    } else if (auto alloca = dynamic_cast<AllocaInst*>(val_ir)) {
        return create_node(DAGNode::ALLOCA_ADDR, alloca, value_to_node, nodes_storage); // 调用成员函数版 create_node
    } else if (auto global = dynamic_cast<GlobalValue*>(val_ir)) { 
        // 确保 GlobalValue 也能正确处理，如果 DAGNode::CONSTANT 无法存储 GlobalValue*，
        // 则需要新的 DAGNode 类型，例如 DAGNode::GLOBAL_ADDR
        return create_node(DAGNode::CONSTANT, global, value_to_node, nodes_storage); // 调用成员函数版 create_node
    }
    // 这是一个尚未在此块中计算的值，假设它需要加载 (从内存或参数)
    return create_node(DAGNode::LOAD, val_ir, value_to_node, nodes_storage); // 调用成员函数版 create_node
}

std::vector<std::unique_ptr<RISCv64CodeGen::DAGNode>> RISCv64CodeGen::build_dag(BasicBlock* bb) {
    std::vector<std::unique_ptr<DAGNode>> nodes_storage; // 存储所有 unique_ptr
    std::map<Value*, DAGNode*> value_to_node; // 将 IR Value* 映射到原始 DAGNode*，用于快速查找

    for (const auto& inst_ptr : bb->getInstructions()) {
        auto inst = inst_ptr.get();

        if (auto alloca = dynamic_cast<AllocaInst*>(inst)) {
            // AllocaInst 本身不产生寄存器中的值，但其地址将被 load/store 使用。
            // 创建一个节点来表示分配内存的地址。
            // 这个地址将是 s0 (帧指针) 的偏移量。
            // 我们将 AllocaInst 指针存储在 DAGNode 的 `value` 字段中。
            // 修正：AllocaInst 类型的 DAGNode 应该有一个 value 对应 AllocaInst*
            // 但它本身不应该有 result_vreg，因为不映射到物理寄存器。
            create_node(DAGNode::ALLOCA_ADDR, alloca, value_to_node, nodes_storage);
        } else if (auto store = dynamic_cast<StoreInst*>(inst)) {
            auto store_node = create_node(DAGNode::STORE, store, value_to_node, nodes_storage);

            // 获取要存储的值
            DAGNode* val_node = get_operand_node(store->getValue(), value_to_node, nodes_storage);

            // 获取内存位置的指针 (基地址)
            Value* ptr_ir = store->getPointer();
            DAGNode* ptr_node = get_operand_node(ptr_ir, value_to_node, nodes_storage);

            store_node->operands.push_back(val_node);
            store_node->operands.push_back(ptr_node);
            ptr_node->users.push_back(store_node);
        } else if (auto load = dynamic_cast<LoadInst*>(inst)) {
            auto load_node = create_node(DAGNode::LOAD, load, value_to_node, nodes_storage);

            // 获取内存位置的指针 (基地址)
            Value* ptr_ir = load->getPointer();
            DAGNode* ptr_node = get_operand_node(ptr_ir, value_to_node, nodes_storage);
            load_node->operands.push_back(ptr_node);
            ptr_node->users.push_back(load_node);
        } else if (auto bin = dynamic_cast<BinaryInst*>(inst)) {
            if (value_to_node.count(bin)) continue; // CSE

            if (bin->getKind() == BinaryInst::kSub || bin->getKind() == BinaryInst::kFSub) {
                Value* lhs_ir = bin->getLhs();
                if (auto const_lhs = dynamic_cast<ConstantValue*>(lhs_ir)) {
                    bool is_neg = false;
                    if (const_lhs->getType()->isInt()) {
                        if (const_lhs->getInt() == 0) {
                            is_neg = true;
                        }
                    } else if (const_lhs->getType()->isFloat()) {
                        if (std::fabs(const_lhs->getFloat()) < std::numeric_limits<float>::epsilon()) {
                            is_neg = true;
                        }
                    }

                    if (is_neg) {
                        auto unary_node = create_node(DAGNode::UNARY, bin, value_to_node, nodes_storage); // 传递参数
                        Value* operand_ir = bin->getRhs();
                        DAGNode* operand_node = get_operand_node(operand_ir, value_to_node, nodes_storage); // 传递参数
                        unary_node->operands.push_back(operand_node);
                        operand_node->users.push_back(unary_node);
                        continue;
                    }
                }
            }
            // 常规二进制操作
            auto bin_node = create_node(DAGNode::BINARY, bin, value_to_node, nodes_storage); // 传递参数

            DAGNode* lhs_node = get_operand_node(bin->getLhs(), value_to_node, nodes_storage); // 传递参数
            DAGNode* rhs_node = get_operand_node(bin->getRhs(), value_to_node, nodes_storage); // 传递参数

            bin_node->operands.push_back(lhs_node);
            bin_node->operands.push_back(rhs_node);
            lhs_node->users.push_back(bin_node);
            rhs_node->users.push_back(bin_node);

        } else if (auto un_inst = dynamic_cast<UnaryInst*>(inst)) {
            if (value_to_node.count(un_inst)) continue;

            auto unary_node = create_node(DAGNode::UNARY, un_inst, value_to_node, nodes_storage); // 传递参数

            Value* operand_ir = un_inst->getOperand(); 
            DAGNode* operand_node = get_operand_node(operand_ir, value_to_node, nodes_storage); // 传递参数

            unary_node->operands.push_back(operand_node);
            operand_node->users.push_back(unary_node);

        } else if (auto call = dynamic_cast<CallInst*>(inst)) {
            if (value_to_node.count(call)) continue;
            auto call_node = create_node(DAGNode::CALL, call, value_to_node, nodes_storage); // 传递参数
            for (auto arg : call->getArguments()) {
                auto arg_val_ir = arg->getValue();
                DAGNode* arg_node = get_operand_node(arg_val_ir, value_to_node, nodes_storage); // 传递参数
                call_node->operands.push_back(arg_node);
                arg_node->users.push_back(call_node);
            }
        } else if (auto ret = dynamic_cast<ReturnInst*>(inst)) {
            if (DEBUG) std::cerr << "处理 RETURN 指令: " << ret->getName() << "\n"; // 调试输出
            auto ret_node = create_node(DAGNode::RETURN, ret, value_to_node, nodes_storage); // 传递参数
            if (ret->hasReturnValue()) {
                auto val_ir = ret->getReturnValue();
                DAGNode* val_node = get_operand_node(val_ir, value_to_node, nodes_storage); // 传递参数
                ret_node->operands.push_back(val_node);
                val_node->users.push_back(ret_node);
            }
        } else if (auto cond_br = dynamic_cast<CondBrInst*>(inst)) {
            auto br_node = create_node(DAGNode::BRANCH, cond_br, value_to_node, nodes_storage); // 传递参数
            auto cond_ir = cond_br->getCondition();

            if (auto constant_cond = dynamic_cast<ConstantValue*>(cond_ir)) {
                br_node->inst = "j " + (constant_cond->getInt() ? cond_br->getThenBlock()->getName() : cond_br->getElseBlock()->getName());
            } else {
                DAGNode* cond_node = get_operand_node(cond_ir, value_to_node, nodes_storage); // 传递参数
                br_node->operands.push_back(cond_node);
                cond_node->users.push_back(br_node);
            }
        } else if (auto uncond_br = dynamic_cast<UncondBrInst*>(inst)) {
            auto br_node = create_node(DAGNode::BRANCH, uncond_br, value_to_node, nodes_storage); // 传递参数
            br_node->inst = "j " + uncond_br->getBlock()->getName();
        }
    }
    return nodes_storage;
}

// 打印 DAG
void RISCv64CodeGen::print_dag(const std::vector<std::unique_ptr<DAGNode>>& dag, const std::string& bb_name) {
    std::cerr << "=== DAG for Basic Block: " << bb_name << " ===\n";
    std::set<DAGNode*> visited;

    // 辅助映射，用于在打印输出中为节点分配顺序 ID
    std::map<DAGNode*, int> node_to_id;
    int current_id = 0;
    for (const auto& node_ptr : dag) {
        node_to_id[node_ptr.get()] = current_id++;
    }

    std::function<void(DAGNode*, int)> print_node = [&](DAGNode* node, int indent) {
        if (!node) return;

        std::string current_indent(indent, ' ');
        int node_id = node_to_id.count(node) ? node_to_id[node] : -1; // 获取分配的 ID

        std::cerr << current_indent << "Node#" << node_id << ": " << node->getNodeKindString();
        if (!node->result_vreg.empty()) {
            std::cerr << " (vreg: " << node->result_vreg << ")";
        }

        if (node->value) {
            std::cerr << " [";
            if (auto inst = dynamic_cast<Instruction*>(node->value)) {
                std::cerr << inst->getKindString();
                if (!inst->getName().empty()) {
                    std::cerr << "(" << inst->getName() << ")";
                }
            } else if (auto constant = dynamic_cast<ConstantValue*>(node->value)) {
                if (constant->isInt()) {
                    std::cerr << "ConstInt(" << constant->getInt() << ")";
                } else {
                    std::cerr << "ConstFloat(" << constant->getFloat() << ")";
                }
            } else if (auto global = dynamic_cast<GlobalValue*>(node->value)) {
                std::cerr << "Global(" << global->getName() << ")";
            } else if (auto alloca = dynamic_cast<AllocaInst*>(node->value)) {
                std::cerr << "Alloca(" << (alloca->getName().empty() ? ("%" + std::to_string(reinterpret_cast<uintptr_t>(alloca) % 1000)) : alloca->getName()) << ")";
            }
            std::cerr << "]";
        }
        std::cerr << " -> Inst: \"" << node->inst << "\""; // 打印选定的指令
        std::cerr << "\n";

        if (visited.find(node) != visited.end()) {
            std::cerr << current_indent << " (已打印后代)\n";
            return; // 避免循环的无限递归
        }
        visited.insert(node);

        if (!node->operands.empty()) {
            std::cerr << current_indent << "  操作数:\n";
            for (auto operand : node->operands) {
                print_node(operand, indent + 4);
            }
        }
        // 移除了 users 打印，以简化输出并避免 DAG 中的冗余递归。
        // Users 更适用于向上遍历，而不是向下遍历。
    };

    // 遍历 DAG，以尊重依赖的方式打印。
    // 当前实现：遍历所有节点，从作为“根”的节点开始打印（没有用户或副作用节点）。
    // 每次打印新的根时，重置 visited 集合，以允许共享子图被重新打印（尽管这不是最高效的方式）。
    for (const auto& node_ptr : dag) {
        // 只有那些没有用户或者表示副作用（如 store/branch/return）的节点才被视为“根”
        // 这样可以确保所有指令（包括那些没有明确结果的）都被打印
        if (node_ptr->users.empty() || node_ptr->kind == DAGNode::STORE || node_ptr->kind == DAGNode::RETURN || node_ptr->kind == DAGNode::BRANCH) {
            visited.clear(); // 为每个根重置 visited，允许重新打印共享子图
            print_node(node_ptr.get(), 0);
        }
    }
    std::cerr << "=== DAG 结束 ===\n\n";
}

// 指令选择
void RISCv64CodeGen::select_instructions(DAGNode* node, const RegAllocResult& alloc) {
    if (!node) return;
    if (!node->inst.empty()) return; // 指令已选择，跳过重复处理

    // 递归地为操作数选择指令，确保依赖先被处理
    for (auto operand : node->operands) {
        if (operand) {
            select_instructions(operand, alloc);
        }
    }

    std::stringstream ss_inst; // 使用 stringstream 构建指令

    // 获取分配的物理寄存器，若未分配则回退到 t0
    auto get_preg_or_temp = [&](const std::string& vreg) {
        if (vreg.empty()) { // 添加对空 vreg 的明确检查
             if (DEBUG) std::cerr << "警告: 虚拟寄存器 (空字符串) 没有分配物理寄存器，使用临时寄存器 t0 代替。\n";
             return reg_to_string(PhysicalReg::T0);
        }
        if (alloc.vreg_to_preg.count(vreg)) {
            return reg_to_string(alloc.vreg_to_preg.at(vreg));
        }
        if (DEBUG) std::cerr << "警告: 虚拟寄存器 " << vreg << " 没有分配物理寄存器，使用临时寄存器 t0 代替。\n";
        return reg_to_string(PhysicalReg::T0); // 回退到临时寄存器 t0
    };

    // 获取栈变量的内存偏移量
    auto get_stack_offset = [&](Value* val) -> std::string { // 返回类型明确为 std::string
        if (alloc.stack_map.count(val)) {
            if (DEBUG) { // 避免在非DEBUG模式下打印大量内容
                std::cout << "获取栈变量的内存偏移量，变量名： " << (val ? val->getName() : "unknown") << std::endl;
            }
            return std::to_string(alloc.stack_map.at(val));
        }
        if (DEBUG) std::cerr << "警告: 栈变量 " << (val ? val->getName() : "unknown") << " 没有在栈映射中找到，使用默认偏移 0。\n";
        // 如果没有找到映射，返回默认偏移量 "0"
        return std::string("0"); // 默认或错误情况
    };

    switch (node->kind) {
        case DAGNode::CONSTANT: {
            // [V2 特性] CONSTANT 节点自身不再生成指令。
            // 它的存在是为了在DAG中标记一个常数值或全局地址。
            // 加载这个值的责任转移给了使用它的节点 (STORE, BINARY, CALL, RETURN)。
            break;
        }
        case DAGNode::ALLOCA_ADDR: {
            // ALLOCA_ADDR 节点不直接生成指令，它仅作为一个地址标记，由 LOAD/STORE 或地址计算使用
            break;
        }
        case DAGNode::LOAD: {
            // 处理加载指令
            if (node->operands.empty() || !node->operands[0]) break;
            std::string dest_reg = get_preg_or_temp(node->result_vreg);
            DAGNode* ptr_node = node->operands[0];

            if (ptr_node->kind == DAGNode::ALLOCA_ADDR) {
                if (auto alloca_inst = dynamic_cast<AllocaInst*>(ptr_node->value)) {
                    int offset = alloc.stack_map.at(alloca_inst);
                    ss_inst << "lw " << dest_reg << ", " << offset << "(s0)";
                }
            } else {
                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 << ")";
            }
            break;
        }
        case DAGNode::STORE: {
            // 处理存储指令
            if (node->operands.size() < 2 || !node->operands[0] || !node->operands[1]) break;
            DAGNode* val_node = node->operands[0];
            DAGNode* ptr_node = node->operands[1];

            std::string src_reg = get_preg_or_temp(val_node->result_vreg);
            
            // [V2 特性] 如果要存储的值是一个常数，在此处立即加载它
            if (val_node->kind == DAGNode::CONSTANT) {
                if (auto constant = dynamic_cast<ConstantValue*>(val_node->value)) {
                    if (constant->isInt()) {
                        ss_inst << "li " << src_reg << ", " << constant->getInt() << "\n\t";
                    } else { // 浮点数常量
                        float f = constant->getFloat();
                        uint32_t float_bits = *(uint32_t*)&f;
                        ss_inst << "li " << src_reg << ", " << float_bits << "\n\t";
                        // 注意：这里假设 src_reg 是一个通用寄存器，需要额外指令移动到浮点寄存器
                        // 如果 STORE 的目标是浮点数，这里逻辑需要调整
                    }
                } else if (auto global = dynamic_cast<GlobalValue*>(val_node->value)) {
                    // 如果要存储的值是另一个全局变量的地址
                    ss_inst << "la " << src_reg << ", " << global->getName() << "\n\t";
                }
            }
            
            // [本次修复] 处理目标地址，并生成最终的存储指令
            if (ptr_node->kind == DAGNode::ALLOCA_ADDR) {
                // 情况1: 存储到栈上的局部变量
                if (auto alloca_inst = dynamic_cast<AllocaInst*>(ptr_node->value)) {
                    int offset = alloc.stack_map.at(alloca_inst);
                    ss_inst << "sw " << src_reg << ", " << offset << "(s0)";
                }
            } else {
                // 情况2: 存储到指针指向的地址 (可能是全局变量或已计算的地址)
                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 << ")";
            }
            break;
        }
        case DAGNode::BINARY: {
            if (node->operands.size() < 2 || !node->operands[0] || !node->operands[1]) break;
            auto bin = dynamic_cast<BinaryInst*>(node->value);
            if (!bin) break;

            std::string dest_reg = get_preg_or_temp(node->result_vreg);
            DAGNode* lhs_node = node->operands[0];
            DAGNode* rhs_node = node->operands[1];

            // [V1 特性] 检查是否是 base + offset 的地址计算
            if (bin->getKind() == BinaryInst::kAdd) {
                DAGNode* base_node = nullptr;
                DAGNode* offset_node = nullptr;

                if (lhs_node->kind == DAGNode::ALLOCA_ADDR) { base_node = lhs_node; offset_node = rhs_node; } 
                else if (rhs_node->kind == DAGNode::ALLOCA_ADDR) { base_node = rhs_node; offset_node = lhs_node; }

                if (base_node) {
                    if (auto alloca_inst = dynamic_cast<AllocaInst*>(base_node->value)) {
                        std::string stack_offset_str = get_stack_offset(alloca_inst);
                        std::string index_offset_reg = get_preg_or_temp(offset_node->result_vreg);
                        
                        // 生成两条指令来计算最终地址：
                        // 1. addi 将 s0 加上 b 的栈偏移量得到 b 的实际基地址
                        ss_inst << "addi " << dest_reg << ", s0, " << stack_offset_str << "\n";
                        // 2. [V3 修复] add 将基地址和索引偏移量相加，得到最终地址。地址计算必须用64位指令。
                        ss_inst << "\tadd " << dest_reg << ", " << dest_reg << ", " << index_offset_reg;
                        node->inst = ss_inst.str();
                        return; // 指令已生成，提前返回
                    }
                }
            }

            std::string lhs_reg = get_preg_or_temp(lhs_node->result_vreg);
            std::string rhs_reg = get_preg_or_temp(rhs_node->result_vreg);
            
            // [V2 特性] & [上次修复] 在生成二元运算指令前，检查操作数是否为常数（立即数或全局地址），并按需加载
            if (lhs_node->kind == DAGNode::CONSTANT) {
                 if (auto c = dynamic_cast<ConstantValue*>(lhs_node->value)) {
                     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 (auto c = dynamic_cast<ConstantValue*>(rhs_node->value)) {
                    // 优化：对于加法和小立即数，直接使用 addi 指令
                    if (bin->getKind() == BinaryInst::kAdd && c->getInt() >= -2048 && c->getInt() < 2048) {
                        ss_inst << "addi " << dest_reg << ", " << lhs_reg << ", " << c->getInt();
                        node->inst = ss_inst.str();
                        return; // 指令已生成，提前返回
                    }
                    // 否则，正常加载
                    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";
                }
            }

            std::string opcode;
            switch (bin->getKind()) {
                // [V1 特性] & [V3 修复] RV64 修改: 整数运算使用带 'w' 后缀的32位指令，地址运算使用64位指令
                case BinaryInst::kAdd:
                    // 通过检查操作数类型来决定使用 64位(add) 还是 32位(addw) 加法
                    if (bin->getLhs()->getType()->isPointer() || bin->getRhs()->getType()->isPointer()) {
                        opcode = "add"; // 指针/地址运算
                    } else {
                        opcode = "addw"; // 普通整数运算
                    }
                    break;
                case BinaryInst::kSub: opcode = "subw"; break;
                case BinaryInst::kMul: opcode = "mulw"; break;
                case Instruction::kDiv: opcode = "divw"; break;
                case Instruction::kRem: opcode = "remw"; break;
                case BinaryInst::kICmpEQ:
                    ss_inst << "subw " << dest_reg << ", " << lhs_reg << ", " << rhs_reg << "\n";
                    ss_inst << "\tseqz " << dest_reg << ", " << dest_reg;
                    node->inst = ss_inst.str();
                    return;
                case BinaryInst::kICmpGE:
                    ss_inst << "slt " << dest_reg << ", " << lhs_reg << ", " << rhs_reg << "\n";
                    ss_inst << "\txori " << dest_reg << ", " << dest_reg << ", 1";
                    node->inst = ss_inst.str();
                    return;
                case BinaryInst::kICmpGT:
                    ss_inst << "slt " << dest_reg << ", " << rhs_reg << ", " << lhs_reg;
                    node->inst = ss_inst.str();
                    return;
                case BinaryInst::kICmpLE:
                    ss_inst << "slt " << dest_reg << ", " << rhs_reg << ", " << lhs_reg << "\n";
                    ss_inst << "\txori " << dest_reg << ", " << dest_reg << ", 1";
                    node->inst = ss_inst.str();
                    return;
                case BinaryInst::kICmpLT:
                    ss_inst << "slt " << dest_reg << ", " << lhs_reg << ", " << rhs_reg;
                    node->inst = ss_inst.str();
                    return;
                case BinaryInst::kICmpNE:
                    ss_inst << "subw " << dest_reg << ", " << lhs_reg << ", " << rhs_reg << "\n";
                    ss_inst << "\tsnez " << dest_reg << ", " << dest_reg;
                    node->inst = ss_inst.str();
                    return;
                default:
                    // [V1 特性] 保留对未实现指令的定义和报错
                    throw std::runtime_error("不支持的二元指令类型: " + bin->getKindString());
            }
            if (!opcode.empty()) {
                ss_inst << opcode << " " << dest_reg << ", " << lhs_reg << ", " << rhs_reg;
            }
            break;
        }
        case DAGNode::UNARY: {
            if (node->operands.empty() || !node->operands[0]) break;
            auto unary = dynamic_cast<UnaryInst*>(node->value);
            if (!unary) break;

            std::string dest_reg = get_preg_or_temp(node->result_vreg);
            std::string src_reg = get_preg_or_temp(node->operands[0]->result_vreg);

            switch (unary->getKind()) {
                case UnaryInst::kNeg:
                    // RV64 修改: 使用 subw 实现32位取负 (negw 伪指令)
                    ss_inst << "subw " << dest_reg << ", x0, " << src_reg;
                    break;
                case UnaryInst::kNot:
                    // 整数逻辑非：seqz rd, rs (rs == 0 时 rd = 1，否则 rd = 0)
                    ss_inst << "seqz " << dest_reg << ", " << src_reg;
                    break;
                // [V1 特性] 保留对未实现指令的定义和报错
                case UnaryInst::kFNeg:
                case UnaryInst::kFNot:
                case UnaryInst::kFtoI:
                case UnaryInst::kItoF:
                case UnaryInst::kBitFtoI:
                case UnaryInst::kBitItoF:
                    throw std::runtime_error("不支持的浮点一元指令类型: " + unary->getKindString());
                default:
                    throw std::runtime_error("不支持的一元指令类型: " + unary->getKindString());
            }
            break;
        }
        case DAGNode::CALL: {
            // 处理函数调用指令
            if (!node->value) break;
            auto call = dynamic_cast<CallInst*>(node->value);
            if (!call) break;

            // [V2/V3 特性] 修正参数处理逻辑
            for (size_t i = 0; i < node->operands.size() && i < 8; ++i) {
                DAGNode* arg_node = node->operands[i];
                if (!arg_node) continue;
                
                std::string arg_preg = reg_to_string(static_cast<PhysicalReg>(static_cast<int>(PhysicalReg::A0) + i));

                // 优先检查参数节点是否为常量，并直接加载
                if (arg_node->kind == DAGNode::CONSTANT) {
                    if (auto const_val = dynamic_cast<ConstantValue*>(arg_node->value)) {
                        ss_inst << "li " << arg_preg << ", " << const_val->getInt() << "\n\t";
                    } else if (auto global_val = dynamic_cast<GlobalValue*>(arg_node->value)) {
                        ss_inst << "la " << arg_preg << ", " << global_val->getName() << "\n\t";
                    }
                } 
                // 如果不是常量，说明是一个计算出的值，使用 mv 指令移动
                else {
                    std::string src_reg = get_preg_or_temp(arg_node->result_vreg);
                    ss_inst << "mv " << arg_preg << ", " << src_reg << "\n\t";
                }
            }
            ss_inst << "call " << call->getCallee()->getName();

            // 处理返回值
            if ((call->getType()->isInt() || call->getType()->isFloat()) && !node->result_vreg.empty()) {
                ss_inst << "\nmv " << get_preg_or_temp(node->result_vreg) << ", a0";
            }
            break;
        }
        case DAGNode::RETURN: {
            // 处理返回指令
            if (!node->operands.empty() && node->operands[0]) {
                DAGNode* ret_val_node = node->operands[0];
                
                // [V2 特性] & [上次修复] 如果返回值是常量（立即数或全局地址），直接加载到 a0
                if (ret_val_node->kind == DAGNode::CONSTANT) {
                    if (auto c = dynamic_cast<ConstantValue*>(ret_val_node->value)) {
                        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 {
                    std::string return_val_reg = get_preg_or_temp(ret_val_node->result_vreg);
                    ss_inst << "mv a0, " << return_val_reg << "\n";
                }
            }

            // 恢复栈帧
            if (alloc.stack_size > 0) {
                int aligned_stack_size = (alloc.stack_size + 15) & ~15;
                // RV64 修改: 使用 ld (load doubleword) 恢复 8 字节的 ra 和 s0
                ss_inst << "\tld ra, " << (aligned_stack_size - 8) << "(sp)\n";
                ss_inst << "\tld s0, " << (aligned_stack_size - 16) << "(sp)\n";
                ss_inst << "\taddi sp, sp, " << aligned_stack_size << "\n";
            }
            ss_inst << "\tret";
            break;
        }
        case DAGNode::BRANCH: {
            // 处理分支指令
            auto br = dynamic_cast<CondBrInst*>(node->value);
            auto uncond_br = dynamic_cast<UncondBrInst*>(node->value);

            if (br) { // 条件分支
                if (node->operands.empty() || !node->operands[0]) break;
                std::string cond_reg = get_preg_or_temp(node->operands[0]->result_vreg);
                std::string then_block = br->getThenBlock()->getName();
                std::string else_block = br->getElseBlock()->getName();

                // [V1 特性] 如果基本块没有名字（例如，匿名块），给它一个伪名称
                if (then_block.empty()) {
                    then_block = ENTRY_BLOCK_PSEUDO_NAME + "_then_" + std::to_string((uintptr_t)br);
                }
                if (else_block.empty()) {
                    else_block = ENTRY_BLOCK_PSEUDO_NAME + "_else_" + std::to_string((uintptr_t)br);
                }

                ss_inst << "bnez " << cond_reg << ", " << then_block << "\n";
                ss_inst << "\tj " << else_block;
            } else if (uncond_br) { // 无条件分支
                std::string target_block = uncond_br->getBlock()->getName();
                if (target_block.empty()) {
                    target_block = ENTRY_BLOCK_PSEUDO_NAME + "_target_" + std::to_string((uintptr_t)uncond_br);
                }
                ss_inst << "j " << target_block;
            }
            break;
        }
        default:
            throw std::runtime_error("不支持的节点类型: " + node->getNodeKindString());
    }
    node->inst = ss_inst.str(); // 存储生成的指令
}

// 指令发射
void RISCv64CodeGen::emit_instructions(DAGNode* node, std::stringstream& ss, const RegAllocResult& alloc, std::set<DAGNode*>& emitted_nodes) {
    if (!node || emitted_nodes.count(node)) {
        return; // 已发射或为空
    }

    // 递归地发射操作数以确保满足依赖关系
    for (auto operand : node->operands) {
        if (operand) {
            emit_instructions(operand, ss, alloc, emitted_nodes);
        }
    }

    // 标记当前节点为已发射
    emitted_nodes.insert(node);

    // 分割多行指令并处理每一行
    std::stringstream node_inst_ss(node->inst);
    std::string line;

    while (std::getline(node_inst_ss, line, '\n')) {
        // 清除前导/尾随空白并移除行开头的潜在标签
        line = std::regex_replace(line, std::regex("^\\s*[^\\s:]*:\\s*"), ""); // 移除标签（例如 `label: inst`）
        line = std::regex_replace(line, std::regex("^\\s+|\\s+$"), ""); // 清除空白

        if (line.empty()) continue;

        // 处理虚拟寄存器替换和溢出/加载逻辑
        std::string processed_line = line;

        // 替换结果虚拟寄存器 (如果此行中存在)
        if (!node->result_vreg.empty() && alloc.vreg_to_preg.count(node->result_vreg)) {
            std::string preg = reg_to_string(alloc.vreg_to_preg.at(node->result_vreg));
            processed_line = std::regex_replace(processed_line, std::regex("\\b" + node->result_vreg + "\\b"), preg);
        }
        
        // 替换操作数虚拟寄存器 (如果此行中存在)
        for (auto operand : node->operands) {
            if (operand && !operand->result_vreg.empty() && alloc.vreg_to_preg.count(operand->result_vreg)) {
                std::string operand_preg = reg_to_string(alloc.vreg_to_preg.at(operand->result_vreg));
                processed_line = std::regex_replace(processed_line, std::regex("\\b" + operand->result_vreg + "\\b"), operand_preg);
            }
        }

        // 添加处理后的指令
        ss << "    " << processed_line << "\n";
    }
}

// 辅助函数：将集合打印为字符串
std::string print_set(const std::set<std::string>& s) {
    std::stringstream ss;
    ss << "{";
    bool first = true;
    for (const auto& elem : s) {
        if (!first) {
            ss << ", ";
        }
        ss << elem;
        first = false;
    }
    ss << "}";
    return ss.str();
}

// 活跃性分析（更新以返回 live_in 和 live_out）
LivenessResult RISCv64CodeGen::liveness_analysis(Function* func) {
    LivenessResult result;
    bool changed = true;

    // 初始化 live_in 和 live_out
    for (const auto& bb : func->getBasicBlocks()) {
        for (const auto& inst_ptr : bb->getInstructions()) {
            result.live_in[inst_ptr.get()] = {};
            result.live_out[inst_ptr.get()] = {};
        }
    }

    int iteration_count = 0;
    while (changed) {
        changed = false;
        iteration_count++;
        if (DEEPDEBUG) std::cerr << "\n--- 活跃性分析迭代: " << iteration_count << " ---" << std::endl;

        // 逆序遍历基本块
        for (auto it = func->getBasicBlocks_NoRange().rbegin(); it != func->getBasicBlocks_NoRange().rend(); ++it) {
            auto bb = it->get();
            if (DEEPDEBUG) std::cerr << "  基本块: " << bb->getName() << std::endl;

            // 计算基本块末尾的 live_out 集合，即所有后继基本块 live_in 的并集
            std::set<std::string> live_out_for_bb;
            for (const auto& succ_bb : bb->getSuccessors()) {
                if (!succ_bb->getInstructions().empty()) {
                    Instruction* first_inst_in_succ = succ_bb->getInstructions().front().get();
                    if (result.live_in.count(first_inst_in_succ)) {
                        const auto& succ_live_in = result.live_in.at(first_inst_in_succ);
                        live_out_for_bb.insert(succ_live_in.begin(), succ_live_in.end());
                    }
                }
            }

            // 逆序遍历指令
            for (auto inst_it = bb->getInstructions().rbegin(); inst_it != bb->getInstructions().rend(); ++inst_it) {
                auto inst = inst_it->get();
                if (DEEPDEBUG) std::cerr << "    指令 (BB: " << bb->getName() << ", 地址: " << static_cast<void*>(inst) << ")" << std::endl;
                
                std::set<std::string> current_live_in = result.live_in[inst];
                std::set<std::string> current_live_out = result.live_out[inst];
                std::set<std::string> new_live_out;

                // 计算当前指令的 live_out
                if (inst_it == bb->getInstructions().rbegin()) {
                    // 对于块中的最后一条指令，其 live_out 是块的 live_out
                    new_live_out = live_out_for_bb;
                } else {
                    // 否则，其 live_out 是其后继指令的 live_in
                    auto next_inst_it = std::prev(inst_it);
                    new_live_out = result.live_in[next_inst_it->get()];
                }

                std::set<std::string> use_set, def_set;

                // 定义 (Def)
                if (value_vreg_map.count(inst) && !inst->getType()->isVoid() && !dynamic_cast<AllocaInst*>(inst) && !dynamic_cast<StoreInst*>(inst) &&
                    !dynamic_cast<ReturnInst*>(inst) && !dynamic_cast<CondBrInst*>(inst) && !dynamic_cast<UncondBrInst*>(inst)) {
                    def_set.insert(value_vreg_map.at(inst));
                }

                // 使用 (Use)
                for (const auto& operand_use : inst->getOperands()) {
                    Value* operand = operand_use->getValue();
                    if (value_vreg_map.count(operand) && !dynamic_cast<AllocaInst*>(operand)) {
                        use_set.insert(value_vreg_map.at(operand));
                    }
                }
                
                // 数据流方程: live_in[i] = use[i] U (live_out[i] - def[i])
                std::set<std::string> new_live_in = use_set;
                for (const auto& vreg : new_live_out) {
                    if (def_set.find(vreg) == def_set.end()) {
                        new_live_in.insert(vreg);
                    }
                }

                // 如果活跃性集合发生变化，更新并继续迭代
                if (new_live_in != current_live_in || new_live_out != current_live_out) {
                    result.live_in[inst] = new_live_in;
                    result.live_out[inst] = new_live_out;
                    changed = true;
                }
            }
        }
    }
    return result;
}


// 干扰图构建 (使用正确的 live_out 集合)
std::map<std::string, std::set<std::string>> RISCv64CodeGen::build_interference_graph(
    const LivenessResult& liveness) {
    std::map<std::string, std::set<std::string>> graph;

    // 初始化图，确保每个虚拟寄存器都有一个节点
    for (const auto& pair : value_vreg_map) {
        graph[pair.second] = {};
    }

    // 遍历每条指令来构建干扰
    for (const auto& pair : liveness.live_out) {
        Instruction* inst = pair.first;
        const auto& live_out_set = pair.second;

        // 获取该指令定义的 vreg
        std::string defined_vreg;
        if (value_vreg_map.count(inst) && !inst->getType()->isVoid() && !dynamic_cast<AllocaInst*>(inst) && !dynamic_cast<StoreInst*>(inst) &&
            !dynamic_cast<ReturnInst*>(inst) && !dynamic_cast<CondBrInst*>(inst) && !dynamic_cast<UncondBrInst*>(inst)) {
            defined_vreg = value_vreg_map.at(inst);
        }

        // --- 规则一 和 新增的规则三 ---
        if (!defined_vreg.empty()) {
            // 您的“规则一”：定义与出口活跃寄存器冲突 (保留)
            for (const auto& live_vreg : live_out_set) {
                if (defined_vreg != live_vreg) {
                    graph[defined_vreg].insert(live_vreg);
                    graph[live_vreg].insert(defined_vreg);
                }
            }

            // ====================== 新增的、缺失的规则三 ======================
            // 定义与在同一指令中并发使用的寄存器冲突
            for (const auto& operand_use : inst->getOperands()) {
                Value* operand = operand_use->getValue();
                if (value_vreg_map.count(operand)) {
                    const std::string& use_vreg = value_vreg_map.at(operand);
                    if (defined_vreg != use_vreg) {
                        graph[defined_vreg].insert(use_vreg);
                        graph[use_vreg].insert(defined_vreg);
                    }
                }
            }
            // =================================================================
        }

        // --- 您的“规则二”：特殊指令内部的操作数之间也存在干扰 (保留) ---
        if (auto store = dynamic_cast<StoreInst*>(inst)) {
            Value* val_operand = store->getValue();
            Value* ptr_operand = store->getPointer();
            if (value_vreg_map.count(val_operand) && value_vreg_map.count(ptr_operand)) {
                const std::string& val_vreg = value_vreg_map.at(val_operand);
                const std::string& ptr_vreg = value_vreg_map.at(ptr_operand);
                if (val_vreg != ptr_vreg) {
                    graph[val_vreg].insert(ptr_vreg);
                    graph[ptr_vreg].insert(val_vreg);
                }
            }
        } else if (auto bin = dynamic_cast<BinaryInst*>(inst)) {
             Value* lhs_operand = bin->getLhs();
             Value* rhs_operand = bin->getRhs();
             if (value_vreg_map.count(lhs_operand) && value_vreg_map.count(rhs_operand)) {
                const std::string& lhs_vreg = value_vreg_map.at(lhs_operand);
                const std::string& rhs_vreg = value_vreg_map.at(rhs_operand);
                if (lhs_vreg != rhs_vreg) {
                    graph[lhs_vreg].insert(rhs_vreg);
                    graph[rhs_vreg].insert(lhs_vreg);
                }
             }
        } else if (auto call = dynamic_cast<CallInst*>(inst)) {
            std::vector<std::string> arg_vregs;
            for (auto arg_use : call->getArguments()) {
                Value* arg_val = arg_use->getValue();
                if (value_vreg_map.count(arg_val)) {
                    arg_vregs.push_back(value_vreg_map.at(arg_val));
                }
            }
            for (size_t i = 0; i < arg_vregs.size(); ++i) {
                for (size_t j = i + 1; j < arg_vregs.size(); ++j) {
                    graph[arg_vregs[i]].insert(arg_vregs[j]);
                    graph[arg_vregs[j]].insert(arg_vregs[i]);
                }
            }
        }
    }
    return graph;
}

// 图着色（支持浮点寄存器）
void RISCv64CodeGen::color_graph(std::map<std::string, PhysicalReg>& vreg_to_preg,
                                 const std::map<std::string, std::set<std::string>>& interference_graph) {
    vreg_to_preg.clear();

    // 分离整数和浮点寄存器池
    std::vector<PhysicalReg> int_regs = {
        PhysicalReg::T0, PhysicalReg::T1, PhysicalReg::T2, PhysicalReg::T3,
        PhysicalReg::T4, PhysicalReg::T5, PhysicalReg::T6,
        PhysicalReg::A0, PhysicalReg::A1, PhysicalReg::A2, PhysicalReg::A3,
        PhysicalReg::A4, PhysicalReg::A5, PhysicalReg::A6, PhysicalReg::A7,
        PhysicalReg::S0, PhysicalReg::S1, PhysicalReg::S2, PhysicalReg::S3,
        PhysicalReg::S4, PhysicalReg::S5, PhysicalReg::S6, PhysicalReg::S7,
        PhysicalReg::S8, PhysicalReg::S9, PhysicalReg::S10, PhysicalReg::S11
    };
    std::vector<PhysicalReg> float_regs = {
        PhysicalReg::F0, PhysicalReg::F1, PhysicalReg::F2, PhysicalReg::F3,
        PhysicalReg::F4, PhysicalReg::F5, PhysicalReg::F6, PhysicalReg::F7,
        PhysicalReg::F8, PhysicalReg::F9, PhysicalReg::F10, PhysicalReg::F11,
        PhysicalReg::F12, PhysicalReg::F13, PhysicalReg::F14, PhysicalReg::F15,
        PhysicalReg::F16, PhysicalReg::F17, PhysicalReg::F18, PhysicalReg::F19,
        PhysicalReg::F20, PhysicalReg::F21, PhysicalReg::F22, PhysicalReg::F23,
        PhysicalReg::F24, PhysicalReg::F25, PhysicalReg::F26, PhysicalReg::F27,
        PhysicalReg::F28, PhysicalReg::F29, PhysicalReg::F30, PhysicalReg::F31
    };

    // 确定虚拟寄存器类型（整数或浮点）
    auto is_float_vreg = [&](const std::string& vreg) -> bool {
        for (const auto& pair : value_vreg_map) {
            if (pair.second == vreg) {
                if (auto inst = dynamic_cast<Instruction*>(pair.first)) {
                    if (inst->isUnary()) {
                        switch (inst->getKind()) {
                            case Instruction::kFNeg:
                            case Instruction::kFNot:
                            case Instruction::kFtoI:
                            case Instruction::kItoF:
                            case Instruction::kBitFtoI:
                            case Instruction::kBitItoF:
                                return true; // 浮点相关指令
                            default:
                                return inst->getType()->isFloat();
                        }
                    }
                    return inst->getType()->isFloat();
                } else if (auto constant = dynamic_cast<ConstantValue*>(pair.first)) {
                    return constant->isFloat();
                }
            }
        }
        return false; // 默认整数
    };

    // 按度数排序虚拟寄存器
    std::vector<std::pair<std::string, int>> vreg_degrees;
    for (const auto& entry : interference_graph) {
        vreg_degrees.push_back({entry.first, (int)entry.second.size()});
    }
    std::sort(vreg_degrees.begin(), vreg_degrees.end(),
              [](const auto& a, const auto& b) { return a.second > b.second; });

    for (const auto& vreg_deg_pair : vreg_degrees) {
        const std::string& vreg = vreg_deg_pair.first;
        std::set<PhysicalReg> used_colors;
        bool is_float = is_float_vreg(vreg);

        // 收集邻居使用的颜色
        if (interference_graph.count(vreg)) {
            for (const auto& neighbor_vreg : interference_graph.at(vreg)) {
                if (vreg_to_preg.count(neighbor_vreg)) {
                    used_colors.insert(vreg_to_preg.at(neighbor_vreg));
                }
            }
        }

        // 选择合适的寄存器池
        const auto& available_regs = is_float ? float_regs : int_regs;

        // 查找第一个可用的寄存器
        bool colored = false;
        for (PhysicalReg preg : available_regs) {
            if (used_colors.find(preg) == used_colors.end()) {
                vreg_to_preg[vreg] = preg;
                colored = true;
                break;
            }
        }

        if (!colored) {
            std::cerr << "警告: 无法为 " << vreg << " 分配" << (is_float ? "浮点" : "整数") << "寄存器，将溢出到栈。\n";
            // 溢出处理：在 stack_map 中分配栈空间
            // 这里假设每个溢出变量占用 4 字节
            // 注意：实际中需要区分整数和浮点溢出的存储指令（如 sw vs fsw）
        }
    }
}

// 寄存器分配
RISCv64CodeGen::RegAllocResult RISCv64CodeGen::register_allocation(Function* func) {
    eliminate_phi(func);
    vreg_counter = 0;
    value_vreg_map.clear();

    // 为所有产生值的指令和操作数分配虚拟寄存器
    for (const auto& bb_ptr : func->getBasicBlocks()) {
        for (const auto& inst_ptr : bb_ptr->getInstructions()) {
            Instruction* inst = inst_ptr.get();
            if (!inst->getType()->isVoid() && !dynamic_cast<AllocaInst*>(inst)) {
                if (value_vreg_map.find(inst) == value_vreg_map.end()) {
                    value_vreg_map[inst] = "v" + std::to_string(vreg_counter++);
                }
            }
            for (const auto& operand_use : inst->getOperands()) {
                Value* operand = operand_use->getValue();
                if (dynamic_cast<ConstantValue*>(operand) || dynamic_cast<GlobalValue*>(operand)) {
                    if (value_vreg_map.find(operand) == value_vreg_map.end()) {
                        value_vreg_map[operand] = "v" + std::to_string(vreg_counter++);
                    }
                } else if (auto op_inst = dynamic_cast<Instruction*>(operand)) {
                    if (!op_inst->getType()->isVoid() && !dynamic_cast<AllocaInst*>(operand)) {
                        if (value_vreg_map.find(operand) == value_vreg_map.end()) {
                            value_vreg_map[operand] = "v" + std::to_string(vreg_counter++);
                        }
                    }
                }
            }
        }
    }

    RegAllocResult alloc_result;
    int current_stack_offset = 0;
    std::set<AllocaInst*> allocas_in_func;

    // 为 AllocaInst 计算栈空间并分配偏移量
    for (const auto& bb_ptr : func->getBasicBlocks()) {
        for (const auto& inst_ptr : bb_ptr->getInstructions()) {
            if (auto alloca = dynamic_cast<AllocaInst*>(inst_ptr.get())) {
                allocas_in_func.insert(alloca);
            }
        }
    }
    for (auto alloca : allocas_in_func) {
        int total_size = 4;
        auto dims = alloca->getDims();
        if (!dims.empty()) {
            int num_elements = 1;
            for (const auto& dim_use : dims) {
                Value* dim_value = dim_use->getValue();
                if (auto const_dim = dynamic_cast<ConstantValue*>(dim_value)) {
                    num_elements *= const_dim->getInt();
                } else {
                    throw std::runtime_error("数组维度必须是编译时常量");
                }
            }
            total_size *= num_elements;
        }
        alloc_result.stack_map[alloca] = current_stack_offset;
        current_stack_offset += total_size;
    }
    // 为保存的 ra 和 s0 (各8字节) 预留16字节空间
    alloc_result.stack_size = current_stack_offset + 16;

    // 活跃性分析
    LivenessResult liveness = liveness_analysis(func);

    // 构建干扰图
    std::map<std::string, std::set<std::string>> interference_graph = build_interference_graph(liveness);

    // 图着色
    color_graph(alloc_result.vreg_to_preg, interference_graph);

    if (DEBUG) {
        std::cerr << "=== 寄存器分配结果 (vreg_to_preg) ===\n";
        for (const auto& pair : alloc_result.vreg_to_preg) {
            std::cerr << "  " << pair.first << " -> " << reg_to_string(pair.second) << "\n";
        }
        std::cerr << "=== 寄存器分配结果结束 ===\n\n";

        std::cerr << "=== 活跃性分析结果 (live_in sets) ===\n";
        for (const auto& bb_ptr : func->getBasicBlocks()) {
            std::cerr << "Basic Block: " << bb_ptr->getName() << "\n";
            for (const auto& inst_ptr : bb_ptr->getInstructions()) {
                std::cerr << "  Inst: " << inst_ptr->getKindString();
                if (!inst_ptr->getName().empty()) std::cerr << "(" << inst_ptr->getName() << ")";
                if (value_vreg_map.count(inst_ptr.get())) std::cerr << " (Def vreg: " << value_vreg_map.at(inst_ptr.get()) << ")";
                
                std::cerr << " (Live In: ";
                if (liveness.live_in.count(inst_ptr.get())) {
                    std::cerr << print_set(liveness.live_in.at(inst_ptr.get()));
                } else {
                    std::cerr << "{}";
                }
                std::cerr << ")\n";
            }
        }
        std::cerr << "=== 活跃性分析结果结束 ===\n\n";

        std::cerr << "=== 干扰图 ===\n";
        for (const auto& pair : interference_graph) {
            std::cerr << "  " << pair.first << ": " << print_set(pair.second) << "\n";
        }
        std::cerr << "=== 干扰图结束 ===\n\n";
    }

    return alloc_result;
}

// Phi 消除 (简化版，将 Phi 的结果直接复制到每个前驱基本块的末尾)
void RISCv64CodeGen::eliminate_phi(Function* func) {
    // 这是一个占位符。适当的 phi 消除将涉及
    // 在每个前驱基本块的末尾插入 `mov` 指令，用于每个 phi 操作数。
    // 对于给定的 IR 示例，没有 phi 节点，所以这可能不是严格必要的，
    // 但如果前端生成 phi 节点，则有此阶段是好的做法。
    // 目前，我们假设没有生成 phi 节点或者它们已在前端处理。
}

} // namespace sysy