ready to conduct Conflict Graph Coloring
This commit is contained in:
@ -40,6 +40,19 @@ class CFGType {
|
||||
FunctionDefItem *corresponding_func;
|
||||
};
|
||||
|
||||
namespace opt {
|
||||
class MoveInstruct : public ActionItem {
|
||||
public:
|
||||
std::string src_full;
|
||||
std::string dest_full;
|
||||
LLVMType ty;
|
||||
MoveInstruct() = default;
|
||||
void RecursivePrint([[maybe_unused]] std::ostream &os) const {
|
||||
throw std::runtime_error("Move instruction is not an actual LLVM IR instruction");
|
||||
}
|
||||
};
|
||||
} // namespace opt
|
||||
|
||||
template <typename Container, typename Compare = std::less<typename Container::value_type>>
|
||||
Container GetCollectionsIntersection(const Container &a, const Container &b, Compare comp = Compare()) {
|
||||
Container result;
|
||||
|
@ -33,4 +33,15 @@ class LoadSpilledArgs : public ActionItem {
|
||||
throw std::runtime_error("LoadSpilledArgs instruction is not an actual LLVM IR instruction");
|
||||
}
|
||||
};
|
||||
|
||||
class StoreSpilledArgs : public ActionItem {
|
||||
public:
|
||||
size_t arg_id; // [8,+inf)
|
||||
std::string var_full;
|
||||
LLVMType ty;
|
||||
StoreSpilledArgs() = default;
|
||||
void RecursivePrint(std::ostream &os) const {
|
||||
throw std::runtime_error("StoreSpilledArgs instruction is not an actual LLVM IR instruction");
|
||||
}
|
||||
};
|
||||
} // namespace opt
|
@ -2,17 +2,4 @@
|
||||
#include "IR/IR_basic.h"
|
||||
#include "cfg.h"
|
||||
|
||||
namespace opt {
|
||||
class MoveInstruct : public ActionItem {
|
||||
public:
|
||||
std::string src_full;
|
||||
std::string dest_full;
|
||||
LLVMType ty;
|
||||
MoveInstruct() = default;
|
||||
void RecursivePrint([[maybe_unused]] std::ostream &os) const {
|
||||
throw std::runtime_error("Move instruction is not an actual LLVM IR instruction");
|
||||
}
|
||||
};
|
||||
} // namespace opt
|
||||
|
||||
std::shared_ptr<ModuleItem> PhiEliminate(std::shared_ptr<ModuleItem> src);
|
@ -5,6 +5,7 @@
|
||||
#include "cfg.h"
|
||||
#include "tools.h"
|
||||
|
||||
using namespace opt;
|
||||
void VarCollect(CFGType &cfg, std::vector<std::string> &id_to_var, std::unordered_map<std::string, size_t> &var_to_id) {
|
||||
for (auto node : cfg.nodes) {
|
||||
auto block = node->corresponding_block;
|
||||
@ -29,6 +30,15 @@ void VarCollect(CFGType &cfg, std::vector<std::string> &id_to_var, std::unordere
|
||||
} else if (auto select_act = std::dynamic_pointer_cast<SelectItem>(act)) {
|
||||
id_to_var.push_back(select_act->result_full);
|
||||
var_to_id[select_act->result_full] = id_to_var.size() - 1;
|
||||
} else if (auto move_act = std::dynamic_pointer_cast<MoveInstruct>(act)) {
|
||||
id_to_var.push_back(move_act->dest_full);
|
||||
var_to_id[move_act->dest_full] = id_to_var.size() - 1;
|
||||
} else if (auto force_def_act = std::dynamic_pointer_cast<ForceDef>(act)) {
|
||||
id_to_var.push_back(force_def_act->var_full);
|
||||
var_to_id[force_def_act->var_full] = id_to_var.size() - 1;
|
||||
} else if (auto load_spilled_args_act = std::dynamic_pointer_cast<LoadSpilledArgs>(act)) {
|
||||
id_to_var.push_back(load_spilled_args_act->var_full);
|
||||
var_to_id[load_spilled_args_act->var_full] = id_to_var.size() - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -135,6 +145,29 @@ void UseDefCollect(CFGType &cfg, [[maybe_unused]] std::vector<std::string> &id_t
|
||||
if (var_to_id.find(select_act->result_full) != var_to_id.end()) {
|
||||
cur_act_def.push_back(var_to_id[select_act->result_full]);
|
||||
}
|
||||
} else if (auto move_act = std::dynamic_pointer_cast<MoveInstruct>(act)) {
|
||||
if (var_to_id.find(move_act->src_full) != var_to_id.end()) {
|
||||
cur_act_use.push_back(var_to_id[move_act->src_full]);
|
||||
}
|
||||
if (var_to_id.find(move_act->dest_full) != var_to_id.end()) {
|
||||
cur_act_def.push_back(var_to_id[move_act->dest_full]);
|
||||
}
|
||||
} else if (auto force_def_act = std::dynamic_pointer_cast<ForceDef>(act)) {
|
||||
if (var_to_id.find(force_def_act->var_full) != var_to_id.end()) {
|
||||
cur_act_def.push_back(var_to_id[force_def_act->var_full]);
|
||||
}
|
||||
} else if (auto force_use_act = std::dynamic_pointer_cast<ForceUse>(act)) {
|
||||
if (var_to_id.find(force_use_act->var_full) != var_to_id.end()) {
|
||||
cur_act_use.push_back(var_to_id[force_use_act->var_full]);
|
||||
}
|
||||
} else if (auto load_spilled_args_act = std::dynamic_pointer_cast<LoadSpilledArgs>(act)) {
|
||||
if (var_to_id.find(load_spilled_args_act->var_full) != var_to_id.end()) {
|
||||
cur_act_def.push_back(var_to_id[load_spilled_args_act->var_full]);
|
||||
}
|
||||
} else if (auto store_spilled_args_act = std::dynamic_pointer_cast<StoreSpilledArgs>(act)) {
|
||||
if (var_to_id.find(store_spilled_args_act->var_full) != var_to_id.end()) {
|
||||
cur_act_use.push_back(var_to_id[store_spilled_args_act->var_full]);
|
||||
}
|
||||
}
|
||||
std::sort(cur_act_use.begin(), cur_act_use.end());
|
||||
std::sort(cur_act_def.begin(), cur_act_def.end());
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "regalloc.h"
|
||||
#include "IR/IR_basic.h"
|
||||
#include "liveanalysis.h"
|
||||
#include "phieliminate.h"
|
||||
#include "tools.h"
|
||||
|
||||
// RISC-V calling convention compatible
|
||||
@ -69,6 +70,60 @@ void EnforcePhysicalRegs(CFGType &cfg) {
|
||||
}
|
||||
}
|
||||
// TODO: process caller side
|
||||
for (auto node : cfg.nodes) {
|
||||
auto block = node->corresponding_block;
|
||||
for (auto it_act = block->actions.begin(); it_act != block->actions.end(); ++it_act) {
|
||||
if (!std::dynamic_pointer_cast<CallItem>(*it_act)) continue;
|
||||
auto it_next = it_act;
|
||||
++it_next;
|
||||
auto call_act = std::dynamic_pointer_cast<CallItem>(*it_act);
|
||||
if (!std::holds_alternative<LLVMVOIDType>(call_act->return_type)) {
|
||||
auto return_value_collect = std::make_shared<MoveInstruct>();
|
||||
return_value_collect->ty = call_act->return_type;
|
||||
return_value_collect->src_full = "%reg.x10";
|
||||
return_value_collect->dest_full = call_act->result_full;
|
||||
block->actions.insert(it_next, return_value_collect);
|
||||
call_act->result_full = "%reg.x10";
|
||||
}
|
||||
std::unordered_set<std::string> caller_saved_regs_to_process;
|
||||
for (auto reg : caller_saved_regs) {
|
||||
caller_saved_regs_to_process.insert(reg);
|
||||
}
|
||||
for (size_t i = 0; i < call_act->args_val_full.size() & i < 8; i++) {
|
||||
auto new_move = std::make_shared<MoveInstruct>();
|
||||
new_move->ty = call_act->args_ty[i];
|
||||
new_move->src_full = call_act->args_val_full[i];
|
||||
new_move->dest_full = "%reg." + arg_regs[i];
|
||||
block->actions.insert(it_act, new_move);
|
||||
call_act->args_val_full[i] = "%reg." + arg_regs[i];
|
||||
caller_saved_regs_to_process.erase(arg_regs[i]);
|
||||
}
|
||||
if (call_act->args_val_full.size() > 8) {
|
||||
for (size_t i = 8; i < call_act->args_val_full.size(); i++) {
|
||||
auto new_store = std::make_shared<StoreSpilledArgs>();
|
||||
new_store->arg_id = i;
|
||||
new_store->var_full = call_act->args_val_full[i];
|
||||
new_store->ty = call_act->args_ty[i];
|
||||
block->actions.insert(it_act, new_store);
|
||||
}
|
||||
call_act->args_val_full.resize(8);
|
||||
call_act->args_ty.resize(8);
|
||||
}
|
||||
for (auto reg : caller_saved_regs_to_process) {
|
||||
auto new_def = std::make_shared<ForceDef>();
|
||||
new_def->var_full = "%reg." + reg;
|
||||
new_def->ty = LLVMIRIntType(32);
|
||||
block->actions.insert(it_act, new_def);
|
||||
}
|
||||
for (auto reg : caller_saved_regs) {
|
||||
auto new_use = std::make_shared<ForceUse>();
|
||||
new_use->var_full = "%reg." + reg;
|
||||
block->actions.insert(it_next, new_use);
|
||||
}
|
||||
it_act = it_next;
|
||||
--it_act;
|
||||
}
|
||||
}
|
||||
}
|
||||
void ConductRegAllocForFunction([[maybe_unused]] std::shared_ptr<FunctionDefItem> func, CFGType &cfg) {
|
||||
EnforcePhysicalRegs(cfg);
|
||||
|
Reference in New Issue
Block a user