Skip to content

Commit fdb906f

Browse files
V3: Added postdom, and other stuff
1 parent 41afb5f commit fdb906f

File tree

7 files changed

+252
-71
lines changed

7 files changed

+252
-71
lines changed

include/blocks/basic_blocks.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,23 @@ class basic_block {
1010
public:
1111
typedef std::vector<std::shared_ptr<basic_block>> cfg_block;
1212
basic_block(std::string label): name(label) {};
13+
// only does a shallow copy (leaves out predecessors and successors)
14+
// basic_block(basic_block &bb) {
15+
// bb.branch_expr = branch_expr;
16+
// bb.then_branch = then_branch;
17+
// bb.else_branch = else_branch;
18+
// bb.parent = parent;
19+
// bb.ast_index = ast_index;
20+
// bb.ast_depth = ast_depth;
21+
// bb.id = id;
22+
// bb.name = name;
23+
// }
1324

1425
cfg_block predecessor;
1526
cfg_block successor;
1627
block::expr::Ptr branch_expr;
28+
std::shared_ptr<basic_block> then_branch;
29+
std::shared_ptr<basic_block> else_branch;
1730
block::stmt::Ptr parent;
1831
unsigned int ast_index;
1932
unsigned int ast_depth;

include/blocks/dominance.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,9 @@ class dominator_analysis {
1717
// int bb_id;
1818
// std::vector<std::shared_ptr<dominator_tree_>> child_nodes;
1919
// } dominator_tree;
20-
dominator_analysis(basic_block::cfg_block &cfg);
21-
basic_block::cfg_block &cfg_;
20+
dominator_analysis(basic_block::cfg_block cfg, bool is_postdom = false);
21+
basic_block::cfg_block cfg_;
22+
bool is_postdom_;
2223
std::vector<int> &get_postorder_bb_map();
2324
std::vector<int> &get_postorder();
2425
std::vector<int> &get_idom();
@@ -37,6 +38,7 @@ class dominator_analysis {
3738
std::vector<int> postorder_idom;
3839
std::vector<int> postorder;
3940
std::vector<int> postorder_bb_map;
41+
void reverse_cfg();
4042
void postorder_idom_helper(std::vector<bool> &visited, int id);
4143
void postorder_dfs_helper(std::vector<bool> &visited_bbs, int id);
4244
void postorder_dfs();

include/blocks/loops.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,15 @@ class loop {
2828
std::unordered_set<int> blocks_id_map;
2929
std::shared_ptr<loop> parent_loop;
3030
std::shared_ptr<basic_block> header_block;
31+
std::shared_ptr<basic_block> unique_exit_block;
3132
basic_block::cfg_block loop_latch_blocks;
33+
basic_block::cfg_block loop_exit_blocks;
3234
std::vector<std::shared_ptr<loop>> subloops;
3335
};
3436

3537
class loop_info {
3638
public:
37-
loop_info(basic_block::cfg_block ast, dominator_analysis &dt): parent_ast(ast), dta(dt) {
39+
loop_info(basic_block::cfg_block ast, dominator_analysis &dt, dominator_analysis &post_dt): parent_ast(ast), dta(dt), post_dta(post_dt) {
3840
analyze();
3941
}
4042
std::shared_ptr<loop> allocate_loop(std::shared_ptr<basic_block> header);
@@ -47,6 +49,7 @@ class loop_info {
4749
private:
4850
basic_block::cfg_block parent_ast;
4951
dominator_analysis dta;
52+
dominator_analysis post_dta;
5053
std::map<int, std::shared_ptr<loop>> bb_loop_map;
5154
void postorder_dfs_helper(std::vector<int> &postorder_loops_map, std::vector<bool> &visited_loops, int id);
5255
void preorder_dfs_helper(std::vector<int> &preorder_loops_map, std::vector<bool> &visited_loops, int id);

src/blocks/basic_blocks.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,8 @@ basic_block::cfg_block generate_basic_blocks(block::stmt_block::Ptr ast) {
110110
then_bb->successor.push_back(exit_bb);
111111
// set the successor of the original if_stmt block to be this then block
112112
bb->successor.push_back(then_bb);
113+
// set the then branch ptr
114+
bb->then_branch = then_bb;
113115
// push the block to the work_list, to expand it further
114116
work_list.push_front(then_bb);
115117
}
@@ -126,13 +128,19 @@ basic_block::cfg_block generate_basic_blocks(block::stmt_block::Ptr ast) {
126128
else_bb->successor.push_back(exit_bb);
127129
// set the successor of the orignal if_stmt block to be this else block
128130
bb->successor.push_back(else_bb);
131+
// set the else branch ptr
132+
bb->else_branch = else_bb;
129133
// push the block to the work_list, to expand it further
130134
work_list.insert(work_list.begin() + 1, else_bb);
131135
}
132136

133-
// if there is no else block, then have the exit block as successor as well.
137+
// if there is no then/else block, then have the exit block as successor as well.
134138
if (bb->successor.size() <= 1) bb->successor.push_back(exit_bb);
135139

140+
// set the missing block as the exit block
141+
if (!bb->then_branch) bb->then_branch = exit_bb;
142+
else if (!bb->else_branch) bb->else_branch = exit_bb;
143+
136144
return_list.push_back(bb);
137145
}
138146
else if (isa<block::expr_stmt>(bb->parent)) {

src/blocks/dominance.cpp

Lines changed: 59 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,38 @@
22

33
using namespace block;
44

5-
dominator_analysis::dominator_analysis(basic_block::cfg_block &cfg) : cfg_(cfg) {
5+
void dominator_analysis::reverse_cfg() {
6+
// TODO: Add a check for size, it should be greater than 2.
7+
if (cfg_.size() == 0)
8+
assert(0);
9+
10+
std::shared_ptr<basic_block> virtual_exit_bb = std::make_shared<basic_block>("virtualexit0");
11+
virtual_exit_bb->id = cfg_.size();
12+
cfg_.push_back(virtual_exit_bb);
13+
14+
for (auto bb: cfg_) {
15+
if (bb->successor.size() == 0) {
16+
bb->successor.push_back(virtual_exit_bb);
17+
virtual_exit_bb->predecessor.push_back(bb);
18+
}
19+
}
20+
21+
for (auto bb: cfg_) {
22+
basic_block::cfg_block temp_pred = bb->predecessor;
23+
bb->predecessor.clear();
24+
bb->predecessor.insert(bb->predecessor.begin(), bb->successor.begin(), bb->successor.end());
25+
std::reverse(bb->predecessor.begin(), bb->predecessor.end());
26+
bb->successor.clear();
27+
bb->successor.insert(bb->successor.begin(), temp_pred.begin(), temp_pred.end());
28+
std::reverse(bb->successor.begin(), bb->successor.end());
29+
}
30+
}
31+
32+
dominator_analysis::dominator_analysis(basic_block::cfg_block cfg, bool is_postdom) : cfg_(cfg), is_postdom_(is_postdom) {
33+
if (is_postdom) {
34+
reverse_cfg();
35+
}
36+
637
// TODO: Add a check for size, it should be greater than 2.
738
idom.reserve(cfg_.size());
839
idom.assign(cfg_.size(), -1);
@@ -16,7 +47,6 @@ dominator_analysis::dominator_analysis(basic_block::cfg_block &cfg) : cfg_(cfg)
1647

1748
void dominator_analysis::postorder_idom_helper(std::vector<bool> &visited, int id) {
1849
for (int idom_id: idom_map[id]) {
19-
// std::cerr << idom_id << "\n";
2050
if (idom_id != -1 && !visited[idom_id]) {
2151
visited[idom_id] = true;
2252
postorder_idom_helper(visited, idom_id);
@@ -26,21 +56,31 @@ void dominator_analysis::postorder_idom_helper(std::vector<bool> &visited, int i
2656
}
2757

2858
void dominator_analysis::postorder_dfs_helper(std::vector<bool> &visited_bbs, int id) {
29-
for (auto child: cfg_[id]->successor) {
30-
if (!visited_bbs[child->id]) {
31-
visited_bbs[child->id] = true;
32-
postorder_dfs_helper(visited_bbs, child->id);
33-
postorder.push_back(child->id);
59+
for (auto child: cfg_[id]->successor) {
60+
if (!visited_bbs[child->id]) {
61+
visited_bbs[child->id] = true;
62+
postorder_dfs_helper(visited_bbs, child->id);
63+
postorder.push_back(child->id);
64+
}
3465
}
35-
}
3666
}
67+
3768
void dominator_analysis::postorder_dfs() {
3869
std::vector<bool> visited_bbs(cfg_.size());
3970
visited_bbs.assign(visited_bbs.size(), false);
40-
visited_bbs[0] = true;
41-
42-
postorder_dfs_helper(visited_bbs, 0);
43-
postorder.push_back(0);
71+
if (is_postdom_)
72+
visited_bbs[cfg_.size() - 1] = true;
73+
else
74+
visited_bbs[0] = true;
75+
76+
if (is_postdom_) {
77+
postorder_dfs_helper(visited_bbs, cfg_.size() - 1);
78+
postorder.push_back(cfg_.size() - 1);
79+
}
80+
else {
81+
postorder_dfs_helper(visited_bbs, 0);
82+
postorder.push_back(0);
83+
}
4484
}
4585

4686
std::vector<int> &dominator_analysis::get_postorder_bb_map() {
@@ -121,12 +161,16 @@ int dominator_analysis::intersect(int bb1_id, int bb2_id) {
121161
}
122162

123163
void dominator_analysis::analyze() {
124-
postorder_dfs();
164+
postorder_dfs();
125165
for (unsigned int i = 0; i < postorder.size(); i++) {
126166
postorder_bb_map[postorder[i]] = i;
127167
}
128168

129-
idom[0] = 0;
169+
if (is_postdom_)
170+
idom[cfg_.size() - 1] = cfg_.size() - 1;
171+
else
172+
idom[0] = 0;
173+
130174
bool change = false;
131175

132176
do {
@@ -135,7 +179,7 @@ void dominator_analysis::analyze() {
135179
int postorder_bb_num = postorder[i];
136180
std::shared_ptr<basic_block> bb = cfg_[postorder_bb_num];
137181
int bb_id_idom = bb->predecessor[0]->id;
138-
182+
139183
for (unsigned int j = 1; j < bb->predecessor.size(); j++) {
140184
int bb_id_idom_next = bb->predecessor[j]->id;
141185
if (idom[bb_id_idom_next] != -1) {
@@ -150,7 +194,6 @@ void dominator_analysis::analyze() {
150194
}
151195
} while(change);
152196

153-
154197
// build a map of dominators for easy traversal.
155198
for (unsigned int i = 0; i < idom.size(); i++) {
156199
idom_map[idom[i]].push_back(i);

0 commit comments

Comments
 (0)