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