prepare to code selection

This commit is contained in:
ridethepig 2023-05-23 13:58:25 +08:00
parent 8a9c32e820
commit a2d0c211a4
6 changed files with 93 additions and 37 deletions

Binary file not shown.

View File

@ -5,6 +5,14 @@
#include <optional> #include <optional>
#include <sstream> #include <sstream>
#include <string> #include <string>
#include <memory>
#include <vector>
#include <list>
#include <unordered_set>
#include <unordered_map>
#define uptr(type) std::unique_ptr<type>
#define sptr(type) std::shared_ptr<type>
#define panic(message) \ #define panic(message) \
do { \ do { \

69
include/mc_inst.h Normal file
View File

@ -0,0 +1,69 @@
#pragma once
#include "common.h"
namespace codegen{
// a?, t?, ra are caller-saved
// s? are callee-saved
// x0,gp,tp are preserved in user-space
enum class RV64Reg {
x0 = 0, // zero
x1, // ra, caller
x2, // sp, callee
x3, // gp
x4, // tp
x5, // t0, caller
x6,x7, // t1-2, caller
x8, // s0/fp, callee
x9, // s1, callee
x10,x11, // a0-1,caller
x12,x13,x14,x15,x16,x17, // a2-7,caller
x18,x19,x20,x21,x22,x23,x24,x25,x26,x27, // s2-11,callee
x28,x29,x30,x31, // t3-6,caller
};
inline std::string Reg2Name(RV64Reg reg) {
std::string regname = "x" + std::to_string((int)reg);
return regname;
}
class MOperand {
public:
enum class type {
Virt,
Imm,
Reg,
} op_type;
int value;
};
class MInst {
public:
enum class MInstTag {
Add, Sub, Rsb, Mul, Div, Mod, Lt, Le, Ge, Gt, Eq, Ne, And, Or,
LongMul, FMA, Mv, Branch, Jump, Return, Load, Store,Compare, Call, Global,
} tag;
MInst(MInstTag tag) : tag(tag) {}
};
class MBasicBlock {
};
class MFunction {
std::list<uptr(MBasicBlock)> bbs;
};
class MGlobalVar {
};
class MCModule {
std::list<uptr(MFunction)> functions;
std::list<uptr(MGlobalVar)> globals;
};
}

View File

@ -11,36 +11,6 @@
namespace antlrSysY { namespace antlrSysY {
static bool is_alloca_promotable(InstAllocaPtr_t inst) {
for (const auto use : inst->use_list) {
auto user = use.user;
if (dynamic_cast<InstLoad *>(user)) {
const auto li = dynamic_cast<InstLoad *>(user);
if (li->type != inst->type) {
return false;
}
}
else if (dynamic_cast<InstStore *>(user)) {
const auto si = dynamic_cast<InstStore *>(user);
if (si->operand_list[1] == inst || si->type != inst->type) {
return false;
}
}
else if (dynamic_cast<InstGEP *>(user)) {
const auto gep = dynamic_cast<InstGEP *>(user);
for (int i = 1; i < gep->operand_list.size(); ++i) {
if (!Value::is<ConstantInt>(gep->operand_list[i]) || !Value::as<ConstantInt>(gep->operand_list[i])->value) {
return false;
}
}
}
else {
return false;
}
}
return true;
}
struct AllocaInfo { struct AllocaInfo {
std::vector<BasicBlockPtr_t> def_blocks = {}; std::vector<BasicBlockPtr_t> def_blocks = {};
std::vector<BasicBlockPtr_t> use_blocks = {}; std::vector<BasicBlockPtr_t> use_blocks = {};
@ -241,6 +211,14 @@ static void _mem_2_reg(FunctionPtr_t func) {
std::unordered_set<BasicBlockPtr_t> def_blocks(alloca_info.def_blocks.begin(), alloca_info.def_blocks.end()); std::unordered_set<BasicBlockPtr_t> def_blocks(alloca_info.def_blocks.begin(), alloca_info.def_blocks.end());
std::unordered_set<BasicBlockPtr_t> livein_blocks; std::unordered_set<BasicBlockPtr_t> livein_blocks;
live_in_blocks(ai, alloca_info, def_blocks, livein_blocks); live_in_blocks(ai, alloca_info, def_blocks, livein_blocks);
if (VLOG_IS_ON(6)) {
std::cout << "Live-in blocks of " << ai->name << ": [";
for (auto livein : livein_blocks) {
std::cout << livein->name << ", ";
}
std::cout << "]\n";
std::cout.flush();
}
// llvm use IDF to calculate phi blocks. // llvm use IDF to calculate phi blocks.
// But that is too complicated // But that is too complicated
// SSA book Algo 3.1 // SSA book Algo 3.1
@ -256,9 +234,10 @@ static void _mem_2_reg(FunctionPtr_t func) {
auto frontier_index = bb_to_id.at(frontier); auto frontier_index = bb_to_id.at(frontier);
if (!visited[frontier_index]) { if (!visited[frontier_index]) {
visited[frontier_index] = true; visited[frontier_index] = true;
// livein-block opt is workable in IDF, but not here
// if (livein_blocks.count(frontier)) { // if (livein_blocks.count(frontier)) {
auto inst_phi = build_InstPhi(TypeHelper::TYPE_I32, frontier->predecessors, frontier, ai->name); auto inst_phi = build_InstPhi(TypeHelper::TYPE_I32, frontier->predecessors, frontier, ai->name);
phi_to_allocaid.insert({inst_phi, i}); phi_to_allocaid.insert({inst_phi, i});
// } // }
if (!def_blocks.count(frontier)) { if (!def_blocks.count(frontier)) {
worklist.push(frontier); worklist.push(frontier);

View File

@ -533,9 +533,9 @@ std::any Visitor::visitLAndExp(SysyParser::LAndExpContext *ctx) {
for (int i = 0; i < eq_exp_list.size(); ++i) { for (int i = 0; i < eq_exp_list.size(); ++i) {
auto next_block = build_BasicBlock("", _state.current_func, _state.current_bb->itr); auto next_block = build_BasicBlock("", _state.current_func, _state.current_bb->itr);
auto eq_exp = any_to_Value(visitEqExp(eq_exp_list[i])); auto eq_exp = any_to_Value(visitEqExp(eq_exp_list[i]));
auto condition = eq_exp; auto condition = eq_exp;
if (!TypeHelper::isIntegerTypeI1(eq_exp->type)) if (!TypeHelper::isIntegerTypeI1(eq_exp->type))
condition = build_InstBinary(InstTag::Ne, eq_exp, CONST0, _state.current_bb); condition = build_InstBinary(InstTag::Ne, eq_exp, CONST0, _state.current_bb);
build_InstBranch(condition, next_block, ctx->false_block, _state.current_bb); build_InstBranch(condition, next_block, ctx->false_block, _state.current_bb);
_state.current_bb = next_block; _state.current_bb = next_block;
} }

View File

@ -157,7 +157,7 @@ static void _gen_blocks(std::ostream &ostr, const std::list<BasicBlockPtr_t> &bl
} }
for (auto _inst : block->inst_list) { for (auto _inst : block->inst_list) {
ostr << " "; ostr << " ";
VLOG(5) << "Build inst" << _inst->ir_seqno << ": " << _inst->to_string(); VLOG(7) << "Build inst" << _inst->ir_seqno << ": " << _inst->to_string();
switch (_inst->tag) { switch (_inst->tag) {
case InstTag::Br: { case InstTag::Br: {
auto inst = Value::as<InstBranch>(_inst); auto inst = Value::as<InstBranch>(_inst);
@ -166,7 +166,7 @@ static void _gen_blocks(std::ostream &ostr, const std::list<BasicBlockPtr_t> &bl
if (inst->operand_list.size() == 1) { if (inst->operand_list.size() == 1) {
assert(Value::is<BasicBlock>(inst->operand_list[0])); assert(Value::is<BasicBlock>(inst->operand_list[0]));
auto bb_dest = Value::as<BasicBlock>(inst->operand_list[0]); auto bb_dest = Value::as<BasicBlock>(inst->operand_list[0]);
VLOG(6) << "br to " << bb_dest->name; VLOG(7) << "br to " << bb_dest->name;
assert(bb_dest->ir_seqno >= 0); assert(bb_dest->ir_seqno >= 0);
ostr << "label %" << bb_dest->ir_seqno; ostr << "label %" << bb_dest->ir_seqno;
} }
@ -481,7 +481,7 @@ static void _gen_blocks(std::ostream &ostr, const std::list<BasicBlockPtr_t> &bl
void Visitor::llir_gen(std::ostream &ostr) { void Visitor::llir_gen(std::ostream &ostr) {
#pragma region GenLibFuncDecl #pragma region GenLibFuncDecl
for (auto &lib_func_name : libfunc_list) { for (auto &lib_func_name : libfunc_list) {
VLOG(6) << "Gen LibFunc " << lib_func_name; VLOG(7) << "Gen LibFunc " << lib_func_name;
auto lib_func = _func_tab.get_name(lib_func_name).value(); auto lib_func = _func_tab.get_name(lib_func_name).value();
auto lib_func_type = std::dynamic_pointer_cast<FunctionType>(lib_func->type); auto lib_func_type = std::dynamic_pointer_cast<FunctionType>(lib_func->type);
ostr << "declare" ostr << "declare"