#ifndef RISCV64_SIMPLE_REGALLOC_H #define RISCV64_SIMPLE_REGALLOC_H #include "RISCv64LLIR.h" #include "RISCv64ISel.h" #include #include #include // 外部调试级别控制变量的声明 extern int DEBUG; extern int DEEPDEBUG; namespace sysy { class RISCv64AsmPrinter; // 前向声明 /** * @class RISCv64SimpleRegAlloc * @brief 一个简单的一次性图着色寄存器分配器。 * * 该分配器遵循一个线性的、非迭代的流程: * 1. 活跃性分析 * 2. 构建冲突图 * 3. 贪心图着色 * 4. 重写函数代码,插入溢出指令 * * 它与新版后端流水线兼容,但保留了旧版分配器的核心逻辑。 * 溢出处理使用硬编码的物理寄存器。 */ class RISCv64SimpleRegAlloc { public: RISCv64SimpleRegAlloc(MachineFunction* mfunc); /** * @brief 运行寄存器分配的主函数。 */ void run(); private: using LiveSet = std::set; using InterferenceGraph = std::map; // --- 分配流程的各个阶段 --- void unifyArgumentVRegs(); void handleCallingConvention(); void analyzeLiveness(); void buildInterferenceGraph(); void colorGraph(); void rewriteFunction(); // --- 辅助函数 --- /** * @brief 获取指令的Use/Def集合,包含物理寄存器,用于活跃性分析。 * @param instr 机器指令。 * @param use 输出参数,存储使用的寄存器ID。 * @param def 输出参数,存储定义的寄存器ID。 */ void getInstrUseDef_Liveness(const MachineInstr* instr, LiveSet& use, LiveSet& def); /** * @brief 根据vreg的类型信息返回其大小和类型种类。 * @param vreg 虚拟寄存器号。 * @return 一个包含类型信息和大小(字节)的pair。 */ std::pair getTypeAndSize(unsigned vreg); /** * @brief 打印调试用的活跃集信息。 */ void printLiveSet(const LiveSet& s, const std::string& name, std::ostream& os, const RISCv64AsmPrinter& printer); /** * @brief 将寄存器ID(虚拟或物理)转换为可读字符串。 */ std::string regIdToString(unsigned id, const RISCv64AsmPrinter& printer) const; // --- 成员变量 --- MachineFunction* MFunc; RISCv64ISel* ISel; // 可分配的寄存器池 std::vector allocable_int_regs; std::vector allocable_fp_regs; // 硬编码的溢出专用物理寄存器 const PhysicalReg INT_SPILL_REG = PhysicalReg::T2; // 用于 32-bit int const PhysicalReg PTR_SPILL_REG = PhysicalReg::T3; // 用于 64-bit pointer const PhysicalReg FP_SPILL_REG = PhysicalReg::F4; // 用于 32-bit float (ft4) // 活跃性分析结果 std::map live_in_map; std::map live_out_map; // 冲突图 InterferenceGraph interference_graph; // 着色结果和溢出列表 std::map color_map; std::set spilled_vregs; // 映射:将物理寄存器ID映射到它们在冲突图中的特殊虚拟ID std::map preg_to_vreg_id_map; }; } // namespace sysy #endif // RISCV64_SIMPLE_REGALLOC_H