prepare for rv64 sim (ignoring buggy reg alloc)
This commit is contained in:
parent
9b9a96881a
commit
6f1836450a
@ -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<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);
|
||||
|
||||
} // namespace CompSysY
|
||||
@ -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<sptr(MInstMove)> frozen_moves;
|
||||
std::set<sptr(MInstMove)> worklist_moves;
|
||||
std::set<sptr(MInstMove)> active_moves;
|
||||
|
||||
|
||||
void clear() {
|
||||
adj_list.clear();
|
||||
adj_set.clear();
|
||||
|
||||
23
scripts/rv64_sim_env.sh
Normal file
23
scripts/rv64_sim_env.sh
Normal 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
|
||||
@ -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
|
||||
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
|
||||
|
||||
@ -15,11 +15,11 @@
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#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<sptr(MCPass)> mc_passes = {
|
||||
std::make_shared<PassRegAlloc>()
|
||||
};
|
||||
std::vector<sptr(MCPass)> mc_passes = {std::make_shared<PassRegAlloc>()};
|
||||
for (auto pass : mc_passes) {
|
||||
pass->run(mc_module);
|
||||
}
|
||||
|
||||
3
src/mc_asmgen.cpp
Normal file
3
src/mc_asmgen.cpp
Normal file
@ -0,0 +1,3 @@
|
||||
#include "mc_inst.h"
|
||||
#include "common.h"
|
||||
|
||||
@ -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)) {
|
||||
def.push_back(&bin->dst);
|
||||
use.push_back(&bin->op1);
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
#include "pass.h"
|
||||
|
||||
namespace CompSysY {
|
||||
using std::cout, std::endl;
|
||||
|
||||
template <typename T>
|
||||
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) {
|
||||
@ -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<MOperand*> def;
|
||||
std::vector<MOperand*> use;
|
||||
std::vector<MOperand *> def;
|
||||
std::vector<MOperand *> 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<MOperand*> def;
|
||||
std::vector<MOperand*> use;
|
||||
std::vector<MOperand *> def;
|
||||
std::vector<MOperand *> 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);
|
||||
|
||||
BIN
tools/sylib/libsysy_rv64.a
Normal file
BIN
tools/sylib/libsysy_rv64.a
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user