1
1
#include " blocks/loops.h"
2
2
#include < algorithm>
3
3
4
+ std::shared_ptr<loop> loop_info::allocate_loop (std::shared_ptr<basic_block> header) {
5
+ if (!header)
6
+ return nullptr ;
7
+
8
+ loops.push_back (std::make_shared<loop>(header));
9
+ bb_loop_map[header->id ] = loops.back ();
10
+ return loops.back ();
11
+ }
12
+
4
13
void loop_info::analyze () {
5
14
std::vector<int > idom = dta.get_idom ();
6
- for (unsigned int i = 0 ; i < idom.size (); i++) {
7
- std::cout << i << " : " << idom[i] << " \n " ;
15
+
16
+ for (int idom_id: dta.get_postorder_idom_map ()) {
17
+ std::vector<int > backedges;
18
+ int header = idom_id;
19
+
20
+ for (auto backedge: dta.cfg_ [header]->predecessor ) {
21
+ if (dta.dominates (header, backedge->id ) && dta.is_reachable_from_entry (backedge->id )) {
22
+ backedges.push_back (backedge->id );
23
+ }
24
+ }
25
+
26
+ for (int i: backedges) {
27
+ std::cerr << i << " \n " ;
28
+ }
29
+
30
+ if (!backedges.empty ()) {
31
+ std::shared_ptr<loop> new_loop = allocate_loop (dta.cfg_ [header]);
32
+ if (!new_loop)
33
+ continue ;
34
+
35
+ int num_blocks = 0 ;
36
+ int num_subloops = 0 ;
37
+
38
+ auto backedge_iter = backedges.begin ();
39
+ // do a reverse CFG traversal to map basic blocks in this loop.
40
+ basic_block::cfg_block worklist (backedges.size ());
41
+ std::generate (worklist.begin (), worklist.end (), [&backedge_iter, this ](){
42
+ return dta.cfg_ [*(backedge_iter++)];
43
+ });
44
+ for (unsigned int i = 0 ; i < worklist.size (); i++) {
45
+ std::cerr << worklist[i]->id << " \n " ;
46
+ }
47
+ std::cerr << " header-p: " << header << " \n " ;
48
+ while (!worklist.empty ()) {
49
+ unsigned int predecessor_bb_id = worklist.back ()->id ;
50
+ worklist.pop_back ();
51
+
52
+ auto subloop_iter = bb_loop_map.find (predecessor_bb_id);
53
+ if (subloop_iter == bb_loop_map.end ()) {
54
+ if (!dta.is_reachable_from_entry (predecessor_bb_id))
55
+ continue ;
56
+
57
+ bb_loop_map[predecessor_bb_id] = new_loop;
58
+ std::cerr << " bb: " << predecessor_bb_id << " \n " ;
59
+ std::cerr << " loop-h: " << new_loop->header_block ->id << " \n " ;
60
+ ++num_blocks;
61
+ std::cerr << " if 1\n " ;
62
+ // loop has no blocks between header and backedge
63
+ if (predecessor_bb_id == new_loop->header_block ->id )
64
+ continue ;
65
+ std::cerr << " if 2\n " ;
66
+
67
+ worklist.insert (worklist.end (), dta.cfg_ [predecessor_bb_id]->predecessor .begin (), dta.cfg_ [predecessor_bb_id]->predecessor .end ());
68
+ }
69
+ else {
70
+ // this block has already been discovered, mapped to some other loop
71
+ // find the outermost loop
72
+ std::shared_ptr<loop> subloop = subloop_iter->second ;
73
+ std::cerr << " header: " << subloop->header_block ->id << " \n " ;
74
+ while (subloop->parent_loop ) {
75
+ subloop = subloop->parent_loop ;
76
+ }
77
+ std::cerr << " else 1\n " ;
78
+
79
+ if (subloop == new_loop)
80
+ continue ;
81
+
82
+ std::cerr << " else 2\n " ;
83
+ std::cerr << " bb: " << predecessor_bb_id << " \n " ;
84
+
85
+ // discovered a subloop of this loop
86
+ subloop->parent_loop = new_loop;
87
+ ++num_subloops;
88
+ num_blocks = num_blocks + subloop->blocks .size ();
89
+ predecessor_bb_id = subloop->header_block ->id ;
90
+
91
+ for (auto pred: dta.cfg_ [predecessor_bb_id]->predecessor ) {
92
+ auto loop_iter = bb_loop_map.find (pred->id );
93
+ // do not check if loop_iter != bb_loop_map.end(), as a results
94
+ // basic blocks that are not directly part of the natural loops
95
+ // are skipped, like loop latches.
96
+ if (loop_iter->second != subloop)
97
+ worklist.push_back (pred);
98
+ }
99
+ }
100
+ }
101
+ new_loop->subloops .reserve (num_subloops);
102
+ new_loop->blocks .reserve (num_blocks);
103
+ }
8
104
}
9
- }
105
+
106
+ // populate all subloops and loops with blocks
107
+ for (auto bb_id: dta.get_postorder ()) {
108
+ auto subloop_iter = bb_loop_map.find (bb_id);
109
+ std::shared_ptr<loop> subloop = nullptr ;
110
+ std::cerr << bb_id << " " << dta.cfg_ [bb_id]->id << subloop_iter->second ->header_block ->id << " \n " ;
111
+ if (subloop_iter != bb_loop_map.end () && (subloop = subloop_iter->second ) && dta.cfg_ [bb_id] == subloop_iter->second ->header_block ) {
112
+ // check if it is the outermost loop
113
+ std::cerr << " out::::" << subloop->header_block ->id << " \n " ;
114
+ if (subloop->parent_loop != nullptr ) {
115
+ std::cerr << " id::::" << subloop->header_block ->id << " \n " ;
116
+ subloop->parent_loop ->subloops .push_back (subloop);
117
+ }
118
+ else {
119
+ top_level_loops.push_back (subloop);
120
+ }
121
+
122
+ std::reverse (subloop->blocks .begin (), subloop->blocks .end ());
123
+ std::reverse (subloop->subloops .begin (), subloop->subloops .end ());
124
+
125
+ subloop = subloop->parent_loop ;
126
+ }
127
+
128
+ while (subloop) {
129
+ subloop->blocks .push_back (dta.cfg_ [bb_id]);
130
+ subloop = subloop->parent_loop ;
131
+ }
132
+ }
133
+ }
0 commit comments