-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement dominator_tree analysis pass
Add support to build a dominator tree for a given CFG, and add APIs to use the dominator tree to find idoms and dominance information.
- Loading branch information
1 parent
7590972
commit 994ff9f
Showing
6 changed files
with
180 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
#ifndef DOMINANCE_H | ||
#define DOMINANCE_H | ||
#include "blocks/block_visitor.h" | ||
#include "blocks/basic_blocks.h" | ||
#include "blocks/stmt.h" | ||
#include <vector> | ||
#include <stack> | ||
#include <string> | ||
#include <bitset> | ||
#include <algorithm> | ||
|
||
class dominator_tree { | ||
public: | ||
dominator_tree(std::vector<std::shared_ptr<basic_block>> &cfg); | ||
std::vector<int> &get_postorder_bb_map(); | ||
std::vector<int> &get_postorder(); | ||
std::vector<int> &get_idom(); | ||
int get_idom(int bb_id); | ||
bool dominates(int bb1_id, int bb2_id); | ||
bool is_reachable_from_entry(int bb_id); | ||
void analyze(); | ||
|
||
private: | ||
std::vector<int> idom; | ||
std::vector<int> postorder; | ||
std::vector<int> postorder_bb_map; | ||
std::vector<std::shared_ptr<basic_block>> &cfg_; | ||
void postorder_dfs_helper(std::vector<bool> &visited_bbs, int id); | ||
void postorder_dfs(); | ||
int intersect(int bb1_id, int bb2_id); | ||
}; | ||
|
||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
#include "blocks/dominance.h" | ||
|
||
using namespace block; | ||
|
||
dominator_tree::dominator_tree(std::vector<std::shared_ptr<basic_block>> &cfg) : cfg_(cfg) { | ||
// TODO: Add a check for size, it should be greater than 2. | ||
idom.reserve(cfg_.size()); | ||
idom.assign(cfg_.size(), -1); | ||
postorder.reserve(cfg_.size()); | ||
postorder_bb_map.reserve(cfg_.size()); | ||
postorder_bb_map.assign(cfg_.size(), -1); | ||
|
||
// and call the anaylse function | ||
analyze(); | ||
} | ||
|
||
void dominator_tree::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_tree::postorder_dfs() { | ||
std::vector<bool> visited_bbs(cfg_.size()); | ||
visited_bbs.assign(visited_bbs.size(), false); | ||
visited_bbs[0] = true; | ||
|
||
postorder_dfs_helper(visited_bbs, 0); | ||
postorder.push_back(0); | ||
} | ||
|
||
std::vector<int> &dominator_tree::get_postorder_bb_map() { | ||
return postorder_bb_map; | ||
} | ||
|
||
std::vector<int> &dominator_tree::get_postorder() { | ||
return postorder; | ||
} | ||
|
||
std::vector<int> &dominator_tree::get_idom() { | ||
return idom; | ||
} | ||
|
||
int dominator_tree::get_idom(int bb_id) { | ||
if (bb_id >= 0 && bb_id < idom.size()) { | ||
return -1; | ||
} | ||
|
||
return idom[bb_id]; | ||
} | ||
bool dominator_tree::dominates(int bb1_id, int bb2_id) { | ||
if (bb1_id == 0) { | ||
return true; | ||
} | ||
|
||
int pointer = idom[bb2_id]; | ||
while (pointer != 0) { | ||
if (pointer == bb1_id) { | ||
return true; | ||
} | ||
pointer = idom[pointer]; | ||
} | ||
|
||
return false; | ||
} | ||
|
||
bool dominator_tree::is_reachable_from_entry(int bb_id) { | ||
return dominates(0, bb_id); | ||
} | ||
|
||
int dominator_tree::intersect(int bb1_id, int bb2_id) { | ||
while (bb1_id != bb2_id) { | ||
if (postorder_bb_map[bb1_id] < postorder_bb_map[bb2_id]) { | ||
bb1_id = idom[bb1_id]; | ||
} | ||
else { | ||
bb2_id = idom[bb2_id]; | ||
} | ||
} | ||
|
||
return bb1_id; | ||
} | ||
|
||
void dominator_tree::analyze() { | ||
postorder_dfs(); | ||
for (unsigned int i = 0; i < postorder.size(); i++) { | ||
postorder_bb_map[postorder[i]] = i; | ||
} | ||
|
||
idom[0] = 0; | ||
bool change = false; | ||
|
||
do { | ||
change = 0; | ||
for (int i = postorder.size() - 2; i >= 0; i--) { | ||
int postorder_bb_num = postorder[i]; | ||
std::shared_ptr<basic_block> bb = cfg_[postorder_bb_num]; | ||
int bb_id_idom = bb->predecessor[0]->id; | ||
|
||
for (unsigned int j = 1; j < bb->predecessor.size(); j++) { | ||
int bb_id_idom_next = bb->predecessor[j]->id; | ||
if (idom[bb_id_idom_next] != -1) { | ||
bb_id_idom = intersect(bb_id_idom, bb_id_idom_next); | ||
} | ||
} | ||
|
||
if (idom[postorder_bb_num] != bb_id_idom) { | ||
idom[postorder_bb_num] = bb_id_idom; | ||
change = 1; | ||
} | ||
} | ||
} while(change); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters