can out put colored program
This commit is contained in:
@ -372,6 +372,7 @@ class FunctionDefItem : public LLVMIRItemBase {
|
|||||||
std::vector<std::string> args_full_name;
|
std::vector<std::string> args_full_name;
|
||||||
std::shared_ptr<BlockItem> init_block;
|
std::shared_ptr<BlockItem> init_block;
|
||||||
std::vector<std::shared_ptr<BlockItem>> basic_blocks;
|
std::vector<std::shared_ptr<BlockItem>> basic_blocks;
|
||||||
|
size_t spilled_vars;
|
||||||
|
|
||||||
FunctionDefItem() = default;
|
FunctionDefItem() = default;
|
||||||
void RecursivePrint(std::ostream &os) const {
|
void RecursivePrint(std::ostream &os) const {
|
||||||
|
@ -43,7 +43,7 @@ ConfGraph BuildConfGraph(CFGType &cfg) {
|
|||||||
size_t reg_id = cfg.var_to_id["%reg." + reg];
|
size_t reg_id = cfg.var_to_id["%reg." + reg];
|
||||||
res.id_to_node[reg_id]->is_binded_with_physical_reg = true;
|
res.id_to_node[reg_id]->is_binded_with_physical_reg = true;
|
||||||
res.id_to_node[reg_id]->color = std::stoi(reg.substr(1));
|
res.id_to_node[reg_id]->color = std::stoi(reg.substr(1));
|
||||||
std::cerr << "coloring node whith id=" << reg_id << " with color=" << res.id_to_node[reg_id]->color << std::endl;
|
// std::cerr << "coloring node whith id=" << reg_id << " with color=" << res.id_to_node[reg_id]->color << std::endl;
|
||||||
res.id_to_node[reg_id]->degree = ConfGraphNode::kInf;
|
res.id_to_node[reg_id]->degree = ConfGraphNode::kInf;
|
||||||
}
|
}
|
||||||
for (auto cfg_node : cfg.nodes) {
|
for (auto cfg_node : cfg.nodes) {
|
||||||
@ -123,11 +123,11 @@ void DetachNode(ConfGraphNode *node, ConfGraph &confgraph) {
|
|||||||
node->is_temporarily_removed = true;
|
node->is_temporarily_removed = true;
|
||||||
if (node->is_binded_with_physical_reg)
|
if (node->is_binded_with_physical_reg)
|
||||||
throw std::runtime_error("something strange happened: a physical register is removed");
|
throw std::runtime_error("something strange happened: a physical register is removed");
|
||||||
std::cerr << "detaching node containing var ids:";
|
// std::cerr << "detaching node containing var ids:";
|
||||||
for (auto id : node->var_ids) {
|
// for (auto id : node->var_ids) {
|
||||||
std::cerr << id << " ";
|
// std::cerr << id << " ";
|
||||||
}
|
// }
|
||||||
std::cerr << std::endl;
|
// std::cerr << std::endl;
|
||||||
for (auto neighbor : node->neighbors_half_available) {
|
for (auto neighbor : node->neighbors_half_available) {
|
||||||
neighbor->neighbors_half_available.erase(confgraph.adj_table_half_available[neighbor][node]);
|
neighbor->neighbors_half_available.erase(confgraph.adj_table_half_available[neighbor][node]);
|
||||||
confgraph.adj_table_half_available[neighbor].erase(node);
|
confgraph.adj_table_half_available[neighbor].erase(node);
|
||||||
@ -170,6 +170,35 @@ void JoinNode(ConfGraphNode *node, ConfGraph &confgraph) {
|
|||||||
// this function operates on the conflict graph, temporarily remove the node from the graph, it do nothing on the move
|
// this function operates on the conflict graph, temporarily remove the node from the graph, it do nothing on the move
|
||||||
// link graph although they share the same node set
|
// link graph although they share the same node set
|
||||||
// It is also responsible for maintaining all the changes caused by the removal of the node
|
// It is also responsible for maintaining all the changes caused by the removal of the node
|
||||||
|
if (!node->is_temporarily_removed)
|
||||||
|
throw std::runtime_error("something strange happened: a node is not temporarily removed");
|
||||||
|
node->is_temporarily_removed = false;
|
||||||
|
if (node->is_binded_with_physical_reg)
|
||||||
|
throw std::runtime_error("something strange happened: a physical register is removed");
|
||||||
|
// upgrade half available neighbors to available neighbors
|
||||||
|
for (auto neighbor : node->neighbors_half_available) {
|
||||||
|
neighbor->neighbors_half_available.erase(confgraph.adj_table_half_available[neighbor][node]);
|
||||||
|
confgraph.adj_table_half_available[neighbor].erase(node);
|
||||||
|
// node->neighbors_half_available.erase(confgraph.adj_table_half_available[node][neighbor]);
|
||||||
|
confgraph.adj_table_half_available[node].erase(neighbor);
|
||||||
|
neighbor->neighbors.push_back(node);
|
||||||
|
confgraph.adj_table[neighbor][node] = std::prev(neighbor->neighbors.end());
|
||||||
|
node->neighbors.push_back(neighbor);
|
||||||
|
confgraph.adj_table[node][neighbor] = std::prev(node->neighbors.end());
|
||||||
|
}
|
||||||
|
node->neighbors_half_available.clear();
|
||||||
|
// upgrade not available neighbors to half available neighbors
|
||||||
|
for (auto neighbor : node->neighbors_not_available) {
|
||||||
|
neighbor->neighbors_not_available.erase(confgraph.adj_table_not_available[neighbor][node]);
|
||||||
|
confgraph.adj_table_not_available[neighbor].erase(node);
|
||||||
|
// node->neighbors_not_available.erase(confgraph.adj_table_not_available[node][neighbor]);
|
||||||
|
confgraph.adj_table_not_available[node].erase(neighbor);
|
||||||
|
neighbor->neighbors_half_available.push_back(node);
|
||||||
|
confgraph.adj_table_half_available[neighbor][node] = std::prev(neighbor->neighbors_half_available.end());
|
||||||
|
node->neighbors_half_available.push_back(neighbor);
|
||||||
|
confgraph.adj_table_half_available[node][neighbor] = std::prev(node->neighbors_half_available.end());
|
||||||
|
}
|
||||||
|
node->neighbors_not_available.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MergeNodeInto(ConfGraphNode *node, ConfGraphNode *target, ConfGraph &confgraph) {
|
void MergeNodeInto(ConfGraphNode *node, ConfGraphNode *target, ConfGraph &confgraph) {
|
||||||
@ -177,16 +206,16 @@ void MergeNodeInto(ConfGraphNode *node, ConfGraphNode *target, ConfGraph &confgr
|
|||||||
// It is also responsible for maintaining all the changes caused by the merge of the node
|
// It is also responsible for maintaining all the changes caused by the merge of the node
|
||||||
if (node->is_temporarily_removed)
|
if (node->is_temporarily_removed)
|
||||||
throw std::runtime_error("something strange happened: a temporarily removed node is merged");
|
throw std::runtime_error("something strange happened: a temporarily removed node is merged");
|
||||||
std::cerr << "node ids:";
|
// std::cerr << "node ids:";
|
||||||
for (auto id : node->var_ids) {
|
// for (auto id : node->var_ids) {
|
||||||
std::cerr << id << " ";
|
// std::cerr << id << " ";
|
||||||
}
|
// }
|
||||||
std::cerr << std::endl;
|
// std::cerr << std::endl;
|
||||||
std::cerr << "target ids:";
|
// std::cerr << "target ids:";
|
||||||
for (auto id : target->var_ids) {
|
// for (auto id : target->var_ids) {
|
||||||
std::cerr << id << " ";
|
// std::cerr << id << " ";
|
||||||
}
|
// }
|
||||||
std::cerr << std::endl;
|
// std::cerr << std::endl;
|
||||||
confgraph.low_degree_and_move_related.erase(node);
|
confgraph.low_degree_and_move_related.erase(node);
|
||||||
confgraph.low_degree_and_not_move_related.erase(node);
|
confgraph.low_degree_and_not_move_related.erase(node);
|
||||||
confgraph.high_degree_nodes.erase(node);
|
confgraph.high_degree_nodes.erase(node);
|
||||||
@ -264,6 +293,9 @@ void Coalesce(std::shared_ptr<FunctionDefItem> src, CFGType &cfg, ConfGraph &con
|
|||||||
if (src_node == dest_node) {
|
if (src_node == dest_node) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (src_node->is_temporarily_removed || dest_node->is_temporarily_removed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (confgraph.adj_table[src_node].find(dest_node) != confgraph.adj_table[src_node].end()) {
|
if (confgraph.adj_table[src_node].find(dest_node) != confgraph.adj_table[src_node].end()) {
|
||||||
// no need to update low_degree_and_move_related, when confgraph.pending_moves.size()==0, nodes in
|
// no need to update low_degree_and_move_related, when confgraph.pending_moves.size()==0, nodes in
|
||||||
// low_degree_and_move_related will automatically be moved to low_degree_and_not_move_related
|
// low_degree_and_move_related will automatically be moved to low_degree_and_not_move_related
|
||||||
@ -328,12 +360,12 @@ bool ConductColoring(std::shared_ptr<FunctionDefItem> src, CFGType &cfg, ConfGra
|
|||||||
if (cfg.id_to_var.size() != cfg.var_to_id.size()) {
|
if (cfg.id_to_var.size() != cfg.var_to_id.size()) {
|
||||||
throw std::runtime_error("something strange happened: id_to_var and var_to_id do not match");
|
throw std::runtime_error("something strange happened: id_to_var and var_to_id do not match");
|
||||||
}
|
}
|
||||||
for (size_t i = 0; i < cfg.id_to_var.size(); i++) {
|
// for (size_t i = 0; i < cfg.id_to_var.size(); i++) {
|
||||||
std::cerr << "id=" << i << " var=" << cfg.id_to_var[i] << std::endl;
|
// std::cerr << "id=" << i << " var=" << cfg.id_to_var[i] << std::endl;
|
||||||
if (i != cfg.var_to_id[cfg.id_to_var[i]]) {
|
// if (i != cfg.var_to_id[cfg.id_to_var[i]]) {
|
||||||
throw std::runtime_error("something strange happened: id_to_var and var_to_id do not match");
|
// throw std::runtime_error("something strange happened: id_to_var and var_to_id do not match");
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
if (cfg.id_to_var.size() != confgraph.nodes.size()) {
|
if (cfg.id_to_var.size() != confgraph.nodes.size()) {
|
||||||
throw std::runtime_error("something strange happened: id_to_var and confgraph.nodes do not match");
|
throw std::runtime_error("something strange happened: id_to_var and confgraph.nodes do not match");
|
||||||
}
|
}
|
||||||
@ -376,19 +408,93 @@ bool ConductColoring(std::shared_ptr<FunctionDefItem> src, CFGType &cfg, ConfGra
|
|||||||
} else if (confgraph.pending_moves.size() > 0) {
|
} else if (confgraph.pending_moves.size() > 0) {
|
||||||
Coalesce(src, cfg, confgraph);
|
Coalesce(src, cfg, confgraph);
|
||||||
} else if (confgraph.low_degree_and_move_related.size() > 0) {
|
} else if (confgraph.low_degree_and_move_related.size() > 0) {
|
||||||
Freeze(src, cfg, confgraph);
|
bool new_pending_move_available = false;
|
||||||
|
if (confgraph.potential_moves.size() > 0) {
|
||||||
|
std::vector<opt::MoveInstruct *> removed;
|
||||||
|
for (auto move : confgraph.potential_moves) {
|
||||||
|
auto src_node = confgraph.id_to_node[cfg.var_to_id[move->src_full]];
|
||||||
|
auto dest_node = confgraph.id_to_node[cfg.var_to_id[move->dest_full]];
|
||||||
|
src_node = ConfGraphNode::FindFather(src_node);
|
||||||
|
dest_node = ConfGraphNode::FindFather(dest_node);
|
||||||
|
if (src_node == dest_node) {
|
||||||
|
removed.push_back(move);
|
||||||
|
} else if (src_node->is_temporarily_removed || dest_node->is_temporarily_removed) {
|
||||||
|
removed.push_back(move);
|
||||||
|
} else if (confgraph.adj_table[src_node].find(dest_node) != confgraph.adj_table[src_node].end()) {
|
||||||
|
removed.push_back(move);
|
||||||
|
} else {
|
||||||
|
if (src_node->degree < kMaxRegs && dest_node->degree < kMaxRegs) {
|
||||||
|
removed.push_back(move);
|
||||||
|
confgraph.pending_moves.insert(move);
|
||||||
|
new_pending_move_available = true;
|
||||||
|
} else if (src_node->is_binded_with_physical_reg && dest_node->is_binded_with_physical_reg) {
|
||||||
|
removed.push_back(move);
|
||||||
|
confgraph.pending_moves.insert(move);
|
||||||
|
new_pending_move_available = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// std::cerr << "removed size=" << removed.size() << std::endl;
|
||||||
|
for (auto move : removed) {
|
||||||
|
confgraph.potential_moves.erase(move);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!new_pending_move_available) {
|
||||||
|
Freeze(src, cfg, confgraph);
|
||||||
|
}
|
||||||
} else if (confgraph.high_degree_nodes.size() > 0) {
|
} else if (confgraph.high_degree_nodes.size() > 0) {
|
||||||
PotentailSpill(src, cfg, confgraph);
|
PotentailSpill(src, cfg, confgraph);
|
||||||
}
|
}
|
||||||
} while (confgraph.low_degree_and_not_move_related.size() > 0 || confgraph.pending_moves.size() > 0 ||
|
} while (confgraph.low_degree_and_not_move_related.size() > 0 || confgraph.pending_moves.size() > 0 ||
|
||||||
confgraph.low_degree_and_move_related.size() > 0 || confgraph.high_degree_nodes.size() > 0);
|
confgraph.low_degree_and_move_related.size() > 0 || confgraph.high_degree_nodes.size() > 0);
|
||||||
// select and spill
|
// select and spill
|
||||||
return false;
|
size_t living_nodes = confgraph.nodes.size();
|
||||||
if (confgraph.actual_spills.size() > 0) {
|
for (auto node : confgraph.nodes) {
|
||||||
std::cerr << "spilled " << confgraph.actual_spills.size() << " nodes" << std::endl;
|
if (node->is_merged_into != node.get()) {
|
||||||
// allocate memory for spilled nodes
|
living_nodes--;
|
||||||
// rewrite the spilled nodes
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
living_nodes -= allocating_regs.size();
|
||||||
|
if (living_nodes != confgraph.stack.size()) {
|
||||||
|
throw std::runtime_error("something strange happened: living_nodes!=confgraph.stack.size()");
|
||||||
|
}
|
||||||
|
std::vector<size_t> all_colors;
|
||||||
|
for (auto reg : allocating_regs) {
|
||||||
|
all_colors.push_back(std::stoi(reg.substr(1)));
|
||||||
|
}
|
||||||
|
while (confgraph.stack.size() > 0) {
|
||||||
|
auto node = confgraph.stack.back();
|
||||||
|
confgraph.stack.pop_back();
|
||||||
|
std::unordered_set<size_t> available_colors;
|
||||||
|
for (auto color : all_colors) {
|
||||||
|
available_colors.insert(color);
|
||||||
|
}
|
||||||
|
for (auto neighbor : node->neighbors_half_available) {
|
||||||
|
if (!neighbor->is_binded_with_physical_reg) {
|
||||||
|
throw std::runtime_error("something strange happened: neighbor is not binded with physical reg");
|
||||||
|
}
|
||||||
|
available_colors.erase(neighbor->color);
|
||||||
|
}
|
||||||
|
if (available_colors.size() > 0) {
|
||||||
|
node->color = *(available_colors.begin());
|
||||||
|
JoinNode(node, confgraph);
|
||||||
|
node->is_binded_with_physical_reg = true;
|
||||||
|
} else {
|
||||||
|
confgraph.actual_spills.push_back(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::cerr << "totally allocating " << confgraph.nodes.size() - allocating_regs.size() << " nodes" << std::endl;
|
||||||
|
std::cerr << living_nodes << std::endl;
|
||||||
|
std::cerr << "spilled " << confgraph.actual_spills.size() << " nodes" << std::endl;
|
||||||
|
// allocate memory for spilled nodes
|
||||||
|
// rewrite the spilled nodes
|
||||||
|
return false; // as our compiler always hold 4 extra registers in hand, the spilled nodes can be easily handled, so
|
||||||
|
// no need to run many iterations
|
||||||
|
// if (confgraph.actual_spills.size() > 0) {
|
||||||
|
// std::cerr << "spilled " << confgraph.actual_spills.size() << " nodes" << std::endl;
|
||||||
|
// // allocate memory for spilled nodes
|
||||||
|
// // rewrite the spilled nodes
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
// return false;
|
||||||
}
|
}
|
@ -136,13 +136,176 @@ void EnforcePhysicalRegs(CFGType &cfg) {
|
|||||||
entry_node->corresponding_block->actions.push_front(new_def);
|
entry_node->corresponding_block->actions.push_front(new_def);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
void TranslateColorResult(std::shared_ptr<FunctionDefItem> func, CFGType &cfg, ConfGraph &confgraph) {
|
||||||
|
using namespace opt;
|
||||||
|
std::unordered_map<std::string, size_t> spilled_var_to_id;
|
||||||
|
auto &var_to_id = cfg.var_to_id;
|
||||||
|
auto ApplyColoringResult = [&](std::string &var) {
|
||||||
|
auto confnode = confgraph.id_to_node[var_to_id[var]];
|
||||||
|
confnode = ConfGraphNode::FindFather(confnode);
|
||||||
|
if (!confnode->is_binded_with_physical_reg) {
|
||||||
|
if (spilled_var_to_id.find(var) != spilled_var_to_id.end()) {
|
||||||
|
var = "#" + std::to_string(spilled_var_to_id[var]);
|
||||||
|
} else {
|
||||||
|
spilled_var_to_id[var] = func->spilled_vars++;
|
||||||
|
var = "#" + std::to_string(spilled_var_to_id[var]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var = "$reg." + std::to_string(confnode->color);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
for (auto node : cfg.nodes) {
|
||||||
|
auto block = node->corresponding_block;
|
||||||
|
std::vector<size_t> cur_node_use;
|
||||||
|
std::vector<size_t> cur_node_def;
|
||||||
|
bool use_def_init = false;
|
||||||
|
func->spilled_vars = 0;
|
||||||
|
for (auto act : block->actions) {
|
||||||
|
if (auto br_act = std::dynamic_pointer_cast<BRAction>(act)) {
|
||||||
|
if (var_to_id.find(br_act->cond) != var_to_id.end()) {
|
||||||
|
ApplyColoringResult(br_act->cond);
|
||||||
|
}
|
||||||
|
} else if (auto ret_act = std::dynamic_pointer_cast<RETAction>(act)) {
|
||||||
|
if (!std::holds_alternative<LLVMVOIDType>(ret_act->type) && var_to_id.find(ret_act->value) != var_to_id.end()) {
|
||||||
|
ApplyColoringResult(ret_act->value);
|
||||||
|
}
|
||||||
|
} else if (auto bin_act = std::dynamic_pointer_cast<BinaryOperationAction>(act)) {
|
||||||
|
if (var_to_id.find(bin_act->operand1_full) != var_to_id.end()) {
|
||||||
|
ApplyColoringResult(bin_act->operand1_full);
|
||||||
|
}
|
||||||
|
if (var_to_id.find(bin_act->operand2_full) != var_to_id.end()) {
|
||||||
|
ApplyColoringResult(bin_act->operand2_full);
|
||||||
|
}
|
||||||
|
if (var_to_id.find(bin_act->result_full) != var_to_id.end()) {
|
||||||
|
ApplyColoringResult(bin_act->result_full);
|
||||||
|
}
|
||||||
|
} else if (auto load_act = std::dynamic_pointer_cast<LoadAction>(act)) {
|
||||||
|
if (var_to_id.find(load_act->ptr_full) != var_to_id.end()) {
|
||||||
|
ApplyColoringResult(load_act->ptr_full);
|
||||||
|
}
|
||||||
|
if (var_to_id.find(load_act->result_full) != var_to_id.end()) {
|
||||||
|
ApplyColoringResult(load_act->result_full);
|
||||||
|
}
|
||||||
|
} else if (auto store_act = std::dynamic_pointer_cast<StoreAction>(act)) {
|
||||||
|
if (var_to_id.find(store_act->value_full) != var_to_id.end()) {
|
||||||
|
ApplyColoringResult(store_act->value_full);
|
||||||
|
}
|
||||||
|
if (var_to_id.find(store_act->ptr_full) != var_to_id.end()) {
|
||||||
|
ApplyColoringResult(store_act->ptr_full);
|
||||||
|
}
|
||||||
|
} else if (auto get_act = std::dynamic_pointer_cast<GetElementPtrAction>(act)) {
|
||||||
|
std::unordered_set<std::string> used_vars;
|
||||||
|
if (var_to_id.find(get_act->ptr_full) != var_to_id.end()) {
|
||||||
|
ApplyColoringResult(get_act->ptr_full);
|
||||||
|
}
|
||||||
|
for (auto &idx : get_act->indices) {
|
||||||
|
if (var_to_id.find(idx) != var_to_id.end()) {
|
||||||
|
ApplyColoringResult(idx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (var_to_id.find(get_act->result_full) != var_to_id.end()) {
|
||||||
|
ApplyColoringResult(get_act->result_full);
|
||||||
|
}
|
||||||
|
} else if (auto icmp_act = std::dynamic_pointer_cast<ICMPAction>(act)) {
|
||||||
|
if (var_to_id.find(icmp_act->operand1_full) != var_to_id.end()) {
|
||||||
|
ApplyColoringResult(icmp_act->operand1_full);
|
||||||
|
}
|
||||||
|
if (var_to_id.find(icmp_act->operand2_full) != var_to_id.end()) {
|
||||||
|
ApplyColoringResult(icmp_act->operand2_full);
|
||||||
|
}
|
||||||
|
if (var_to_id.find(icmp_act->result_full) != var_to_id.end()) {
|
||||||
|
ApplyColoringResult(icmp_act->result_full);
|
||||||
|
}
|
||||||
|
} else if (auto call_act = std::dynamic_pointer_cast<CallItem>(act)) {
|
||||||
|
for (auto &arg : call_act->args_val_full) {
|
||||||
|
if (var_to_id.find(arg) != var_to_id.end()) {
|
||||||
|
ApplyColoringResult(arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!std::holds_alternative<LLVMVOIDType>(call_act->return_type) &&
|
||||||
|
var_to_id.find(call_act->result_full) != var_to_id.end()) {
|
||||||
|
ApplyColoringResult(call_act->result_full);
|
||||||
|
}
|
||||||
|
} else if (auto select_act = std::dynamic_pointer_cast<SelectItem>(act)) {
|
||||||
|
if (var_to_id.find(select_act->cond_full) != var_to_id.end()) {
|
||||||
|
ApplyColoringResult(select_act->cond_full);
|
||||||
|
}
|
||||||
|
if (var_to_id.find(select_act->true_val_full) != var_to_id.end()) {
|
||||||
|
ApplyColoringResult(select_act->true_val_full);
|
||||||
|
}
|
||||||
|
if (var_to_id.find(select_act->false_val_full) != var_to_id.end()) {
|
||||||
|
ApplyColoringResult(select_act->false_val_full);
|
||||||
|
}
|
||||||
|
if (var_to_id.find(select_act->result_full) != var_to_id.end()) {
|
||||||
|
ApplyColoringResult(select_act->result_full);
|
||||||
|
}
|
||||||
|
} else if (auto move_act = std::dynamic_pointer_cast<MoveInstruct>(act)) {
|
||||||
|
if (VRegCheck(move_act->src_full) && var_to_id.find(move_act->src_full) != var_to_id.end()) {
|
||||||
|
ApplyColoringResult(move_act->src_full);
|
||||||
|
}
|
||||||
|
if (var_to_id.find(move_act->dest_full) != var_to_id.end()) {
|
||||||
|
ApplyColoringResult(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()) {
|
||||||
|
ApplyColoringResult(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()) {
|
||||||
|
ApplyColoringResult(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()) {
|
||||||
|
ApplyColoringResult(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()) {
|
||||||
|
ApplyColoringResult(store_spilled_args_act->var_full);
|
||||||
|
}
|
||||||
|
} else if (auto alloca_act = std::dynamic_pointer_cast<AllocaAction>(act)) {
|
||||||
|
ApplyColoringResult(alloca_act->name_full);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto act = block->exit_action;
|
||||||
|
if (auto br_act = std::dynamic_pointer_cast<BRAction>(act)) {
|
||||||
|
if (var_to_id.find(br_act->cond) != var_to_id.end()) {
|
||||||
|
ApplyColoringResult(br_act->cond);
|
||||||
|
}
|
||||||
|
} else if (auto ret_act = std::dynamic_pointer_cast<RETAction>(act)) {
|
||||||
|
if (!std::holds_alternative<LLVMVOIDType>(ret_act->type) && var_to_id.find(ret_act->value) != var_to_id.end()) {
|
||||||
|
ApplyColoringResult(ret_act->value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (auto act_it = block->actions.begin(); act_it != block->actions.end(); ++act_it) {
|
||||||
|
bool need_remove = false;
|
||||||
|
if (auto move_act = std::dynamic_pointer_cast<MoveInstruct>(*act_it)) {
|
||||||
|
if (move_act->src_full == move_act->dest_full) {
|
||||||
|
need_remove = true;
|
||||||
|
}
|
||||||
|
} else if (auto force_def_act = std::dynamic_pointer_cast<ForceDef>(*act_it)) {
|
||||||
|
need_remove = true;
|
||||||
|
} else if (auto force_use_act = std::dynamic_pointer_cast<ForceUse>(*act_it)) {
|
||||||
|
need_remove = true;
|
||||||
|
}
|
||||||
|
if (need_remove) {
|
||||||
|
auto it_next = act_it;
|
||||||
|
++it_next;
|
||||||
|
block->actions.erase(act_it);
|
||||||
|
act_it = it_next;
|
||||||
|
--act_it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
void ConductRegAllocForFunction(std::shared_ptr<FunctionDefItem> func) {
|
void ConductRegAllocForFunction(std::shared_ptr<FunctionDefItem> func) {
|
||||||
std::cerr << "processing function " << func->func_name_raw << std::endl;
|
std::cerr << "processing function " << func->func_name_raw << std::endl;
|
||||||
CFGType cfg;
|
CFGType cfg;
|
||||||
ConfGraph confgraph;
|
ConfGraph confgraph;
|
||||||
cfg = BuildCFGForFunction(func);
|
cfg = BuildCFGForFunction(func);
|
||||||
EnforcePhysicalRegs(cfg);
|
EnforcePhysicalRegs(cfg);
|
||||||
func->RecursivePrint(std::cerr);
|
// func->RecursivePrint(std::cerr);
|
||||||
do {
|
do {
|
||||||
cfg.init();
|
cfg.init();
|
||||||
cfg = BuildCFGForFunction(func);
|
cfg = BuildCFGForFunction(func);
|
||||||
@ -150,6 +313,8 @@ void ConductRegAllocForFunction(std::shared_ptr<FunctionDefItem> func) {
|
|||||||
confgraph.init();
|
confgraph.init();
|
||||||
confgraph = BuildConfGraph(cfg);
|
confgraph = BuildConfGraph(cfg);
|
||||||
} while (ConductColoring(func, cfg, confgraph));
|
} while (ConductColoring(func, cfg, confgraph));
|
||||||
|
TranslateColorResult(func, cfg, confgraph);
|
||||||
|
func->RecursivePrint(std::cerr);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<ModuleItem> RegAlloc(std::shared_ptr<ModuleItem> src) {
|
std::shared_ptr<ModuleItem> RegAlloc(std::shared_ptr<ModuleItem> src) {
|
||||||
|
Reference in New Issue
Block a user