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