diff --git a/include/llir_value.h b/include/llir_value.h index d3e1fc1..9765e53 100644 --- a/include/llir_value.h +++ b/include/llir_value.h @@ -10,6 +10,7 @@ #include #include #include +#include namespace antlrSysY { @@ -161,10 +162,10 @@ public: std::list successors; std::list predecessors; - BasicBlockPtr_t idomer; // dominating node - std::list idom_list; // immediate dominated nodes - std::list dom_list; // dominated nodes - std::list dom_frontier; + BasicBlockPtr_t IDOM; // dominating node + std::unordered_set idom_set; // immediate dominated nodes + std::unordered_set DOM_set; // dominated nodes + std::unordered_set DF_set; int dom_level; int _dom_helper_index; int dom_dfs_in; diff --git a/src/algo_dominance.cpp b/src/algo_dominance.cpp index 85d3be1..9076861 100644 --- a/src/algo_dominance.cpp +++ b/src/algo_dominance.cpp @@ -17,7 +17,7 @@ static void _bitwise_set(std::vector &op1, int l, int r, bool val) { static void _gen_dom_level(BasicBlockPtr_t bb, int level) { bb->dom_level = level; - for (auto succ : bb->idom_list) { + for (auto succ : bb->idom_set) { _gen_dom_level(succ, level + 1); } } @@ -30,13 +30,13 @@ void gen_dominance(FunctionPtr_t func) { const int N = func->bb_list.size(); auto itr = func->bb_list.begin(); for (auto basicblock : func->bb_list) { - basicblock->idom_list.clear(); - basicblock->dom_list.clear(); + basicblock->idom_set.clear(); + basicblock->DOM_set.clear(); basicblock->_dom_helper_index = bb_list.size(); bb_list.push_back(basicblock); } std::vector> dom(N); - dom[0].resize(N); + dom[0].resize(N, 0); dom[0][0] = 1; // Dom(0) = {0} // Dom(i) <- N (= {0, 1, 2,...}) for (int i = 1; i < N; ++i) { @@ -49,7 +49,7 @@ void gen_dominance(FunctionPtr_t func) { int i = 0; for (int i = 1; i < N; ++i) { auto cur_bb = bb_list[i]; - std::vector temp(true, N); + std::vector temp(N, 1); // temp = {i} union (intersect Dom(j)), j in pred(i) for (auto pred : cur_bb->predecessors) { _bitwise_and(temp, dom[pred->_dom_helper_index]); @@ -66,26 +66,26 @@ void gen_dominance(FunctionPtr_t func) { for (int i = 0; i < N; ++i) { for (int j = 0; j < N; ++j) { if (dom[i][j]) { - bb_list[i]->dom_list.push_back(bb_list[j]); + bb_list[i]->DOM_set.insert(bb_list[j]); } } } // get domees and immediate domer for (int i = 0; i < N; ++i) { - for (auto domer1 : bb_list[i]->dom_list) { + for (auto domer1 : bb_list[i]->DOM_set) { if (domer1 == bb_list[i]) continue; bool flag = true; // if dom(i)[j] dom dom(i)[k], it cannot be the immediate domer of i - for (auto domer2 : bb_list[i]->dom_list) { + for (auto domer2 : bb_list[i]->DOM_set) { if (domer2 == bb_list[i] || domer2 == domer1) continue; - if (std::find(domer2->dom_list.begin(), domer2->dom_list.end(), domer1) != domer2->dom_list.end()) { + if (std::find(domer2->DOM_set.begin(), domer2->DOM_set.end(), domer1) != domer2->DOM_set.end()) { flag = false; break; } } if (flag) { - bb_list[i]->idomer = domer1; - domer1->idom_list.push_back(bb_list[i]); + bb_list[i]->IDOM = domer1; + domer1->idom_set.insert(bb_list[i]); break; } } @@ -109,15 +109,15 @@ void gen_dominance_frontier(FunctionPtr_t func) { runner <- IDOM(runner) */ for (auto bb : func->bb_list) { - bb->dom_frontier.clear(); + bb->DF_set.clear(); } for (auto n : func->bb_list) { if (n->predecessors.size() >= 2) { for (auto pred : n->predecessors) { auto runner = pred; - while (runner != n->idomer) { - runner->dom_frontier.push_back(n); - runner = runner->idomer; + while (runner != n->IDOM) { + runner->DF_set.insert(n); + runner = runner->IDOM; } } } @@ -128,7 +128,7 @@ void update_dfs_numbers(BasicBlockPtr_t bb, bool rst) { static int dfs_num; if (rst) dfs_num = 0; bb->dom_dfs_in = dfs_num++; - for (auto child : bb->dom_list) { + for (auto child : bb->DOM_set) { update_dfs_numbers(child, false); } bb->dom_dfs_out = dfs_num++; diff --git a/src/main.cpp b/src/main.cpp index 09e9ac7..75b5361 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -94,7 +94,7 @@ int main(int argc, const char **argv) { std::vector> passes = { std::make_shared(), - // std::make_shared(), + std::make_shared(), }; for (auto pass : passes) { diff --git a/src/pass_build_cfg.cpp b/src/pass_build_cfg.cpp index ce46116..6ff3c86 100644 --- a/src/pass_build_cfg.cpp +++ b/src/pass_build_cfg.cpp @@ -2,9 +2,37 @@ #include "common.h" #include "llir.h" #include "passes.h" +#include namespace antlrSysY { +static void print_cfg_info(BasicBlockPtr_t bb) { + std::cout << "---" << bb->name << "---\n"; + std::cout << " pred: ["; + for (auto pred : bb->predecessors) { + std::cout << pred->name << ", "; + } + std::cout << "]\n"; + std::cout << " succ: ["; + for (auto succ : bb->successors) { + std::cout << succ->name << ", "; + } + std::cout << "]\n"; + std::cout.flush(); +} + +static void print_cfg(BasicBlockPtr_t rt, bool rst = false) { + static std::unordered_set vis; + if (rst) vis.clear(); + print_cfg_info(rt); + for (auto succ : rt->successors) { + if (!vis.count(succ)) { + vis.insert(succ); + print_cfg(succ); + } + } +} + static void connect(BasicBlockPtr_t pred, BasicBlockPtr_t succ) { pred->successors.push_back(succ); succ->predecessors.push_back(pred); @@ -16,7 +44,7 @@ static void _build_cfg(const FunctionPtr_t func) { if (bb->inst_list.size() == 1 && Value::is(bb->inst_list.front())){ auto br = Value::as(bb->inst_list.front()); if (br->operand_list.size() == 1) { - LOG(DEBUG) << "remove dummy jump block:" << bb->name; + VLOG(6) << "remove dummy jump block:" << bb->name; for (auto &use : bb->use_list) { use.user->operand_list[use.op_index] = br->operand_list[0]; br->operand_list[0]->use_list.push_back({br->operand_list[0], use.user, use.op_index}); @@ -55,6 +83,8 @@ static void _build_cfg(const FunctionPtr_t func) { else ++ itr; } + + print_cfg(func->bb_list.front(), true); } void PassBuildCFG::run(const Module &module) { diff --git a/src/pass_mem2reg.cpp b/src/pass_mem2reg.cpp index c22a533..6a649e8 100644 --- a/src/pass_mem2reg.cpp +++ b/src/pass_mem2reg.cpp @@ -123,13 +123,57 @@ struct RenameInfo { std::vector value_list; }; +static void print_dom_info(BasicBlockPtr_t bb) { + std::cout << bb->name << ":\n"; + std::cout << " level: " << bb->dom_level << "\n"; + std::cout << " pred: ["; + for (auto pred : bb->predecessors) { + std::cout << pred->name << ", "; + } + std::cout << "]\n"; + std::cout << " succ: ["; + for (auto succ : bb->successors) { + std::cout << succ->name << ", "; + } + std::cout << "]\n"; + std::cout << " idomer: "; + if (bb->IDOM) std::cout << bb->IDOM->name; + else std::cout << "null"; + std::cout << "\n"; + std::cout << " dom: ["; + for (auto dom : bb->DOM_set) { + std::cout << dom->name << ", "; + } + std::cout << "]\n"; + std::cout << " idom: ["; + for (auto idom : bb->idom_set) { + std::cout << idom->name << ", "; + } + std::cout << "]\n"; + std::cout << " DF: ["; + for (auto df : bb->DF_set) { + std::cout << df->name << ", "; + } + std::cout << "]\n"; + std::cout.flush(); +} + +static void print_dom_tree(BasicBlockPtr_t rt) { + print_dom_info(rt); + for (auto idom : rt->idom_set) { + print_dom_tree(idom); + } +} + // llvm:PromoteMemoryToRegister.cpp // https://roife.github.io/2022/02/07/mem2reg/ // https://github.com/Enna1/LLVM-Study-Notes/blob/master/source/ssa/SSA-Construction.rst static void _mem_2_reg(FunctionPtr_t func) { + VLOG(4) << "Run mem2reg for " << func->name; VLOG(4) << " Gen Dominance Tree & Frontier"; gen_dominance(func); gen_dominance_frontier(func); + print_dom_tree(func->bb_list.front()); // actually, all variable alloca is placed at block head, so we collect them first std::vector alloca_list; std::unordered_map alloca_to_id; @@ -191,7 +235,7 @@ static void _mem_2_reg(FunctionPtr_t func) { while (!worklist.empty()) { auto bb = worklist.front(); worklist.pop(); - for (auto frontier : bb->dom_frontier) { + for (auto frontier : bb->DF_set) { auto frontier_index = bb_to_id.at(frontier); if (!visited[frontier_index]) { visited[frontier_index] = true; diff --git a/src/visitor.cpp b/src/visitor.cpp index 7cc28f2..45d4218 100644 --- a/src/visitor.cpp +++ b/src/visitor.cpp @@ -724,7 +724,7 @@ std::any Visitor::visitLVal(SysyParser::LValContext *ctx) { auto _lval = _scope_tab.get_name(name); sysy_assert(_lval.has_value()); auto lval = _lval.value(); - VLOG(5) << "lVal found: " << lval->to_string(); + VLOG(6) << "lVal found: " << lval->to_string(); // @retval: ConstantInt if (lval->type->type_tag == Type::TypeTag::IntegerType) { return {lval};