diff --git a/include/mc_inst.h b/include/mc_inst.h index 1e37003..cde97d6 100644 --- a/include/mc_inst.h +++ b/include/mc_inst.h @@ -43,6 +43,10 @@ enum class RV64Reg { t5, t6, // t3-6,caller }; +inline const char* enum_to_string(const RV64Reg& tag) { + const static char* _str_tab[] = {"x0","ra","sp","gp","tp","t0","t1","t2","s0","s1","a0","a1","a2","a3","a4","a5","a6","a7","s2","s3","s4","s5","s6","s7","s8","s9","s1","s1","t3","t4","t5","t6",}; + return _str_tab[(unsigned)tag]; +} // riscv calling convention see: https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-cc.adoc @@ -73,6 +77,11 @@ enum class MOpTag { PreColor, Colored, }; +inline const char* enum_to_string(const MOpTag& tag) { + const static char* _str_tab[] = { "Invalid", "Virt", "Imm", "PreColor", "Colored" }; + return _str_tab[(unsigned)tag]; +} + class MOperand { public: MOpTag op_type = MOpTag::Invalid; @@ -107,6 +116,19 @@ public: bool need_clr() const { return op_type == MOpTag::PreColor || op_type == MOpTag::Virt; } + std::string to_string() { + std::string ret = enum_to_string(op_type); + ret += "("; + switch (op_type) { + case MOpTag::Imm: + case MOpTag::Virt: ret += std::to_string(value); break; + case MOpTag::PreColor: ret += enum_to_string((RV64Reg)value); break; + case MOpTag::Colored: ret += enum_to_string((RV64Reg)value); break; + case MOpTag::Invalid: assert(0); + } + ret += ")"; + return ret; + } }; enum class MInstTag { @@ -351,7 +373,7 @@ public: }; void get_inst_defuse(sptr(MInst) inst, std::vector &def, std::vector &use); -void get_inst_defuse(sptr(MInst) inst, std::vector &def, std::vector &use); +void get_inst_defuse(sptr(MInst) inst, std::vector &def, std::vector &use); void set_bb_def_use(sptr(MFunction) func); } // namespace CompSysY \ No newline at end of file diff --git a/include/pass.h b/include/pass.h index bae206c..f467431 100644 --- a/include/pass.h +++ b/include/pass.h @@ -4,6 +4,8 @@ #include "llir_module.h" #include "machcode.h" +#define DEBUG_REGALLOC + namespace CompSysY { class Pass { public: @@ -78,7 +80,7 @@ private: std::set frozen_moves; std::set worklist_moves; std::set active_moves; - + void clear() { adj_list.clear(); adj_set.clear(); diff --git a/scripts/rv64_sim_env.sh b/scripts/rv64_sim_env.sh new file mode 100644 index 0000000..deb168c --- /dev/null +++ b/scripts/rv64_sim_env.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +#1 install toolchain +yay -S riscv64-linux-gnu-gcc tdc spike + +#2 install proxy-kernel + +git clone https://github.com/riscv-software-src/riscv-pk --depth=1 +cd riscv-pk +mkdir build; cd build; mkdir dist +../configure --prefix=$(pwd)/dist --host=riscv64-linux-gnu +make -j`nproc` +make install +echo "export PATH=\$PATH:$(pwd)/dist/riscv64-linux-gnu/bin" >> ~/.zshrc +exec zsh + +#3 compile +riscv64-linux-gnu-gcc -x c -S main.sy -o main.s +riscv64-linux-gnu-as main.s -o main.o +riscv64-linux-gnu-gcc -static main.o tools/sylib/libsysy_rv64.a -o main + +#4 run +spike $(which pk) main \ No newline at end of file diff --git a/scripts/sylib-gen.sh b/scripts/sylib-gen.sh index 0d219e9..f8f8e14 100644 --- a/scripts/sylib-gen.sh +++ b/scripts/sylib-gen.sh @@ -1,3 +1,5 @@ #!/bin/bash clang -c -m32 -fPIC tools/sylib/sylib.c -include tools/sylib/sylib.h -o tools/sylib/sylib.o -ar rcs tools/sylib/libsysy_x86.a tools/sylib/sylib.o \ No newline at end of file +ar rcs tools/sylib/libsysy_x86.a tools/sylib/sylib.o +riscv64-linux-gnu-gcc -c -fPIC tools/sylib/sylib.c -include tools/sylib/sylib.h -o tools/sylib/sylib.o +riscv64-linux-gnu-ar rcs tools/sylib/libsysy_rv64.a tools/sylib/sylib.o diff --git a/src/main.cpp b/src/main.cpp index 3586d3a..0411bf7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -15,11 +15,11 @@ #include #include +#define ELPP_NO_LOG_TO_FILE INITIALIZE_EASYLOGGINGPP using namespace CompSysY; using namespace antlr4; -using namespace CompSysY; class AbortErrorListener : public BaseErrorListener { public: @@ -71,6 +71,7 @@ int main(int argc, const char **argv) { defaultConf.set(el::Level::Error, el::ConfigurationType::Format, "%levshort %loc %msg"); defaultConf.set(el::Level::Info, el::ConfigurationType::Format, "%levshort %loc %msg"); defaultConf.set(el::Level::Verbose, el::ConfigurationType::Format, "%levshort%vlevel %loc %msg"); + defaultConf.set(el::Level::Trace, el::ConfigurationType::Format, "%levshort %msg"); el::Loggers::addFlag(el::LoggingFlag::ColoredTerminalOutput); el::Loggers::reconfigureLogger("default", defaultConf); #pragma endregion @@ -128,9 +129,7 @@ int main(int argc, const char **argv) { MCModule mc_module; mc_module.IR2MC(visitor.module); - std::vector mc_passes = { - std::make_shared() - }; + std::vector mc_passes = {std::make_shared()}; for (auto pass : mc_passes) { pass->run(mc_module); } diff --git a/src/mc_asmgen.cpp b/src/mc_asmgen.cpp new file mode 100644 index 0000000..0d2ecb6 --- /dev/null +++ b/src/mc_asmgen.cpp @@ -0,0 +1,3 @@ +#include "mc_inst.h" +#include "common.h" + diff --git a/src/mc_codegen.cpp b/src/mc_codegen.cpp index 4792d4a..c9f9de0 100644 --- a/src/mc_codegen.cpp +++ b/src/mc_codegen.cpp @@ -557,7 +557,7 @@ void get_inst_defuse(sptr(MInst) inst, std::vector &def, std::vector &def, std::vector &use) { +void get_inst_defuse(sptr(MInst) inst, std::vector &def, std::vector &use) { if (auto bin = shared_cast(inst)) { def.push_back(&bin->dst); use.push_back(&bin->op1); diff --git a/src/pass_reg_alloc.cpp b/src/pass_reg_alloc.cpp index 88a97f1..de7509a 100644 --- a/src/pass_reg_alloc.cpp +++ b/src/pass_reg_alloc.cpp @@ -1,6 +1,7 @@ #include "pass.h" namespace CompSysY { +using std::cout, std::endl; template static std::set set_union(const std::set &u1, const std::set &u2) { @@ -51,6 +52,32 @@ static void liveness_analysis(sptr(MFunction) func) { } } } +#ifdef DEBUG_REGALLOC + LOG(TRACE) << "SLA info in " << func->ir_func->name; + for (auto bb : func->bb_list) { + cout << "BB "<< bb->ir_bb->name << endl; + cout << " def: "; + for (auto def : bb->def) { + cout << def.to_string() << ", "; + } + cout << "\n"; + cout << " use: "; + for (auto use : bb->use) { + cout << use.to_string() << ", "; + } + cout << "\n"; + cout << " livein: "; + for (auto livein : bb->livein) { + cout << livein.to_string() << ", "; + } + cout << "\n"; + cout << " liveout: "; + for (auto liveout : bb->liveout) { + cout << liveout.to_string() << ", "; + } + cout << "\n"; + } +#endif } void PassRegAlloc::add_edge(const MOperand &u, const MOperand &v) { @@ -366,8 +393,8 @@ void PassRegAlloc::assign_colors(sptr(MFunction) func) { // patch all the color info back to the MCIR tree, note the pointer type here for (auto bb : func->bb_list) { for (auto inst : bb->inst_list) { - std::vector def; - std::vector use; + std::vector def; + std::vector use; get_inst_defuse(inst, def, use); for (auto d : def) { if (ASSOC_FOUND(color, *d)) *d = color.at(*d); @@ -383,19 +410,19 @@ void PassRegAlloc::rewrite_program(sptr(MFunction) func) { for (auto v : spilled_nodes) { for (auto bb : func->bb_list) { sptr(MInst) firstuse = nullptr; - sptr(MInst) lastdef = nullptr; - int vr = -1; + sptr(MInst) lastdef = nullptr; + int vr = -1; for (auto inst : bb->inst_list) { - std::vector def; - std::vector use; + std::vector def; + std::vector use; get_inst_defuse(inst, def, use); for (auto d : def) { - if (vr < 0) vr = func->virt_reg_cnt ++; + if (vr < 0) vr = func->virt_reg_cnt++; d->value = vr; - lastdef = inst; + lastdef = inst; } for (auto u : use) { - if (vr < 0) vr = func->virt_reg_cnt ++; + if (vr < 0) vr = func->virt_reg_cnt++; u->value = vr; if (!lastdef && !firstuse) firstuse = inst; } @@ -414,15 +441,15 @@ void PassRegAlloc::rewrite_program(sptr(MFunction) func) { } }; if (firstuse) { - auto inst_ld = MInstLoad::New(firstuse); - inst_ld->addr = MOperand::PreClrReg(RV64Reg::sp); - inst_ld->dst = MOperand::VirtReg(vr); + auto inst_ld = MInstLoad::New(firstuse); + inst_ld->addr = MOperand::PreClrReg(RV64Reg::sp); + inst_ld->dst = MOperand::VirtReg(vr); inst_ld->offset = gen_off(inst_ld); } if (lastdef) { - auto inst_st = MInstStore::New(lastdef, true); - inst_st->addr = MOperand::PreClrReg(RV64Reg::sp); - inst_st->data = MOperand::VirtReg(vr); + auto inst_st = MInstStore::New(lastdef, true); + inst_st->addr = MOperand::PreClrReg(RV64Reg::sp); + inst_st->data = MOperand::VirtReg(vr); inst_st->offset = gen_off(inst_st); } } @@ -452,16 +479,20 @@ void PassRegAlloc::reg_alloc(sptr(MFunction) func) { do { flag = false; if (!simplify_worklist.empty()) { - simplify(); flag = true; + simplify(); + flag = true; } if (!worklist_moves.empty()) { - coalesce(); flag = true; + coalesce(); + flag = true; } if (!freeze_worklist.empty()) { - freeze(); flag = true; + freeze(); + flag = true; } if (!spill_worklist.empty()) { - select_spill(); flag = true; + select_spill(); + flag = true; } } while (flag); assign_colors(func); diff --git a/tools/sylib/libsysy_rv64.a b/tools/sylib/libsysy_rv64.a new file mode 100644 index 0000000..e8c62f9 Binary files /dev/null and b/tools/sylib/libsysy_rv64.a differ