@@ -10,6 +10,16 @@ std::shared_ptr<loop> loop_info::allocate_loop(std::shared_ptr<basic_block> head
1010 return loops.back ();
1111}
1212
13+ void loop_info::postorder_dfs_helper (std::vector<int > &postorder_loops_map, std::vector<bool > &visited_loops, int id) {
14+ for (auto subloop: loops[id]->subloops ) {
15+ if (!visited_loops[subloop->loop_id ]) {
16+ visited_loops[subloop->loop_id ] = true ;
17+ postorder_dfs_helper (postorder_loops_map, visited_loops, subloop->loop_id );
18+ postorder_loops_map.push_back (subloop->loop_id );
19+ }
20+ }
21+ }
22+
1323void loop_info::analyze () {
1424 std::vector<int > idom = dta.get_idom ();
1525
@@ -126,4 +136,203 @@ void loop_info::analyze() {
126136 }
127137 }
128138 }
129- }
139+
140+ // Assign id to the loops
141+ for (unsigned int i = 0 ; i < loops.size (); i++) {
142+ loops[i]->loop_id = i;
143+ }
144+
145+ // build a loop tree
146+ std::vector<bool > visited_loops (loops.size ());
147+ visited_loops.assign (visited_loops.size (), false );
148+ for (auto loop: top_level_loops) {
149+ std::vector<int > postorder_loop_tree;
150+ visited_loops[loop->loop_id ] = true ;
151+
152+ postorder_dfs_helper (postorder_loop_tree, visited_loops, loop->loop_id );
153+ postorder_loop_tree.push_back (loop->loop_id );
154+ postorder_loops_map[loop->loop_id ] = postorder_loop_tree;
155+ }
156+ }
157+
158+ static stmt::Ptr get_loop_block (std::shared_ptr<basic_block> loop_header, block::stmt_block::Ptr ast) {
159+ block::stmt::Ptr current_ast = to<block::stmt>(ast);
160+ std::vector<stmt::Ptr> current_block = to<block::stmt_block>(current_ast)->stmts ;
161+ // unsigned int ast_index = loop_header->ast_index;
162+ std::deque<stmt::Ptr> worklist;
163+ std::map<stmt::Ptr, stmt::Ptr> ast_parent_map;
164+
165+ for (auto stmt: current_block) {
166+ ast_parent_map[stmt] = current_ast;
167+ }
168+ worklist.insert (worklist.end (), current_block.begin (), current_block.end ());
169+
170+ while (worklist.size ()) {
171+ stmt::Ptr worklist_top = worklist.front ();
172+ worklist.pop_front ();
173+
174+ if (isa<block::stmt_block>(worklist_top)) {
175+ stmt_block::Ptr wl_stmt_block = to<stmt_block>(worklist_top);
176+ for (auto stmt: wl_stmt_block->stmts ) {
177+ ast_parent_map[stmt] = worklist_top;
178+ }
179+ worklist.insert (worklist.end (), wl_stmt_block->stmts .begin (), wl_stmt_block->stmts .end ());
180+ }
181+ else if (isa<block::if_stmt>(worklist_top)) {
182+ if_stmt::Ptr wl_if_stmt = to<if_stmt>(worklist_top);
183+
184+ if (to<stmt_block>(wl_if_stmt->then_stmt )->stmts .size () != 0 ) {
185+ stmt_block::Ptr wl_if_then_stmt = to<stmt_block>(wl_if_stmt->then_stmt );
186+ for (auto stmt: wl_if_then_stmt->stmts ) {
187+ ast_parent_map[stmt] = worklist_top;
188+ }
189+ worklist.insert (worklist.end (), wl_if_then_stmt->stmts .begin (), wl_if_then_stmt->stmts .end ());
190+ }
191+ if (to<stmt_block>(wl_if_stmt->else_stmt )->stmts .size () != 0 ) {
192+ stmt_block::Ptr wl_if_else_stmt = to<stmt_block>(wl_if_stmt->else_stmt );
193+ for (auto stmt: wl_if_else_stmt->stmts ) {
194+ ast_parent_map[stmt] = worklist_top;
195+ }
196+ worklist.insert (worklist.end (), wl_if_else_stmt->stmts .begin (), wl_if_else_stmt->stmts .end ());
197+ }
198+ }
199+ else if (isa<block::label_stmt>(worklist_top)) {
200+ label_stmt::Ptr wl_label_stmt = to<label_stmt>(worklist_top);
201+ if (worklist_top == loop_header->parent )
202+ return ast_parent_map[worklist_top];
203+ }
204+ else if (isa<block::goto_stmt>(worklist_top)) {
205+ goto_stmt::Ptr wl_goto_stmt = to<goto_stmt>(worklist_top);
206+ if (worklist_top == loop_header->parent )
207+ return ast_parent_map[worklist_top];
208+ }
209+ }
210+
211+ return nullptr ;
212+ }
213+
214+ static void replace_loop_latches (std::shared_ptr<loop> loop, block::stmt_block::Ptr ast) {
215+ for (auto latch : loop->loop_latch_blocks ) {
216+ stmt::Ptr loop_latch_ast = get_loop_block (latch, ast);
217+ if (isa<stmt_block>(loop_latch_ast)) {
218+ std::vector<stmt::Ptr> &temp_loop_ast = to<stmt_block>(loop_latch_ast)->stmts ;
219+ std::replace (temp_loop_ast.begin (), temp_loop_ast.end (), temp_loop_ast[latch->ast_index ], to<stmt>(std::make_shared<continue_stmt>()));
220+ }
221+ else if (isa<if_stmt>(loop_latch_ast)) {
222+ stmt_block::Ptr if_then_block = to<block::stmt_block>(to<block::if_stmt>(loop_latch_ast)->then_stmt );
223+ stmt_block::Ptr if_else_block = to<block::stmt_block>(to<block::if_stmt>(loop_latch_ast)->else_stmt );
224+
225+ if (if_then_block->stmts .size () && if_then_block->stmts [latch->ast_index ] == latch->parent ) {
226+ std::replace (if_then_block->stmts .begin (), if_then_block->stmts .end (), if_then_block->stmts [latch->ast_index ], to<stmt>(std::make_shared<continue_stmt>()));
227+ }
228+ else if (if_else_block->stmts .size () && if_else_block->stmts [latch->ast_index ] == latch->parent ) {
229+ std::replace (if_else_block->stmts .begin (), if_else_block->stmts .end (), if_else_block->stmts [latch->ast_index ], to<stmt>(std::make_shared<continue_stmt>()));
230+ }
231+ }
232+ }
233+ }
234+
235+ block::stmt_block::Ptr loop_info::convert_to_ast (block::stmt_block::Ptr ast) {
236+ for (auto loop_map: postorder_loops_map) {
237+ // std::cerr << "== top level loop tree ==\n";
238+ for (auto postorder: loop_map.second ) {
239+ // std::cerr << postorder <<"\n";
240+ block::stmt::Ptr loop_header_ast = get_loop_block (loops[postorder]->header_block , ast);
241+
242+ while_stmt::Ptr while_block = std::make_shared<while_stmt>();
243+ while_block->cond = std::make_shared<int_const>();
244+ to<int_const>(while_block->cond )->value = 1 ;
245+ while_block->body = std::make_shared<stmt_block>();
246+
247+ if (isa<block::stmt_block>(loop_header_ast)) {
248+ unsigned int ast_index = loops[postorder]->header_block ->ast_index ;
249+ if (to<block::stmt_block>(loop_header_ast)->stmts [ast_index] == loops[postorder]->header_block ->parent ) {
250+ stmt_block::Ptr then_block = to<block::stmt_block>(to<block::if_stmt>(to<block::stmt_block>(loop_header_ast)->stmts [ast_index + 1 ])->then_stmt );
251+ stmt_block::Ptr else_block = to<block::stmt_block>(to<block::if_stmt>(to<block::stmt_block>(loop_header_ast)->stmts [ast_index + 1 ])->else_stmt );
252+
253+ // if (isa<goto_stmt>(then_block->stmts.back())) {
254+ // then_block->stmts.pop_back();
255+ // then_block->stmts.push_back(std::make_shared<continue_stmt>());
256+ // }
257+ replace_loop_latches (loops[postorder], ast);
258+
259+ else_block->stmts .push_back (std::make_shared<break_stmt>());
260+ to<stmt_block>(while_block->body )->stmts .push_back (to<block::stmt_block>(loop_header_ast)->stmts [ast_index + 1 ]);
261+ // while_block->cond = to<block::if_stmt>(to<block::stmt_block>(loop_header_ast)->stmts[ast_index + 1])->cond;
262+ // while_block->dump(std::cerr, 0);
263+ // std::cerr << "found loop header in stmt block\n";
264+
265+ // if block to be replaced with while block
266+ std::vector<stmt::Ptr> &temp_ast = to<block::stmt_block>(loop_header_ast)->stmts ;
267+ std::replace (temp_ast.begin (), temp_ast.end (), temp_ast[ast_index + 1 ], to<stmt>(while_block));
268+ temp_ast.erase (temp_ast.begin () + ast_index);
269+ }
270+ else {
271+ // std::cerr << "not found loop header in stmt block\n";
272+ }
273+ }
274+ else if (isa<block::if_stmt>(loop_header_ast)) {
275+ unsigned int ast_index = loops[postorder]->header_block ->ast_index ;
276+ stmt_block::Ptr if_then_block = to<block::stmt_block>(to<block::if_stmt>(loop_header_ast)->then_stmt );
277+ stmt_block::Ptr if_else_block = to<block::stmt_block>(to<block::if_stmt>(loop_header_ast)->else_stmt );
278+
279+ if (if_then_block->stmts .size () != 0 ) {
280+ if (if_then_block->stmts [ast_index] == loops[postorder]->header_block ->parent ) {
281+ stmt_block::Ptr then_block = to<block::stmt_block>(to<block::if_stmt>(if_then_block->stmts [ast_index + 1 ])->then_stmt );
282+ stmt_block::Ptr else_block = to<block::stmt_block>(to<block::if_stmt>(if_then_block->stmts [ast_index + 1 ])->else_stmt );
283+
284+ replace_loop_latches (loops[postorder], ast);
285+
286+ else_block->stmts .push_back (std::make_shared<break_stmt>());
287+ to<stmt_block>(while_block->body )->stmts .push_back (if_then_block->stmts [ast_index + 1 ]);
288+ // while_block->cond = to<block::if_stmt>(loop_header_ast)->cond;
289+
290+ // while_block->dump(std::cerr, 0);
291+ // std::cerr << "found loop header in if-then stmt\n";
292+
293+ // if block to be replaced with while block
294+ std::vector<stmt::Ptr> &temp_ast = if_then_block->stmts ;
295+ std::replace (temp_ast.begin (), temp_ast.end (), temp_ast[ast_index + 1 ], to<stmt>(while_block));
296+ temp_ast.erase (temp_ast.begin () + ast_index);
297+ }
298+ else {
299+ // loop_header_ast->dump(std::cerr, 0);
300+ // std::cerr << "not found loop header in if-then stmt\n";
301+ }
302+ }
303+ else if (if_else_block->stmts .size () != 0 ) {
304+ if (if_else_block->stmts [ast_index] == loops[postorder]->header_block ->parent ) {
305+ stmt_block::Ptr then_block = to<block::stmt_block>(to<block::if_stmt>(if_else_block->stmts [ast_index + 1 ])->then_stmt );
306+ stmt_block::Ptr else_block = to<block::stmt_block>(to<block::if_stmt>(if_else_block->stmts [ast_index + 1 ])->else_stmt );
307+
308+ replace_loop_latches (loops[postorder], ast);
309+
310+ else_block->stmts .push_back (std::make_shared<break_stmt>());
311+ to<stmt_block>(while_block->body )->stmts .push_back (if_else_block->stmts [ast_index + 1 ]);
312+ // while_block->cond = to<block::if_stmt>(loop_header_ast)->cond;
313+
314+ // while_block->dump(std::cerr, 0);
315+ // std::cerr << "found loop header in if-else stmt\n";
316+
317+ // if block to be replaced with while block
318+ std::vector<stmt::Ptr> &temp_ast = if_else_block->stmts ;
319+ std::replace (temp_ast.begin (), temp_ast.end (), temp_ast[ast_index + 1 ], to<stmt>(while_block));
320+ temp_ast.erase (temp_ast.begin () + ast_index);
321+ }
322+ else {
323+ // loop_header_ast->dump(std::cerr, 0);
324+ // std::cerr << "not found loop header in if-else stmt\n";
325+ }
326+ }
327+ }
328+ else {
329+ // std::cerr << "loop header not found\n";
330+ }
331+ // insert into AST - std::replace
332+ // set the ast to loop depth + 1
333+ // loops[loop_tree.first]->header_block->ast_index
334+ }
335+ }
336+
337+ return ast;
338+ }
0 commit comments