47 /* Avoid annoying special cases of edges going to exit 48 block. */ 49 50 for (ei = ei_start (EXIT_BLOCK_PTR->preds); (e = ei_safe_edge (ei)); ) 51 if ((e->flags & EDGE_FALLTHRU) && !single_succ_p (e->src)) 52 split_edge (e); 53 else 54 ei_next (&ei); 55 56 /* Find the loops. */ 57 58 if (flow_loops_find (loops) <= 1) 59 { 60 /* No loops. */ 61 flow_loops_free (loops); 62 free (loops); 63 64 return NULL; 65 } 66 67 /* Not going to update these. */ 68 free (loops->cfg.rc_order); 69 loops->cfg.rc_order = NULL; 70 free (loops->cfg.dfs_order); 71 loops->cfg.dfs_order = NULL; 72 73 /* Create pre-headers. */ 74 if (flags & LOOPS_HAVE_PREHEADERS) 75 create_preheaders (loops, CP_SIMPLE_PREHEADERS); 76 77 /* Force all latches to have only single successor. */ 78 if (flags & LOOPS_HAVE_SIMPLE_LATCHES) 79 force_single_succ_latches (loops); 80 81 /* Mark irreducible loops. */ 82 if (flags & LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS) 83 mark_irreducible_loops (loops); 84 85 if (flags & LOOPS_HAVE_MARKED_SINGLE_EXITS) 86 mark_single_exit_loops (loops); 87 88 /* Dump loops. */ 89 flow_loops_dump (loops, dump_file, NULL, 1); 90 91#ifdef ENABLE_CHECKING 92 verify_dominators (CDI_DOMINATORS); 93 verify_loop_structure (loops); 94#endif 95 96 return loops; 97} 98 99/* Finalize loop optimizer. */ 100void 101loop_optimizer_finalize (struct loops *loops) 102{ 103 unsigned i; 104 105 if (!loops) 106 return; 107 108 for (i = 1; i < loops->num; i++) 109 if (loops->parray[i]) 110 free_simple_loop_desc (loops->parray[i]); 111 112 /* Clean up. */ 113 flow_loops_free (loops); 114 free (loops); 115 116 /* Checking. */ 117#ifdef ENABLE_CHECKING 118 verify_flow_info (); 119#endif 120} 121 122 123/* Gate for the RTL loop superpass. The actual passes are subpasses. 124 See passes.c for more on that. */ 125 126static bool 127gate_handle_loop2 (void) 128{ 129 return (optimize > 0 130 && (flag_move_loop_invariants 131 || flag_unswitch_loops 132 || flag_peel_loops 133 || flag_unroll_loops 134#ifdef HAVE_doloop_end 135 || (flag_branch_on_count_reg && HAVE_doloop_end) 136#endif 137 )); 138} 139 140struct tree_opt_pass pass_loop2 = 141{ 142 "loop2", /* name */ 143 gate_handle_loop2, /* gate */ 144 NULL, /* execute */ 145 NULL, /* sub */ 146 NULL, /* next */ 147 0, /* static_pass_number */ 148 TV_LOOP, /* tv_id */ 149 0, /* properties_required */ 150 0, /* properties_provided */ 151 0, /* properties_destroyed */ 152 0, /* todo_flags_start */ 153 TODO_dump_func | 154 TODO_ggc_collect, /* todo_flags_finish */ 155 'L' /* letter */ 156}; 157 158 159/* Initialization of the RTL loop passes. */ 160static unsigned int 161rtl_loop_init (void) 162{ 163 if (dump_file) 164 dump_flow_info (dump_file, dump_flags); 165 166 /* Initialize structures for layout changes. */ 167 cfg_layout_initialize (0); 168 169 current_loops = loop_optimizer_init (LOOPS_NORMAL); 170 return 0; 171} 172 173struct tree_opt_pass pass_rtl_loop_init = 174{ 175 "loop2_init", /* name */ 176 NULL, /* gate */ 177 rtl_loop_init, /* execute */ 178 NULL, /* sub */ 179 NULL, /* next */ 180 0, /* static_pass_number */ 181 TV_LOOP, /* tv_id */ 182 0, /* properties_required */ 183 0, /* properties_provided */ 184 0, /* properties_destroyed */ 185 0, /* todo_flags_start */ 186 TODO_dump_func, /* todo_flags_finish */ 187 'L' /* letter */ 188}; 189 190 191/* Finalization of the RTL loop passes. */ 192static unsigned int 193rtl_loop_done (void) 194{ 195 basic_block bb; 196 197 if (current_loops) 198 loop_optimizer_finalize (current_loops); 199 200 free_dominance_info (CDI_DOMINATORS); 201 202 /* Finalize layout changes. */ 203 FOR_EACH_BB (bb) 204 if (bb->next_bb != EXIT_BLOCK_PTR) 205 bb->aux = bb->next_bb; 206 cfg_layout_finalize (); 207 208 cleanup_cfg (CLEANUP_EXPENSIVE); 209 delete_trivially_dead_insns (get_insns (), max_reg_num ()); 210 reg_scan (get_insns (), max_reg_num ()); 211 if (dump_file) 212 dump_flow_info (dump_file, dump_flags); 213 214 current_loops = NULL; 215 return 0; 216} 217 218struct tree_opt_pass pass_rtl_loop_done = 219{ 220 "loop2_done", /* name */ 221 NULL, /* gate */ 222 rtl_loop_done, /* execute */ 223 NULL, /* sub */ 224 NULL, /* next */ 225 0, /* static_pass_number */ 226 TV_LOOP, /* tv_id */ 227 0, /* properties_required */ 228 0, /* properties_provided */ 229 0, /* properties_destroyed */ 230 0, /* todo_flags_start */ 231 TODO_dump_func, /* todo_flags_finish */ 232 'L' /* letter */ 233}; 234 235 236/* Loop invariant code motion. */ 237static bool 238gate_rtl_move_loop_invariants (void) 239{ 240 return flag_move_loop_invariants; 241} 242 243static unsigned int 244rtl_move_loop_invariants (void) 245{ 246 if (current_loops) 247 move_loop_invariants (current_loops); 248 return 0; 249} 250 251struct tree_opt_pass pass_rtl_move_loop_invariants = 252{ 253 "loop2_invariant", /* name */ 254 gate_rtl_move_loop_invariants, /* gate */ 255 rtl_move_loop_invariants, /* execute */ 256 NULL, /* sub */ 257 NULL, /* next */ 258 0, /* static_pass_number */ 259 TV_LOOP, /* tv_id */ 260 0, /* properties_required */ 261 0, /* properties_provided */ 262 0, /* properties_destroyed */ 263 0, /* todo_flags_start */ 264 TODO_dump_func, /* todo_flags_finish */ 265 'L' /* letter */ 266}; 267 268 269/* Loop unswitching for RTL. */ 270static bool 271gate_rtl_unswitch (void) 272{ 273 return flag_unswitch_loops; 274} 275 276static unsigned int 277rtl_unswitch (void) 278{ 279 if (current_loops) 280 unswitch_loops (current_loops); 281 return 0; 282} 283 284struct tree_opt_pass pass_rtl_unswitch = 285{ 286 "loop2_unswitch", /* name */ 287 gate_rtl_unswitch, /* gate */ 288 rtl_unswitch, /* execute */ 289 NULL, /* sub */ 290 NULL, /* next */ 291 0, /* static_pass_number */ 292 TV_LOOP, /* tv_id */ 293 0, /* properties_required */ 294 0, /* properties_provided */ 295 0, /* properties_destroyed */ 296 0, /* todo_flags_start */ 297 TODO_dump_func, /* todo_flags_finish */ 298 'L' /* letter */ 299}; 300 301 302/* Loop unswitching for RTL. */ 303static bool 304gate_rtl_unroll_and_peel_loops (void) 305{ 306 return (flag_peel_loops || flag_unroll_loops || flag_unroll_all_loops); 307} 308 309static unsigned int 310rtl_unroll_and_peel_loops (void) 311{ 312 if (current_loops) 313 { 314 int flags = 0; 315 316 if (flag_peel_loops) 317 flags |= UAP_PEEL; 318 if (flag_unroll_loops) 319 flags |= UAP_UNROLL; 320 if (flag_unroll_all_loops) 321 flags |= UAP_UNROLL_ALL; 322 323 unroll_and_peel_loops (current_loops, flags); 324 } 325 return 0; 326} 327 328struct tree_opt_pass pass_rtl_unroll_and_peel_loops = 329{ 330 "loop2_unroll", /* name */ 331 gate_rtl_unroll_and_peel_loops, /* gate */ 332 rtl_unroll_and_peel_loops, /* execute */ 333 NULL, /* sub */ 334 NULL, /* next */ 335 0, /* static_pass_number */ 336 TV_LOOP, /* tv_id */ 337 0, /* properties_required */ 338 0, /* properties_provided */ 339 0, /* properties_destroyed */ 340 0, /* todo_flags_start */ 341 TODO_dump_func, /* todo_flags_finish */ 342 'L' /* letter */ 343}; 344 345 346/* The doloop optimization. */ 347static bool 348gate_rtl_doloop (void) 349{ 350#ifdef HAVE_doloop_end 351 return (flag_branch_on_count_reg && HAVE_doloop_end); 352#else 353 return 0; 354#endif 355} 356 357static unsigned int 358rtl_doloop (void) 359{ 360#ifdef HAVE_doloop_end 361 if (current_loops) 362 doloop_optimize_loops (current_loops); 363#endif 364 return 0; 365} 366 367struct tree_opt_pass pass_rtl_doloop = 368{ 369 "loop2_doloop", /* name */ 370 gate_rtl_doloop, /* gate */ 371 rtl_doloop, /* execute */ 372 NULL, /* sub */ 373 NULL, /* next */ 374 0, /* static_pass_number */ 375 TV_LOOP, /* tv_id */ 376 0, /* properties_required */ 377 0, /* properties_provided */ 378 0, /* properties_destroyed */ 379 0, /* todo_flags_start */ 380 TODO_dump_func, /* todo_flags_finish */ 381 'L' /* letter */ 382}; 383
| 54 /* Avoid annoying special cases of edges going to exit 55 block. */ 56 57 for (ei = ei_start (EXIT_BLOCK_PTR->preds); (e = ei_safe_edge (ei)); ) 58 if ((e->flags & EDGE_FALLTHRU) && !single_succ_p (e->src)) 59 split_edge (e); 60 else 61 ei_next (&ei); 62 63 /* Find the loops. */ 64 65 if (flow_loops_find (loops) <= 1) 66 { 67 /* No loops. */ 68 flow_loops_free (loops); 69 free (loops); 70 71 return NULL; 72 } 73 74 /* Not going to update these. */ 75 free (loops->cfg.rc_order); 76 loops->cfg.rc_order = NULL; 77 free (loops->cfg.dfs_order); 78 loops->cfg.dfs_order = NULL; 79 80 /* Create pre-headers. */ 81 if (flags & LOOPS_HAVE_PREHEADERS) 82 create_preheaders (loops, CP_SIMPLE_PREHEADERS); 83 84 /* Force all latches to have only single successor. */ 85 if (flags & LOOPS_HAVE_SIMPLE_LATCHES) 86 force_single_succ_latches (loops); 87 88 /* Mark irreducible loops. */ 89 if (flags & LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS) 90 mark_irreducible_loops (loops); 91 92 if (flags & LOOPS_HAVE_MARKED_SINGLE_EXITS) 93 mark_single_exit_loops (loops); 94 95 /* Dump loops. */ 96 flow_loops_dump (loops, dump_file, NULL, 1); 97 98#ifdef ENABLE_CHECKING 99 verify_dominators (CDI_DOMINATORS); 100 verify_loop_structure (loops); 101#endif 102 103 return loops; 104} 105 106/* Finalize loop optimizer. */ 107void 108loop_optimizer_finalize (struct loops *loops) 109{ 110 unsigned i; 111 112 if (!loops) 113 return; 114 115 for (i = 1; i < loops->num; i++) 116 if (loops->parray[i]) 117 free_simple_loop_desc (loops->parray[i]); 118 119 /* Clean up. */ 120 flow_loops_free (loops); 121 free (loops); 122 123 /* Checking. */ 124#ifdef ENABLE_CHECKING 125 verify_flow_info (); 126#endif 127} 128 129 130/* Gate for the RTL loop superpass. The actual passes are subpasses. 131 See passes.c for more on that. */ 132 133static bool 134gate_handle_loop2 (void) 135{ 136 return (optimize > 0 137 && (flag_move_loop_invariants 138 || flag_unswitch_loops 139 || flag_peel_loops 140 || flag_unroll_loops 141#ifdef HAVE_doloop_end 142 || (flag_branch_on_count_reg && HAVE_doloop_end) 143#endif 144 )); 145} 146 147struct tree_opt_pass pass_loop2 = 148{ 149 "loop2", /* name */ 150 gate_handle_loop2, /* gate */ 151 NULL, /* execute */ 152 NULL, /* sub */ 153 NULL, /* next */ 154 0, /* static_pass_number */ 155 TV_LOOP, /* tv_id */ 156 0, /* properties_required */ 157 0, /* properties_provided */ 158 0, /* properties_destroyed */ 159 0, /* todo_flags_start */ 160 TODO_dump_func | 161 TODO_ggc_collect, /* todo_flags_finish */ 162 'L' /* letter */ 163}; 164 165 166/* Initialization of the RTL loop passes. */ 167static unsigned int 168rtl_loop_init (void) 169{ 170 if (dump_file) 171 dump_flow_info (dump_file, dump_flags); 172 173 /* Initialize structures for layout changes. */ 174 cfg_layout_initialize (0); 175 176 current_loops = loop_optimizer_init (LOOPS_NORMAL); 177 return 0; 178} 179 180struct tree_opt_pass pass_rtl_loop_init = 181{ 182 "loop2_init", /* name */ 183 NULL, /* gate */ 184 rtl_loop_init, /* execute */ 185 NULL, /* sub */ 186 NULL, /* next */ 187 0, /* static_pass_number */ 188 TV_LOOP, /* tv_id */ 189 0, /* properties_required */ 190 0, /* properties_provided */ 191 0, /* properties_destroyed */ 192 0, /* todo_flags_start */ 193 TODO_dump_func, /* todo_flags_finish */ 194 'L' /* letter */ 195}; 196 197 198/* Finalization of the RTL loop passes. */ 199static unsigned int 200rtl_loop_done (void) 201{ 202 basic_block bb; 203 204 if (current_loops) 205 loop_optimizer_finalize (current_loops); 206 207 free_dominance_info (CDI_DOMINATORS); 208 209 /* Finalize layout changes. */ 210 FOR_EACH_BB (bb) 211 if (bb->next_bb != EXIT_BLOCK_PTR) 212 bb->aux = bb->next_bb; 213 cfg_layout_finalize (); 214 215 cleanup_cfg (CLEANUP_EXPENSIVE); 216 delete_trivially_dead_insns (get_insns (), max_reg_num ()); 217 reg_scan (get_insns (), max_reg_num ()); 218 if (dump_file) 219 dump_flow_info (dump_file, dump_flags); 220 221 current_loops = NULL; 222 return 0; 223} 224 225struct tree_opt_pass pass_rtl_loop_done = 226{ 227 "loop2_done", /* name */ 228 NULL, /* gate */ 229 rtl_loop_done, /* execute */ 230 NULL, /* sub */ 231 NULL, /* next */ 232 0, /* static_pass_number */ 233 TV_LOOP, /* tv_id */ 234 0, /* properties_required */ 235 0, /* properties_provided */ 236 0, /* properties_destroyed */ 237 0, /* todo_flags_start */ 238 TODO_dump_func, /* todo_flags_finish */ 239 'L' /* letter */ 240}; 241 242 243/* Loop invariant code motion. */ 244static bool 245gate_rtl_move_loop_invariants (void) 246{ 247 return flag_move_loop_invariants; 248} 249 250static unsigned int 251rtl_move_loop_invariants (void) 252{ 253 if (current_loops) 254 move_loop_invariants (current_loops); 255 return 0; 256} 257 258struct tree_opt_pass pass_rtl_move_loop_invariants = 259{ 260 "loop2_invariant", /* name */ 261 gate_rtl_move_loop_invariants, /* gate */ 262 rtl_move_loop_invariants, /* execute */ 263 NULL, /* sub */ 264 NULL, /* next */ 265 0, /* static_pass_number */ 266 TV_LOOP, /* tv_id */ 267 0, /* properties_required */ 268 0, /* properties_provided */ 269 0, /* properties_destroyed */ 270 0, /* todo_flags_start */ 271 TODO_dump_func, /* todo_flags_finish */ 272 'L' /* letter */ 273}; 274 275 276/* Loop unswitching for RTL. */ 277static bool 278gate_rtl_unswitch (void) 279{ 280 return flag_unswitch_loops; 281} 282 283static unsigned int 284rtl_unswitch (void) 285{ 286 if (current_loops) 287 unswitch_loops (current_loops); 288 return 0; 289} 290 291struct tree_opt_pass pass_rtl_unswitch = 292{ 293 "loop2_unswitch", /* name */ 294 gate_rtl_unswitch, /* gate */ 295 rtl_unswitch, /* execute */ 296 NULL, /* sub */ 297 NULL, /* next */ 298 0, /* static_pass_number */ 299 TV_LOOP, /* tv_id */ 300 0, /* properties_required */ 301 0, /* properties_provided */ 302 0, /* properties_destroyed */ 303 0, /* todo_flags_start */ 304 TODO_dump_func, /* todo_flags_finish */ 305 'L' /* letter */ 306}; 307 308 309/* Loop unswitching for RTL. */ 310static bool 311gate_rtl_unroll_and_peel_loops (void) 312{ 313 return (flag_peel_loops || flag_unroll_loops || flag_unroll_all_loops); 314} 315 316static unsigned int 317rtl_unroll_and_peel_loops (void) 318{ 319 if (current_loops) 320 { 321 int flags = 0; 322 323 if (flag_peel_loops) 324 flags |= UAP_PEEL; 325 if (flag_unroll_loops) 326 flags |= UAP_UNROLL; 327 if (flag_unroll_all_loops) 328 flags |= UAP_UNROLL_ALL; 329 330 unroll_and_peel_loops (current_loops, flags); 331 } 332 return 0; 333} 334 335struct tree_opt_pass pass_rtl_unroll_and_peel_loops = 336{ 337 "loop2_unroll", /* name */ 338 gate_rtl_unroll_and_peel_loops, /* gate */ 339 rtl_unroll_and_peel_loops, /* execute */ 340 NULL, /* sub */ 341 NULL, /* next */ 342 0, /* static_pass_number */ 343 TV_LOOP, /* tv_id */ 344 0, /* properties_required */ 345 0, /* properties_provided */ 346 0, /* properties_destroyed */ 347 0, /* todo_flags_start */ 348 TODO_dump_func, /* todo_flags_finish */ 349 'L' /* letter */ 350}; 351 352 353/* The doloop optimization. */ 354static bool 355gate_rtl_doloop (void) 356{ 357#ifdef HAVE_doloop_end 358 return (flag_branch_on_count_reg && HAVE_doloop_end); 359#else 360 return 0; 361#endif 362} 363 364static unsigned int 365rtl_doloop (void) 366{ 367#ifdef HAVE_doloop_end 368 if (current_loops) 369 doloop_optimize_loops (current_loops); 370#endif 371 return 0; 372} 373 374struct tree_opt_pass pass_rtl_doloop = 375{ 376 "loop2_doloop", /* name */ 377 gate_rtl_doloop, /* gate */ 378 rtl_doloop, /* execute */ 379 NULL, /* sub */ 380 NULL, /* next */ 381 0, /* static_pass_number */ 382 TV_LOOP, /* tv_id */ 383 0, /* properties_required */ 384 0, /* properties_provided */ 385 0, /* properties_destroyed */ 386 0, /* todo_flags_start */ 387 TODO_dump_func, /* todo_flags_finish */ 388 'L' /* letter */ 389}; 390
|