diff --git a/src/ir/ir.hpp b/src/ir/ir.hpp index 3eb2fd739d279d490bb9c27aab8469eac0843c06..edbb76c1bb1bf010a42a89cfc81fac44af5741da 100755 --- a/src/ir/ir.hpp +++ b/src/ir/ir.hpp @@ -259,6 +259,7 @@ public: bool check_is_entry() {return is_entry;} void del_ins(ptr<ir::ir_instr> ins); void del_ins_by_vec(ptr_list<ir::ir_instr> del_ins); + void replace_ins_lst(std::list<ptr<ir::ir_instr>> new_instructions) {this->instructions = new_instructions;} void mark_ret() {is_return_bb = true;} bool is_ret() {return is_return_bb;} void mark_fun(ptr<ir::ir_userfunc> fun) {cur_func = fun;} @@ -408,6 +409,7 @@ public: ptr_list<ir::alloc> get_var_list() {return alloc_list;} ptr<ir::ir_basicblock> get_entry() {return entry;} void del_alloc(ptr_list<ir::alloc> del_items); + void replace_alloc(ptr_list<ir::alloc> new_vec) {this->alloc_list = new_vec;} std::vector<ptr<ir::ir_memobj>> get_params() {return func_args;} // std::set<ptr<ir::ir_userfunc>> get_caller() {return caller;} void mark_fun(ptr<ir::ir_userfunc> fun) {cur_fun_ptr = fun;} diff --git a/src/parser/SyntaxAnalyse.cpp b/src/parser/SyntaxAnalyse.cpp index e4361c742d3d553ef83ed4b70c99d451a2043fa2..8ebf9d2fd35b4e5ac1dfbc35b38eb6d79b9d8f02 100755 --- a/src/parser/SyntaxAnalyse.cpp +++ b/src/parser/SyntaxAnalyse.cpp @@ -108,13 +108,16 @@ void SynataxAnalyseBlock(ast::block_syntax *&self, ast::block_syntax *block_item void SynataxAnalyseBlockItems(ast::block_syntax *&self, ast::block_syntax *block_items, ast::stmt_syntax *stmt) { if(block_items && stmt){ - self = new ast::block_syntax; - self->line = line_number + 1; - for(auto i : block_items->body){ - self->body.push_back(i); - } - self->body.emplace_back(stmt); - delete block_items; + // self = new ast::block_syntax; + // self->line = line_number + 1; + // for(auto i : block_items->body){ + // self->body.push_back(i); + // } + // self->body.emplace_back(stmt); + // delete block_items; + block_items->line = line_number + 1; + block_items->body.emplace_back(stmt); + self = block_items; }else if(!stmt && !block_items){ self = nullptr; }else { diff --git a/src/passes/mem2reg.cpp b/src/passes/mem2reg.cpp index 6f75abccdb26544e2c59534234dfdf281491e646..4d56bda6b06184b54d486dec9f4250e5a6084086 100644 --- a/src/passes/mem2reg.cpp +++ b/src/passes/mem2reg.cpp @@ -26,6 +26,7 @@ void Passes::Mem2Reg::run() { void Passes::Mem2Reg::rename(ptr<ir::ir_userfunc> fun, ptr<ir::ir_basicblock> block, std::unordered_map<ptr<ir::ir_memobj>, ptr_list<ir::ir_value>> &stack, std::unordered_map<ptr<ir::ir_reg>, ptr<ir::ir_memobj>> phi_r_m, std::unordered_map<ptr<ir::ir_reg>, ptr<ir::ir_memobj>> reg_mem, std::unordered_map<ptr<ir::ir_value>, ptr<ir::ir_value>> replace_map, std::unordered_map<ptr<ir::ir_basicblock>, bool> &visited) { std::unordered_map<ptr<ir::ir_memobj>, int> pop_cnt; ptr_list<ir::ir_instr> del_ins; + std::list<ptr<ir::ir_instr>> reserved_ins; visited[block] = true; for(auto ins : block->get_instructions()) { auto is_phi = std::dynamic_pointer_cast<ir::phi>(ins); @@ -37,6 +38,7 @@ void Passes::Mem2Reg::rename(ptr<ir::ir_userfunc> fun, ptr<ir::ir_basicblock> bl stack[it->second].push_back(it->first); pop_cnt[it->second]++; } + reserved_ins.push_back(ins); // ins->replace_reg(replace_map); } else if(is_store) { @@ -47,6 +49,9 @@ void Passes::Mem2Reg::rename(ptr<ir::ir_userfunc> fun, ptr<ir::ir_basicblock> bl pop_cnt[it->second]++; del_ins.push_back(ins); } + else{ + reserved_ins.push_back(ins); + } } else if(is_load) { auto it = reg_mem.find(is_load->get_addr()); @@ -55,9 +60,13 @@ void Passes::Mem2Reg::rename(ptr<ir::ir_userfunc> fun, ptr<ir::ir_basicblock> bl replace_map[is_load->get_dst()] = stack[it->second].back(); del_ins.push_back(ins); } + else { + reserved_ins.push_back(ins); + } } else { ins->replace_reg(replace_map); + reserved_ins.push_back(ins); } } for(auto successor : fun->check_nxt(block)) { @@ -95,12 +104,18 @@ void Passes::Mem2Reg::rename(ptr<ir::ir_userfunc> fun, ptr<ir::ir_basicblock> bl stack[mem].pop_back(); } } - block->del_ins_by_vec(del_ins); + if(del_ins.size() > reserved_ins.size()) { + block->replace_ins_lst(reserved_ins); + } + else { + block->del_ins_by_vec(del_ins); + } } void Passes::Mem2Reg::rename_variables(ptr<ir::ir_userfunc> fun, std::unordered_map<ptr<ir::ir_reg>, ptr<ir::ir_memobj>> phi_r_m) { auto alloc = fun->get_var_list(); ptr_list<ir::alloc> del_items; + ptr_list<ir::alloc> reserved_items; std::unordered_map<ptr<ir::ir_memobj>, ptr_list<ir::ir_value>> stack; std::unordered_map<ptr<ir::ir_reg>, ptr<ir::ir_memobj>> reg_mem; auto dom_tree = dominator_tree[fun]; @@ -110,11 +125,19 @@ void Passes::Mem2Reg::rename_variables(ptr<ir::ir_userfunc> fun, std::unordered_ reg_mem[def->get_var()->get_addr()] = def->get_var(); del_items.push_back(def); } + else { + reserved_items.push_back(def); + } } std::unordered_map<ptr<ir::ir_value>, ptr<ir::ir_value>> replace_map; std::unordered_map<ptr<ir::ir_basicblock>, bool> visited; rename(fun, fun->get_entry(), stack, phi_r_m, reg_mem, replace_map, visited); - fun->del_alloc(del_items); + if(del_items.size() > reserved_items.size()) { + fun->replace_alloc(reserved_items); + } + else { + fun->del_alloc(del_items); + } } std::unordered_map<ptr<ir::ir_reg>, ptr<ir::ir_memobj>> Passes::Mem2Reg::insert_phi_ins(ptr<ir::ir_userfunc> fun) { @@ -322,6 +345,12 @@ void Passes::Mem2Reg::calc_postorder(ptr<ir::ir_basicblock> node, ptr<ir::ir_use void Passes::Mem2Reg::analyse_cfg_flow_and_defs(ptr<ir::ir_userfunc> fun) { auto blocks = fun->get_bbs(); + std::unordered_map<ptr<ir::ir_reg>, ptr<ir::ir_memobj>> addr_map; + for(auto alloc : fun->get_var_list()) { + auto obj = alloc->get_var(); + assert(addr_map.find(obj->get_addr()) == addr_map.end()); + addr_map.insert({obj->get_addr(), obj}); + } std::unordered_map<ptr<ir::ir_basicblock>, ptr_list<ir::ir_basicblock>> predecessor; // std::unordered_map<ptr<ir::ir_basicblock>, ptr_list<ir::ir_basicblock>> s_back_trace; // 回边 std::unordered_map<ptr<ir::ir_basicblock>, ptr_list<ir::ir_basicblock>> nxt; // cfgä¸çš„é€†æ˜ å°„ @@ -364,11 +393,15 @@ void Passes::Mem2Reg::analyse_cfg_flow_and_defs(ptr<ir::ir_userfunc> fun) { } if(store_ins) { auto addr = store_ins->get_addr(); - for(auto alloc : fun->get_var_list()) { - if(alloc->get_var()->get_addr() == addr) { - defs[alloc->get_var()].push_back(block); - break; - } + // for(auto alloc : fun->get_var_list()) { + // if(alloc->get_var()->get_addr() == addr) { + // defs[alloc->get_var()].push_back(block); + // break; + // } + // } + auto it = addr_map.find(addr); + if(it != addr_map.end()) { + defs[it->second].push_back(block); } } } diff --git a/src/riscv/coloring_allocator.cpp b/src/riscv/coloring_allocator.cpp index 789b6824aecb7a4285eab33907ecf2e927f2fa00..bb211283bee5bb705029afa94e4b1c1bfb09a06d 100644 --- a/src/riscv/coloring_allocator.cpp +++ b/src/riscv/coloring_allocator.cpp @@ -10,6 +10,7 @@ #include <memory> // #include <queue> #include <unordered_map> +#include <unordered_set> #include <vector> LoongArch::ColoringAllocator::ColoringAllocator(ptr<ir::ir_userfunc> fun, int base_reg, ptr_list<ir::global_def> global_var) : fun(fun) { @@ -679,17 +680,31 @@ void LoongArch::ColoringAllocator::build_ig() { ig[v].insert(u); } } - for(auto i_it = use_reg.begin(); i_it != use_reg.end(); i_it++) { - auto u = *i_it; - if(is_target(u) && !u->check_global() && !u->check_local()) { - for(auto j_it = std::next(i_it); j_it != use_reg.end(); j_it++) { - auto v = *j_it; - if(is_target(v) && !v->check_global() && !v->check_local()) { - ig[u].insert(v); - ig[v].insert(u); - } - } - } + + // for(auto i_it = use_reg.begin(); i_it != use_reg.end(); i_it++) { + // auto u = *i_it; + // if(is_target(u) && !u->check_global() && !u->check_local()) { + // for(auto j_it = std::next(i_it); j_it != use_reg.end(); j_it++) { + // auto v = *j_it; + // if(is_target(v) && !v->check_global() && !v->check_local()) { + // ig[u].insert(v); + // ig[v].insert(u); + // } + // } + // } + // } + } + std::unordered_set<ptr<ir::ir_reg>> conf_set; + auto use_reg = ins->use_reg(); + for(auto u : use_reg) { + if(is_target(u) && !u->check_global() && !u->check_local()) { + conf_set.insert(u); + } + } + for(auto u : use_reg) { + if(is_target(u) && !u->check_global() && !u->check_local()) { + ig[u].insert(conf_set.begin(), conf_set.end()); + ig[u].erase(u); } } }