diff --git a/docs/riscv-spec-20191213.pdf b/docs/riscv-spec-20191213.pdf new file mode 100644 index 0000000..533c1cb Binary files /dev/null and b/docs/riscv-spec-20191213.pdf differ diff --git a/include/common.h b/include/common.h index 17b43ff..bb12664 100644 --- a/include/common.h +++ b/include/common.h @@ -5,6 +5,14 @@ #include #include #include +#include +#include +#include +#include +#include + +#define uptr(type) std::unique_ptr +#define sptr(type) std::shared_ptr #define panic(message) \ do { \ diff --git a/include/mc_inst.h b/include/mc_inst.h new file mode 100644 index 0000000..6a29d11 --- /dev/null +++ b/include/mc_inst.h @@ -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 bbs; + +}; + +class MGlobalVar { + +}; + +class MCModule { + std::list functions; + std::list globals; +}; + +} \ No newline at end of file diff --git a/src/pass_mem2reg.cpp b/src/pass_mem2reg.cpp index 3522de8..c3c6457 100644 --- a/src/pass_mem2reg.cpp +++ b/src/pass_mem2reg.cpp @@ -11,36 +11,6 @@ namespace antlrSysY { -static bool is_alloca_promotable(InstAllocaPtr_t inst) { - for (const auto use : inst->use_list) { - auto user = use.user; - if (dynamic_cast(user)) { - const auto li = dynamic_cast(user); - if (li->type != inst->type) { - return false; - } - } - else if (dynamic_cast(user)) { - const auto si = dynamic_cast(user); - if (si->operand_list[1] == inst || si->type != inst->type) { - return false; - } - } - else if (dynamic_cast(user)) { - const auto gep = dynamic_cast(user); - for (int i = 1; i < gep->operand_list.size(); ++i) { - if (!Value::is(gep->operand_list[i]) || !Value::as(gep->operand_list[i])->value) { - return false; - } - } - } - else { - return false; - } - } - return true; -} - struct AllocaInfo { std::vector def_blocks = {}; std::vector use_blocks = {}; @@ -241,6 +211,14 @@ static void _mem_2_reg(FunctionPtr_t func) { std::unordered_set def_blocks(alloca_info.def_blocks.begin(), alloca_info.def_blocks.end()); std::unordered_set 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. // But that is too complicated // 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); if (!visited[frontier_index]) { visited[frontier_index] = true; + // livein-block opt is workable in IDF, but not here // if (livein_blocks.count(frontier)) { - auto inst_phi = build_InstPhi(TypeHelper::TYPE_I32, frontier->predecessors, frontier, ai->name); - phi_to_allocaid.insert({inst_phi, i}); + auto inst_phi = build_InstPhi(TypeHelper::TYPE_I32, frontier->predecessors, frontier, ai->name); + phi_to_allocaid.insert({inst_phi, i}); // } if (!def_blocks.count(frontier)) { worklist.push(frontier); diff --git a/src/visitor.cpp b/src/visitor.cpp index 6c3e9cd..5bcaa2b 100644 --- a/src/visitor.cpp +++ b/src/visitor.cpp @@ -533,9 +533,9 @@ std::any Visitor::visitLAndExp(SysyParser::LAndExpContext *ctx) { for (int i = 0; i < eq_exp_list.size(); ++i) { auto next_block = build_BasicBlock("", _state.current_func, _state.current_bb->itr); 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)) - 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); _state.current_bb = next_block; } diff --git a/src/visitor_llir_gen.cpp b/src/visitor_llir_gen.cpp index b94f85c..5ff0c06 100644 --- a/src/visitor_llir_gen.cpp +++ b/src/visitor_llir_gen.cpp @@ -157,7 +157,7 @@ static void _gen_blocks(std::ostream &ostr, const std::list &bl } for (auto _inst : block->inst_list) { ostr << " "; - VLOG(5) << "Build inst" << _inst->ir_seqno << ": " << _inst->to_string(); + VLOG(7) << "Build inst" << _inst->ir_seqno << ": " << _inst->to_string(); switch (_inst->tag) { case InstTag::Br: { auto inst = Value::as(_inst); @@ -166,7 +166,7 @@ static void _gen_blocks(std::ostream &ostr, const std::list &bl if (inst->operand_list.size() == 1) { assert(Value::is(inst->operand_list[0])); auto bb_dest = Value::as(inst->operand_list[0]); - VLOG(6) << "br to " << bb_dest->name; + VLOG(7) << "br to " << bb_dest->name; assert(bb_dest->ir_seqno >= 0); ostr << "label %" << bb_dest->ir_seqno; } @@ -481,7 +481,7 @@ static void _gen_blocks(std::ostream &ostr, const std::list &bl void Visitor::llir_gen(std::ostream &ostr) { #pragma region GenLibFuncDecl 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_type = std::dynamic_pointer_cast(lib_func->type); ostr << "declare"