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