Skip to content

Commit

Permalink
Now postdom can also handle infinite loops
Browse files Browse the repository at this point in the history
  • Loading branch information
VedantParanjape committed Sep 30, 2023
1 parent 4bfdc9d commit 2005723
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 28 deletions.
8 changes: 5 additions & 3 deletions include/blocks/dominance.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<int> &get_postorder_bb_map();
std::vector<int> &get_postorder();
std::vector<int> &get_preorder_bb_map();
Expand All @@ -44,10 +46,10 @@ class dominator_analysis {
std::vector<int> preorder_bb_map;
void reverse_cfg();
void postorder_idom_helper(std::vector<bool> &visited, int id);
void postorder_dfs_helper(std::vector<bool> &visited_bbs, int id);
void postorder_dfs();
void postorder_dfs_helper(std::vector<bool> &visited_bbs, int id, int depth);
void postorder_dfs(bool reverse_cfg);
void preorder_dfs_helper(std::vector<bool> &visited_bbs, int id);
void preorder_dfs();
void preorder_dfs(bool reverse_cfg);
int intersect(int bb1_id, int bb2_id);
};

Expand Down
67 changes: 47 additions & 20 deletions src/blocks/dominance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,28 @@ void dominator_analysis::reverse_cfg() {
assert(0);

std::shared_ptr<basic_block> virtual_exit_bb = std::make_shared<basic_block>("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);
virtual_exit_bb->predecessor.push_back(bb);
}
}

// 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();
Expand All @@ -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);

Expand All @@ -58,30 +75,40 @@ void dominator_analysis::postorder_idom_helper(std::vector<bool> &visited, int i
}
}

void dominator_analysis::postorder_dfs_helper(std::vector<bool> &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<bool> &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<bool> 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);
}
}
Expand All @@ -96,15 +123,15 @@ void dominator_analysis::preorder_dfs_helper(std::vector<bool> &visited_bbs, int
}
}

void dominator_analysis::preorder_dfs() {
void dominator_analysis::preorder_dfs(bool reverse_cfg) {
std::vector<bool> 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);
}
Expand Down Expand Up @@ -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;
}
Expand Down
6 changes: 6 additions & 0 deletions src/blocks/loops.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -270,6 +273,8 @@ stmt::Ptr loop::convert_to_ast_impl(dominator_analysis &dta_, std::vector<std::p
if_stmt::Ptr if_stmt_copy = std::make_shared<if_stmt>();
if_stmt_copy->then_stmt = to<stmt>(std::make_shared<stmt_block>());
if_stmt_copy->else_stmt = to<stmt>(std::make_shared<stmt_block>());
if_stmt_copy->annotation = to<if_stmt>(bb->parent)->annotation;

if (condition_block == bb) {
while_block->cond = to<if_stmt>(bb->parent)->cond;

Expand Down Expand Up @@ -621,6 +626,7 @@ block::stmt_block::Ptr loop_info::convert_to_ast(block::stmt_block::Ptr ast) {
if_stmt_copy->then_stmt = to<stmt>(std::make_shared<stmt_block>());
if_stmt_copy->else_stmt = to<stmt>(std::make_shared<stmt_block>());
if_stmt_copy->cond = to<if_stmt>(bb->parent)->cond;
if_stmt_copy->annotation = to<if_stmt>(bb->parent)->annotation;

// push the then branch onto worklist. (worklist should be a pair <processed, destination>) ?
if (bb->then_branch) {
Expand Down
15 changes: 10 additions & 5 deletions src/builder/builder_context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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";
Expand Down Expand Up @@ -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";
Expand Down Expand Up @@ -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<block::stmt_block>(ast));
ast = LI.convert_to_ast(block::to<block::stmt_block>(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;
Expand Down

0 comments on commit 2005723

Please sign in to comment.