1+ #include " blocks/dominance.h"
2+
3+ using namespace block ;
4+
5+ dominator_tree::dominator_tree (std::vector<std::shared_ptr<basic_block>> &cfg) : cfg_(cfg) {
6+ // TODO: Add a check for size, it should be greater than 2.
7+ idom.reserve (cfg_.size ());
8+ idom.assign (cfg_.size (), -1 );
9+ postorder.reserve (cfg_.size ());
10+ postorder_bb_map.reserve (cfg_.size ());
11+ postorder_bb_map.assign (cfg_.size (), -1 );
12+
13+ // and call the anaylse function
14+ analyze ();
15+ }
16+
17+ void dominator_tree::postorder_dfs_helper (std::vector<bool > &visited_bbs, int id) {
18+ for (auto child: cfg_[id]->successor ) {
19+ if (!visited_bbs[child->id ]) {
20+ visited_bbs[child->id ] = true ;
21+ postorder_dfs_helper (visited_bbs, child->id );
22+ postorder.push_back (child->id );
23+ }
24+ }
25+ }
26+ void dominator_tree::postorder_dfs () {
27+ std::vector<bool > visited_bbs (cfg_.size ());
28+ visited_bbs.assign (visited_bbs.size (), false );
29+ visited_bbs[0 ] = true ;
30+
31+ postorder_dfs_helper (visited_bbs, 0 );
32+ postorder.push_back (0 );
33+ }
34+
35+ std::vector<int > &dominator_tree::get_postorder_bb_map () {
36+ return postorder_bb_map;
37+ }
38+
39+ std::vector<int > &dominator_tree::get_postorder () {
40+ return postorder;
41+ }
42+
43+ std::vector<int > &dominator_tree::get_idom () {
44+ return idom;
45+ }
46+
47+ int dominator_tree::get_idom (int bb_id) {
48+ if (bb_id >= 0 && bb_id < idom.size ()) {
49+ return -1 ;
50+ }
51+
52+ return idom[bb_id];
53+ }
54+ bool dominator_tree::dominates (int bb1_id, int bb2_id) {
55+ if (bb1_id == 0 ) {
56+ return true ;
57+ }
58+
59+ int pointer = idom[bb2_id];
60+ while (pointer != 0 ) {
61+ if (pointer == bb1_id) {
62+ return true ;
63+ }
64+ pointer = idom[pointer];
65+ }
66+
67+ return false ;
68+ }
69+
70+ bool dominator_tree::is_reachable_from_entry (int bb_id) {
71+ return dominates (0 , bb_id);
72+ }
73+
74+ int dominator_tree::intersect (int bb1_id, int bb2_id) {
75+ while (bb1_id != bb2_id) {
76+ if (postorder_bb_map[bb1_id] < postorder_bb_map[bb2_id]) {
77+ bb1_id = idom[bb1_id];
78+ }
79+ else {
80+ bb2_id = idom[bb2_id];
81+ }
82+ }
83+
84+ return bb1_id;
85+ }
86+
87+ void dominator_tree::analyze () {
88+ postorder_dfs ();
89+ for (unsigned int i = 0 ; i < postorder.size (); i++) {
90+ postorder_bb_map[postorder[i]] = i;
91+ }
92+
93+ idom[0 ] = 0 ;
94+ bool change = false ;
95+
96+ do {
97+ change = 0 ;
98+ for (int i = postorder.size () - 2 ; i >= 0 ; i--) {
99+ int postorder_bb_num = postorder[i];
100+ std::shared_ptr<basic_block> bb = cfg_[postorder_bb_num];
101+ int bb_id_idom = bb->predecessor [0 ]->id ;
102+
103+ for (unsigned int j = 1 ; j < bb->predecessor .size (); j++) {
104+ int bb_id_idom_next = bb->predecessor [j]->id ;
105+ if (idom[bb_id_idom_next] != -1 ) {
106+ bb_id_idom = intersect (bb_id_idom, bb_id_idom_next);
107+ }
108+ }
109+
110+ if (idom[postorder_bb_num] != bb_id_idom) {
111+ idom[postorder_bb_num] = bb_id_idom;
112+ change = 1 ;
113+ }
114+ }
115+ } while (change);
116+ }
0 commit comments