[backend] introduced DAG, GraphAlloc

This commit is contained in:
Lixuanwang
2025-06-23 15:38:01 +08:00
parent af00612376
commit 7d37bd7528
2 changed files with 408 additions and 214 deletions

View File

@@ -6,61 +6,57 @@
#include <vector>
#include <map>
#include <set>
#include <memory>
namespace sysy {
class RISCv32CodeGen {
public:
explicit RISCv32CodeGen(Module* mod) : module(mod) {}
std::string code_gen(); // 生成模块的汇编代码
private:
Module* module;
// 物理寄存器
enum class PhysicalReg {
S0, // x8, 帧指针
T0, T1, T2, T3, T4, T5, T6, // x5-x7, x28-x31
A0, A1, A2, A3, A4, A5, A6, A7 // x10-x17
};
static const std::vector<PhysicalReg> allocable_regs;
// 操作数
struct Operand {
enum class Kind { Reg, Imm, Label };
Kind kind;
Value* value; // 用于寄存器
std::string label; // 用于标签或立即数
Operand(Kind k, Value* v) : kind(k), value(v), label("") {}
Operand(Kind k, const std::string& l) : kind(k), value(nullptr), label(l) {}
S0, T0, T1, T2, T3, T4, T5, T6,
A0, A1, A2, A3, A4, A5, A6, A7
};
// RISC-V 指令
struct RISCv32Inst {
std::string opcode;
std::vector<Operand> operands;
RISCv32Inst(const std::string& op, const std::vector<Operand>& ops)
: opcode(op), operands(ops) {}
// Move DAGNode and RegAllocResult to public section
struct DAGNode {
enum NodeKind { CONSTANT, LOAD, STORE, BINARY, CALL, RETURN };
NodeKind kind;
Value* value = nullptr;
std::string inst;
std::string result_reg;
std::vector<DAGNode*> operands;
std::vector<DAGNode*> users;
DAGNode(NodeKind k) : kind(k) {}
};
// 寄存器分配结果
struct RegAllocResult {
std::map<Value*, PhysicalReg> reg_map; // 虚拟寄存器到物理寄存器的映射
std::map<Value*, int> stack_map; // 虚拟寄存器到堆栈槽的映射
int stack_size; // 堆栈帧大小
std::map<std::string, PhysicalReg> vreg_to_preg;
std::map<Value*, int> stack_map;
int stack_size = 0;
};
// 后端方法
RISCv32CodeGen(Module* mod) : module(mod) {}
std::string code_gen();
std::string module_gen();
std::string function_gen(Function* func);
std::string basicBlock_gen(BasicBlock* bb, const RegAllocResult& alloc);
std::vector<std::string> instruction_gen(Instruction* inst, const RegAllocResult& alloc);
std::vector<std::unique_ptr<DAGNode>> build_dag(BasicBlock* bb);
void select_instructions(DAGNode* node, const RegAllocResult& alloc); // Use const
void emit_instructions(DAGNode* node, std::vector<std::string>& insts, const RegAllocResult& alloc); // Add alloc
std::map<Instruction*, std::set<std::string>> liveness_analysis(Function* func);
std::map<std::string, std::set<std::string>> build_interference_graph(
const std::map<Instruction*, std::set<std::string>>& live_sets);
void color_graph(std::map<std::string, PhysicalReg>& vreg_to_preg,
const std::map<std::string, std::set<std::string>>& interference_graph);
RegAllocResult register_allocation(Function* func);
void eliminate_phi(Function* func);
std::map<Instruction*, std::set<Value*>> liveness_analysis(Function* func);
std::map<Value*, std::set<Value*>> build_interference_graph(
const std::map<Instruction*, std::set<Value*>>& live_sets);
std::string reg_to_string(PhysicalReg reg);
private:
static const std::vector<PhysicalReg> allocable_regs;
std::map<Value*, std::string> value_vreg_map;
Module* module;
};
} // namespace sysy