11#include " blocks/loops.h"
22#include < algorithm>
33
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+
413void loop_info::analyze () {
514 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+ }
8104 }
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