1 1.1 mrg /* Loop unswitching. 2 1.1 mrg Copyright (C) 2004-2022 Free Software Foundation, Inc. 3 1.1 mrg 4 1.1 mrg This file is part of GCC. 5 1.1 mrg 6 1.1 mrg GCC is free software; you can redistribute it and/or modify it 7 1.1 mrg under the terms of the GNU General Public License as published by the 8 1.1 mrg Free Software Foundation; either version 3, or (at your option) any 9 1.1 mrg later version. 10 1.1 mrg 11 1.1 mrg GCC is distributed in the hope that it will be useful, but WITHOUT 12 1.1 mrg ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 1.1 mrg FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 1.1 mrg for more details. 15 1.1 mrg 16 1.1 mrg You should have received a copy of the GNU General Public License 17 1.1 mrg along with GCC; see the file COPYING3. If not see 18 1.1 mrg <http://www.gnu.org/licenses/>. */ 19 1.1 mrg 20 1.1 mrg #include "config.h" 21 1.1 mrg #include "system.h" 22 1.1 mrg #include "coretypes.h" 23 1.1 mrg #include "backend.h" 24 1.1 mrg #include "tree.h" 25 1.1 mrg #include "gimple.h" 26 1.1 mrg #include "tree-pass.h" 27 1.1 mrg #include "ssa.h" 28 1.1 mrg #include "fold-const.h" 29 1.1 mrg #include "gimplify.h" 30 1.1 mrg #include "tree-cfg.h" 31 1.1 mrg #include "tree-ssa.h" 32 1.1 mrg #include "tree-ssa-loop-niter.h" 33 1.1 mrg #include "tree-ssa-loop.h" 34 1.1 mrg #include "tree-into-ssa.h" 35 1.1 mrg #include "cfgloop.h" 36 1.1 mrg #include "tree-inline.h" 37 1.1 mrg #include "gimple-iterator.h" 38 1.1 mrg #include "cfghooks.h" 39 1.1 mrg #include "tree-ssa-loop-manip.h" 40 1.1 mrg #include "tree-vectorizer.h" 41 1.1 mrg 42 1.1 mrg /* This file implements the loop unswitching, i.e. transformation of loops like 43 1.1 mrg 44 1.1 mrg while (A) 45 1.1 mrg { 46 1.1 mrg if (inv) 47 1.1 mrg B; 48 1.1 mrg 49 1.1 mrg X; 50 1.1 mrg 51 1.1 mrg if (!inv) 52 1.1 mrg C; 53 1.1 mrg } 54 1.1 mrg 55 1.1 mrg where inv is the loop invariant, into 56 1.1 mrg 57 1.1 mrg if (inv) 58 1.1 mrg { 59 1.1 mrg while (A) 60 1.1 mrg { 61 1.1 mrg B; 62 1.1 mrg X; 63 1.1 mrg } 64 1.1 mrg } 65 1.1 mrg else 66 1.1 mrg { 67 1.1 mrg while (A) 68 1.1 mrg { 69 1.1 mrg X; 70 1.1 mrg C; 71 1.1 mrg } 72 1.1 mrg } 73 1.1 mrg 74 1.1 mrg Inv is considered invariant iff the values it compares are both invariant; 75 1.1 mrg tree-ssa-loop-im.cc ensures that all the suitable conditions are in this 76 1.1 mrg shape. */ 77 1.1 mrg 78 1.1 mrg static class loop *tree_unswitch_loop (class loop *, basic_block, tree); 79 1.1 mrg static bool tree_unswitch_single_loop (class loop *, int); 80 1.1 mrg static tree tree_may_unswitch_on (basic_block, class loop *); 81 1.1 mrg static bool tree_unswitch_outer_loop (class loop *); 82 1.1 mrg static edge find_loop_guard (class loop *, vec<gimple *>&); 83 1.1 mrg static bool empty_bb_without_guard_p (class loop *, basic_block, 84 1.1 mrg vec<gimple *>&); 85 1.1 mrg static bool used_outside_loop_p (class loop *, tree, vec<gimple *>&); 86 1.1 mrg static void hoist_guard (class loop *, edge); 87 1.1 mrg static bool check_exit_phi (class loop *); 88 1.1 mrg static tree get_vop_from_header (class loop *); 89 1.1 mrg 90 1.1 mrg /* Main entry point. Perform loop unswitching on all suitable loops. */ 91 1.1 mrg 92 1.1 mrg unsigned int 93 1.1 mrg tree_ssa_unswitch_loops (void) 94 1.1 mrg { 95 1.1 mrg bool changed = false; 96 1.1 mrg 97 1.1 mrg /* Go through all loops starting from innermost. */ 98 1.1 mrg for (auto loop : loops_list (cfun, LI_FROM_INNERMOST)) 99 1.1 mrg { 100 1.1 mrg if (!loop->inner) 101 1.1 mrg /* Unswitch innermost loop. */ 102 1.1 mrg changed |= tree_unswitch_single_loop (loop, 0); 103 1.1 mrg else 104 1.1 mrg changed |= tree_unswitch_outer_loop (loop); 105 1.1 mrg } 106 1.1 mrg 107 1.1 mrg if (changed) 108 1.1 mrg return TODO_cleanup_cfg; 109 1.1 mrg return 0; 110 1.1 mrg } 111 1.1 mrg 112 1.1 mrg /* Return TRUE if an SSA_NAME maybe undefined and is therefore 113 1.1 mrg unsuitable for unswitching. STMT is the statement we are 114 1.1 mrg considering for unswitching and LOOP is the loop it appears in. */ 115 1.1 mrg 116 1.1 mrg static bool 117 1.1 mrg is_maybe_undefined (const tree name, gimple *stmt, class loop *loop) 118 1.1 mrg { 119 1.1 mrg /* The loop header is the only block we can trivially determine that 120 1.1 mrg will always be executed. If the comparison is in the loop 121 1.1 mrg header, we know it's OK to unswitch on it. */ 122 1.1 mrg if (gimple_bb (stmt) == loop->header) 123 1.1 mrg return false; 124 1.1 mrg 125 1.1 mrg auto_bitmap visited_ssa; 126 1.1 mrg auto_vec<tree> worklist; 127 1.1 mrg worklist.safe_push (name); 128 1.1 mrg bitmap_set_bit (visited_ssa, SSA_NAME_VERSION (name)); 129 1.1 mrg while (!worklist.is_empty ()) 130 1.1 mrg { 131 1.1 mrg tree t = worklist.pop (); 132 1.1 mrg 133 1.1 mrg /* If it's obviously undefined, avoid further computations. */ 134 1.1 mrg if (ssa_undefined_value_p (t, true)) 135 1.1 mrg return true; 136 1.1 mrg 137 1.1 mrg if (ssa_defined_default_def_p (t)) 138 1.1 mrg continue; 139 1.1 mrg 140 1.1 mrg gimple *def = SSA_NAME_DEF_STMT (t); 141 1.1 mrg 142 1.1 mrg /* Check that all the PHI args are fully defined. */ 143 1.1 mrg if (gphi *phi = dyn_cast <gphi *> (def)) 144 1.1 mrg { 145 1.1 mrg for (unsigned i = 0; i < gimple_phi_num_args (phi); ++i) 146 1.1 mrg { 147 1.1 mrg tree t = gimple_phi_arg_def (phi, i); 148 1.1 mrg /* If an SSA has already been seen, it may be a loop, 149 1.1 mrg but we can continue and ignore this use. Otherwise, 150 1.1 mrg add the SSA_NAME to the queue and visit it later. */ 151 1.1 mrg if (TREE_CODE (t) == SSA_NAME 152 1.1 mrg && bitmap_set_bit (visited_ssa, SSA_NAME_VERSION (t))) 153 1.1 mrg worklist.safe_push (t); 154 1.1 mrg } 155 1.1 mrg continue; 156 1.1 mrg } 157 1.1 mrg 158 1.1 mrg /* Uses in stmts always executed when the region header executes 159 1.1 mrg are fine. */ 160 1.1 mrg if (dominated_by_p (CDI_DOMINATORS, loop->header, gimple_bb (def))) 161 1.1 mrg continue; 162 1.1 mrg 163 1.1 mrg /* Handle calls and memory loads conservatively. */ 164 1.1 mrg if (!is_gimple_assign (def) 165 1.1 mrg || (gimple_assign_single_p (def) 166 1.1 mrg && gimple_vuse (def))) 167 1.1 mrg return true; 168 1.1 mrg 169 1.1 mrg /* Check that any SSA names used to define NAME are also fully 170 1.1 mrg defined. */ 171 1.1 mrg use_operand_p use_p; 172 1.1 mrg ssa_op_iter iter; 173 1.1 mrg FOR_EACH_SSA_USE_OPERAND (use_p, def, iter, SSA_OP_USE) 174 1.1 mrg { 175 1.1 mrg tree t = USE_FROM_PTR (use_p); 176 1.1 mrg /* If an SSA has already been seen, it may be a loop, 177 1.1 mrg but we can continue and ignore this use. Otherwise, 178 1.1 mrg add the SSA_NAME to the queue and visit it later. */ 179 1.1 mrg if (bitmap_set_bit (visited_ssa, SSA_NAME_VERSION (t))) 180 1.1 mrg worklist.safe_push (t); 181 1.1 mrg } 182 1.1 mrg } 183 1.1 mrg return false; 184 1.1 mrg } 185 1.1 mrg 186 1.1 mrg /* Checks whether we can unswitch LOOP on condition at end of BB -- one of its 187 1.1 mrg basic blocks (for what it means see comments below). */ 188 1.1 mrg 189 1.1 mrg static tree 190 1.1 mrg tree_may_unswitch_on (basic_block bb, class loop *loop) 191 1.1 mrg { 192 1.1 mrg gimple *last, *def; 193 1.1 mrg gcond *stmt; 194 1.1 mrg tree cond, use; 195 1.1 mrg basic_block def_bb; 196 1.1 mrg ssa_op_iter iter; 197 1.1 mrg 198 1.1 mrg /* BB must end in a simple conditional jump. */ 199 1.1 mrg last = last_stmt (bb); 200 1.1 mrg if (!last || gimple_code (last) != GIMPLE_COND) 201 1.1 mrg return NULL_TREE; 202 1.1 mrg stmt = as_a <gcond *> (last); 203 1.1 mrg 204 1.1 mrg /* To keep the things simple, we do not directly remove the conditions, 205 1.1 mrg but just replace tests with 0 != 0 resp. 1 != 0. Prevent the infinite 206 1.1 mrg loop where we would unswitch again on such a condition. */ 207 1.1 mrg if (gimple_cond_true_p (stmt) || gimple_cond_false_p (stmt)) 208 1.1 mrg return NULL_TREE; 209 1.1 mrg 210 1.1 mrg /* Condition must be invariant. */ 211 1.1 mrg FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE) 212 1.1 mrg { 213 1.1 mrg def = SSA_NAME_DEF_STMT (use); 214 1.1 mrg def_bb = gimple_bb (def); 215 1.1 mrg if (def_bb 216 1.1 mrg && flow_bb_inside_loop_p (loop, def_bb)) 217 1.1 mrg return NULL_TREE; 218 1.1 mrg /* Unswitching on undefined values would introduce undefined 219 1.1 mrg behavior that the original program might never exercise. */ 220 1.1 mrg if (is_maybe_undefined (use, stmt, loop)) 221 1.1 mrg return NULL_TREE; 222 1.1 mrg } 223 1.1 mrg 224 1.1 mrg cond = build2 (gimple_cond_code (stmt), boolean_type_node, 225 1.1 mrg gimple_cond_lhs (stmt), gimple_cond_rhs (stmt)); 226 1.1 mrg 227 1.1 mrg return cond; 228 1.1 mrg } 229 1.1 mrg 230 1.1 mrg /* Simplifies COND using checks in front of the entry of the LOOP. Just very 231 1.1 mrg simplish (sufficient to prevent us from duplicating loop in unswitching 232 1.1 mrg unnecessarily). */ 233 1.1 mrg 234 1.1 mrg static tree 235 1.1 mrg simplify_using_entry_checks (class loop *loop, tree cond) 236 1.1 mrg { 237 1.1 mrg edge e = loop_preheader_edge (loop); 238 1.1 mrg gimple *stmt; 239 1.1 mrg 240 1.1 mrg while (1) 241 1.1 mrg { 242 1.1 mrg stmt = last_stmt (e->src); 243 1.1 mrg if (stmt 244 1.1 mrg && gimple_code (stmt) == GIMPLE_COND 245 1.1 mrg && gimple_cond_code (stmt) == TREE_CODE (cond) 246 1.1 mrg && operand_equal_p (gimple_cond_lhs (stmt), 247 1.1 mrg TREE_OPERAND (cond, 0), 0) 248 1.1 mrg && operand_equal_p (gimple_cond_rhs (stmt), 249 1.1 mrg TREE_OPERAND (cond, 1), 0)) 250 1.1 mrg return (e->flags & EDGE_TRUE_VALUE 251 1.1 mrg ? boolean_true_node 252 1.1 mrg : boolean_false_node); 253 1.1 mrg 254 1.1 mrg if (!single_pred_p (e->src)) 255 1.1 mrg return cond; 256 1.1 mrg 257 1.1 mrg e = single_pred_edge (e->src); 258 1.1 mrg if (e->src == ENTRY_BLOCK_PTR_FOR_FN (cfun)) 259 1.1 mrg return cond; 260 1.1 mrg } 261 1.1 mrg } 262 1.1 mrg 263 1.1 mrg /* Unswitch single LOOP. NUM is number of unswitchings done; we do not allow 264 1.1 mrg it to grow too much, it is too easy to create example on that the code would 265 1.1 mrg grow exponentially. */ 266 1.1 mrg 267 1.1 mrg static bool 268 1.1 mrg tree_unswitch_single_loop (class loop *loop, int num) 269 1.1 mrg { 270 1.1 mrg basic_block *bbs; 271 1.1 mrg class loop *nloop; 272 1.1 mrg unsigned i, found; 273 1.1 mrg tree cond = NULL_TREE; 274 1.1 mrg gimple *stmt; 275 1.1 mrg bool changed = false; 276 1.1 mrg HOST_WIDE_INT iterations; 277 1.1 mrg 278 1.1 mrg dump_user_location_t loc = find_loop_location (loop); 279 1.1 mrg 280 1.1 mrg /* Perform initial tests if unswitch is eligible. */ 281 1.1 mrg if (num == 0) 282 1.1 mrg { 283 1.1 mrg /* Do not unswitch in cold regions. */ 284 1.1 mrg if (optimize_loop_for_size_p (loop)) 285 1.1 mrg { 286 1.1 mrg if (dump_enabled_p ()) 287 1.1 mrg dump_printf_loc (MSG_NOTE, loc, 288 1.1 mrg "Not unswitching cold loops\n"); 289 1.1 mrg return false; 290 1.1 mrg } 291 1.1 mrg 292 1.1 mrg /* The loop should not be too large, to limit code growth. */ 293 1.1 mrg if (tree_num_loop_insns (loop, &eni_size_weights) 294 1.1 mrg > (unsigned) param_max_unswitch_insns) 295 1.1 mrg { 296 1.1 mrg if (dump_enabled_p ()) 297 1.1 mrg dump_printf_loc (MSG_NOTE, loc, 298 1.1 mrg "Not unswitching, loop too big\n"); 299 1.1 mrg return false; 300 1.1 mrg } 301 1.1 mrg 302 1.1 mrg /* If the loop is not expected to iterate, there is no need 303 1.1 mrg for unswitching. */ 304 1.1 mrg iterations = estimated_loop_iterations_int (loop); 305 1.1 mrg if (iterations < 0) 306 1.1 mrg iterations = likely_max_loop_iterations_int (loop); 307 1.1 mrg if (iterations >= 0 && iterations <= 1) 308 1.1 mrg { 309 1.1 mrg if (dump_enabled_p ()) 310 1.1 mrg dump_printf_loc (MSG_NOTE, loc, 311 1.1 mrg "Not unswitching, loop is not expected" 312 1.1 mrg " to iterate\n"); 313 1.1 mrg return false; 314 1.1 mrg } 315 1.1 mrg } 316 1.1 mrg 317 1.1 mrg i = 0; 318 1.1 mrg bbs = get_loop_body (loop); 319 1.1 mrg found = loop->num_nodes; 320 1.1 mrg 321 1.1 mrg while (1) 322 1.1 mrg { 323 1.1 mrg /* Find a bb to unswitch on. */ 324 1.1 mrg for (; i < loop->num_nodes; i++) 325 1.1 mrg if ((cond = tree_may_unswitch_on (bbs[i], loop))) 326 1.1 mrg break; 327 1.1 mrg 328 1.1 mrg if (i == loop->num_nodes) 329 1.1 mrg { 330 1.1 mrg if (dump_enabled_p () 331 1.1 mrg && num > param_max_unswitch_level) 332 1.1 mrg dump_printf_loc (MSG_MISSED_OPTIMIZATION, loc, 333 1.1 mrg "Not unswitching anymore, hit max level\n"); 334 1.1 mrg 335 1.1 mrg if (found == loop->num_nodes) 336 1.1 mrg { 337 1.1 mrg free (bbs); 338 1.1 mrg return changed; 339 1.1 mrg } 340 1.1 mrg break; 341 1.1 mrg } 342 1.1 mrg 343 1.1 mrg cond = simplify_using_entry_checks (loop, cond); 344 1.1 mrg stmt = last_stmt (bbs[i]); 345 1.1 mrg if (integer_nonzerop (cond)) 346 1.1 mrg { 347 1.1 mrg /* Remove false path. */ 348 1.1 mrg gimple_cond_set_condition_from_tree (as_a <gcond *> (stmt), 349 1.1 mrg boolean_true_node); 350 1.1 mrg changed = true; 351 1.1 mrg } 352 1.1 mrg else if (integer_zerop (cond)) 353 1.1 mrg { 354 1.1 mrg /* Remove true path. */ 355 1.1 mrg gimple_cond_set_condition_from_tree (as_a <gcond *> (stmt), 356 1.1 mrg boolean_false_node); 357 1.1 mrg changed = true; 358 1.1 mrg } 359 1.1 mrg /* Do not unswitch too much. */ 360 1.1 mrg else if (num > param_max_unswitch_level) 361 1.1 mrg { 362 1.1 mrg i++; 363 1.1 mrg continue; 364 1.1 mrg } 365 1.1 mrg /* In nested tree_unswitch_single_loop first optimize all conditions 366 1.1 mrg using entry checks, then discover still reachable blocks in the 367 1.1 mrg loop and find the condition only among those still reachable bbs. */ 368 1.1 mrg else if (num != 0) 369 1.1 mrg { 370 1.1 mrg if (found == loop->num_nodes) 371 1.1 mrg found = i; 372 1.1 mrg i++; 373 1.1 mrg continue; 374 1.1 mrg } 375 1.1 mrg else 376 1.1 mrg { 377 1.1 mrg found = i; 378 1.1 mrg break; 379 1.1 mrg } 380 1.1 mrg 381 1.1 mrg update_stmt (stmt); 382 1.1 mrg i++; 383 1.1 mrg } 384 1.1 mrg 385 1.1 mrg if (num != 0) 386 1.1 mrg { 387 1.1 mrg basic_block *tos, *worklist; 388 1.1 mrg 389 1.1 mrg /* When called recursively, first do a quick discovery 390 1.1 mrg of reachable bbs after the above changes and only 391 1.1 mrg consider conditions in still reachable bbs. */ 392 1.1 mrg tos = worklist = XNEWVEC (basic_block, loop->num_nodes); 393 1.1 mrg 394 1.1 mrg for (i = 0; i < loop->num_nodes; i++) 395 1.1 mrg bbs[i]->flags &= ~BB_REACHABLE; 396 1.1 mrg 397 1.1 mrg /* Start with marking header. */ 398 1.1 mrg *tos++ = bbs[0]; 399 1.1 mrg bbs[0]->flags |= BB_REACHABLE; 400 1.1 mrg 401 1.1 mrg /* Iterate: find everything reachable from what we've already seen 402 1.1 mrg within the same innermost loop. Don't look through false edges 403 1.1 mrg if condition is always true or true edges if condition is 404 1.1 mrg always false. */ 405 1.1 mrg while (tos != worklist) 406 1.1 mrg { 407 1.1 mrg basic_block b = *--tos; 408 1.1 mrg edge e; 409 1.1 mrg edge_iterator ei; 410 1.1 mrg int flags = 0; 411 1.1 mrg 412 1.1 mrg if (EDGE_COUNT (b->succs) == 2) 413 1.1 mrg { 414 1.1 mrg gimple *stmt = last_stmt (b); 415 1.1 mrg if (stmt 416 1.1 mrg && gimple_code (stmt) == GIMPLE_COND) 417 1.1 mrg { 418 1.1 mrg gcond *cond_stmt = as_a <gcond *> (stmt); 419 1.1 mrg if (gimple_cond_true_p (cond_stmt)) 420 1.1 mrg flags = EDGE_FALSE_VALUE; 421 1.1 mrg else if (gimple_cond_false_p (cond_stmt)) 422 1.1 mrg flags = EDGE_TRUE_VALUE; 423 1.1 mrg } 424 1.1 mrg } 425 1.1 mrg 426 1.1 mrg FOR_EACH_EDGE (e, ei, b->succs) 427 1.1 mrg { 428 1.1 mrg basic_block dest = e->dest; 429 1.1 mrg 430 1.1 mrg if (dest->loop_father == loop 431 1.1 mrg && !(dest->flags & BB_REACHABLE) 432 1.1 mrg && !(e->flags & flags)) 433 1.1 mrg { 434 1.1 mrg *tos++ = dest; 435 1.1 mrg dest->flags |= BB_REACHABLE; 436 1.1 mrg } 437 1.1 mrg } 438 1.1 mrg } 439 1.1 mrg 440 1.1 mrg free (worklist); 441 1.1 mrg 442 1.1 mrg /* Find a bb to unswitch on. */ 443 1.1 mrg for (; found < loop->num_nodes; found++) 444 1.1 mrg if ((bbs[found]->flags & BB_REACHABLE) 445 1.1 mrg && (cond = tree_may_unswitch_on (bbs[found], loop))) 446 1.1 mrg break; 447 1.1 mrg 448 1.1 mrg if (found == loop->num_nodes) 449 1.1 mrg { 450 1.1 mrg free (bbs); 451 1.1 mrg return changed; 452 1.1 mrg } 453 1.1 mrg } 454 1.1 mrg 455 1.1 mrg if (dump_enabled_p ()) 456 1.1 mrg dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc, 457 1.1 mrg "Unswitching loop on condition: %G\n", 458 1.1 mrg last_stmt (bbs[found])); 459 1.1 mrg 460 1.1 mrg initialize_original_copy_tables (); 461 1.1 mrg /* Unswitch the loop on this condition. */ 462 1.1 mrg nloop = tree_unswitch_loop (loop, bbs[found], cond); 463 1.1 mrg if (!nloop) 464 1.1 mrg { 465 1.1 mrg free_original_copy_tables (); 466 1.1 mrg free (bbs); 467 1.1 mrg return changed; 468 1.1 mrg } 469 1.1 mrg 470 1.1 mrg /* Update the SSA form after unswitching. */ 471 1.1 mrg update_ssa (TODO_update_ssa); 472 1.1 mrg free_original_copy_tables (); 473 1.1 mrg 474 1.1 mrg /* Invoke itself on modified loops. */ 475 1.1 mrg tree_unswitch_single_loop (nloop, num + 1); 476 1.1 mrg tree_unswitch_single_loop (loop, num + 1); 477 1.1 mrg free (bbs); 478 1.1 mrg return true; 479 1.1 mrg } 480 1.1 mrg 481 1.1 mrg /* Unswitch a LOOP w.r. to given basic block UNSWITCH_ON. We only support 482 1.1 mrg unswitching of innermost loops. COND is the condition determining which 483 1.1 mrg loop is entered -- the new loop is entered if COND is true. Returns NULL 484 1.1 mrg if impossible, new loop otherwise. */ 485 1.1 mrg 486 1.1 mrg static class loop * 487 1.1 mrg tree_unswitch_loop (class loop *loop, 488 1.1 mrg basic_block unswitch_on, tree cond) 489 1.1 mrg { 490 1.1 mrg profile_probability prob_true; 491 1.1 mrg edge edge_true, edge_false; 492 1.1 mrg 493 1.1 mrg /* Some sanity checking. */ 494 1.1 mrg gcc_assert (flow_bb_inside_loop_p (loop, unswitch_on)); 495 1.1 mrg gcc_assert (EDGE_COUNT (unswitch_on->succs) == 2); 496 1.1 mrg gcc_assert (loop->inner == NULL); 497 1.1 mrg 498 1.1 mrg extract_true_false_edges_from_block (unswitch_on, &edge_true, &edge_false); 499 1.1 mrg prob_true = edge_true->probability; 500 1.1 mrg return loop_version (loop, unshare_expr (cond), 501 1.1 mrg NULL, prob_true, 502 1.1 mrg prob_true.invert (), 503 1.1 mrg prob_true, prob_true.invert (), 504 1.1 mrg false); 505 1.1 mrg } 506 1.1 mrg 507 1.1 mrg /* Unswitch outer loops by hoisting invariant guard on 508 1.1 mrg inner loop without code duplication. */ 509 1.1 mrg static bool 510 1.1 mrg tree_unswitch_outer_loop (class loop *loop) 511 1.1 mrg { 512 1.1 mrg edge exit, guard; 513 1.1 mrg HOST_WIDE_INT iterations; 514 1.1 mrg 515 1.1 mrg gcc_assert (loop->inner); 516 1.1 mrg if (loop->inner->next) 517 1.1 mrg return false; 518 1.1 mrg /* Accept loops with single exit only which is not from inner loop. */ 519 1.1 mrg exit = single_exit (loop); 520 1.1 mrg if (!exit || exit->src->loop_father != loop) 521 1.1 mrg return false; 522 1.1 mrg /* Check that phi argument of exit edge is not defined inside loop. */ 523 1.1 mrg if (!check_exit_phi (loop)) 524 1.1 mrg return false; 525 1.1 mrg /* If the loop is not expected to iterate, there is no need 526 1.1 mrg for unswitching. */ 527 1.1 mrg iterations = estimated_loop_iterations_int (loop); 528 1.1 mrg if (iterations < 0) 529 1.1 mrg iterations = likely_max_loop_iterations_int (loop); 530 1.1 mrg if (iterations >= 0 && iterations <= 1) 531 1.1 mrg { 532 1.1 mrg if (dump_enabled_p ()) 533 1.1 mrg dump_printf_loc (MSG_MISSED_OPTIMIZATION, find_loop_location (loop), 534 1.1 mrg "Not unswitching, loop is not expected" 535 1.1 mrg " to iterate\n"); 536 1.1 mrg return false; 537 1.1 mrg } 538 1.1 mrg 539 1.1 mrg bool changed = false; 540 1.1 mrg auto_vec<gimple *> dbg_to_reset; 541 1.1 mrg while ((guard = find_loop_guard (loop, dbg_to_reset))) 542 1.1 mrg { 543 1.1 mrg if (! changed) 544 1.1 mrg rewrite_virtuals_into_loop_closed_ssa (loop); 545 1.1 mrg hoist_guard (loop, guard); 546 1.1 mrg for (gimple *debug_stmt : dbg_to_reset) 547 1.1 mrg { 548 1.1 mrg gimple_debug_bind_reset_value (debug_stmt); 549 1.1 mrg update_stmt (debug_stmt); 550 1.1 mrg } 551 1.1 mrg dbg_to_reset.truncate (0); 552 1.1 mrg changed = true; 553 1.1 mrg } 554 1.1 mrg return changed; 555 1.1 mrg } 556 1.1 mrg 557 1.1 mrg /* Checks if the body of the LOOP is within an invariant guard. If this 558 1.1 mrg is the case, returns the edge that jumps over the real body of the loop, 559 1.1 mrg otherwise returns NULL. */ 560 1.1 mrg 561 1.1 mrg static edge 562 1.1 mrg find_loop_guard (class loop *loop, vec<gimple *> &dbg_to_reset) 563 1.1 mrg { 564 1.1 mrg basic_block header = loop->header; 565 1.1 mrg edge guard_edge, te, fe; 566 1.1 mrg basic_block *body = NULL; 567 1.1 mrg unsigned i; 568 1.1 mrg tree use; 569 1.1 mrg ssa_op_iter iter; 570 1.1 mrg 571 1.1 mrg /* We check for the following situation: 572 1.1 mrg 573 1.1 mrg while (1) 574 1.1 mrg { 575 1.1 mrg [header]] 576 1.1 mrg loop_phi_nodes; 577 1.1 mrg something1; 578 1.1 mrg if (cond1) 579 1.1 mrg body; 580 1.1 mrg nvar = phi(orig, bvar) ... for all variables changed in body; 581 1.1 mrg [guard_end] 582 1.1 mrg something2; 583 1.1 mrg if (cond2) 584 1.1 mrg break; 585 1.1 mrg something3; 586 1.1 mrg } 587 1.1 mrg 588 1.1 mrg where: 589 1.1 mrg 590 1.1 mrg 1) cond1 is loop invariant 591 1.1 mrg 2) If cond1 is false, then the loop is essentially empty; i.e., 592 1.1 mrg a) nothing in something1, something2 and something3 has side 593 1.1 mrg effects 594 1.1 mrg b) anything defined in something1, something2 and something3 595 1.1 mrg is not used outside of the loop. */ 596 1.1 mrg 597 1.1 mrg gcond *cond; 598 1.1 mrg do 599 1.1 mrg { 600 1.1 mrg basic_block next = NULL; 601 1.1 mrg if (single_succ_p (header)) 602 1.1 mrg next = single_succ (header); 603 1.1 mrg else 604 1.1 mrg { 605 1.1 mrg cond = safe_dyn_cast <gcond *> (last_stmt (header)); 606 1.1 mrg if (! cond) 607 1.1 mrg return NULL; 608 1.1 mrg extract_true_false_edges_from_block (header, &te, &fe); 609 1.1 mrg /* Make sure to skip earlier hoisted guards that are left 610 1.1 mrg in place as if (true). */ 611 1.1 mrg if (gimple_cond_true_p (cond)) 612 1.1 mrg next = te->dest; 613 1.1 mrg else if (gimple_cond_false_p (cond)) 614 1.1 mrg next = fe->dest; 615 1.1 mrg else 616 1.1 mrg break; 617 1.1 mrg } 618 1.1 mrg /* Never traverse a backedge. */ 619 1.1 mrg if (header->loop_father->header == next) 620 1.1 mrg return NULL; 621 1.1 mrg header = next; 622 1.1 mrg } 623 1.1 mrg while (1); 624 1.1 mrg if (!flow_bb_inside_loop_p (loop, te->dest) 625 1.1 mrg || !flow_bb_inside_loop_p (loop, fe->dest)) 626 1.1 mrg return NULL; 627 1.1 mrg 628 1.1 mrg if (just_once_each_iteration_p (loop, te->dest) 629 1.1 mrg || (single_succ_p (te->dest) 630 1.1 mrg && just_once_each_iteration_p (loop, single_succ (te->dest)))) 631 1.1 mrg { 632 1.1 mrg if (just_once_each_iteration_p (loop, fe->dest)) 633 1.1 mrg return NULL; 634 1.1 mrg guard_edge = te; 635 1.1 mrg } 636 1.1 mrg else if (just_once_each_iteration_p (loop, fe->dest) 637 1.1 mrg || (single_succ_p (fe->dest) 638 1.1 mrg && just_once_each_iteration_p (loop, single_succ (fe->dest)))) 639 1.1 mrg guard_edge = fe; 640 1.1 mrg else 641 1.1 mrg return NULL; 642 1.1 mrg 643 1.1 mrg dump_user_location_t loc = find_loop_location (loop); 644 1.1 mrg 645 1.1 mrg /* Guard edge must skip inner loop. */ 646 1.1 mrg if (!dominated_by_p (CDI_DOMINATORS, loop->inner->header, 647 1.1 mrg guard_edge == fe ? te->dest : fe->dest)) 648 1.1 mrg { 649 1.1 mrg if (dump_enabled_p ()) 650 1.1 mrg dump_printf_loc (MSG_MISSED_OPTIMIZATION, loc, 651 1.1 mrg "Guard edge %d --> %d is not around the loop!\n", 652 1.1 mrg guard_edge->src->index, guard_edge->dest->index); 653 1.1 mrg return NULL; 654 1.1 mrg } 655 1.1 mrg if (guard_edge->dest == loop->latch) 656 1.1 mrg { 657 1.1 mrg if (dump_enabled_p ()) 658 1.1 mrg dump_printf_loc (MSG_MISSED_OPTIMIZATION, loc, 659 1.1 mrg "Guard edge destination is loop latch.\n"); 660 1.1 mrg return NULL; 661 1.1 mrg } 662 1.1 mrg 663 1.1 mrg if (dump_enabled_p ()) 664 1.1 mrg dump_printf_loc (MSG_NOTE, loc, 665 1.1 mrg "Considering guard %d -> %d in loop %d\n", 666 1.1 mrg guard_edge->src->index, guard_edge->dest->index, 667 1.1 mrg loop->num); 668 1.1 mrg /* Check if condition operands do not have definitions inside loop since 669 1.1 mrg any bb copying is not performed. */ 670 1.1 mrg FOR_EACH_SSA_TREE_OPERAND (use, cond, iter, SSA_OP_USE) 671 1.1 mrg { 672 1.1 mrg gimple *def = SSA_NAME_DEF_STMT (use); 673 1.1 mrg basic_block def_bb = gimple_bb (def); 674 1.1 mrg if (def_bb 675 1.1 mrg && flow_bb_inside_loop_p (loop, def_bb)) 676 1.1 mrg { 677 1.1 mrg if (dump_enabled_p ()) 678 1.1 mrg dump_printf_loc (MSG_NOTE, loc, "guard operands have definitions" 679 1.1 mrg " inside loop\n"); 680 1.1 mrg return NULL; 681 1.1 mrg } 682 1.1 mrg } 683 1.1 mrg 684 1.1 mrg body = get_loop_body (loop); 685 1.1 mrg for (i = 0; i < loop->num_nodes; i++) 686 1.1 mrg { 687 1.1 mrg basic_block bb = body[i]; 688 1.1 mrg if (bb->loop_father != loop) 689 1.1 mrg continue; 690 1.1 mrg if (bb->flags & BB_IRREDUCIBLE_LOOP) 691 1.1 mrg { 692 1.1 mrg if (dump_enabled_p ()) 693 1.1 mrg dump_printf_loc (MSG_MISSED_OPTIMIZATION, loc, 694 1.1 mrg "Block %d is marked as irreducible in loop\n", 695 1.1 mrg bb->index); 696 1.1 mrg guard_edge = NULL; 697 1.1 mrg goto end; 698 1.1 mrg } 699 1.1 mrg if (!empty_bb_without_guard_p (loop, bb, dbg_to_reset)) 700 1.1 mrg { 701 1.1 mrg if (dump_enabled_p ()) 702 1.1 mrg dump_printf_loc (MSG_MISSED_OPTIMIZATION, loc, 703 1.1 mrg "Block %d has side effects\n", bb->index); 704 1.1 mrg guard_edge = NULL; 705 1.1 mrg goto end; 706 1.1 mrg } 707 1.1 mrg } 708 1.1 mrg 709 1.1 mrg if (dump_enabled_p ()) 710 1.1 mrg dump_printf_loc (MSG_NOTE, loc, 711 1.1 mrg "suitable to hoist\n"); 712 1.1 mrg end: 713 1.1 mrg if (body) 714 1.1 mrg free (body); 715 1.1 mrg return guard_edge; 716 1.1 mrg } 717 1.1 mrg 718 1.1 mrg /* Returns true if 719 1.1 mrg 1) no statement in BB has side effects 720 1.1 mrg 2) assuming that edge GUARD is always taken, all definitions in BB 721 1.1 mrg are noy used outside of the loop. 722 1.1 mrg KNOWN_INVARIANTS is a set of ssa names we know to be invariant, and 723 1.1 mrg PROCESSED is a set of ssa names for that we already tested whether they 724 1.1 mrg are invariant or not. Uses in debug stmts outside of the loop are 725 1.1 mrg pushed to DBG_TO_RESET. */ 726 1.1 mrg 727 1.1 mrg static bool 728 1.1 mrg empty_bb_without_guard_p (class loop *loop, basic_block bb, 729 1.1 mrg vec<gimple *> &dbg_to_reset) 730 1.1 mrg { 731 1.1 mrg basic_block exit_bb = single_exit (loop)->src; 732 1.1 mrg bool may_be_used_outside = (bb == exit_bb 733 1.1 mrg || !dominated_by_p (CDI_DOMINATORS, bb, exit_bb)); 734 1.1 mrg tree name; 735 1.1 mrg ssa_op_iter op_iter; 736 1.1 mrg 737 1.1 mrg /* Phi nodes do not have side effects, but their results might be used 738 1.1 mrg outside of the loop. */ 739 1.1 mrg if (may_be_used_outside) 740 1.1 mrg { 741 1.1 mrg for (gphi_iterator gsi = gsi_start_phis (bb); 742 1.1 mrg !gsi_end_p (gsi); gsi_next (&gsi)) 743 1.1 mrg { 744 1.1 mrg gphi *phi = gsi.phi (); 745 1.1 mrg name = PHI_RESULT (phi); 746 1.1 mrg if (virtual_operand_p (name)) 747 1.1 mrg continue; 748 1.1 mrg 749 1.1 mrg if (used_outside_loop_p (loop, name, dbg_to_reset)) 750 1.1 mrg return false; 751 1.1 mrg } 752 1.1 mrg } 753 1.1 mrg 754 1.1 mrg for (gimple_stmt_iterator gsi = gsi_start_bb (bb); 755 1.1 mrg !gsi_end_p (gsi); gsi_next (&gsi)) 756 1.1 mrg { 757 1.1 mrg gimple *stmt = gsi_stmt (gsi); 758 1.1 mrg if (is_gimple_debug (stmt)) 759 1.1 mrg continue; 760 1.1 mrg 761 1.1 mrg if (gimple_has_side_effects (stmt)) 762 1.1 mrg return false; 763 1.1 mrg 764 1.1 mrg if (gimple_vdef(stmt)) 765 1.1 mrg return false; 766 1.1 mrg 767 1.1 mrg FOR_EACH_SSA_TREE_OPERAND (name, stmt, op_iter, SSA_OP_DEF) 768 1.1 mrg { 769 1.1 mrg if (may_be_used_outside 770 1.1 mrg && used_outside_loop_p (loop, name, dbg_to_reset)) 771 1.1 mrg return false; 772 1.1 mrg } 773 1.1 mrg } 774 1.1 mrg return true; 775 1.1 mrg } 776 1.1 mrg 777 1.1 mrg /* Return true if NAME is used outside of LOOP. Pushes debug stmts that 778 1.1 mrg have such uses to DBG_TO_RESET but do not consider such uses. */ 779 1.1 mrg 780 1.1 mrg static bool 781 1.1 mrg used_outside_loop_p (class loop *loop, tree name, vec<gimple *> &dbg_to_reset) 782 1.1 mrg { 783 1.1 mrg imm_use_iterator it; 784 1.1 mrg use_operand_p use; 785 1.1 mrg 786 1.1 mrg FOR_EACH_IMM_USE_FAST (use, it, name) 787 1.1 mrg { 788 1.1 mrg gimple *stmt = USE_STMT (use); 789 1.1 mrg if (!flow_bb_inside_loop_p (loop, gimple_bb (stmt))) 790 1.1 mrg { 791 1.1 mrg if (!is_gimple_debug (stmt)) 792 1.1 mrg return true; 793 1.1 mrg dbg_to_reset.safe_push (stmt); 794 1.1 mrg } 795 1.1 mrg } 796 1.1 mrg 797 1.1 mrg return false; 798 1.1 mrg } 799 1.1 mrg 800 1.1 mrg /* Return argument for loop preheader edge in header virtual phi if any. */ 801 1.1 mrg 802 1.1 mrg static tree 803 1.1 mrg get_vop_from_header (class loop *loop) 804 1.1 mrg { 805 1.1 mrg for (gphi_iterator gsi = gsi_start_phis (loop->header); 806 1.1 mrg !gsi_end_p (gsi); gsi_next (&gsi)) 807 1.1 mrg { 808 1.1 mrg gphi *phi = gsi.phi (); 809 1.1 mrg if (!virtual_operand_p (gimple_phi_result (phi))) 810 1.1 mrg continue; 811 1.1 mrg return PHI_ARG_DEF_FROM_EDGE (phi, loop_preheader_edge (loop)); 812 1.1 mrg } 813 1.1 mrg return NULL_TREE; 814 1.1 mrg } 815 1.1 mrg 816 1.1 mrg /* Move the check of GUARD outside of LOOP. */ 817 1.1 mrg 818 1.1 mrg static void 819 1.1 mrg hoist_guard (class loop *loop, edge guard) 820 1.1 mrg { 821 1.1 mrg edge exit = single_exit (loop); 822 1.1 mrg edge preh = loop_preheader_edge (loop); 823 1.1 mrg basic_block pre_header = preh->src; 824 1.1 mrg basic_block bb; 825 1.1 mrg edge te, fe, e, new_edge; 826 1.1 mrg gimple *stmt; 827 1.1 mrg basic_block guard_bb = guard->src; 828 1.1 mrg edge not_guard; 829 1.1 mrg gimple_stmt_iterator gsi; 830 1.1 mrg int flags = 0; 831 1.1 mrg bool fix_dom_of_exit; 832 1.1 mrg gcond *cond_stmt, *new_cond_stmt; 833 1.1 mrg 834 1.1 mrg bb = get_immediate_dominator (CDI_DOMINATORS, exit->dest); 835 1.1 mrg fix_dom_of_exit = flow_bb_inside_loop_p (loop, bb); 836 1.1 mrg gsi = gsi_last_bb (guard_bb); 837 1.1 mrg stmt = gsi_stmt (gsi); 838 1.1 mrg gcc_assert (gimple_code (stmt) == GIMPLE_COND); 839 1.1 mrg cond_stmt = as_a <gcond *> (stmt); 840 1.1 mrg extract_true_false_edges_from_block (guard_bb, &te, &fe); 841 1.1 mrg /* Insert guard to PRE_HEADER. */ 842 1.1 mrg gsi = gsi_last_bb (pre_header); 843 1.1 mrg /* Create copy of COND_STMT. */ 844 1.1 mrg new_cond_stmt = gimple_build_cond (gimple_cond_code (cond_stmt), 845 1.1 mrg gimple_cond_lhs (cond_stmt), 846 1.1 mrg gimple_cond_rhs (cond_stmt), 847 1.1 mrg NULL_TREE, NULL_TREE); 848 1.1 mrg gsi_insert_after (&gsi, new_cond_stmt, GSI_NEW_STMT); 849 1.1 mrg /* Convert COND_STMT to true/false conditional. */ 850 1.1 mrg if (guard == te) 851 1.1 mrg gimple_cond_make_false (cond_stmt); 852 1.1 mrg else 853 1.1 mrg gimple_cond_make_true (cond_stmt); 854 1.1 mrg update_stmt (cond_stmt); 855 1.1 mrg /* Create new loop pre-header. */ 856 1.1 mrg e = split_block (pre_header, last_stmt (pre_header)); 857 1.1 mrg 858 1.1 mrg dump_user_location_t loc = find_loop_location (loop); 859 1.1 mrg 860 1.1 mrg if (dump_enabled_p ()) 861 1.1 mrg { 862 1.1 mrg char buffer[64]; 863 1.1 mrg guard->probability.dump (buffer); 864 1.1 mrg 865 1.1 mrg dump_printf_loc (MSG_NOTE, loc, 866 1.1 mrg "Moving guard %i->%i (prob %s) to bb %i, " 867 1.1 mrg "new preheader is %i\n", 868 1.1 mrg guard->src->index, guard->dest->index, 869 1.1 mrg buffer, e->src->index, e->dest->index); 870 1.1 mrg } 871 1.1 mrg 872 1.1 mrg gcc_assert (loop_preheader_edge (loop)->src == e->dest); 873 1.1 mrg 874 1.1 mrg if (guard == fe) 875 1.1 mrg { 876 1.1 mrg e->flags = EDGE_TRUE_VALUE; 877 1.1 mrg flags |= EDGE_FALSE_VALUE; 878 1.1 mrg not_guard = te; 879 1.1 mrg } 880 1.1 mrg else 881 1.1 mrg { 882 1.1 mrg e->flags = EDGE_FALSE_VALUE; 883 1.1 mrg flags |= EDGE_TRUE_VALUE; 884 1.1 mrg not_guard = fe; 885 1.1 mrg } 886 1.1 mrg new_edge = make_edge (pre_header, exit->dest, flags); 887 1.1 mrg 888 1.1 mrg /* Determine the probability that we skip the loop. Assume that loop has 889 1.1 mrg same average number of iterations regardless outcome of guard. */ 890 1.1 mrg new_edge->probability = guard->probability; 891 1.1 mrg profile_count skip_count = guard->src->count.nonzero_p () 892 1.1 mrg ? guard->count ().apply_scale (pre_header->count, 893 1.1 mrg guard->src->count) 894 1.1 mrg : guard->count ().apply_probability (new_edge->probability); 895 1.1 mrg 896 1.1 mrg if (skip_count > e->count ()) 897 1.1 mrg { 898 1.1 mrg fprintf (dump_file, " Capping count; expect profile inconsistency\n"); 899 1.1 mrg skip_count = e->count (); 900 1.1 mrg } 901 1.1 mrg if (dump_enabled_p ()) 902 1.1 mrg { 903 1.1 mrg char buffer[64]; 904 1.1 mrg new_edge->probability.dump (buffer); 905 1.1 mrg 906 1.1 mrg dump_printf_loc (MSG_NOTE, loc, 907 1.1 mrg "Estimated probability of skipping loop is %s\n", 908 1.1 mrg buffer); 909 1.1 mrg } 910 1.1 mrg 911 1.1 mrg /* Update profile after the transform: 912 1.1 mrg 913 1.1 mrg First decrease count of path from newly hoisted loop guard 914 1.1 mrg to loop header... */ 915 1.1 mrg e->probability = new_edge->probability.invert (); 916 1.1 mrg e->dest->count = e->count (); 917 1.1 mrg 918 1.1 mrg /* ... now update profile to represent that original guard will be optimized 919 1.1 mrg away ... */ 920 1.1 mrg guard->probability = profile_probability::never (); 921 1.1 mrg not_guard->probability = profile_probability::always (); 922 1.1 mrg 923 1.1 mrg /* ... finally scale everything in the loop except for guarded basic blocks 924 1.1 mrg where profile does not change. */ 925 1.1 mrg basic_block *body = get_loop_body (loop); 926 1.1 mrg 927 1.1 mrg for (unsigned int i = 0; i < loop->num_nodes; i++) 928 1.1 mrg { 929 1.1 mrg basic_block bb = body[i]; 930 1.1 mrg if (!dominated_by_p (CDI_DOMINATORS, bb, not_guard->dest)) 931 1.1 mrg { 932 1.1 mrg if (dump_enabled_p ()) 933 1.1 mrg dump_printf_loc (MSG_NOTE, loc, 934 1.1 mrg "Scaling nonguarded BBs in loop: %i\n", 935 1.1 mrg bb->index); 936 1.1 mrg if (e->probability.initialized_p ()) 937 1.1 mrg scale_bbs_frequencies (&bb, 1, e->probability); 938 1.1 mrg } 939 1.1 mrg } 940 1.1 mrg 941 1.1 mrg if (fix_dom_of_exit) 942 1.1 mrg set_immediate_dominator (CDI_DOMINATORS, exit->dest, pre_header); 943 1.1 mrg /* Add NEW_ADGE argument for all phi in post-header block. */ 944 1.1 mrg bb = exit->dest; 945 1.1 mrg for (gphi_iterator gsi = gsi_start_phis (bb); 946 1.1 mrg !gsi_end_p (gsi); gsi_next (&gsi)) 947 1.1 mrg { 948 1.1 mrg gphi *phi = gsi.phi (); 949 1.1 mrg tree arg; 950 1.1 mrg if (virtual_operand_p (gimple_phi_result (phi))) 951 1.1 mrg { 952 1.1 mrg arg = get_vop_from_header (loop); 953 1.1 mrg if (arg == NULL_TREE) 954 1.1 mrg /* Use exit edge argument. */ 955 1.1 mrg arg = PHI_ARG_DEF_FROM_EDGE (phi, exit); 956 1.1 mrg add_phi_arg (phi, arg, new_edge, UNKNOWN_LOCATION); 957 1.1 mrg } 958 1.1 mrg else 959 1.1 mrg { 960 1.1 mrg /* Use exit edge argument. */ 961 1.1 mrg arg = PHI_ARG_DEF_FROM_EDGE (phi, exit); 962 1.1 mrg add_phi_arg (phi, arg, new_edge, UNKNOWN_LOCATION); 963 1.1 mrg } 964 1.1 mrg } 965 1.1 mrg 966 1.1 mrg if (dump_enabled_p ()) 967 1.1 mrg dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc, 968 1.1 mrg "Guard hoisted\n"); 969 1.1 mrg 970 1.1 mrg free (body); 971 1.1 mrg } 972 1.1 mrg 973 1.1 mrg /* Return true if phi argument for exit edge can be used 974 1.1 mrg for edge around loop. */ 975 1.1 mrg 976 1.1 mrg static bool 977 1.1 mrg check_exit_phi (class loop *loop) 978 1.1 mrg { 979 1.1 mrg edge exit = single_exit (loop); 980 1.1 mrg basic_block pre_header = loop_preheader_edge (loop)->src; 981 1.1 mrg 982 1.1 mrg for (gphi_iterator gsi = gsi_start_phis (exit->dest); 983 1.1 mrg !gsi_end_p (gsi); gsi_next (&gsi)) 984 1.1 mrg { 985 1.1 mrg gphi *phi = gsi.phi (); 986 1.1 mrg tree arg; 987 1.1 mrg gimple *def; 988 1.1 mrg basic_block def_bb; 989 1.1 mrg if (virtual_operand_p (gimple_phi_result (phi))) 990 1.1 mrg continue; 991 1.1 mrg arg = PHI_ARG_DEF_FROM_EDGE (phi, exit); 992 1.1 mrg if (TREE_CODE (arg) != SSA_NAME) 993 1.1 mrg continue; 994 1.1 mrg def = SSA_NAME_DEF_STMT (arg); 995 1.1 mrg if (!def) 996 1.1 mrg continue; 997 1.1 mrg def_bb = gimple_bb (def); 998 1.1 mrg if (!def_bb) 999 1.1 mrg continue; 1000 1.1 mrg if (!dominated_by_p (CDI_DOMINATORS, pre_header, def_bb)) 1001 1.1 mrg /* Definition inside loop! */ 1002 1.1 mrg return false; 1003 1.1 mrg /* Check loop closed phi invariant. */ 1004 1.1 mrg if (!flow_bb_inside_loop_p (def_bb->loop_father, pre_header)) 1005 1.1 mrg return false; 1006 1.1 mrg } 1007 1.1 mrg return true; 1008 1.1 mrg } 1009 1.1 mrg 1010 1.1 mrg /* Loop unswitching pass. */ 1011 1.1 mrg 1012 1.1 mrg namespace { 1013 1.1 mrg 1014 1.1 mrg const pass_data pass_data_tree_unswitch = 1015 1.1 mrg { 1016 1.1 mrg GIMPLE_PASS, /* type */ 1017 1.1 mrg "unswitch", /* name */ 1018 1.1 mrg OPTGROUP_LOOP, /* optinfo_flags */ 1019 1.1 mrg TV_TREE_LOOP_UNSWITCH, /* tv_id */ 1020 1.1 mrg PROP_cfg, /* properties_required */ 1021 1.1 mrg 0, /* properties_provided */ 1022 1.1 mrg 0, /* properties_destroyed */ 1023 1.1 mrg 0, /* todo_flags_start */ 1024 1.1 mrg 0, /* todo_flags_finish */ 1025 1.1 mrg }; 1026 1.1 mrg 1027 1.1 mrg class pass_tree_unswitch : public gimple_opt_pass 1028 1.1 mrg { 1029 1.1 mrg public: 1030 1.1 mrg pass_tree_unswitch (gcc::context *ctxt) 1031 1.1 mrg : gimple_opt_pass (pass_data_tree_unswitch, ctxt) 1032 1.1 mrg {} 1033 1.1 mrg 1034 1.1 mrg /* opt_pass methods: */ 1035 1.1 mrg virtual bool gate (function *) { return flag_unswitch_loops != 0; } 1036 1.1 mrg virtual unsigned int execute (function *); 1037 1.1 mrg 1038 1.1 mrg }; // class pass_tree_unswitch 1039 1.1 mrg 1040 1.1 mrg unsigned int 1041 1.1 mrg pass_tree_unswitch::execute (function *fun) 1042 1.1 mrg { 1043 1.1 mrg if (number_of_loops (fun) <= 1) 1044 1.1 mrg return 0; 1045 1.1 mrg 1046 1.1 mrg return tree_ssa_unswitch_loops (); 1047 1.1 mrg } 1048 1.1 mrg 1049 1.1 mrg } // anon namespace 1050 1.1 mrg 1051 1.1 mrg gimple_opt_pass * 1052 1.1 mrg make_pass_tree_unswitch (gcc::context *ctxt) 1053 1.1 mrg { 1054 1.1 mrg return new pass_tree_unswitch (ctxt); 1055 1.1 mrg } 1056 1.1 mrg 1057 1.1 mrg 1058