合并backend、backend-IRC到midend

This commit is contained in:
Lixuanwang
2025-08-03 15:18:52 +08:00
parent 5b43f208ac
commit f8e423f579
17 changed files with 1966 additions and 1135 deletions

View File

@@ -0,0 +1,20 @@
#ifndef ELIMINATE_FRAME_INDICES_H
#define ELIMINATE_FRAME_INDICES_H
#include "RISCv64LLIR.h"
namespace sysy {
class EliminateFrameIndicesPass {
public:
// Pass 的主入口函数
void runOnMachineFunction(MachineFunction* mfunc);
private:
// 帮助计算类型大小的辅助函数从原RegAlloc中移出
unsigned getTypeSizeInBytes(Type* type);
};
} // namespace sysy
#endif // ELIMINATE_FRAME_INDICES_H

View File

@@ -22,7 +22,6 @@ private:
// 函数级代码生成 (实现新的流水线)
std::string function_gen(Function* func);
// 私有辅助函数,用于根据类型计算其占用的字节数。
unsigned getTypeSizeInBytes(Type* type);

View File

@@ -3,6 +3,7 @@
#include "IR.h" // 确保包含了您自己的IR头文件
#include <string>
#include <iostream>
#include <vector>
#include <memory>
#include <cstdint>
@@ -38,7 +39,7 @@ enum class PhysicalReg {
// 用于内部表示物理寄存器在干扰图中的节点ID一个简单的特殊ID确保不与vreg_counter冲突
// 假设 vreg_counter 不会达到这么大的值
PHYS_REG_START_ID = 100000,
PHYS_REG_START_ID = 1000000,
PHYS_REG_END_ID = PHYS_REG_START_ID + 320, // 预留足够的空间
};
@@ -195,6 +196,11 @@ public:
preg = new_preg;
is_virtual = false;
}
void setVRegNum(unsigned new_vreg_num) {
vreg_num = new_vreg_num;
is_virtual = true; // 确保设置vreg时操作数状态正确
}
private:
unsigned vreg_num = 0;
PhysicalReg preg = PhysicalReg::ZERO;
@@ -274,14 +280,15 @@ private:
// 栈帧信息
struct StackFrameInfo {
int locals_size = 0; // 仅为AllocaInst分配的大小
int locals_end_offset = 0; // 记录局部变量分配结束后的偏移量(相对于s0为负)
int spill_size = 0; // 仅为溢出分配的大小
int total_size = 0; // 总大小
int callee_saved_size = 0; // 保存寄存器的大小
std::map<unsigned, int> alloca_offsets; // <AllocaInst的vreg, 栈偏移>
std::map<unsigned, int> spill_offsets; // <溢出vreg, 栈偏移>
std::set<PhysicalReg> used_callee_saved_regs; // 使用的保存寄存器
std::map<unsigned, PhysicalReg> vreg_to_preg_map;
std::vector<PhysicalReg> callee_saved_regs; // 用于存储需要保存的被调用者保存寄存器列表
std::map<unsigned, PhysicalReg> vreg_to_preg_map; // RegAlloc最终的分配结果
std::vector<PhysicalReg> callee_saved_regs_to_store; // 已排序的、需要存取的被调用者保存寄存器
};
// 机器函数
@@ -295,7 +302,7 @@ public:
StackFrameInfo& getFrameInfo() { return frame_info; }
const std::vector<std::unique_ptr<MachineBasicBlock>>& getBlocks() const { return blocks; }
std::vector<std::unique_ptr<MachineBasicBlock>>& getBlocks() { return blocks; }
void dumpStackFrameInfo(std::ostream& os = std::cerr) const;
void addBlock(std::unique_ptr<MachineBasicBlock> block) {
blocks.push_back(std::move(block));
}

View File

@@ -8,6 +8,7 @@
#include "CalleeSavedHandler.h"
#include "LegalizeImmediates.h"
#include "PrologueEpilogueInsertion.h"
#include "EliminateFrameIndices.h"
#include "Pass.h"
#include "DivStrengthReduction.h"

View File

@@ -3,9 +3,15 @@
#include "RISCv64LLIR.h"
#include "RISCv64ISel.h" // 包含 RISCv64ISel.h 以访问 ISel 和 Value 类型
#include <set>
#include <vector>
#include <map>
#include <stack>
extern int DEBUG;
extern int DEEPDEBUG;
extern int DEBUGLENGTH; // 用于限制调试输出的长度
extern int DEEPERDEBUG; // 用于更深层次的调试输出
namespace sysy {
@@ -17,58 +23,98 @@ public:
void run();
private:
using LiveSet = std::set<unsigned>; // 活跃虚拟寄存器集合
using InterferenceGraph = std::map<unsigned, std::set<unsigned>>;
// 类型定义与Python版本对应
using VRegSet = std::set<unsigned>;
using InterferenceGraph = std::map<unsigned, VRegSet>;
using VRegStack = std::vector<unsigned>; // 使用vector模拟栈方便遍历
using MoveList = std::map<unsigned, std::set<const MachineInstr*>>;
using AliasMap = std::map<unsigned, unsigned>;
using ColorMap = std::map<unsigned, PhysicalReg>;
using VRegMoveSet = std::set<const MachineInstr*>;
// 栈帧管理
void eliminateFrameIndices();
// 活跃性分析
// --- 核心算法流程 ---
void initialize();
void build();
void makeWorklist();
void simplify();
void coalesce();
void freeze();
void selectSpill();
void assignColors();
void rewriteProgram();
bool doAllocation();
void applyColoring();
void dumpState(const std::string &stage);
void precolorByCallingConvention();
// --- 辅助函数 ---
void getInstrUseDef(const MachineInstr* instr, VRegSet& use, VRegSet& def);
void getInstrUseDef_Liveness(const MachineInstr *instr, VRegSet &use, VRegSet &def);
void addEdge(unsigned u, unsigned v);
VRegSet adjacent(unsigned n);
VRegMoveSet nodeMoves(unsigned n);
bool moveRelated(unsigned n);
void decrementDegree(unsigned m);
void enableMoves(const VRegSet& nodes);
unsigned getAlias(unsigned n);
void addWorklist(unsigned u);
bool briggsHeuristic(unsigned u, unsigned v);
bool georgeHeuristic(unsigned u, unsigned v);
void combine(unsigned u, unsigned v);
void freezeMoves(unsigned u);
void collectUsedCalleeSavedRegs();
bool isFPVReg(unsigned vreg) const;
std::string regToString(PhysicalReg reg);
std::string regIdToString(unsigned id);
// --- 活跃性分析 ---
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;
RISCv64ISel* ISel;
// 干扰图
InterferenceGraph interference_graph;
// 图着色结果
std::map<unsigned, PhysicalReg> color_map; // vreg -> preg
std::set<unsigned> spilled_vregs; // 被溢出的vreg集合
// 可用的物理寄存器池
// --- 算法数据结构 ---
// 寄存器池
std::vector<PhysicalReg> allocable_int_regs;
std::vector<PhysicalReg> allocable_fp_regs;
int K_int; // 整数寄存器数量
int K_fp; // 浮点寄存器数量
// 存储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);
// 节点集合
VRegSet precolored; // 预着色的节点 (物理寄存器)
VRegSet initial; // 初始的、所有待处理的虚拟寄存器节点
VRegSet simplifyWorklist;
VRegSet freezeWorklist;
VRegSet spillWorklist;
VRegSet spilledNodes;
VRegSet coalescedNodes;
VRegSet coloredNodes;
VRegStack selectStack;
// 辅助函数,用于打印集合
static void printLiveSet(const LiveSet& s, const std::string& name, std::ostream& os);
// Move指令相关
std::set<const MachineInstr*> coalescedMoves;
std::set<const MachineInstr*> constrainedMoves;
std::set<const MachineInstr*> frozenMoves;
std::set<const MachineInstr*> worklistMoves;
std::set<const MachineInstr*> activeMoves;
// 数据结构
InterferenceGraph adjSet;
std::map<unsigned, VRegSet> adjList; // 邻接表
std::map<unsigned, int> degree;
MoveList moveList;
AliasMap alias;
ColorMap color_map;
// 活跃性分析结果
std::map<const MachineInstr*, VRegSet> live_in_map;
std::map<const MachineInstr*, VRegSet> live_out_map;
// VReg -> Value* 和 VReg -> Type* 的映射
const std::map<unsigned, Value*>& vreg_to_value_map;
const std::map<unsigned, Type*>& vreg_type_map;
};
} // namespace sysy