#ifndef RISCV64_REGALLOC_H
#define RISCV64_REGALLOC_H

#include "RISCv64LLIR.h"
#include "RISCv64ISel.h" // 包含 RISCv64ISel.h 以访问 ISel 和 Value 类型

namespace sysy {

class RISCv64RegAlloc {
public:
    RISCv64RegAlloc(MachineFunction* mfunc);

    // 模块主入口
    void run();

private:
    using LiveSet = std::set<unsigned>; // 活跃虚拟寄存器集合
    using InterferenceGraph = std::map<unsigned, std::set<unsigned>>;

    // 栈帧管理
    void eliminateFrameIndices();
    
    // 活跃性分析
    void analyzeLiveness();

    // 构建干扰图
    void buildInterferenceGraph();

    // 图着色分配寄存器
    void colorGraph();

    // 重写函数，替换vreg并插入溢出代码
    void rewriteFunction();
    
    // 辅助函数，获取指令的Use/Def集合
    void getInstrUseDef(MachineInstr* instr, LiveSet& use, LiveSet& def);

    // 辅助函数，处理调用约定
    void handleCallingConvention();

    MachineFunction* MFunc;
    
    // 活跃性分析结果
    std::map<const MachineInstr*, LiveSet> live_in_map;
    std::map<const MachineInstr*, LiveSet> live_out_map;

    // 干扰图
    InterferenceGraph interference_graph;

    // 图着色结果
    std::map<unsigned, PhysicalReg> color_map; // vreg -> preg
    std::set<unsigned> spilled_vregs;         // 被溢出的vreg集合

    // 可用的物理寄存器池
    std::vector<PhysicalReg> allocable_int_regs;

    // 存储vreg到IR Value*的反向映射
    // 这个map将在run()函数开始时被填充，并在rewriteFunction()中使用。
    std::map<unsigned, Value*> vreg_to_value_map;
    std::map<PhysicalReg, unsigned> preg_to_vreg_id_map; // 物理寄存器到特殊vreg ID的映射
    
    // 用于计算类型大小的辅助函数
    unsigned getTypeSizeInBytes(Type* type);
    
};

} // namespace sysy

#endif // RISCV64_REGALLOC_H