64 lines
2.1 KiB
C++
64 lines
2.1 KiB
C++
#ifndef RISCV32_BACKEND_H
|
|
#define RISCV32_BACKEND_H
|
|
|
|
#include "IR.h"
|
|
#include <string>
|
|
#include <vector>
|
|
#include <map>
|
|
#include <set>
|
|
#include <memory>
|
|
|
|
namespace sysy {
|
|
|
|
class RISCv32CodeGen {
|
|
public:
|
|
enum class PhysicalReg {
|
|
S0, T0, T1, T2, T3, T4, T5, T6,
|
|
A0, A1, A2, A3, A4, A5, A6, A7
|
|
};
|
|
|
|
// 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<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::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::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
|
|
|
|
#endif // RISCV32_BACKEND_H
|