Line data Source code
1 : /* Loop unswitching.
2 : Copyright (C) 2004-2026 Free Software Foundation, Inc.
3 :
4 : This file is part of GCC.
5 :
6 : GCC is free software; you can redistribute it and/or modify it
7 : under the terms of the GNU General Public License as published by the
8 : Free Software Foundation; either version 3, or (at your option) any
9 : later version.
10 :
11 : GCC is distributed in the hope that it will be useful, but WITHOUT
12 : ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 : for more details.
15 :
16 : You should have received a copy of the GNU General Public License
17 : along with GCC; see the file COPYING3. If not see
18 : <http://www.gnu.org/licenses/>. */
19 :
20 : #include "config.h"
21 : #include "system.h"
22 : #include "coretypes.h"
23 : #include "backend.h"
24 : #include "tree.h"
25 : #include "gimple.h"
26 : #include "tree-pass.h"
27 : #include "ssa.h"
28 : #include "fold-const.h"
29 : #include "gimplify.h"
30 : #include "tree-cfg.h"
31 : #include "tree-ssa.h"
32 : #include "tree-ssa-loop-niter.h"
33 : #include "tree-ssa-loop.h"
34 : #include "tree-into-ssa.h"
35 : #include "cfgloop.h"
36 : #include "tree-inline.h"
37 : #include "gimple-iterator.h"
38 : #include "cfghooks.h"
39 : #include "tree-ssa-loop-manip.h"
40 : #include "tree-vectorizer.h"
41 : #include "tree-pretty-print.h"
42 : #include "gimple-range.h"
43 : #include "dbgcnt.h"
44 : #include "cfganal.h"
45 :
46 : /* This file implements the loop unswitching, i.e. transformation of loops like
47 :
48 : while (A)
49 : {
50 : if (inv)
51 : B;
52 :
53 : X;
54 :
55 : if (!inv)
56 : C;
57 : }
58 :
59 : where inv is the loop invariant, into
60 :
61 : if (inv)
62 : {
63 : while (A)
64 : {
65 : B;
66 : X;
67 : }
68 : }
69 : else
70 : {
71 : while (A)
72 : {
73 : X;
74 : C;
75 : }
76 : }
77 :
78 : Inv is considered invariant iff the values it compares are both invariant;
79 : tree-ssa-loop-im.cc ensures that all the suitable conditions are in this
80 : shape. */
81 :
82 : /* Loop unswitching algorithm for innermost loops works in the following steps:
83 :
84 : 1) Number of instructions is estimated for each BB that belongs to a loop.
85 : 2) Unswitching candidates are found for gcond and gswitch statements
86 : (note that an unswitching predicate for a gswitch actually corresponds
87 : to a non-default edge so it can contain multiple cases).
88 : 3) The so called unswitch predicates are stored in a cache where the
89 : gimple_uid of the last stmt in a basic-block is an index to the cache.
90 : 4) We consider one by one the unswitching candidates and calculate BBs that
91 : will be reachable in the unswitch version.
92 : 5) A selected predicate is chosen and we simplify the CFG (dead edges) in
93 : both versions of the loop. We utilize both Ranger for condition
94 : simplification and also symbol equivalence. The folded if conditions
95 : are replaced with true/false values, while for gswitch we mark the
96 : corresponding edges with a pass-defined unreachable flag.
97 : 6) Every time we unswitch a loop, we save unswitch_predicate to a vector
98 : together with information if true or false edge was taken. Doing that
99 : we have a so called PREDICATE_PATH that is utilized for simplification
100 : of the cloned loop.
101 : 7) The process is repeated until we reach a growth threshold or all
102 : unswitching opportunities are taken. */
103 :
104 : /* A tuple that holds a GENERIC condition and value range for an unswitching
105 : predicate. */
106 :
107 : struct unswitch_predicate
108 : {
109 : /* CTOR for a switch edge predicate. */
110 106 : unswitch_predicate (tree cond, tree lhs_, int edge_index_, edge e,
111 : const int_range_max& edge_range)
112 106 : : condition (cond), lhs (lhs_),
113 106 : true_range (edge_range), edge_index (edge_index_), switch_p (true)
114 : {
115 106 : gcc_assert (!(e->flags & (EDGE_TRUE_VALUE|EDGE_FALSE_VALUE))
116 : && irange::supports_p (TREE_TYPE (lhs)));
117 106 : false_range = true_range;
118 106 : if (!false_range.varying_p ()
119 106 : && !false_range.undefined_p ())
120 106 : false_range.invert ();
121 106 : count = e->count ();
122 106 : num = predicates->length ();
123 106 : predicates->safe_push (this);
124 106 : }
125 :
126 : /* CTOR for a GIMPLE condition statement. */
127 2785 : unswitch_predicate (gcond *stmt)
128 2785 : : switch_p (false)
129 : {
130 2785 : basic_block bb = gimple_bb (stmt);
131 2785 : if (EDGE_SUCC (bb, 0)->flags & EDGE_TRUE_VALUE)
132 2731 : edge_index = 0;
133 : else
134 54 : edge_index = 1;
135 2785 : lhs = gimple_cond_lhs (stmt);
136 2785 : tree rhs = gimple_cond_rhs (stmt);
137 2785 : enum tree_code code = gimple_cond_code (stmt);
138 2785 : condition = build2 (code, boolean_type_node, lhs, rhs);
139 2785 : count = profile_count::max_prefer_initialized (EDGE_SUCC (bb, 0)->count (),
140 2785 : EDGE_SUCC (bb, 1)->count ());
141 2785 : if (irange::supports_p (TREE_TYPE (lhs)))
142 : {
143 2619 : auto range_op = range_op_handler (code);
144 2619 : int_range<2> rhs_range (TREE_TYPE (rhs));
145 2619 : if (CONSTANT_CLASS_P (rhs))
146 : {
147 2488 : wide_int w = wi::to_wide (rhs);
148 2488 : rhs_range.set (TREE_TYPE (rhs), w, w);
149 2488 : }
150 2619 : if (!range_op.op1_range (true_range, TREE_TYPE (lhs),
151 5238 : range_true (), rhs_range)
152 7857 : || !range_op.op1_range (false_range, TREE_TYPE (lhs),
153 5238 : range_false (), rhs_range))
154 : {
155 0 : true_range.set_varying (TREE_TYPE (lhs));
156 0 : false_range.set_varying (TREE_TYPE (lhs));
157 : }
158 2619 : }
159 2785 : num = predicates->length ();
160 2785 : predicates->safe_push (this);
161 2785 : }
162 :
163 : /* Copy ranges for purpose of usage in predicate path. */
164 :
165 : inline void
166 7614 : copy_merged_ranges ()
167 : {
168 7614 : merged_true_range = true_range;
169 7614 : merged_false_range = false_range;
170 7614 : }
171 :
172 : /* GENERIC unswitching expression testing LHS against CONSTANT. */
173 : tree condition;
174 :
175 : /* LHS of the expression. */
176 : tree lhs;
177 :
178 : /* Initial ranges (when the expression is true/false) for the expression. */
179 : int_range_max true_range = {}, false_range = {};
180 :
181 : /* Modified range that is part of a predicate path. */
182 : int_range_max merged_true_range = {}, merged_false_range = {};
183 :
184 : /* Index of the edge the predicate belongs to in the successor vector. */
185 : int edge_index;
186 :
187 : /* The profile count of this predicate. */
188 : profile_count count;
189 :
190 : /* Whether the predicate was created from a switch statement. */
191 : bool switch_p;
192 :
193 : /* The number of the predicate in the predicates vector below. */
194 : unsigned num;
195 :
196 : /* Vector of all used predicates, used for assigning a unique id that
197 : can be used for bitmap operations. */
198 : static vec<unswitch_predicate *> *predicates;
199 : };
200 :
201 : vec<unswitch_predicate *> *unswitch_predicate::predicates;
202 :
203 : /* Ranger instance used in the pass. */
204 : static gimple_ranger *ranger = NULL;
205 :
206 : /* Cache storage for unswitch_predicate belonging to a basic block. */
207 : static vec<vec<unswitch_predicate *>> *bb_predicates;
208 :
209 : /* The type represents a predicate path leading to a basic block. */
210 : typedef vec<std::pair<unswitch_predicate *, bool>> predicate_vector;
211 :
212 : static class loop *tree_unswitch_loop (class loop *, edge, tree);
213 : static bool tree_unswitch_single_loop (class loop *, dump_user_location_t,
214 : predicate_vector &predicate_path,
215 : unsigned loop_size, unsigned &budget,
216 : int ignored_edge_flag, bitmap,
217 : unswitch_predicate * = NULL,
218 : basic_block = NULL);
219 : static void
220 : find_unswitching_predicates_for_bb (basic_block bb, class loop *loop,
221 : class loop *&outer_loop,
222 : vec<unswitch_predicate *> &candidates,
223 : unswitch_predicate *&hottest,
224 : basic_block &hottest_bb);
225 : static bool tree_unswitch_outer_loop (class loop *);
226 : static edge find_loop_guard (class loop *, vec<gimple *>&);
227 : static bool empty_bb_without_guard_p (class loop *, basic_block,
228 : vec<gimple *>&);
229 : static bool used_outside_loop_p (class loop *, tree, vec<gimple *>&);
230 : static void hoist_guard (class loop *, edge);
231 : static bool check_exit_phi (class loop *);
232 : static tree get_vop_from_header (class loop *);
233 : static void clean_up_after_unswitching (int);
234 :
235 : /* Return vector of predicates that belong to a basic block. */
236 :
237 : static vec<unswitch_predicate *> &
238 471093 : get_predicates_for_bb (basic_block bb)
239 : {
240 471093 : gimple *last = last_nondebug_stmt (bb);
241 471093 : return (*bb_predicates)[last == NULL ? 0 : gimple_uid (last)];
242 : }
243 :
244 : /* Save predicates that belong to a basic block. */
245 :
246 : static void
247 2817 : set_predicates_for_bb (basic_block bb, vec<unswitch_predicate *> predicates)
248 : {
249 5634 : gimple_set_uid (last_nondebug_stmt (bb), bb_predicates->length ());
250 2817 : bb_predicates->safe_push (predicates);
251 2817 : }
252 :
253 : /* Initialize LOOP information reused during the unswitching pass.
254 : Return total number of instructions in the loop. Adjusts LOOP to
255 : the outermost loop all candidates are invariant in. */
256 :
257 : static unsigned
258 62174 : init_loop_unswitch_info (class loop *&loop, unswitch_predicate *&hottest,
259 : basic_block &hottest_bb)
260 : {
261 62174 : unsigned total_insns = 0;
262 :
263 62174 : basic_block *bbs = get_loop_body (loop);
264 :
265 : /* Unswitch only nests with no sibling loops. */
266 62174 : class loop *outer_loop = loop;
267 62174 : unsigned max_depth = param_max_unswitch_depth;
268 62174 : while (loop_outer (outer_loop)->num != 0
269 17790 : && !loop_outer (outer_loop)->inner->next
270 84497 : && --max_depth != 0)
271 11159 : outer_loop = loop_outer (outer_loop);
272 62174 : hottest = NULL;
273 62174 : hottest_bb = NULL;
274 : /* Find all unswitching candidates in the innermost loop. */
275 290632 : for (unsigned i = 0; i != loop->num_nodes; i++)
276 : {
277 : /* Find a bb to unswitch on. */
278 228458 : vec<unswitch_predicate *> candidates;
279 228458 : candidates.create (1);
280 228458 : find_unswitching_predicates_for_bb (bbs[i], loop, outer_loop, candidates,
281 : hottest, hottest_bb);
282 228458 : if (!candidates.is_empty ())
283 2817 : set_predicates_for_bb (bbs[i], candidates);
284 : else
285 : {
286 225641 : candidates.release ();
287 225641 : gimple *last = last_nondebug_stmt (bbs[i]);
288 225641 : if (last != NULL)
289 142481 : gimple_set_uid (last, 0);
290 : }
291 : }
292 :
293 62174 : if (outer_loop != loop)
294 : {
295 8537 : free (bbs);
296 8537 : bbs = get_loop_body (outer_loop);
297 : }
298 :
299 : /* Calculate instruction count. */
300 360434 : for (unsigned i = 0; i < outer_loop->num_nodes; i++)
301 : {
302 298260 : unsigned insns = 0;
303 1631590 : for (gimple_stmt_iterator gsi = gsi_start_bb (bbs[i]); !gsi_end_p (gsi);
304 1035070 : gsi_next (&gsi))
305 1035070 : insns += estimate_num_insns (gsi_stmt (gsi), &eni_size_weights);
306 : /* No predicates to unswitch on in the outer loops. */
307 298260 : if (!flow_bb_inside_loop_p (loop, bbs[i]))
308 : {
309 69802 : gimple *last = last_nondebug_stmt (bbs[i]);
310 69802 : if (last != NULL)
311 42052 : gimple_set_uid (last, 0);
312 : }
313 :
314 298260 : bbs[i]->aux = (void *)(uintptr_t)insns;
315 298260 : total_insns += insns;
316 : }
317 :
318 62174 : free (bbs);
319 :
320 62174 : loop = outer_loop;
321 62174 : return total_insns;
322 : }
323 :
324 : /* Main entry point. Perform loop unswitching on all suitable loops. */
325 :
326 : unsigned int
327 28166 : tree_ssa_unswitch_loops (function *fun)
328 : {
329 28166 : bool changed_unswitch = false;
330 28166 : bool changed_hoist = false;
331 28166 : auto_edge_flag ignored_edge_flag (fun);
332 28166 : mark_ssa_maybe_undefs ();
333 :
334 28166 : ranger = enable_ranger (fun);
335 :
336 : /* Go through all loops starting from innermost, hoisting guards. */
337 164361 : for (auto loop : loops_list (fun, LI_FROM_INNERMOST))
338 : {
339 79863 : if (loop->inner)
340 14477 : changed_hoist |= tree_unswitch_outer_loop (loop);
341 28166 : }
342 :
343 : /* Go through innermost loops, unswitching on invariant predicates
344 : within those. */
345 149884 : for (auto loop : loops_list (fun, LI_ONLY_INNERMOST))
346 : {
347 : /* Perform initial tests if unswitch is eligible. */
348 65386 : dump_user_location_t loc = find_loop_location (loop);
349 :
350 : /* Do not unswitch in cold regions. */
351 65386 : if (optimize_loop_for_size_p (loop))
352 : {
353 1219 : if (dump_enabled_p ())
354 0 : dump_printf_loc (MSG_NOTE, loc,
355 : "Not unswitching cold loops\n");
356 3212 : continue;
357 : }
358 :
359 : /* If the loop is not expected to iterate, there is no need
360 : for unswitching. */
361 64167 : HOST_WIDE_INT iterations = estimated_loop_iterations_int (loop);
362 64167 : if (iterations < 0)
363 38489 : iterations = likely_max_loop_iterations_int (loop);
364 64167 : if (iterations >= 0 && iterations <= 1)
365 : {
366 1993 : if (dump_enabled_p ())
367 2 : dump_printf_loc (MSG_NOTE, loc,
368 : "Not unswitching, loop is not expected"
369 : " to iterate\n");
370 1993 : continue;
371 : }
372 :
373 62174 : bb_predicates = new vec<vec<unswitch_predicate *>> ();
374 62174 : bb_predicates->safe_push (vec<unswitch_predicate *> ());
375 62174 : unswitch_predicate::predicates = new vec<unswitch_predicate *> ();
376 :
377 : /* Unswitch loop. */
378 62174 : unswitch_predicate *hottest;
379 62174 : basic_block hottest_bb;
380 62174 : unsigned int loop_size = init_loop_unswitch_info (loop, hottest,
381 : hottest_bb);
382 62174 : unsigned int budget = loop_size + param_max_unswitch_insns;
383 :
384 62174 : predicate_vector predicate_path;
385 62174 : predicate_path.create (8);
386 62174 : auto_bitmap handled;
387 62174 : changed_unswitch |= tree_unswitch_single_loop (loop, loc, predicate_path,
388 : loop_size, budget,
389 : ignored_edge_flag, handled,
390 : hottest, hottest_bb);
391 62174 : predicate_path.release ();
392 :
393 251513 : for (auto predlist : bb_predicates)
394 64991 : predlist.release ();
395 62174 : bb_predicates->release ();
396 62174 : delete bb_predicates;
397 62174 : bb_predicates = NULL;
398 :
399 189413 : for (auto pred : unswitch_predicate::predicates)
400 2891 : delete pred;
401 62174 : unswitch_predicate::predicates->release ();
402 62174 : delete unswitch_predicate::predicates;
403 62174 : unswitch_predicate::predicates = NULL;
404 62174 : }
405 :
406 28166 : disable_ranger (fun);
407 28166 : clear_aux_for_blocks ();
408 :
409 28166 : if (changed_unswitch)
410 1353 : clean_up_after_unswitching (ignored_edge_flag);
411 :
412 28166 : if (changed_unswitch || changed_hoist)
413 1857 : return TODO_cleanup_cfg;
414 :
415 : return 0;
416 28166 : }
417 :
418 : /* Return TRUE if an SSA_NAME maybe undefined and is therefore
419 : unsuitable for unswitching. STMT is the statement we are
420 : considering for unswitching and LOOP is the loop it appears in. */
421 :
422 : static bool
423 18322 : is_maybe_undefined (const tree name, gimple *stmt, class loop *loop)
424 : {
425 : /* The loop header is the only block we can trivially determine that
426 : will always be executed. If the comparison is in the loop
427 : header, we know it's OK to unswitch on it. */
428 0 : if (gimple_bb (stmt) == loop->header)
429 : return false;
430 :
431 8858 : return ssa_name_maybe_undef_p (name);
432 : }
433 :
434 : /* Checks whether we can unswitch LOOP on condition at end of BB -- one of its
435 : basic blocks (for what it means see comments below).
436 : All candidates all filled to the provided vector CANDIDATES.
437 : OUTER_LOOP is updated to the innermost loop all found candidates are
438 : invariant in. */
439 :
440 : static void
441 228458 : find_unswitching_predicates_for_bb (basic_block bb, class loop *loop,
442 : class loop *&outer_loop,
443 : vec<unswitch_predicate *> &candidates,
444 : unswitch_predicate *&hottest,
445 : basic_block &hottest_bb)
446 : {
447 228458 : gimple *last, *def;
448 228458 : tree use;
449 228458 : basic_block def_bb;
450 228458 : ssa_op_iter iter;
451 :
452 : /* BB must end in a simple conditional jump. */
453 228458 : last = *gsi_last_bb (bb);
454 228458 : if (!last)
455 200995 : return;
456 :
457 145657 : if (gcond *stmt = safe_dyn_cast <gcond *> (last))
458 : {
459 : /* To keep the things simple, we do not directly remove the conditions,
460 : but just replace tests with 0 != 0 resp. 1 != 0. Prevent the infinite
461 : loop where we would unswitch again on such a condition. */
462 120843 : if (gimple_cond_true_p (stmt) || gimple_cond_false_p (stmt))
463 118058 : return;
464 :
465 : /* At least the LHS needs to be symbolic. */
466 120843 : if (TREE_CODE (gimple_cond_lhs (stmt)) != SSA_NAME)
467 : return;
468 :
469 : /* Condition must be invariant. */
470 138374 : FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
471 : {
472 135589 : def = SSA_NAME_DEF_STMT (use);
473 135589 : def_bb = gimple_bb (def);
474 135589 : if (def_bb
475 135589 : && flow_bb_inside_loop_p (loop, def_bb))
476 : return;
477 : /* Unswitching on undefined values would introduce undefined
478 : behavior that the original program might never exercise. */
479 25933 : if (is_maybe_undefined (use, stmt, loop))
480 : return;
481 : }
482 : /* Narrow OUTER_LOOP. */
483 2785 : if (outer_loop != loop)
484 1547 : FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
485 : {
486 779 : def = SSA_NAME_DEF_STMT (use);
487 779 : def_bb = gimple_bb (def);
488 779 : while (outer_loop != loop
489 1113 : && ((def_bb && flow_bb_inside_loop_p (outer_loop, def_bb))
490 1394 : || is_maybe_undefined (use, stmt, outer_loop)))
491 334 : outer_loop = superloop_at_depth (loop,
492 668 : loop_depth (outer_loop) + 1);
493 : }
494 :
495 2785 : unswitch_predicate *predicate = new unswitch_predicate (stmt);
496 2785 : candidates.safe_push (predicate);
497 : /* If we unswitch on this predicate we isolate both paths, so
498 : pick the highest count for updating of the hottest predicate
499 : to unswitch on first. */
500 2785 : if (!hottest || predicate->count > hottest->count)
501 : {
502 1835 : hottest = predicate;
503 1835 : hottest_bb = bb;
504 : }
505 : }
506 27631 : else if (gswitch *stmt = safe_dyn_cast <gswitch *> (last))
507 : {
508 168 : unsigned nlabels = gimple_switch_num_labels (stmt);
509 168 : tree idx = gimple_switch_index (stmt);
510 168 : tree idx_type = TREE_TYPE (idx);
511 168 : if (!gimple_range_ssa_p (idx) || nlabels < 1)
512 136 : return;
513 : /* Index must be invariant. */
514 167 : def = SSA_NAME_DEF_STMT (idx);
515 167 : def_bb = gimple_bb (def);
516 167 : if (def_bb
517 167 : && flow_bb_inside_loop_p (loop, def_bb))
518 : return;
519 : /* Unswitching on undefined values would introduce undefined
520 : behavior that the original program might never exercise. */
521 51 : if (is_maybe_undefined (idx, stmt, loop))
522 : return;
523 : /* Narrow OUTER_LOOP. */
524 32 : while (outer_loop != loop
525 32 : && ((def_bb && flow_bb_inside_loop_p (outer_loop, def_bb))
526 4 : || is_maybe_undefined (idx, stmt, outer_loop)))
527 0 : outer_loop = superloop_at_depth (loop,
528 0 : loop_depth (outer_loop) + 1);
529 :
530 : /* Build compound expression for all outgoing edges of the switch. */
531 32 : auto_vec<tree, 16> preds;
532 32 : auto_vec<int_range_max> edge_range;
533 64 : preds.safe_grow_cleared (EDGE_COUNT (gimple_bb (stmt)->succs), true);
534 64 : edge_range.safe_grow_cleared (EDGE_COUNT (gimple_bb (stmt)->succs), true);
535 32 : edge e;
536 32 : edge_iterator ei;
537 32 : unsigned edge_index = 0;
538 167 : FOR_EACH_EDGE (e, ei, gimple_bb (stmt)->succs)
539 135 : e->aux = (void *)(uintptr_t)edge_index++;
540 146 : for (unsigned i = 1; i < gimple_switch_num_labels (stmt); ++i)
541 : {
542 114 : tree lab = gimple_switch_label (stmt, i);
543 114 : tree cmp;
544 114 : int_range<2> lab_range;
545 114 : tree low = fold_convert (idx_type, CASE_LOW (lab));
546 114 : if (CASE_HIGH (lab) != NULL_TREE)
547 : {
548 3 : tree high = fold_convert (idx_type, CASE_HIGH (lab));
549 3 : tree cmp1 = fold_build2 (GE_EXPR, boolean_type_node, idx, low);
550 3 : tree cmp2 = fold_build2 (LE_EXPR, boolean_type_node, idx, high);
551 3 : cmp = fold_build2 (BIT_AND_EXPR, boolean_type_node, cmp1, cmp2);
552 3 : lab_range.set (idx_type, wi::to_wide (low), wi::to_wide (high));
553 : }
554 : else
555 : {
556 111 : cmp = fold_build2 (EQ_EXPR, boolean_type_node, idx, low);
557 111 : wide_int w = wi::to_wide (low);
558 111 : lab_range.set (idx_type, w, w);
559 111 : }
560 :
561 : /* Combine the expression with the existing one. */
562 114 : basic_block dest = label_to_block (cfun, CASE_LABEL (lab));
563 114 : e = find_edge (gimple_bb (stmt), dest);
564 114 : tree &expr = preds[(uintptr_t)e->aux];
565 114 : if (expr == NULL_TREE)
566 106 : expr = cmp;
567 : else
568 8 : expr = fold_build2 (BIT_IOR_EXPR, boolean_type_node, expr, cmp);
569 114 : edge_range[(uintptr_t)e->aux].union_ (lab_range);
570 114 : }
571 :
572 : /* Now register the predicates. */
573 167 : for (edge_index = 0; edge_index < preds.length (); ++edge_index)
574 : {
575 135 : edge e = EDGE_SUCC (gimple_bb (stmt), edge_index);
576 135 : e->aux = NULL;
577 135 : if (preds[edge_index] != NULL_TREE)
578 : {
579 106 : unswitch_predicate *predicate
580 106 : = new unswitch_predicate (preds[edge_index], idx,
581 : edge_index, e,
582 106 : edge_range[edge_index]);
583 106 : candidates.safe_push (predicate);
584 106 : if (!hottest || predicate->count > hottest->count)
585 : {
586 26 : hottest = predicate;
587 26 : hottest_bb = bb;
588 : }
589 : }
590 : }
591 32 : }
592 : }
593 :
594 : /* Merge ranges for the last item of PREDICATE_PATH with a predicate
595 : that shared the same LHS. */
596 :
597 : static void
598 7614 : merge_last (predicate_vector &predicate_path)
599 : {
600 7614 : unswitch_predicate *last_predicate = predicate_path.last ().first;
601 :
602 11518 : for (int i = predicate_path.length () - 2; i >= 0; i--)
603 : {
604 4918 : unswitch_predicate *predicate = predicate_path[i].first;
605 4918 : bool true_edge = predicate_path[i].second;
606 :
607 4918 : if (operand_equal_p (predicate->lhs, last_predicate->lhs, 0))
608 : {
609 1014 : irange &other = (true_edge ? predicate->merged_true_range
610 : : predicate->merged_false_range);
611 1014 : last_predicate->merged_true_range.intersect (other);
612 1014 : last_predicate->merged_false_range.intersect (other);
613 1014 : return;
614 : }
615 : }
616 : }
617 :
618 : /* Add PREDICATE to PREDICATE_PATH on TRUE_EDGE. */
619 :
620 : static void
621 7614 : add_predicate_to_path (predicate_vector &predicate_path,
622 : unswitch_predicate *predicate, bool true_edge)
623 : {
624 7614 : predicate->copy_merged_ranges ();
625 7614 : predicate_path.safe_push (std::make_pair (predicate, true_edge));
626 7614 : merge_last (predicate_path);
627 7614 : }
628 :
629 : static bool
630 1301 : find_range_for_lhs (predicate_vector &predicate_path, tree lhs,
631 : int_range_max &range)
632 : {
633 2616 : for (int i = predicate_path.length () - 1; i >= 0; i--)
634 : {
635 1301 : unswitch_predicate *predicate = predicate_path[i].first;
636 1301 : bool true_edge = predicate_path[i].second;
637 :
638 1301 : if (operand_equal_p (predicate->lhs, lhs, 0))
639 : {
640 1287 : range = (true_edge ? predicate->merged_true_range
641 1287 : : predicate->merged_false_range);
642 1287 : return !range.undefined_p ();
643 : }
644 : }
645 :
646 : return false;
647 : }
648 :
649 : /* Simplifies STMT using the predicate we unswitched on which is the last
650 : in PREDICATE_PATH. For switch statements add newly unreachable edges
651 : to IGNORED_EDGES (but do not set IGNORED_EDGE_FLAG on them). */
652 :
653 : static tree
654 65012 : evaluate_control_stmt_using_entry_checks (gimple *stmt,
655 : predicate_vector &predicate_path,
656 : int ignored_edge_flag,
657 : hash_set<edge> *ignored_edges)
658 : {
659 65012 : unswitch_predicate *last_predicate = predicate_path.last ().first;
660 65012 : bool true_edge = predicate_path.last ().second;
661 :
662 65012 : if (gcond *cond = dyn_cast<gcond *> (stmt))
663 : {
664 64638 : tree lhs = gimple_cond_lhs (cond);
665 64638 : if (!operand_equal_p (lhs, last_predicate->lhs))
666 : return NULL_TREE;
667 : /* Try a symbolic match which works for floating point and fully
668 : symbolic conditions. */
669 19057 : if (gimple_cond_code (cond) == TREE_CODE (last_predicate->condition)
670 37555 : && operand_equal_p (gimple_cond_rhs (cond),
671 18498 : TREE_OPERAND (last_predicate->condition, 1)))
672 18090 : return true_edge ? boolean_true_node : boolean_false_node;
673 : /* Else try ranger if it supports LHS. */
674 967 : else if (irange::supports_p (TREE_TYPE (lhs)))
675 : {
676 967 : int_range<2> r;
677 967 : int_range_max path_range;
678 :
679 967 : if (find_range_for_lhs (predicate_path, lhs, path_range)
680 967 : && fold_range (r, cond, path_range)
681 1934 : && r.singleton_p ())
682 362 : return r.zero_p () ? boolean_false_node : boolean_true_node;
683 967 : }
684 : }
685 374 : else if (gswitch *swtch = dyn_cast<gswitch *> (stmt))
686 : {
687 374 : unsigned nlabels = gimple_switch_num_labels (swtch);
688 :
689 374 : tree idx = gimple_switch_index (swtch);
690 :
691 : /* Already folded switch. */
692 374 : if (TREE_CONSTANT (idx))
693 207 : return NULL_TREE;
694 :
695 334 : int_range_max path_range;
696 334 : if (!find_range_for_lhs (predicate_path, idx, path_range))
697 : return NULL_TREE;
698 :
699 : tree result = NULL_TREE;
700 : edge single_edge = NULL;
701 2018 : for (unsigned i = 0; i < nlabels; ++i)
702 : {
703 1698 : tree lab = gimple_switch_label (swtch, i);
704 1698 : basic_block dest = label_to_block (cfun, CASE_LABEL (lab));
705 1698 : edge e = find_edge (gimple_bb (stmt), dest);
706 1698 : if (e->flags & ignored_edge_flag)
707 392 : continue;
708 :
709 1306 : int_range_max r;
710 1306 : if (!ranger->gori ().edge_range_p (r, e, idx,
711 : *get_global_range_query ()))
712 0 : continue;
713 1306 : r.intersect (path_range);
714 1306 : if (r.undefined_p ())
715 643 : ignored_edges->add (e);
716 : else
717 : {
718 663 : if (!single_edge)
719 : {
720 320 : single_edge = e;
721 320 : result = CASE_LOW (lab);
722 : }
723 343 : else if (single_edge != e)
724 1306 : result = NULL;
725 : }
726 1306 : }
727 :
728 : /* Only one edge from the switch is alive. */
729 320 : if (single_edge && result)
730 : return result;
731 334 : }
732 :
733 : return NULL_TREE;
734 : }
735 :
736 : /* Simplify LOOP based on PREDICATE_PATH where dead edges are properly
737 : marked. */
738 :
739 : static bool
740 4826 : simplify_loop_version (class loop *loop, predicate_vector &predicate_path,
741 : int ignored_edge_flag, bitmap handled)
742 : {
743 4826 : bool changed = false;
744 4826 : basic_block *bbs = get_loop_body (loop);
745 :
746 4826 : hash_set<edge> ignored_edges;
747 48708 : for (unsigned i = 0; i != loop->num_nodes; i++)
748 : {
749 43882 : vec<unswitch_predicate *> &predicates = get_predicates_for_bb (bbs[i]);
750 43882 : if (predicates.is_empty ())
751 33756 : continue;
752 :
753 10126 : gimple *stmt = *gsi_last_bb (bbs[i]);
754 10126 : tree folded = evaluate_control_stmt_using_entry_checks (stmt,
755 : predicate_path,
756 : ignored_edge_flag,
757 : &ignored_edges);
758 :
759 10126 : if (gcond *cond = dyn_cast<gcond *> (stmt))
760 : {
761 9942 : if (folded)
762 : {
763 : /* Remove path. */
764 5462 : if (integer_nonzerop (folded))
765 2668 : gimple_cond_set_condition_from_tree (cond, boolean_true_node);
766 : else
767 2794 : gimple_cond_set_condition_from_tree (cond, boolean_false_node);
768 :
769 5462 : gcc_assert (predicates.length () == 1);
770 5462 : bitmap_set_bit (handled, predicates[0]->num);
771 :
772 5462 : update_stmt (cond);
773 5462 : changed = true;
774 : }
775 : }
776 44066 : else if (gswitch *swtch = dyn_cast<gswitch *> (stmt))
777 : {
778 184 : edge e;
779 184 : edge_iterator ei;
780 968 : FOR_EACH_EDGE (e, ei, bbs[i]->succs)
781 784 : if (ignored_edges.contains (e))
782 274 : e->flags |= ignored_edge_flag;
783 :
784 790 : for (unsigned j = 0; j < predicates.length (); j++)
785 : {
786 606 : edge e = EDGE_SUCC (bbs[i], predicates[j]->edge_index);
787 606 : if (ignored_edges.contains (e))
788 204 : bitmap_set_bit (handled, predicates[j]->num);
789 : }
790 :
791 184 : if (folded)
792 : {
793 70 : gimple_switch_set_index (swtch, folded);
794 70 : update_stmt (swtch);
795 70 : changed = true;
796 : }
797 : }
798 : }
799 :
800 4826 : free (bbs);
801 4826 : return changed;
802 4826 : }
803 :
804 : /* Evaluate reachable blocks in LOOP and call VISIT on them, aborting the
805 : DFS walk if VISIT returns true. When PREDICATE_PATH is specified then
806 : take into account that when computing reachability, otherwise just
807 : look at the simplified state and IGNORED_EDGE_FLAG. */
808 :
809 : template <typename VisitOp>
810 : static void
811 68070 : evaluate_bbs (class loop *loop, predicate_vector *predicate_path,
812 : int ignored_edge_flag, VisitOp visit)
813 : {
814 68070 : auto_bb_flag reachable_flag (cfun);
815 68070 : auto_vec<basic_block, 10> worklist (loop->num_nodes);
816 68070 : auto_vec<basic_block, 10> reachable (loop->num_nodes);
817 68070 : hash_set<edge> ignored_edges;
818 :
819 68070 : loop->header->flags |= reachable_flag;
820 68070 : worklist.quick_push (loop->header);
821 68070 : reachable.safe_push (loop->header);
822 :
823 639389 : while (!worklist.is_empty ())
824 : {
825 : edge e;
826 : edge_iterator ei;
827 572022 : int flags = ignored_edge_flag;
828 572022 : basic_block bb = worklist.pop ();
829 :
830 572022 : if (visit (bb))
831 : break;
832 :
833 571319 : gimple *last = *gsi_last_bb (bb);
834 296061 : if (gcond *cond = safe_dyn_cast <gcond *> (last))
835 : {
836 275258 : if (gimple_cond_true_p (cond))
837 : flags = EDGE_FALSE_VALUE;
838 269182 : else if (gimple_cond_false_p (cond))
839 : flags = EDGE_TRUE_VALUE;
840 262151 : else if (predicate_path)
841 : {
842 : tree res;
843 113666 : if (!get_predicates_for_bb (bb).is_empty ()
844 54696 : && (res = evaluate_control_stmt_using_entry_checks
845 54696 : (cond, *predicate_path, ignored_edge_flag,
846 : &ignored_edges)))
847 19534 : flags = (integer_nonzerop (res)
848 12990 : ? EDGE_FALSE_VALUE : EDGE_TRUE_VALUE);
849 : }
850 : }
851 571783 : else if (gswitch *swtch = safe_dyn_cast<gswitch *> (last))
852 : if (predicate_path
853 571783 : && !get_predicates_for_bb (bb).is_empty ())
854 190 : evaluate_control_stmt_using_entry_checks (swtch, *predicate_path,
855 : ignored_edge_flag,
856 : &ignored_edges);
857 :
858 : /* Note that for the moment we do not account reachable conditions
859 : which are simplified to take a known edge as zero size nor
860 : are we accounting for the required addition of the versioning
861 : condition. Those should cancel out conservatively. */
862 :
863 1420214 : FOR_EACH_EDGE (e, ei, bb->succs)
864 : {
865 848895 : basic_block dest = e->dest;
866 :
867 848895 : if (flow_bb_inside_loop_p (loop, dest)
868 739271 : && !(dest->flags & reachable_flag)
869 528441 : && !(e->flags & flags)
870 1353167 : && !ignored_edges.contains (e))
871 : {
872 504016 : dest->flags |= reachable_flag;
873 504016 : worklist.safe_push (dest);
874 504016 : reachable.safe_push (dest);
875 : }
876 : }
877 : }
878 :
879 : /* Clear the flag from basic blocks. */
880 708226 : while (!reachable.is_empty ())
881 572086 : reachable.pop ()->flags &= ~reachable_flag;
882 68070 : }
883 :
884 : /* Evaluate how many instruction will we have if we unswitch LOOP (with BBS)
885 : based on PREDICATE predicate (using PREDICATE_PATH). Store the
886 : result in TRUE_SIZE and FALSE_SIZE. */
887 :
888 : static void
889 1394 : evaluate_loop_insns_for_predicate (class loop *loop,
890 : predicate_vector &predicate_path,
891 : unswitch_predicate *predicate,
892 : int ignored_edge_flag,
893 : unsigned *true_size, unsigned *false_size)
894 : {
895 1394 : unsigned size = 0;
896 260063 : auto sum_size = [&](basic_block bb) -> bool
897 258669 : { size += (uintptr_t)bb->aux; return false; };
898 :
899 1394 : add_predicate_to_path (predicate_path, predicate, true);
900 1394 : evaluate_bbs (loop, &predicate_path, ignored_edge_flag, sum_size);
901 1394 : predicate_path.pop ();
902 1394 : unsigned true_loop_cost = size;
903 :
904 1394 : size = 0;
905 1394 : add_predicate_to_path (predicate_path, predicate, false);
906 1394 : evaluate_bbs (loop, &predicate_path, ignored_edge_flag, sum_size);
907 1394 : predicate_path.pop ();
908 1394 : unsigned false_loop_cost = size;
909 :
910 1394 : *true_size = true_loop_cost;
911 1394 : *false_size = false_loop_cost;
912 1394 : }
913 :
914 : /* Unswitch single LOOP. PREDICATE_PATH contains so far used predicates
915 : for unswitching. BUDGET is number of instruction for which we can increase
916 : the loop and is updated when unswitching occurs. If HOTTEST is not
917 : NULL then pick this candidate as the one to unswitch on. */
918 :
919 : static bool
920 67000 : tree_unswitch_single_loop (class loop *loop, dump_user_location_t loc,
921 : predicate_vector &predicate_path,
922 : unsigned loop_size, unsigned &budget,
923 : int ignored_edge_flag, bitmap handled,
924 : unswitch_predicate *hottest, basic_block hottest_bb)
925 : {
926 67000 : class loop *nloop;
927 67000 : bool changed = false;
928 67000 : unswitch_predicate *predicate = NULL;
929 67000 : basic_block predicate_bb = NULL;
930 67000 : unsigned true_size = 0, false_size = 0;
931 :
932 380353 : auto check_predicates = [&](basic_block bb) -> bool
933 : {
934 337123 : for (auto pred : get_predicates_for_bb (bb))
935 : {
936 8387 : if (bitmap_bit_p (handled, pred->num))
937 6993 : continue;
938 :
939 1394 : evaluate_loop_insns_for_predicate (loop, predicate_path,
940 : pred, ignored_edge_flag,
941 : &true_size, &false_size);
942 :
943 : /* We'll get LOOP replaced with a simplified version according
944 : to PRED estimated to TRUE_SIZE and a copy simplified
945 : according to the inverted PRED estimated to FALSE_SIZE. */
946 1394 : if (true_size + false_size < budget + loop_size)
947 : {
948 703 : predicate = pred;
949 703 : predicate_bb = bb;
950 :
951 : /* There are cases where true_size and false_size add up to
952 : less than the original loop_size. We do not want to
953 : grow the remaining budget because of that. */
954 703 : if (true_size + false_size > loop_size)
955 703 : budget -= (true_size + false_size - loop_size);
956 :
957 : /* FIXME: right now we select first candidate, but we can
958 : choose the cheapest or hottest one. */
959 703 : return true;
960 : }
961 691 : else if (dump_enabled_p ())
962 13 : dump_printf_loc (MSG_NOTE, loc,
963 : "not unswitching condition, cost too big "
964 : "(%u insns copied to %u and %u)\n", loop_size,
965 : true_size, false_size);
966 : }
967 : return false;
968 67000 : };
969 :
970 67000 : if (hottest)
971 : {
972 1718 : predicate = hottest;
973 1718 : predicate_bb = hottest_bb;
974 : }
975 : else
976 : /* Check predicates of reachable blocks. */
977 65282 : evaluate_bbs (loop, NULL, ignored_edge_flag, check_predicates);
978 :
979 67000 : if (predicate != NULL)
980 : {
981 2421 : if (!dbg_cnt (loop_unswitch))
982 0 : goto exit;
983 :
984 2421 : if (dump_enabled_p ())
985 : {
986 101 : dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc,
987 : "unswitching %sloop %d on %qs with condition: %T\n",
988 101 : loop->inner ? "outer " : "",
989 101 : loop->num, predicate->switch_p ? "switch" : "if",
990 : predicate->condition);
991 101 : dump_printf_loc (MSG_NOTE, loc,
992 : "optimized sizes estimated to %u (true) "
993 : "and %u (false) from original size %u\n",
994 : true_size, false_size, loop_size);
995 : }
996 :
997 2421 : bitmap_set_bit (handled, predicate->num);
998 2421 : initialize_original_copy_tables ();
999 : /* Unswitch the loop on this condition. */
1000 2421 : nloop = tree_unswitch_loop (loop, EDGE_SUCC (predicate_bb,
1001 : predicate->edge_index),
1002 : predicate->condition);
1003 2421 : if (!nloop)
1004 : {
1005 8 : free_original_copy_tables ();
1006 8 : goto exit;
1007 : }
1008 :
1009 : /* Copy BB costs. */
1010 2413 : basic_block *bbs2 = get_loop_body (nloop);
1011 24354 : for (unsigned i = 0; i < nloop->num_nodes; i++)
1012 21941 : bbs2[i]->aux = get_bb_original (bbs2[i])->aux;
1013 2413 : free (bbs2);
1014 :
1015 2413 : free_original_copy_tables ();
1016 :
1017 : /* Update the SSA form after unswitching. */
1018 2413 : update_ssa (TODO_update_ssa_no_phi);
1019 :
1020 : /* Invoke itself on modified loops. */
1021 2413 : bitmap handled_copy = BITMAP_ALLOC (NULL);
1022 2413 : bitmap_copy (handled_copy, handled);
1023 2413 : add_predicate_to_path (predicate_path, predicate, false);
1024 2413 : changed |= simplify_loop_version (nloop, predicate_path,
1025 : ignored_edge_flag, handled_copy);
1026 2413 : tree_unswitch_single_loop (nloop, loc, predicate_path,
1027 : false_size, budget,
1028 : ignored_edge_flag, handled_copy);
1029 2413 : predicate_path.pop ();
1030 2413 : BITMAP_FREE (handled_copy);
1031 :
1032 : /* FIXME: After unwinding above we have to reset all ->handled
1033 : flags as otherwise we fail to realize unswitching opportunities
1034 : in the below recursion. See gcc.dg/loop-unswitch-16.c */
1035 2413 : add_predicate_to_path (predicate_path, predicate, true);
1036 2413 : changed |= simplify_loop_version (loop, predicate_path,
1037 : ignored_edge_flag, handled);
1038 2413 : tree_unswitch_single_loop (loop, loc, predicate_path,
1039 : true_size, budget,
1040 : ignored_edge_flag, handled);
1041 2413 : predicate_path.pop ();
1042 2413 : changed = true;
1043 : }
1044 :
1045 64579 : exit:
1046 67000 : return changed;
1047 : }
1048 :
1049 : /* Unswitch a LOOP w.r. to given EDGE_TRUE. We only support unswitching of
1050 : innermost loops. COND is the condition determining which loop is entered;
1051 : the new loop is entered if COND is true. Returns NULL if impossible, new
1052 : loop otherwise. */
1053 :
1054 : static class loop *
1055 2421 : tree_unswitch_loop (class loop *loop, edge edge_true, tree cond)
1056 : {
1057 : /* Some sanity checking. */
1058 2421 : gcc_assert (flow_bb_inside_loop_p (loop, edge_true->src));
1059 2421 : gcc_assert (EDGE_COUNT (edge_true->src->succs) >= 2);
1060 :
1061 2421 : profile_probability prob_true = edge_true->probability;
1062 2421 : return loop_version (loop, unshare_expr (cond),
1063 : NULL, prob_true,
1064 : prob_true.invert (),
1065 : prob_true, prob_true.invert (),
1066 2421 : false);
1067 : }
1068 :
1069 : /* Unswitch outer loops by hoisting invariant guard on
1070 : inner loop without code duplication. */
1071 : static bool
1072 14477 : tree_unswitch_outer_loop (class loop *loop)
1073 : {
1074 14477 : edge exit, guard;
1075 14477 : HOST_WIDE_INT iterations;
1076 :
1077 14477 : gcc_assert (loop->inner);
1078 14477 : if (loop->inner->next)
1079 : return false;
1080 : /* Accept loops with single exit only which is not from inner loop. */
1081 12284 : exit = single_exit (loop);
1082 12284 : if (!exit || exit->src->loop_father != loop)
1083 : return false;
1084 : /* Check that phi argument of exit edge is not defined inside loop. */
1085 8503 : if (!check_exit_phi (loop))
1086 : return false;
1087 : /* If the loop is not expected to iterate, there is no need
1088 : for unswitching. */
1089 6092 : iterations = estimated_loop_iterations_int (loop);
1090 6092 : if (iterations < 0)
1091 3698 : iterations = likely_max_loop_iterations_int (loop);
1092 6092 : if (iterations >= 0 && iterations <= 1)
1093 : {
1094 275 : if (dump_enabled_p ())
1095 0 : dump_printf_loc (MSG_MISSED_OPTIMIZATION, find_loop_location (loop),
1096 : "Not unswitching, loop is not expected"
1097 : " to iterate\n");
1098 275 : return false;
1099 : }
1100 :
1101 5817 : bool changed = false;
1102 5817 : auto_vec<gimple *> dbg_to_reset;
1103 7561 : while ((guard = find_loop_guard (loop, dbg_to_reset)))
1104 : {
1105 1744 : hoist_guard (loop, guard);
1106 1744 : for (gimple *debug_stmt : dbg_to_reset)
1107 : {
1108 0 : gimple_debug_bind_reset_value (debug_stmt);
1109 0 : update_stmt (debug_stmt);
1110 : }
1111 1744 : dbg_to_reset.truncate (0);
1112 1744 : changed = true;
1113 : }
1114 5817 : return changed;
1115 5817 : }
1116 :
1117 : /* Checks if the body of the LOOP is within an invariant guard. If this
1118 : is the case, returns the edge that jumps over the real body of the loop,
1119 : otherwise returns NULL. */
1120 :
1121 : static edge
1122 7561 : find_loop_guard (class loop *loop, vec<gimple *> &dbg_to_reset)
1123 : {
1124 7561 : basic_block header = loop->header;
1125 7561 : edge guard_edge, te, fe;
1126 7561 : basic_block *body = NULL;
1127 14814 : unsigned i;
1128 14814 : tree use;
1129 14814 : ssa_op_iter iter;
1130 :
1131 : /* We check for the following situation:
1132 :
1133 : while (1)
1134 : {
1135 : [header]]
1136 : loop_phi_nodes;
1137 : something1;
1138 : if (cond1)
1139 : body;
1140 : nvar = phi(orig, bvar) ... for all variables changed in body;
1141 : [guard_end]
1142 : something2;
1143 : if (cond2)
1144 : break;
1145 : something3;
1146 : }
1147 :
1148 : where:
1149 :
1150 : 1) cond1 is loop invariant
1151 : 2) If cond1 is false, then the loop is essentially empty; i.e.,
1152 : a) nothing in something1, something2 and something3 has side
1153 : effects
1154 : b) anything defined in something1, something2 and something3
1155 : is not used outside of the loop. */
1156 :
1157 14814 : gcond *cond;
1158 14814 : do
1159 : {
1160 14814 : basic_block next = NULL;
1161 14814 : if (single_succ_p (header))
1162 4434 : next = single_succ (header);
1163 : else
1164 : {
1165 26415 : cond = safe_dyn_cast <gcond *> (*gsi_last_bb (header));
1166 10380 : if (! cond)
1167 : return NULL;
1168 10380 : extract_true_false_edges_from_block (header, &te, &fe);
1169 : /* Make sure to skip earlier hoisted guards that are left
1170 : in place as if (true). */
1171 10380 : if (gimple_cond_true_p (cond))
1172 323 : next = te->dest;
1173 10057 : else if (gimple_cond_false_p (cond))
1174 2496 : next = fe->dest;
1175 : else
1176 : break;
1177 : }
1178 : /* Never traverse a backedge. */
1179 7253 : if (header->loop_father->header == next)
1180 : return NULL;
1181 : header = next;
1182 : }
1183 : while (1);
1184 7561 : if (!flow_bb_inside_loop_p (loop, te->dest)
1185 7561 : || !flow_bb_inside_loop_p (loop, fe->dest))
1186 79 : return NULL;
1187 :
1188 7482 : if (just_once_each_iteration_p (loop, te->dest)
1189 7482 : || (single_succ_p (te->dest)
1190 4442 : && just_once_each_iteration_p (loop, single_succ (te->dest))))
1191 : {
1192 3812 : if (just_once_each_iteration_p (loop, fe->dest))
1193 : return NULL;
1194 3802 : guard_edge = te;
1195 : }
1196 3670 : else if (just_once_each_iteration_p (loop, fe->dest)
1197 3670 : || (single_succ_p (fe->dest)
1198 1905 : && just_once_each_iteration_p (loop, single_succ (fe->dest))))
1199 2191 : guard_edge = fe;
1200 : else
1201 1479 : return NULL;
1202 :
1203 5993 : dump_user_location_t loc = find_loop_location (loop);
1204 :
1205 : /* Guard edge must skip inner loop. */
1206 5993 : if (!dominated_by_p (CDI_DOMINATORS, loop->inner->header,
1207 5993 : guard_edge == fe ? te->dest : fe->dest))
1208 : {
1209 2383 : if (dump_enabled_p ())
1210 4 : dump_printf_loc (MSG_MISSED_OPTIMIZATION, loc,
1211 : "Guard edge %d --> %d is not around the loop!\n",
1212 4 : guard_edge->src->index, guard_edge->dest->index);
1213 2383 : return NULL;
1214 : }
1215 3610 : if (guard_edge->dest == loop->latch)
1216 : {
1217 0 : if (dump_enabled_p ())
1218 0 : dump_printf_loc (MSG_MISSED_OPTIMIZATION, loc,
1219 : "Guard edge destination is loop latch.\n");
1220 0 : return NULL;
1221 : }
1222 :
1223 3610 : if (dump_enabled_p ())
1224 103 : dump_printf_loc (MSG_NOTE, loc,
1225 : "Considering guard %d -> %d in loop %d\n",
1226 103 : guard_edge->src->index, guard_edge->dest->index,
1227 : loop->num);
1228 : /* Check if condition operands do not have definitions inside loop since
1229 : any bb copying is not performed. */
1230 6402 : FOR_EACH_SSA_TREE_OPERAND (use, cond, iter, SSA_OP_USE)
1231 : {
1232 4496 : gimple *def = SSA_NAME_DEF_STMT (use);
1233 4496 : basic_block def_bb = gimple_bb (def);
1234 4496 : if (def_bb
1235 4496 : && flow_bb_inside_loop_p (loop, def_bb))
1236 : {
1237 1704 : if (dump_enabled_p ())
1238 96 : dump_printf_loc (MSG_NOTE, loc, "guard operands have definitions"
1239 : " inside loop\n");
1240 1704 : return NULL;
1241 : }
1242 : }
1243 :
1244 1906 : body = get_loop_body (loop);
1245 22139 : for (i = 0; i < loop->num_nodes; i++)
1246 : {
1247 20395 : basic_block bb = body[i];
1248 20395 : if (bb->loop_father != loop)
1249 10315 : continue;
1250 10080 : if (bb->flags & BB_IRREDUCIBLE_LOOP)
1251 : {
1252 0 : if (dump_enabled_p ())
1253 0 : dump_printf_loc (MSG_MISSED_OPTIMIZATION, loc,
1254 : "Block %d is marked as irreducible in loop\n",
1255 : bb->index);
1256 0 : guard_edge = NULL;
1257 0 : goto end;
1258 : }
1259 : /* If any of the not skipped blocks has side-effects or defs with
1260 : uses outside of the loop we cannot hoist the guard. */
1261 10080 : if (!dominated_by_p (CDI_DOMINATORS,
1262 10080 : bb, guard_edge == te ? fe->dest : te->dest)
1263 10080 : && !empty_bb_without_guard_p (loop, bb, dbg_to_reset))
1264 : {
1265 162 : if (dump_enabled_p ())
1266 0 : dump_printf_loc (MSG_MISSED_OPTIMIZATION, loc,
1267 : "Block %d has side effects\n", bb->index);
1268 162 : guard_edge = NULL;
1269 162 : goto end;
1270 : }
1271 : }
1272 :
1273 1744 : if (dump_enabled_p ())
1274 7 : dump_printf_loc (MSG_NOTE, loc,
1275 : "suitable to hoist\n");
1276 1737 : end:
1277 1906 : if (body)
1278 1906 : free (body);
1279 : return guard_edge;
1280 : }
1281 :
1282 : /* Returns true if
1283 : 1) no statement in BB has side effects
1284 : 2) assuming that edge GUARD is always taken, all definitions in BB
1285 : are noy used outside of the loop.
1286 : KNOWN_INVARIANTS is a set of ssa names we know to be invariant, and
1287 : PROCESSED is a set of ssa names for that we already tested whether they
1288 : are invariant or not. Uses in debug stmts outside of the loop are
1289 : pushed to DBG_TO_RESET. */
1290 :
1291 : static bool
1292 7077 : empty_bb_without_guard_p (class loop *loop, basic_block bb,
1293 : vec<gimple *> &dbg_to_reset)
1294 : {
1295 7077 : basic_block exit_bb = single_exit (loop)->src;
1296 7077 : bool may_be_used_outside = (bb == exit_bb
1297 7077 : || !dominated_by_p (CDI_DOMINATORS, bb, exit_bb));
1298 5189 : tree name;
1299 5189 : ssa_op_iter op_iter;
1300 :
1301 : /* Phi nodes do not have side effects, but their results might be used
1302 : outside of the loop. */
1303 5189 : if (may_be_used_outside)
1304 : {
1305 5189 : for (gphi_iterator gsi = gsi_start_phis (bb);
1306 11099 : !gsi_end_p (gsi); gsi_next (&gsi))
1307 : {
1308 5910 : gphi *phi = gsi.phi ();
1309 5910 : name = PHI_RESULT (phi);
1310 11820 : if (virtual_operand_p (name))
1311 3735 : continue;
1312 :
1313 2175 : if (used_outside_loop_p (loop, name, dbg_to_reset))
1314 0 : return false;
1315 : }
1316 : }
1317 :
1318 14154 : for (gimple_stmt_iterator gsi = gsi_start_bb (bb);
1319 16434 : !gsi_end_p (gsi); gsi_next (&gsi))
1320 : {
1321 9519 : gimple *stmt = gsi_stmt (gsi);
1322 9519 : if (is_gimple_debug (stmt))
1323 1094 : continue;
1324 :
1325 8425 : if (gimple_has_side_effects (stmt))
1326 : return false;
1327 :
1328 12422 : if (gimple_vdef(stmt))
1329 : return false;
1330 :
1331 12300 : FOR_EACH_SSA_TREE_OPERAND (name, stmt, op_iter, SSA_OP_DEF)
1332 : {
1333 4037 : if (may_be_used_outside
1334 4037 : && used_outside_loop_p (loop, name, dbg_to_reset))
1335 : return false;
1336 : }
1337 : }
1338 : return true;
1339 : }
1340 :
1341 : /* Return true if NAME is used outside of LOOP. Pushes debug stmts that
1342 : have such uses to DBG_TO_RESET but do not consider such uses. */
1343 :
1344 : static bool
1345 6190 : used_outside_loop_p (class loop *loop, tree name, vec<gimple *> &dbg_to_reset)
1346 : {
1347 6190 : imm_use_iterator it;
1348 6190 : use_operand_p use;
1349 :
1350 24231 : FOR_EACH_IMM_USE_FAST (use, it, name)
1351 : {
1352 11851 : gimple *stmt = USE_STMT (use);
1353 11851 : if (!flow_bb_inside_loop_p (loop, gimple_bb (stmt)))
1354 : {
1355 0 : if (!is_gimple_debug (stmt))
1356 0 : return true;
1357 0 : dbg_to_reset.safe_push (stmt);
1358 : }
1359 0 : }
1360 :
1361 6190 : return false;
1362 : }
1363 :
1364 : /* Return argument for loop preheader edge in header virtual phi if any. */
1365 :
1366 : static tree
1367 1733 : get_vop_from_header (class loop *loop)
1368 : {
1369 1733 : for (gphi_iterator gsi = gsi_start_phis (loop->header);
1370 3492 : !gsi_end_p (gsi); gsi_next (&gsi))
1371 : {
1372 3492 : gphi *phi = gsi.phi ();
1373 6984 : if (!virtual_operand_p (gimple_phi_result (phi)))
1374 1759 : continue;
1375 1733 : return PHI_ARG_DEF_FROM_EDGE (phi, loop_preheader_edge (loop));
1376 : }
1377 0 : return NULL_TREE;
1378 : }
1379 :
1380 : /* Move the check of GUARD outside of LOOP. */
1381 :
1382 : static void
1383 1744 : hoist_guard (class loop *loop, edge guard)
1384 : {
1385 1744 : edge exit = single_exit (loop);
1386 1744 : edge preh = loop_preheader_edge (loop);
1387 1744 : basic_block pre_header = preh->src;
1388 1744 : basic_block bb;
1389 1744 : edge te, fe, e, new_edge;
1390 1744 : gimple *stmt;
1391 1744 : basic_block guard_bb = guard->src;
1392 1744 : edge not_guard;
1393 1744 : gimple_stmt_iterator gsi;
1394 1744 : int flags = 0;
1395 1744 : bool fix_dom_of_exit;
1396 1744 : gcond *cond_stmt, *new_cond_stmt;
1397 :
1398 1744 : bb = get_immediate_dominator (CDI_DOMINATORS, exit->dest);
1399 1744 : fix_dom_of_exit = flow_bb_inside_loop_p (loop, bb);
1400 1744 : gsi = gsi_last_bb (guard_bb);
1401 1744 : stmt = gsi_stmt (gsi);
1402 1744 : gcc_assert (gimple_code (stmt) == GIMPLE_COND);
1403 1744 : cond_stmt = as_a <gcond *> (stmt);
1404 1744 : extract_true_false_edges_from_block (guard_bb, &te, &fe);
1405 : /* Insert guard to PRE_HEADER. */
1406 1744 : gsi = gsi_last_bb (pre_header);
1407 : /* Create copy of COND_STMT. */
1408 1744 : new_cond_stmt = gimple_build_cond (gimple_cond_code (cond_stmt),
1409 : gimple_cond_lhs (cond_stmt),
1410 : gimple_cond_rhs (cond_stmt),
1411 : NULL_TREE, NULL_TREE);
1412 1744 : gsi_insert_after (&gsi, new_cond_stmt, GSI_NEW_STMT);
1413 : /* Convert COND_STMT to true/false conditional. */
1414 1744 : if (guard == te)
1415 1546 : gimple_cond_make_false (cond_stmt);
1416 : else
1417 198 : gimple_cond_make_true (cond_stmt);
1418 1744 : update_stmt (cond_stmt);
1419 : /* Create new loop pre-header. */
1420 1744 : e = split_block (pre_header, last_nondebug_stmt (pre_header));
1421 :
1422 1744 : dump_user_location_t loc = find_loop_location (loop);
1423 :
1424 1744 : if (dump_enabled_p ())
1425 : {
1426 7 : char buffer[64];
1427 7 : guard->probability.dump (buffer);
1428 :
1429 7 : dump_printf_loc (MSG_NOTE, loc,
1430 : "Moving guard %i->%i (prob %s) to bb %i, "
1431 : "new preheader is %i\n",
1432 7 : guard->src->index, guard->dest->index,
1433 7 : buffer, e->src->index, e->dest->index);
1434 : }
1435 :
1436 1744 : gcc_assert (loop_preheader_edge (loop)->src == e->dest);
1437 :
1438 1744 : if (guard == fe)
1439 : {
1440 198 : e->flags = EDGE_TRUE_VALUE;
1441 198 : flags |= EDGE_FALSE_VALUE;
1442 198 : not_guard = te;
1443 : }
1444 : else
1445 : {
1446 1546 : e->flags = EDGE_FALSE_VALUE;
1447 1546 : flags |= EDGE_TRUE_VALUE;
1448 1546 : not_guard = fe;
1449 : }
1450 1744 : new_edge = make_edge (pre_header, exit->dest, flags);
1451 :
1452 : /* Determine the probability that we skip the loop. Assume that loop has
1453 : same average number of iterations regardless outcome of guard. */
1454 1744 : new_edge->probability = guard->probability;
1455 3488 : profile_count skip_count = guard->src->count.nonzero_p ()
1456 3488 : ? guard->count ().apply_scale (pre_header->count,
1457 1744 : guard->src->count)
1458 0 : : guard->count ().apply_probability (new_edge->probability);
1459 :
1460 1744 : if (skip_count > e->count ())
1461 : {
1462 0 : if (dump_file && (dump_flags & TDF_DETAILS))
1463 0 : fprintf (dump_file, " Capping count; expect profile inconsistency\n");
1464 0 : skip_count = e->count ();
1465 : }
1466 1744 : if (dump_enabled_p ())
1467 : {
1468 7 : char buffer[64];
1469 7 : new_edge->probability.dump (buffer);
1470 :
1471 7 : dump_printf_loc (MSG_NOTE, loc,
1472 : "Estimated probability of skipping loop is %s\n",
1473 : buffer);
1474 : }
1475 :
1476 : /* Update profile after the transform:
1477 :
1478 : First decrease count of path from newly hoisted loop guard
1479 : to loop header... */
1480 1744 : e->probability = new_edge->probability.invert ();
1481 1744 : e->dest->count = e->count ();
1482 :
1483 : /* ... now update profile to represent that original guard will be optimized
1484 : away ... */
1485 1744 : guard->probability = profile_probability::never ();
1486 1744 : not_guard->probability = profile_probability::always ();
1487 :
1488 : /* ... finally scale everything in the loop except for guarded basic blocks
1489 : where profile does not change. */
1490 1744 : basic_block *body = get_loop_body (loop);
1491 :
1492 21681 : for (unsigned int i = 0; i < loop->num_nodes; i++)
1493 : {
1494 19937 : basic_block bb = body[i];
1495 19937 : if (!dominated_by_p (CDI_DOMINATORS, bb, not_guard->dest))
1496 : {
1497 6619 : if (dump_enabled_p ())
1498 27 : dump_printf_loc (MSG_NOTE, loc,
1499 : "Scaling nonguarded BBs in loop: %i\n",
1500 : bb->index);
1501 6619 : if (e->probability.initialized_p ())
1502 6619 : scale_bbs_frequencies (&bb, 1, e->probability);
1503 : }
1504 : }
1505 :
1506 1744 : if (fix_dom_of_exit)
1507 664 : set_immediate_dominator (CDI_DOMINATORS, exit->dest, pre_header);
1508 : /* Add NEW_ADGE argument for all phi in post-header block. */
1509 1744 : bb = exit->dest;
1510 1744 : for (gphi_iterator gsi = gsi_start_phis (bb);
1511 3674 : !gsi_end_p (gsi); gsi_next (&gsi))
1512 : {
1513 1930 : gphi *phi = gsi.phi ();
1514 1930 : tree arg;
1515 3860 : if (virtual_operand_p (gimple_phi_result (phi)))
1516 : {
1517 1733 : arg = get_vop_from_header (loop);
1518 1733 : if (arg == NULL_TREE)
1519 : /* Use exit edge argument. */
1520 0 : arg = PHI_ARG_DEF_FROM_EDGE (phi, exit);
1521 1733 : add_phi_arg (phi, arg, new_edge, UNKNOWN_LOCATION);
1522 : }
1523 : else
1524 : {
1525 : /* Use exit edge argument. */
1526 197 : arg = PHI_ARG_DEF_FROM_EDGE (phi, exit);
1527 197 : add_phi_arg (phi, arg, new_edge, UNKNOWN_LOCATION);
1528 : }
1529 : }
1530 :
1531 1744 : if (dump_enabled_p ())
1532 7 : dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc,
1533 : "Guard hoisted\n");
1534 :
1535 1744 : free (body);
1536 1744 : }
1537 :
1538 : /* Return true if phi argument for exit edge can be used
1539 : for edge around loop. */
1540 :
1541 : static bool
1542 8503 : check_exit_phi (class loop *loop)
1543 : {
1544 8503 : edge exit = single_exit (loop);
1545 8503 : basic_block pre_header = loop_preheader_edge (loop)->src;
1546 :
1547 8503 : for (gphi_iterator gsi = gsi_start_phis (exit->dest);
1548 14714 : !gsi_end_p (gsi); gsi_next (&gsi))
1549 : {
1550 8622 : gphi *phi = gsi.phi ();
1551 8622 : tree arg;
1552 8622 : gimple *def;
1553 8622 : basic_block def_bb;
1554 17244 : if (virtual_operand_p (gimple_phi_result (phi)))
1555 6056 : continue;
1556 2566 : arg = PHI_ARG_DEF_FROM_EDGE (phi, exit);
1557 2566 : if (TREE_CODE (arg) != SSA_NAME)
1558 12 : continue;
1559 2554 : def = SSA_NAME_DEF_STMT (arg);
1560 2554 : if (!def)
1561 0 : continue;
1562 2554 : def_bb = gimple_bb (def);
1563 2554 : if (!def_bb)
1564 0 : continue;
1565 2554 : if (!dominated_by_p (CDI_DOMINATORS, pre_header, def_bb))
1566 : /* Definition inside loop! */
1567 2411 : return false;
1568 : /* Check loop closed phi invariant. */
1569 143 : if (!flow_bb_inside_loop_p (def_bb->loop_father, pre_header))
1570 : return false;
1571 : }
1572 6092 : return true;
1573 : }
1574 :
1575 : /* Remove all dead cases from switches that are unswitched. */
1576 :
1577 : static void
1578 1353 : clean_up_after_unswitching (int ignored_edge_flag)
1579 : {
1580 1353 : basic_block bb;
1581 1353 : edge e;
1582 1353 : edge_iterator ei;
1583 1353 : bool removed_edge = false;
1584 :
1585 72080 : FOR_EACH_BB_FN (bb, cfun)
1586 : {
1587 141454 : gswitch *stmt= safe_dyn_cast <gswitch *> (*gsi_last_bb (bb));
1588 153 : if (stmt && !CONSTANT_CLASS_P (gimple_switch_index (stmt)))
1589 : {
1590 74 : unsigned nlabels = gimple_switch_num_labels (stmt);
1591 74 : unsigned index = 1;
1592 74 : tree lab = gimple_switch_default_label (stmt);
1593 148 : edge default_e = find_edge (gimple_bb (stmt),
1594 74 : label_to_block (cfun, CASE_LABEL (lab)));
1595 333 : for (unsigned i = 1; i < nlabels; ++i)
1596 : {
1597 259 : tree lab = gimple_switch_label (stmt, i);
1598 259 : basic_block dest = label_to_block (cfun, CASE_LABEL (lab));
1599 259 : edge e = find_edge (gimple_bb (stmt), dest);
1600 259 : if (e == NULL)
1601 : ; /* The edge is already removed. */
1602 251 : else if (e->flags & ignored_edge_flag)
1603 : {
1604 : /* We may not remove the default label so we also have
1605 : to preserve its edge. But we can remove the
1606 : non-default CASE sharing the edge. */
1607 89 : if (e != default_e)
1608 : {
1609 89 : remove_edge (e);
1610 89 : removed_edge = true;
1611 : }
1612 : }
1613 : else
1614 : {
1615 162 : gimple_switch_set_label (stmt, index, lab);
1616 162 : ++index;
1617 : }
1618 : }
1619 :
1620 74 : if (index != nlabels)
1621 35 : gimple_switch_set_num_labels (stmt, index);
1622 : }
1623 :
1624 : /* Clean up the ignored_edge_flag from edges. */
1625 170926 : FOR_EACH_EDGE (e, ei, bb->succs)
1626 100199 : e->flags &= ~ignored_edge_flag;
1627 : }
1628 :
1629 : /* If we removed an edge we possibly have to recompute dominators. */
1630 1353 : if (removed_edge)
1631 30 : free_dominance_info (CDI_DOMINATORS);
1632 1353 : }
1633 :
1634 : /* Loop unswitching pass. */
1635 :
1636 : namespace {
1637 :
1638 : const pass_data pass_data_tree_unswitch =
1639 : {
1640 : GIMPLE_PASS, /* type */
1641 : "unswitch", /* name */
1642 : OPTGROUP_LOOP, /* optinfo_flags */
1643 : TV_TREE_LOOP_UNSWITCH, /* tv_id */
1644 : PROP_cfg, /* properties_required */
1645 : 0, /* properties_provided */
1646 : 0, /* properties_destroyed */
1647 : 0, /* todo_flags_start */
1648 : 0, /* todo_flags_finish */
1649 : };
1650 :
1651 : class pass_tree_unswitch : public gimple_opt_pass
1652 : {
1653 : public:
1654 285722 : pass_tree_unswitch (gcc::context *ctxt)
1655 571444 : : gimple_opt_pass (pass_data_tree_unswitch, ctxt)
1656 : {}
1657 :
1658 : /* opt_pass methods: */
1659 241458 : bool gate (function *) final override { return flag_unswitch_loops != 0; }
1660 : unsigned int execute (function *) final override;
1661 :
1662 : }; // class pass_tree_unswitch
1663 :
1664 : unsigned int
1665 28166 : pass_tree_unswitch::execute (function *fun)
1666 : {
1667 56332 : if (number_of_loops (fun) <= 1)
1668 : return 0;
1669 :
1670 28166 : return tree_ssa_unswitch_loops (fun);
1671 : }
1672 :
1673 : } // anon namespace
1674 :
1675 : gimple_opt_pass *
1676 285722 : make_pass_tree_unswitch (gcc::context *ctxt)
1677 : {
1678 285722 : return new pass_tree_unswitch (ctxt);
1679 : }
1680 :
1681 :
|