prepare to code selection
This commit is contained in:
parent
8a9c32e820
commit
a2d0c211a4
BIN
docs/riscv-spec-20191213.pdf
Normal file
BIN
docs/riscv-spec-20191213.pdf
Normal file
Binary file not shown.
@ -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
69
include/mc_inst.h
Normal 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;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
@ -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,6 +234,7 @@ 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});
|
||||||
|
|||||||
@ -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"
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user