[backend-llir]修复了许多重构的bug

This commit is contained in:
Lixuanwang
2025-07-19 17:50:14 +08:00
parent d4a6996d74
commit 9528335a04
11 changed files with 513 additions and 497 deletions

View File

@@ -8,29 +8,23 @@ namespace sysy {
class RISCv64AsmPrinter {
public:
// 主入口将整个MachineFunction打印到指定的输出流
void runOnMachineFunction(MachineFunction* mfunc, std::ostream& os);
RISCv64AsmPrinter(MachineFunction* mfunc);
// 主入口
void run(std::ostream& os);
private:
// 打印单个基本块
// 打印各个部分
void printPrologue();
void printEpilogue();
void printBasicBlock(MachineBasicBlock* mbb);
// 打印单条指令
void printInstruction(MachineInstr* instr, MachineBasicBlock* parent_bb);
// 打印函数序言
void printPrologue(MachineFunction* mfunc);
void printInstruction(MachineInstr* instr);
// 打印函数尾声
void printEpilogue(MachineFunction* mfunc);
// 将物理寄存器枚举转换为字符串 (从原RISCv64Backend迁移)
// 辅助函数
std::string regToString(PhysicalReg reg);
// 打印单个操作数
void printOperand(MachineOperand* op);
std::ostream* OS; // 指向当前输出流
MachineFunction* MFunc;
std::ostream* OS;
};
} // namespace sysy

View File

@@ -1,10 +1,8 @@
#ifndef RISCV64_BACKEND_H
#define RISCV64_BACKEND_H
#include "IR.h" // 只需包含高层IR定义
#include "IR.h"
#include <string>
#include <vector>
#include <memory>
namespace sysy {
@@ -12,14 +10,12 @@ namespace sysy {
class RISCv64CodeGen {
public:
RISCv64CodeGen(Module* mod) : module(mod) {}
// 唯一的公共入口点
std::string code_gen();
private:
// 模块级代码生成 (处理全局变量和驱动函数生成)
// 模块级代码生成
std::string module_gen();
// 函数级代码生成 (实现新的流水线)
std::string function_gen(Function* func);

View File

@@ -1,10 +1,7 @@
#ifndef RISCV64_ISEL_H
#define RISCV64_ISEL_H
#include "IR.h"
#include "RISCv64LLIR.h"
#include <memory>
#include <map>
namespace sysy {
@@ -14,43 +11,34 @@ public:
// 模块主入口将一个高层IR函数转换为底层LLIR函数
std::unique_ptr<MachineFunction> runOnFunction(Function* func);
// 公开接口以便后续模块如RegAlloc可以查询或创建vreg
unsigned getVReg(Value* val);
unsigned getNewVReg() { return vreg_counter++; }
private:
// DAG节点定义作为ISel的内部实现细节
struct DAGNode {
enum NodeKind { CONSTANT, LOAD, STORE, BINARY, CALL, RETURN, BRANCH, ALLOCA_ADDR, UNARY, MEMSET };
NodeKind kind;
Value* value = nullptr;
std::vector<DAGNode*> operands;
DAGNode(NodeKind k) : kind(k) {}
};
// 为当前函数生成LLIR
struct DAGNode;
// 指令选择主流程
void select();
// 为单个基本块生成指令
void selectBasicBlock(BasicBlock* bb);
// 核心函数为DAG节点选择并生成MachineInstr
void selectNode(DAGNode* node);
// --- DAG 构建相关函数 (从原RISCv64Backend迁移) ---
// DAG 构建相关函数 (从原RISCv64Backend迁移)
std::vector<std::unique_ptr<DAGNode>> build_dag(BasicBlock* bb);
DAGNode* get_operand_node(Value* val_ir, std::map<Value*, DAGNode*>& value_to_node, std::vector<std::unique_ptr<DAGNode>>& nodes_storage);
DAGNode* create_node(DAGNode::NodeKind kind, Value* val, std::map<Value*, DAGNode*>& value_to_node, std::vector<std::unique_ptr<DAGNode>>& nodes_storage);
// --- 辅助函数 ---
// 为一个IR Value获取/分配一个虚拟寄存器号
unsigned getVReg(Value* val);
DAGNode* get_operand_node(Value* val_ir, std::map<Value*, DAGNode*>&, std::vector<std::unique_ptr<DAGNode>>&);
DAGNode* create_node(int kind, Value* val, std::map<Value*, DAGNode*>&, std::vector<std::unique_ptr<DAGNode>>&);
// 状态
Function* F; // 当前处理的高层IR函数
std::unique_ptr<MachineFunction> MFunc; // 正在构建的底层LLIR函数
MachineBasicBlock* CurMBB; // 当前正在处理的机器基本块
// 映射关系
std::map<Value*, unsigned> vreg_map;
std::map<const BasicBlock*, MachineBasicBlock*> bb_map;
std::map<Value*, DAGNode*> value_to_node_map; // 用于selectNode中查找
unsigned vreg_counter;
int local_label_counter;

View File

@@ -1,66 +1,51 @@
#ifndef RISCV64_LLIR_H
#define RISCV64_LLIR_H
#include "IR.h" // 确保包含了您自己的IR头文件
#include <string>
#include <vector>
#include <memory>
#include <cstdint>
#include <map>
// 前向声明,避免循环引用
namespace sysy {
class Function;
class RISCv64ISel;
}
namespace sysy {
// 物理寄存器定义 (从 RISCv64Backend.h 移至此)
// 物理寄存器定义
enum class PhysicalReg {
ZERO, RA, SP, GP, TP, T0, T1, T2, S0, S1, A0, A1, A2, A3, A4, A5, A6, A7, S2, S3, S4, S5, S6, S7, S8, S9, S10, S11, T3, T4, T5, T6,
F0, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, F14, F15,F16, F17, F18, F19, F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F30, F31
};
// RISC-V 指令操作码枚举
enum class RVOpcodes {
// 算术指令
ADD, ADDI, ADDW, ADDIW,
SUB, SUBW,
MUL, MULW,
DIV, DIVW,
REM, REMW,
ADD, ADDI, ADDW, ADDIW, SUB, SUBW, MUL, MULW, DIV, DIVW, REM, REMW,
// 逻辑指令
XOR, XORI,
OR, ORI,
AND, ANDI,
XOR, XORI, OR, ORI, AND, ANDI,
// 移位指令
SLL, SLLI, SLLW, SLLIW,
SRL, SRLI, SRLW, SRLIW,
SRA, SRAI, SRAW, SRAIW,
SLL, SLLI, SLLW, SLLIW, SRL, SRLI, SRLW, SRLIW, SRA, SRAI, SRAW, SRAIW,
// 比较指令
SLT, SLTI, SLTU, SLTIU,
// 内存访问指令
LW, LH, LB, LWU, LHU, LBU,
SW, SH, SB,
LD, SD, // 64位
LW, LH, LB, LWU, LHU, LBU, SW, SH, SB, LD, SD,
// 控制流指令
J, JAL, JALR, RET, // RET 是 JALR x0, 0(ra) 的伪指令
J, JAL, JALR, RET,
BEQ, BNE, BLT, BGE, BLTU, BGEU,
// 伪指令 (方便指令选择)
LI, // Load Immediate
LA, // Load Address
MV, // Move register
NEG, // Negate
NEGW, // Negate Word
SEQZ, // Set if Equal to Zero
SNEZ, // Set if Not Equal to Zero
// 伪指令
LI, LA, MV, NEG, NEGW, SEQZ, SNEZ,
// 函数调用
CALL,
// 特殊标记,非指令
LABEL, // 用于表示一个标签位置
LABEL,
// 新增伪指令,用于解耦栈帧处理
FRAME_LOAD, // 从栈帧加载 (AllocaInst)
FRAME_STORE, // 保存到栈帧 (AllocaInst)
};
class MachineOperand;
@@ -72,22 +57,13 @@ class MachineInstr;
class MachineBasicBlock;
class MachineFunction;
// --- 操作数定义 ---
// 操作数基类
class MachineOperand {
public:
enum OperandKind {
KIND_REG,
KIND_IMM,
KIND_LABEL,
KIND_MEM
};
enum OperandKind { KIND_REG, KIND_IMM, KIND_LABEL, KIND_MEM };
MachineOperand(OperandKind kind) : kind(kind) {}
virtual ~MachineOperand() = default;
OperandKind getKind() const { return kind; }
private:
OperandKind kind;
};
@@ -111,7 +87,6 @@ public:
preg = new_preg;
is_virtual = false;
}
private:
unsigned vreg_num = 0;
PhysicalReg preg = PhysicalReg::ZERO;
@@ -121,9 +96,7 @@ private:
// 立即数操作数
class ImmOperand : public MachineOperand {
public:
ImmOperand(int64_t value)
: MachineOperand(KIND_IMM), value(value) {}
ImmOperand(int64_t value) : MachineOperand(KIND_IMM), value(value) {}
int64_t getValue() const { return value; }
private:
int64_t value;
@@ -132,9 +105,7 @@ private:
// 标签操作数
class LabelOperand : public MachineOperand {
public:
LabelOperand(const std::string& name)
: MachineOperand(KIND_LABEL), name(name) {}
LabelOperand(const std::string& name) : MachineOperand(KIND_LABEL), name(name) {}
const std::string& getName() const { return name; }
private:
std::string name;
@@ -145,33 +116,25 @@ class MemOperand : public MachineOperand {
public:
MemOperand(std::unique_ptr<RegOperand> base, std::unique_ptr<ImmOperand> offset)
: MachineOperand(KIND_MEM), base(std::move(base)), offset(std::move(offset)) {}
RegOperand* getBase() const { return base.get(); }
ImmOperand* getOffset() const { return offset.get(); }
private:
std::unique_ptr<RegOperand> base;
std::unique_ptr<ImmOperand> offset;
};
// --- 组织结构定义 ---
// 机器指令
class MachineInstr {
public:
MachineInstr(RVOpcodes opcode) : opcode(opcode) {}
RVOpcodes getOpcode() const { return opcode; }
// 注意返回const引用因为通常不直接修改指令的操作数列表
const std::vector<std::unique_ptr<MachineOperand>>& getOperands() const { return operands; }
// 提供一个非const版本用于内部修改
std::vector<std::unique_ptr<MachineOperand>>& getOperands() { return operands; }
void addOperand(std::unique_ptr<MachineOperand> operand) {
operands.push_back(std::move(operand));
}
private:
RVOpcodes opcode;
std::vector<std::unique_ptr<MachineOperand>> operands;
@@ -185,8 +148,6 @@ public:
const std::string& getName() const { return name; }
MachineFunction* getParent() const { return parent; }
// 同时提供 const 和 non-const 版本
const std::vector<std::unique_ptr<MachineInstr>>& getInstructions() const { return instructions; }
std::vector<std::unique_ptr<MachineInstr>>& getInstructions() { return instructions; }
@@ -196,43 +157,44 @@ public:
std::vector<MachineBasicBlock*> successors;
std::vector<MachineBasicBlock*> predecessors;
private:
std::string name;
std::vector<std::unique_ptr<MachineInstr>> instructions;
MachineFunction* parent; // 指向所属函数
MachineFunction* parent;
};
// 栈帧信息
struct StackFrameInfo {
int frame_size = 0;
std::map<int, int> spill_slots; // <虚拟寄存器号, 栈偏移>
// ... 未来可以添加更多信息
int locals_size = 0; // 仅为AllocaInst分配的大小
int spill_size = 0; // 仅为溢出分配的大小
int total_size = 0; // 总大小
std::map<unsigned, int> alloca_offsets; // <AllocaInst的vreg, 栈偏移>
std::map<unsigned, int> spill_offsets; // <溢出vreg, 栈偏移>
};
// 机器函数
class MachineFunction {
public:
MachineFunction(const std::string& name) : name(name) {}
MachineFunction(Function* func, RISCv64ISel* isel) : F(func), name(func->getName()), isel(isel) {}
Function* getFunc() const { return F; }
RISCv64ISel* getISel() const { return isel; }
const std::string& getName() const { return name; }
StackFrameInfo& getFrameInfo() { return frame_info; }
// 同时提供 const 和 non-const 版本
const std::vector<std::unique_ptr<MachineBasicBlock>>& getBlocks() const { return blocks; }
std::vector<std::unique_ptr<MachineBasicBlock>>& getBlocks() { return blocks; }
void addBlock(std::unique_ptr<MachineBasicBlock> block) {
blocks.push_back(std::move(block));
}
private:
Function* F;
RISCv64ISel* isel; // 指向创建它的ISel用于获取vreg映射等信息
std::string name;
std::vector<std::unique_ptr<MachineBasicBlock>> blocks;
StackFrameInfo frame_info;
};
} // namespace sysy
#endif // RISCV64_LLIR_H

View File

@@ -0,0 +1,18 @@
// RISCv64Passes.h
#ifndef RISCV64_PASSES_H
#define RISCV64_PASSES_H
#include "RISCv64LLIR.h"
namespace sysy {
// 此处为未来优化Pass的基类或独立类定义
// 例如:
// class PeepholeOptimizer {
// public:
// void runOnMachineFunction(MachineFunction* mfunc);
// };
} // namespace sysy
#endif // RISCV64_PASSES_H

View File

@@ -2,9 +2,6 @@
#define RISCV64_REGALLOC_H
#include "RISCv64LLIR.h"
#include <map>
#include <set>
#include <vector>
namespace sysy {
@@ -19,6 +16,9 @@ private:
using LiveSet = std::set<unsigned>; // 活跃虚拟寄存器集合
using InterferenceGraph = std::map<unsigned, std::set<unsigned>>;
// 栈帧管理
void eliminateFrameIndices();
// 活跃性分析
void analyzeLiveness();
@@ -28,7 +28,7 @@ private:
// 图着色分配寄存器
void colorGraph();
// 重写函数,将虚拟寄存器替换为物理寄存器,并插入溢出代码
// 重写函数,替换vreg并插入溢出代码
void rewriteFunction();
// 辅助函数获取指令的Use/Def集合
@@ -37,8 +37,8 @@ private:
MachineFunction* MFunc;
// 活跃性分析结果
std::map<MachineInstr*, LiveSet> live_in_map;
std::map<MachineInstr*, LiveSet> live_out_map;
std::map<const MachineInstr*, LiveSet> live_in_map;
std::map<const MachineInstr*, LiveSet> live_out_map;
// 干扰图
InterferenceGraph interference_graph;
@@ -49,7 +49,6 @@ private:
// 可用的物理寄存器池
std::vector<PhysicalReg> allocable_int_regs;
std::vector<PhysicalReg> allocable_float_regs; // (为未来浮点支持预留)
};
} // namespace sysy