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