diff --git a/include/blocks/dominance.h b/include/blocks/dominance.h index 9dfa598..85cd44e 100644 --- a/include/blocks/dominance.h +++ b/include/blocks/dominance.h @@ -20,6 +20,8 @@ class dominator_analysis { dominator_analysis(basic_block::cfg_block cfg, bool is_postdom = false); basic_block::cfg_block cfg_; bool is_postdom_; + int max_depth; + unsigned int max_depth_bb_id; std::vector &get_postorder_bb_map(); std::vector &get_postorder(); std::vector &get_preorder_bb_map(); @@ -44,10 +46,10 @@ class dominator_analysis { std::vector preorder_bb_map; void reverse_cfg(); void postorder_idom_helper(std::vector &visited, int id); - void postorder_dfs_helper(std::vector &visited_bbs, int id); - void postorder_dfs(); + void postorder_dfs_helper(std::vector &visited_bbs, int id, int depth); + void postorder_dfs(bool reverse_cfg); void preorder_dfs_helper(std::vector &visited_bbs, int id); - void preorder_dfs(); + void preorder_dfs(bool reverse_cfg); int intersect(int bb1_id, int bb2_id); }; diff --git a/src/blocks/dominance.cpp b/src/blocks/dominance.cpp index 234767c..d24630e 100644 --- a/src/blocks/dominance.cpp +++ b/src/blocks/dominance.cpp @@ -8,9 +8,6 @@ void dominator_analysis::reverse_cfg() { assert(0); std::shared_ptr virtual_exit_bb = std::make_shared("virtualexit0"); - virtual_exit_bb->id = cfg_.size(); - cfg_.push_back(virtual_exit_bb); - for (auto bb: cfg_) { if (bb->successor.size() == 0) { bb->successor.push_back(virtual_exit_bb); @@ -18,6 +15,21 @@ void dominator_analysis::reverse_cfg() { } } + // if CFG is an inifite loop, we don't have a exit block + // so we need to find the farthest block from the entry + // of the loop and consider that as one of the exit blocks + if (!virtual_exit_bb->predecessor.size()) { + std::cerr << "infinite loop\n"; + postorder_dfs(false); + + auto bb_virtual_backedge = cfg_[max_depth_bb_id]; + bb_virtual_backedge->successor.push_back(virtual_exit_bb); + virtual_exit_bb->predecessor.push_back(bb_virtual_backedge); + } + + virtual_exit_bb->id = cfg_.size(); + cfg_.push_back(virtual_exit_bb); + for (auto bb: cfg_) { basic_block::cfg_block temp_pred = bb->predecessor; bb->predecessor.clear(); @@ -35,12 +47,17 @@ dominator_analysis::dominator_analysis(basic_block::cfg_block cfg, bool is_postd } // TODO: Add a check for size, it should be greater than 2. + idom.clear(); idom.reserve(cfg_.size()); idom.assign(cfg_.size(), -1); + postorder.clear(); postorder.reserve(cfg_.size()); + postorder_bb_map.clear(); postorder_bb_map.reserve(cfg_.size()); postorder_bb_map.assign(cfg_.size(), -1); + preorder.clear(); preorder.reserve(cfg_.size()); + preorder_bb_map.clear(); preorder_bb_map.reserve(cfg_.size()); preorder_bb_map.assign(cfg_.size(), -1); @@ -58,30 +75,40 @@ void dominator_analysis::postorder_idom_helper(std::vector &visited, int i } } -void dominator_analysis::postorder_dfs_helper(std::vector &visited_bbs, int id) { - for (auto child: cfg_[id]->successor) { - if (!visited_bbs[child->id]) { - visited_bbs[child->id] = true; - postorder_dfs_helper(visited_bbs, child->id); - postorder.push_back(child->id); - } +void dominator_analysis::postorder_dfs_helper(std::vector &visited_bbs, int id, int depth) { + if (depth > max_depth) { + max_depth = depth; + max_depth_bb_id = id; + } + + for (auto child: cfg_[id]->successor) { + if (!visited_bbs[child->id]) { + visited_bbs[child->id] = true; + postorder_dfs_helper(visited_bbs, child->id, depth + 1); + postorder.push_back(child->id); } + } } -void dominator_analysis::postorder_dfs() { +void dominator_analysis::postorder_dfs(bool reverse_cfg) { + int current_depth = 0; + max_depth = current_depth; + std::vector visited_bbs(cfg_.size()); visited_bbs.assign(visited_bbs.size(), false); - if (is_postdom_) + if (reverse_cfg) visited_bbs[cfg_.size() - 1] = true; else visited_bbs[0] = true; - if (is_postdom_) { - postorder_dfs_helper(visited_bbs, cfg_.size() - 1); + if (reverse_cfg) { + max_depth_bb_id = cfg_.size() - 1; + postorder_dfs_helper(visited_bbs, cfg_.size() - 1, current_depth + 1); postorder.push_back(cfg_.size() - 1); } else { - postorder_dfs_helper(visited_bbs, 0); + max_depth_bb_id = 0; + postorder_dfs_helper(visited_bbs, 0, current_depth + 1); postorder.push_back(0); } } @@ -96,15 +123,15 @@ void dominator_analysis::preorder_dfs_helper(std::vector &visited_bbs, int } } -void dominator_analysis::preorder_dfs() { +void dominator_analysis::preorder_dfs(bool reverse_cfg) { std::vector visited_bbs(cfg_.size()); visited_bbs.assign(visited_bbs.size(), false); - if (is_postdom_) + if (reverse_cfg) visited_bbs[cfg_.size() - 1] = true; else visited_bbs[0] = true; - if (is_postdom_) { + if (reverse_cfg) { preorder.push_back(cfg_.size() - 1); preorder_dfs_helper(visited_bbs, cfg_.size() - 1); } @@ -200,8 +227,8 @@ int dominator_analysis::intersect(int bb1_id, int bb2_id) { } void dominator_analysis::analyze() { - preorder_dfs(); - postorder_dfs(); + preorder_dfs(is_postdom_); + postorder_dfs(is_postdom_); for (unsigned int i = 0; i < preorder.size(); i++) { preorder_bb_map[preorder[i]] = i; } diff --git a/src/blocks/loops.cpp b/src/blocks/loops.cpp index aaa7aca..7294ed3 100644 --- a/src/blocks/loops.cpp +++ b/src/blocks/loops.cpp @@ -184,6 +184,9 @@ void loop_info::analyze() { continue; int unique_postdom = post_dta.get_idom(loop->loop_exit_blocks[0]->id); + if (unique_postdom == -1) + continue; + bool unique_postdom_flag = true; for (auto exit_bb: loop->loop_exit_blocks) { if (post_dta.get_idom(exit_bb->id) != unique_postdom) { @@ -270,6 +273,8 @@ stmt::Ptr loop::convert_to_ast_impl(dominator_analysis &dta_, std::vector(); if_stmt_copy->then_stmt = to(std::make_shared()); if_stmt_copy->else_stmt = to(std::make_shared()); + if_stmt_copy->annotation = to(bb->parent)->annotation; + if (condition_block == bb) { while_block->cond = to(bb->parent)->cond; @@ -621,6 +626,7 @@ block::stmt_block::Ptr loop_info::convert_to_ast(block::stmt_block::Ptr ast) { if_stmt_copy->then_stmt = to(std::make_shared()); if_stmt_copy->else_stmt = to(std::make_shared()); if_stmt_copy->cond = to(bb->parent)->cond; + if_stmt_copy->annotation = to(bb->parent)->annotation; // push the then branch onto worklist. (worklist should be a pair ) ? if (bb->then_branch) { diff --git a/src/builder/builder_context.cpp b/src/builder/builder_context.cpp index b01adac..30d6bbe 100644 --- a/src/builder/builder_context.cpp +++ b/src/builder/builder_context.cpp @@ -294,6 +294,7 @@ block::stmt::Ptr builder_context::extract_ast_from_function_impl(void) { block::eliminate_redundant_vars(ast); } + // return ast; if (feature_unstructured) return ast; @@ -325,6 +326,8 @@ block::stmt::Ptr builder_context::extract_ast_from_function_impl(void) { dominator_analysis dom(BBs); dominator_analysis post_dom(post_BBs, true); + std::cerr << "max depth: " << dom.max_depth << "\n"; + std::cerr << "max depth bb id: " << dom.max_depth_bb_id << "\n"; std::cerr << "== postorder map ==\n"; for (int i: dom.get_postorder_bb_map()) { std::cerr << i << "\n"; @@ -382,6 +385,8 @@ block::stmt::Ptr builder_context::extract_ast_from_function_impl(void) { } std::cerr << "== postorder idom ==\n"; + std::cerr << "(postdom) max depth: " << post_dom.max_depth << "\n"; + std::cerr << "(postdom) max depth bb id: " << post_dom.max_depth_bb_id << "\n"; std::cerr << "== (postdom) postorder map ==\n"; for (int i: post_dom.get_postorder_bb_map()) { std::cerr << i << "\n"; @@ -491,13 +496,13 @@ block::stmt::Ptr builder_context::extract_ast_from_function_impl(void) { std::cerr << "++++++ loop info ++++++ \n"; std::cerr << "++++++ convert to ast ++++++ \n"; - // ast = LI.convert_to_ast(block::to(ast)); + ast = LI.convert_to_ast(block::to(ast)); std::cerr << "++++++ convert to ast ++++++ \n"; - block::loop_finder finder; - finder.ast = ast; - ast->accept(&finder); - return ast; + // block::loop_finder finder; + // finder.ast = ast; + // ast->accept(&finder); + // return ast; block::for_loop_finder for_finder; for_finder.ast = ast;