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