CompilerSysY/include/pass.h
ridethepig 40ac8b9d65 SCCP
2023-06-15 22:14:00 +08:00

160 lines
5.4 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#pragma once
#include "common.h"
#include "llir_module.h"
#include "machcode.h"
// #define DEBUG_REGALLOC
namespace CompSysY {
class Pass {
public:
std::string pass_name;
Pass(const std::string &name) : pass_name(name) {}
virtual ~Pass() = default;
virtual void run(const Module &module) = 0;
};
class PassSCCP final : public Pass {
public:
PassSCCP() : Pass("const fold") {}
void run(const Module &module) override;
enum class ConstLatTag { Top = 0, Const, Bottom };
struct ConstLat {
ConstLatTag tag = ConstLatTag::Top;
int value = ~0;
bool is_top() const {
return tag == ConstLatTag::Top;
}
bool is_bot() const {
return tag == ConstLatTag::Bottom;
}
bool is_const() const {
return tag == ConstLatTag::Const;
}
bool operator==(const ConstLat &op2) const {
return tag == op2.tag && value == op2.value;
}
bool operator!=(const ConstLat &op2) const {
return !(tag == op2.tag && value == op2.value);
}
static ConstLat get_bot() {
return {ConstLatTag::Bottom, ~0};
}
};
private:
typedef std::pair<int, int> edge_type;
std::set<edge_type> FLowWL;
std::set<edge_type> SSAWL;
std::map<edge_type, bool> ExecFlag;
std::map<Value *, ConstLat> LatCell;
std::unordered_map<Instruction *, int> inst_id;
std::unordered_map<int, Instruction *> id_inst;
std::set<std::pair<int, int>> edge_set;
std::unordered_map<int, std::unordered_set<int>> edge_list;
void build_single_inst_block(Function *func);
void Initialize(Function *);
void SCCP(Function *);
void Visit_Phi(InstPhi *);
void Visit_Inst(Instruction *);
ConstLat Lat_Eval(Instruction *inst);
void post_sccp();
};
class PassMem2Reg final : public Pass {
public:
PassMem2Reg() : Pass("mem2reg") {}
void run(const Module &module) override;
};
class PassBuildCFG final : public Pass {
public:
PassBuildCFG() : Pass("build_cfg") {}
void run(const Module &module) override;
};
class MCPass {
public:
std::string pass_name;
MCPass(const std::string &name) : pass_name(name) {}
virtual void run(const MCModule &module) = 0;
};
class PassRegAlloc final : public MCPass {
public:
PassRegAlloc() : MCPass("regalloc") {}
virtual void run(const MCModule &module) override;
const static int K = 32 - 5; // Not Allocate-able: x0, gp, tp; Reserve: sp, ra
// exclude: x0, ra, sp, gp, tp (0, 1, 2, 3, 4)
static inline std::unordered_set<int> _ok_colors = {5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31};
private:
// 可以按照指令内容(而不是指针地址)来给Move排序,使得算法具有更好的确定性,便于调试
struct MvCmp {
bool operator()(MInstMove *const &lhs, const MInstMove *const &rhs) const {
if (lhs->dst != rhs->dst) return lhs->dst < rhs->dst;
if (lhs->src != rhs->src) return lhs->src < rhs->src;
return false;
}
};
/*以下这些集合**各不相交**
precolored机器寄存器集合每个寄存器都预先指派了一种颜色
initial临时寄存器集合其中的元素既没有预着色也没有被处理
simplifyWorklist:低度数的传送无关的结点表。
freezeWorklist低度数的传送有关的结点表。
spillWorklist:高度数的结点表。
spilledNodes在本轮中要被溢出的结点集合初始为空。
coalescedNodes已合并的寄存器集合。当合并u,v时将v加人到这个集合中u则被放回到某个工作表中或反之
coloredNodes :已成功着色的结点集合。
selectstack一个包含从图中删除的临时变量的栈
*/
void reg_alloc(MFunction *);
void build(MFunction *);
void add_edge(const MOperand &u, const MOperand &v);
void make_work_list(MFunction *func);
bool move_related(const MOperand &n);
std::set<MInstMove *, MvCmp> node_moves(const MOperand &n);
std::set<MOperand> adjacent(const MOperand &n);
void decrement_degree(const MOperand &m);
void enable_moves(const MOperand &n);
void simplify();
void coalesce();
void add_work_list(const MOperand &u);
bool OK(const MOperand &t, const MOperand &r);
bool conservative(const std::set<MOperand> &nodes);
MOperand get_alias(const MOperand &n);
void combine(const MOperand &u, const MOperand &v);
void freeze();
void freeze_moves(const MOperand &u);
void select_spill();
void assign_colors(MFunction *func);
void rewrite_program(MFunction *func);
void clear();
void set_color(MFunction *);
void apply_coalesced(MFunction *);
std::map<MOperand, std::set<MOperand>> adj_list;
std::set<std::pair<MOperand, MOperand>> adj_set;
std::map<MOperand, unsigned> degree;
std::map<MOperand, std::set<MInstMove *, MvCmp>> move_list;
std::map<MOperand, MOperand> color;
std::map<MOperand, MOperand> alias;
std::set<MOperand> initial;
std::set<MOperand> simplify_worklist;
std::set<MOperand> freeze_worklist;
std::set<MOperand> spill_worklist;
std::set<MOperand> spilled_nodes;
std::set<MOperand> coalesced_nodes;
std::set<MOperand> colored_nodes;
std::vector<MOperand> select_stack;
std::set<MInstMove *, MvCmp> coalesced_moves;
std::set<MInstMove *, MvCmp> constrained_moves;
std::set<MInstMove *, MvCmp> frozen_moves;
std::set<MInstMove *, MvCmp> worklist_moves;
std::set<MInstMove *, MvCmp> active_moves;
};
} // namespace CompSysY