prepare for rv64 sim (ignoring buggy reg alloc)

This commit is contained in:
ridethepig 2023-05-29 01:23:10 +08:00
parent 9b9a96881a
commit 6f1836450a
9 changed files with 109 additions and 27 deletions

View File

@ -43,6 +43,10 @@ enum class RV64Reg {
t5, t5,
t6, // t3-6,caller 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 // 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, PreColor,
Colored, 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 { class MOperand {
public: public:
MOpTag op_type = MOpTag::Invalid; MOpTag op_type = MOpTag::Invalid;
@ -107,6 +116,19 @@ public:
bool need_clr() const { bool need_clr() const {
return op_type == MOpTag::PreColor || op_type == MOpTag::Virt; 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 { enum class MInstTag {
@ -351,7 +373,7 @@ public:
}; };
void get_inst_defuse(sptr(MInst) inst, std::vector<MOperand> &def, std::vector<MOperand> &use); void get_inst_defuse(sptr(MInst) inst, std::vector<MOperand> &def, std::vector<MOperand> &use);
void get_inst_defuse(sptr(MInst) inst, std::vector<MOperand*> &def, std::vector<MOperand*> &use); void get_inst_defuse(sptr(MInst) inst, std::vector<MOperand *> &def, std::vector<MOperand *> &use);
void set_bb_def_use(sptr(MFunction) func); void set_bb_def_use(sptr(MFunction) func);
} // namespace CompSysY } // namespace CompSysY

View File

@ -4,6 +4,8 @@
#include "llir_module.h" #include "llir_module.h"
#include "machcode.h" #include "machcode.h"
#define DEBUG_REGALLOC
namespace CompSysY { namespace CompSysY {
class Pass { class Pass {
public: public:

23
scripts/rv64_sim_env.sh Normal file
View File

@ -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

View File

@ -1,3 +1,5 @@
#!/bin/bash #!/bin/bash
clang -c -m32 -fPIC tools/sylib/sylib.c -include tools/sylib/sylib.h -o tools/sylib/sylib.o 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 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

View File

@ -15,11 +15,11 @@
#include <memory> #include <memory>
#include <string> #include <string>
#define ELPP_NO_LOG_TO_FILE
INITIALIZE_EASYLOGGINGPP INITIALIZE_EASYLOGGINGPP
using namespace CompSysY; using namespace CompSysY;
using namespace antlr4; using namespace antlr4;
using namespace CompSysY;
class AbortErrorListener : public BaseErrorListener { class AbortErrorListener : public BaseErrorListener {
public: 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::Error, el::ConfigurationType::Format, "%levshort %loc %msg");
defaultConf.set(el::Level::Info, 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::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::addFlag(el::LoggingFlag::ColoredTerminalOutput);
el::Loggers::reconfigureLogger("default", defaultConf); el::Loggers::reconfigureLogger("default", defaultConf);
#pragma endregion #pragma endregion
@ -128,9 +129,7 @@ int main(int argc, const char **argv) {
MCModule mc_module; MCModule mc_module;
mc_module.IR2MC(visitor.module); mc_module.IR2MC(visitor.module);
std::vector<sptr(MCPass)> mc_passes = { std::vector<sptr(MCPass)> mc_passes = {std::make_shared<PassRegAlloc>()};
std::make_shared<PassRegAlloc>()
};
for (auto pass : mc_passes) { for (auto pass : mc_passes) {
pass->run(mc_module); pass->run(mc_module);
} }

3
src/mc_asmgen.cpp Normal file
View File

@ -0,0 +1,3 @@
#include "mc_inst.h"
#include "common.h"

View File

@ -557,7 +557,7 @@ void get_inst_defuse(sptr(MInst) inst, std::vector<MOperand> &def, std::vector<M
} }
} }
void get_inst_defuse(sptr(MInst) inst, std::vector<MOperand*> &def, std::vector<MOperand*> &use) { void get_inst_defuse(sptr(MInst) inst, std::vector<MOperand *> &def, std::vector<MOperand *> &use) {
if (auto bin = shared_cast<MInstBinary>(inst)) { if (auto bin = shared_cast<MInstBinary>(inst)) {
def.push_back(&bin->dst); def.push_back(&bin->dst);
use.push_back(&bin->op1); use.push_back(&bin->op1);

View File

@ -1,6 +1,7 @@
#include "pass.h" #include "pass.h"
namespace CompSysY { namespace CompSysY {
using std::cout, std::endl;
template <typename T> template <typename T>
static std::set<T> set_union(const std::set<T> &u1, const std::set<T> &u2) { static std::set<T> set_union(const std::set<T> &u1, const std::set<T> &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) { 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 // patch all the color info back to the MCIR tree, note the pointer type here
for (auto bb : func->bb_list) { for (auto bb : func->bb_list) {
for (auto inst : bb->inst_list) { for (auto inst : bb->inst_list) {
std::vector<MOperand*> def; std::vector<MOperand *> def;
std::vector<MOperand*> use; std::vector<MOperand *> use;
get_inst_defuse(inst, def, use); get_inst_defuse(inst, def, use);
for (auto d : def) { for (auto d : def) {
if (ASSOC_FOUND(color, *d)) *d = color.at(*d); if (ASSOC_FOUND(color, *d)) *d = color.at(*d);
@ -386,16 +413,16 @@ void PassRegAlloc::rewrite_program(sptr(MFunction) func) {
sptr(MInst) lastdef = nullptr; sptr(MInst) lastdef = nullptr;
int vr = -1; int vr = -1;
for (auto inst : bb->inst_list) { for (auto inst : bb->inst_list) {
std::vector<MOperand*> def; std::vector<MOperand *> def;
std::vector<MOperand*> use; std::vector<MOperand *> use;
get_inst_defuse(inst, def, use); get_inst_defuse(inst, def, use);
for (auto d : def) { for (auto d : def) {
if (vr < 0) vr = func->virt_reg_cnt ++; if (vr < 0) vr = func->virt_reg_cnt++;
d->value = vr; d->value = vr;
lastdef = inst; lastdef = inst;
} }
for (auto u : use) { for (auto u : use) {
if (vr < 0) vr = func->virt_reg_cnt ++; if (vr < 0) vr = func->virt_reg_cnt++;
u->value = vr; u->value = vr;
if (!lastdef && !firstuse) firstuse = inst; if (!lastdef && !firstuse) firstuse = inst;
} }
@ -452,16 +479,20 @@ void PassRegAlloc::reg_alloc(sptr(MFunction) func) {
do { do {
flag = false; flag = false;
if (!simplify_worklist.empty()) { if (!simplify_worklist.empty()) {
simplify(); flag = true; simplify();
flag = true;
} }
if (!worklist_moves.empty()) { if (!worklist_moves.empty()) {
coalesce(); flag = true; coalesce();
flag = true;
} }
if (!freeze_worklist.empty()) { if (!freeze_worklist.empty()) {
freeze(); flag = true; freeze();
flag = true;
} }
if (!spill_worklist.empty()) { if (!spill_worklist.empty()) {
select_spill(); flag = true; select_spill();
flag = true;
} }
} while (flag); } while (flag);
assign_colors(func); assign_colors(func);

BIN
tools/sylib/libsysy_rv64.a Normal file

Binary file not shown.