]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/tree-ssa-loop-ch.cc
Fix latent bug in loop header copying which forgets to update the loop header pointer
[thirdparty/gcc.git] / gcc / tree-ssa-loop-ch.cc
1 /* Loop header copying on trees.
2 Copyright (C) 2004-2023 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 "cfghooks.h"
27 #include "tree-pass.h"
28 #include "gimple-ssa.h"
29 #include "gimple-iterator.h"
30 #include "tree-cfg.h"
31 #include "tree-into-ssa.h"
32 #include "cfgloop.h"
33 #include "tree-inline.h"
34 #include "tree-ssa-threadedge.h"
35 #include "tree-ssa-sccvn.h"
36 #include "tree-phinodes.h"
37 #include "ssa-iterators.h"
38 #include "value-range.h"
39 #include "gimple-range.h"
40 #include "gimple-range-path.h"
41 #include "cfganal.h"
42
43 /* Duplicates headers of loops if they are small enough, so that the statements
44 in the loop body are always executed when the loop is entered. This
45 increases effectiveness of code motion optimizations, and reduces the need
46 for loop preconditioning. */
47
48 /* Given a path through edge E, whose last statement is COND, return
49 the range of the solved conditional in R. */
50
51 static void
52 edge_range_query (irange &r, edge e, gcond *cond, gimple_ranger &ranger)
53 {
54 auto_vec<basic_block> path (2);
55 path.safe_push (e->dest);
56 path.safe_push (e->src);
57 path_range_query query (ranger, path);
58 if (!query.range_of_stmt (r, cond))
59 r.set_varying (boolean_type_node);
60 }
61
62 /* Return true if the condition on the first iteration of the loop can
63 be statically determined. */
64
65 static bool
66 entry_loop_condition_is_static (class loop *l, gimple_ranger *ranger)
67 {
68 edge e = loop_preheader_edge (l);
69 gcond *last = safe_dyn_cast <gcond *> (last_stmt (e->dest));
70
71 if (!last)
72 return false;
73
74 edge true_e, false_e;
75 extract_true_false_edges_from_block (e->dest, &true_e, &false_e);
76
77 /* If neither edge is the exit edge, this is not a case we'd like to
78 special-case. */
79 if (!loop_exit_edge_p (l, true_e) && !loop_exit_edge_p (l, false_e))
80 return false;
81
82 tree desired_static_value;
83 if (loop_exit_edge_p (l, true_e))
84 desired_static_value = boolean_false_node;
85 else
86 desired_static_value = boolean_true_node;
87
88 int_range<2> r;
89 edge_range_query (r, e, last, *ranger);
90 return r == int_range<2> (desired_static_value, desired_static_value);
91 }
92
93 /* Check whether we should duplicate HEADER of LOOP. At most *LIMIT
94 instructions should be duplicated, limit is decreased by the actual
95 amount. */
96
97 static bool
98 should_duplicate_loop_header_p (basic_block header, class loop *loop,
99 int *limit)
100 {
101 gimple_stmt_iterator bsi;
102
103 gcc_assert (!header->aux);
104
105 gcc_assert (EDGE_COUNT (header->succs) > 0);
106 if (single_succ_p (header))
107 {
108 if (dump_file && (dump_flags & TDF_DETAILS))
109 fprintf (dump_file,
110 " Not duplicating bb %i: it is single succ.\n",
111 header->index);
112 return false;
113 }
114
115 if (flow_bb_inside_loop_p (loop, EDGE_SUCC (header, 0)->dest)
116 && flow_bb_inside_loop_p (loop, EDGE_SUCC (header, 1)->dest))
117 {
118 if (dump_file && (dump_flags & TDF_DETAILS))
119 fprintf (dump_file,
120 " Not duplicating bb %i: both successors are in loop.\n",
121 loop->num);
122 return false;
123 }
124
125 /* If this is not the original loop header, we want it to have just
126 one predecessor in order to match the && pattern. */
127 if (header != loop->header && !single_pred_p (header))
128 {
129 if (dump_file && (dump_flags & TDF_DETAILS))
130 fprintf (dump_file,
131 " Not duplicating bb %i: it has mutiple predecestors.\n",
132 header->index);
133 return false;
134 }
135
136 gcond *last = safe_dyn_cast <gcond *> (last_stmt (header));
137 if (!last)
138 {
139 if (dump_file && (dump_flags & TDF_DETAILS))
140 fprintf (dump_file,
141 " Not duplicating bb %i: it does not end by conditional.\n",
142 header->index);
143 return false;
144 }
145
146 for (gphi_iterator psi = gsi_start_phis (header); !gsi_end_p (psi);
147 gsi_next (&psi))
148 {
149 gphi *phi = psi.phi ();
150 tree res = gimple_phi_result (phi);
151 if (INTEGRAL_TYPE_P (TREE_TYPE (res))
152 || POINTER_TYPE_P (TREE_TYPE (res)))
153 gimple_set_uid (phi, 1 /* IV */);
154 else
155 gimple_set_uid (phi, 0);
156 }
157
158 /* Count number of instructions and punt on calls.
159 Populate stmts INV/IV flag to later apply heuristics to the
160 kind of conditions we want to copy. */
161 for (bsi = gsi_start_bb (header); !gsi_end_p (bsi); gsi_next (&bsi))
162 {
163 gimple *last = gsi_stmt (bsi);
164
165 if (gimple_code (last) == GIMPLE_LABEL)
166 continue;
167
168 if (is_gimple_debug (last))
169 continue;
170
171 if (gimple_code (last) == GIMPLE_CALL
172 && (!gimple_inexpensive_call_p (as_a <gcall *> (last))
173 /* IFN_LOOP_DIST_ALIAS means that inner loop is distributed
174 at current loop's header. Don't copy in this case. */
175 || gimple_call_internal_p (last, IFN_LOOP_DIST_ALIAS)))
176 {
177 if (dump_file && (dump_flags & TDF_DETAILS))
178 fprintf (dump_file,
179 " Not duplicating bb %i: it contains call.\n",
180 header->index);
181 return false;
182 }
183
184 *limit -= estimate_num_insns (last, &eni_size_weights);
185 if (*limit < 0)
186 {
187 if (dump_file && (dump_flags & TDF_DETAILS))
188 fprintf (dump_file,
189 " Not duplicating bb %i contains too many insns.\n",
190 header->index);
191 return false;
192 }
193
194 /* Classify the stmt based on whether its computation is based
195 on a IV or whether it is invariant in the loop. */
196 gimple_set_uid (last, 0);
197 if (!gimple_vuse (last))
198 {
199 bool inv = true;
200 bool iv = false;
201 ssa_op_iter i;
202 tree op;
203 FOR_EACH_SSA_TREE_OPERAND (op, last, i, SSA_OP_USE)
204 if (!SSA_NAME_IS_DEFAULT_DEF (op)
205 && flow_bb_inside_loop_p (loop,
206 gimple_bb (SSA_NAME_DEF_STMT (op))))
207 {
208 if (!(gimple_uid (SSA_NAME_DEF_STMT (op)) & 2 /* INV */))
209 inv = false;
210 if (gimple_uid (SSA_NAME_DEF_STMT (op)) & 1 /* IV */)
211 iv = true;
212 }
213 gimple_set_uid (last, (iv ? 1 : 0) | (inv ? 2 : 0));
214 }
215 }
216
217 /* If the condition tests a non-IV loop variant we do not want to rotate
218 the loop further. Unless this is the original loop header. */
219 tree lhs = gimple_cond_lhs (last);
220 tree rhs = gimple_cond_rhs (last);
221 if (header != loop->header
222 && ((TREE_CODE (lhs) == SSA_NAME
223 && !SSA_NAME_IS_DEFAULT_DEF (lhs)
224 && flow_bb_inside_loop_p (loop, gimple_bb (SSA_NAME_DEF_STMT (lhs)))
225 && gimple_uid (SSA_NAME_DEF_STMT (lhs)) == 0)
226 || (TREE_CODE (rhs) == SSA_NAME
227 && !SSA_NAME_IS_DEFAULT_DEF (rhs)
228 && flow_bb_inside_loop_p (loop,
229 gimple_bb (SSA_NAME_DEF_STMT (rhs)))
230 && gimple_uid (SSA_NAME_DEF_STMT (rhs)) == 0)))
231 {
232 if (dump_file && (dump_flags & TDF_DETAILS))
233 fprintf (dump_file,
234 " Not duplicating bb %i: condition based on non-IV loop"
235 " variant.\n", header->index);
236 return false;
237 }
238
239 return true;
240 }
241
242 /* Checks whether LOOP is a do-while style loop. */
243
244 static bool
245 do_while_loop_p (class loop *loop)
246 {
247 gimple *stmt = last_stmt (loop->latch);
248
249 /* If the latch of the loop is not empty, it is not a do-while loop. */
250 if (stmt
251 && gimple_code (stmt) != GIMPLE_LABEL)
252 {
253 if (dump_file && (dump_flags & TDF_DETAILS))
254 fprintf (dump_file,
255 "Loop %i is not do-while loop: latch is not empty.\n",
256 loop->num);
257 return false;
258 }
259
260 /* If the latch does not have a single predecessor, it is not a
261 do-while loop. */
262 if (!single_pred_p (loop->latch))
263 {
264 if (dump_file && (dump_flags & TDF_DETAILS))
265 fprintf (dump_file,
266 "Loop %i is not do-while loop: latch has multiple "
267 "predecessors.\n", loop->num);
268 return false;
269 }
270
271 /* If the latch predecessor doesn't exit the loop, it is not a
272 do-while loop. */
273 if (!loop_exits_from_bb_p (loop, single_pred (loop->latch)))
274 {
275 if (dump_file && (dump_flags & TDF_DETAILS))
276 fprintf (dump_file,
277 "Loop %i is not do-while loop: latch predecessor "
278 "does not exit loop.\n", loop->num);
279 return false;
280 }
281
282 if (dump_file && (dump_flags & TDF_DETAILS))
283 fprintf (dump_file, "Loop %i is do-while loop\n", loop->num);
284
285 return true;
286 }
287
288 namespace {
289
290 /* Common superclass for both header-copying phases. */
291 class ch_base : public gimple_opt_pass
292 {
293 protected:
294 ch_base (pass_data data, gcc::context *ctxt)
295 : gimple_opt_pass (data, ctxt)
296 {}
297
298 /* Copies headers of all loops in FUN for which process_loop_p is true. */
299 unsigned int copy_headers (function *fun);
300
301 /* Return true to copy headers of LOOP or false to skip. */
302 virtual bool process_loop_p (class loop *loop) = 0;
303 };
304
305 const pass_data pass_data_ch =
306 {
307 GIMPLE_PASS, /* type */
308 "ch", /* name */
309 OPTGROUP_LOOP, /* optinfo_flags */
310 TV_TREE_CH, /* tv_id */
311 ( PROP_cfg | PROP_ssa ), /* properties_required */
312 0, /* properties_provided */
313 0, /* properties_destroyed */
314 0, /* todo_flags_start */
315 0, /* todo_flags_finish */
316 };
317
318 class pass_ch : public ch_base
319 {
320 public:
321 pass_ch (gcc::context *ctxt)
322 : ch_base (pass_data_ch, ctxt)
323 {}
324
325 /* opt_pass methods: */
326 bool gate (function *) final override { return flag_tree_ch != 0; }
327
328 /* Initialize and finalize loop structures, copying headers inbetween. */
329 unsigned int execute (function *) final override;
330
331 opt_pass * clone () final override { return new pass_ch (m_ctxt); }
332
333 protected:
334 /* ch_base method: */
335 bool process_loop_p (class loop *loop) final override;
336 }; // class pass_ch
337
338 const pass_data pass_data_ch_vect =
339 {
340 GIMPLE_PASS, /* type */
341 "ch_vect", /* name */
342 OPTGROUP_LOOP, /* optinfo_flags */
343 TV_TREE_CH, /* tv_id */
344 ( PROP_cfg | PROP_ssa ), /* properties_required */
345 0, /* properties_provided */
346 0, /* properties_destroyed */
347 0, /* todo_flags_start */
348 0, /* todo_flags_finish */
349 };
350
351 /* This is a more aggressive version of the same pass, designed to run just
352 before if-conversion and vectorization, to put more loops into the form
353 required for those phases. */
354 class pass_ch_vect : public ch_base
355 {
356 public:
357 pass_ch_vect (gcc::context *ctxt)
358 : ch_base (pass_data_ch_vect, ctxt)
359 {}
360
361 /* opt_pass methods: */
362 bool gate (function *fun) final override
363 {
364 return flag_tree_ch != 0
365 && (flag_tree_loop_vectorize != 0 || fun->has_force_vectorize_loops);
366 }
367
368 /* Just copy headers, no initialization/finalization of loop structures. */
369 unsigned int execute (function *) final override;
370
371 protected:
372 /* ch_base method: */
373 bool process_loop_p (class loop *loop) final override;
374 }; // class pass_ch_vect
375
376 /* For all loops, copy the condition at the end of the loop body in front
377 of the loop. This is beneficial since it increases efficiency of
378 code motion optimizations. It also saves one jump on entry to the loop. */
379
380 unsigned int
381 ch_base::copy_headers (function *fun)
382 {
383 basic_block header;
384 edge exit, entry;
385 basic_block *bbs, *copied_bbs;
386 unsigned n_bbs;
387 unsigned bbs_size;
388 bool changed = false;
389
390 if (number_of_loops (fun) <= 1)
391 return 0;
392
393 bbs = XNEWVEC (basic_block, n_basic_blocks_for_fn (fun));
394 copied_bbs = XNEWVEC (basic_block, n_basic_blocks_for_fn (fun));
395 bbs_size = n_basic_blocks_for_fn (fun);
396
397 auto_vec<loop_p> candidates;
398 auto_vec<std::pair<edge, loop_p> > copied;
399
400 mark_dfs_back_edges ();
401 gimple_ranger *ranger = new gimple_ranger;
402 for (auto loop : loops_list (cfun, 0))
403 {
404 int initial_limit = param_max_loop_header_insns;
405 int remaining_limit = initial_limit;
406 if (dump_file && (dump_flags & TDF_DETAILS))
407 fprintf (dump_file,
408 "Analyzing loop %i\n", loop->num);
409
410 header = loop->header;
411
412 /* If the loop is already a do-while style one (either because it was
413 written as such, or because jump threading transformed it into one),
414 we might be in fact peeling the first iteration of the loop. This
415 in general is not a good idea. Also avoid touching infinite loops. */
416 if (!loop_has_exit_edges (loop)
417 || !process_loop_p (loop))
418 continue;
419
420 /* Avoid loop header copying when optimizing for size unless we can
421 determine that the loop condition is static in the first
422 iteration. */
423 if (optimize_loop_for_size_p (loop)
424 && !loop->force_vectorize
425 && !entry_loop_condition_is_static (loop, ranger))
426 {
427 if (dump_file && (dump_flags & TDF_DETAILS))
428 fprintf (dump_file,
429 " Not duplicating bb %i: optimizing for size.\n",
430 header->index);
431 continue;
432 }
433
434 if (should_duplicate_loop_header_p (header, loop, &remaining_limit))
435 candidates.safe_push (loop);
436 }
437 /* Do not use ranger after we change the IL and not have updated SSA. */
438 delete ranger;
439
440 for (auto loop : candidates)
441 {
442 int initial_limit = param_max_loop_header_insns;
443 int remaining_limit = initial_limit;
444 if (dump_file && (dump_flags & TDF_DETAILS))
445 fprintf (dump_file,
446 "Copying headers of loop %i\n", loop->num);
447
448 header = loop->header;
449
450 /* Iterate the header copying up to limit; this takes care of the cases
451 like while (a && b) {...}, where we want to have both of the conditions
452 copied. TODO -- handle while (a || b) - like cases, by not requiring
453 the header to have just a single successor and copying up to
454 postdominator. */
455
456 exit = NULL;
457 n_bbs = 0;
458 while (should_duplicate_loop_header_p (header, loop, &remaining_limit))
459 {
460 if (dump_file && (dump_flags & TDF_DETAILS))
461 fprintf (dump_file, " Will duplicate bb %i\n", header->index);
462
463 /* Find a successor of header that is inside a loop; i.e. the new
464 header after the condition is copied. */
465 if (flow_bb_inside_loop_p (loop, EDGE_SUCC (header, 0)->dest))
466 exit = EDGE_SUCC (header, 0);
467 else
468 exit = EDGE_SUCC (header, 1);
469 bbs[n_bbs++] = header;
470 gcc_assert (bbs_size > n_bbs);
471 header = exit->dest;
472 }
473
474 if (!exit)
475 continue;
476
477 if (dump_file && (dump_flags & TDF_DETAILS))
478 fprintf (dump_file,
479 "Duplicating header of the loop %d up to edge %d->%d,"
480 " %i insns.\n",
481 loop->num, exit->src->index, exit->dest->index,
482 initial_limit - remaining_limit);
483
484 /* Ensure that the header will have just the latch as a predecessor
485 inside the loop. */
486 if (!single_pred_p (exit->dest))
487 exit = single_pred_edge (split_edge (exit));
488
489 entry = loop_preheader_edge (loop);
490
491 propagate_threaded_block_debug_into (exit->dest, entry->dest);
492 if (!gimple_duplicate_sese_region (entry, exit, bbs, n_bbs, copied_bbs,
493 true))
494 {
495 if (dump_file && (dump_flags & TDF_DETAILS))
496 fprintf (dump_file, "Duplication failed.\n");
497 continue;
498 }
499 copied.safe_push (std::make_pair (entry, loop));
500
501 /* If the loop has the form "for (i = j; i < j + 10; i++)" then
502 this copying can introduce a case where we rely on undefined
503 signed overflow to eliminate the preheader condition, because
504 we assume that "j < j + 10" is true. We don't want to warn
505 about that case for -Wstrict-overflow, because in general we
506 don't warn about overflow involving loops. Prevent the
507 warning by setting the no_warning flag in the condition. */
508 if (warn_strict_overflow > 0)
509 {
510 unsigned int i;
511
512 for (i = 0; i < n_bbs; ++i)
513 {
514 gimple_stmt_iterator bsi;
515
516 for (bsi = gsi_start_bb (copied_bbs[i]);
517 !gsi_end_p (bsi);
518 gsi_next (&bsi))
519 {
520 gimple *stmt = gsi_stmt (bsi);
521 if (gimple_code (stmt) == GIMPLE_COND)
522 {
523 tree lhs = gimple_cond_lhs (stmt);
524 if (gimple_cond_code (stmt) != EQ_EXPR
525 && gimple_cond_code (stmt) != NE_EXPR
526 && INTEGRAL_TYPE_P (TREE_TYPE (lhs))
527 && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (lhs)))
528 suppress_warning (stmt, OPT_Wstrict_overflow_);
529 }
530 else if (is_gimple_assign (stmt))
531 {
532 enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
533 tree rhs1 = gimple_assign_rhs1 (stmt);
534 if (TREE_CODE_CLASS (rhs_code) == tcc_comparison
535 && rhs_code != EQ_EXPR
536 && rhs_code != NE_EXPR
537 && INTEGRAL_TYPE_P (TREE_TYPE (rhs1))
538 && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (rhs1)))
539 suppress_warning (stmt, OPT_Wstrict_overflow_);
540 }
541 }
542 }
543 }
544
545 /* Update header of the loop. */
546 loop->header = header;
547 /* Find correct latch. We only duplicate chain of conditionals so
548 there should be precisely two edges to the new header. One entry
549 edge and one to latch. */
550 FOR_EACH_EDGE (e, ei, loop->header->preds)
551 if (header != e->src)
552 {
553 loop->latch = e->src;
554 break;
555 }
556 /* Ensure that the latch and the preheader is simple (we know that they
557 are not now, since there was the loop exit condition. */
558 split_edge (loop_preheader_edge (loop));
559 split_edge (loop_latch_edge (loop));
560
561 if (dump_file && (dump_flags & TDF_DETAILS))
562 {
563 if (do_while_loop_p (loop))
564 fprintf (dump_file, "Loop %d is now do-while loop.\n", loop->num);
565 else
566 fprintf (dump_file, "Loop %d is still not do-while loop.\n",
567 loop->num);
568 }
569
570 changed = true;
571 }
572
573 if (changed)
574 {
575 if (flag_checking)
576 verify_loop_structure ();
577 update_ssa (TODO_update_ssa);
578 /* After updating SSA form perform CSE on the loop header
579 copies. This is esp. required for the pass before
580 vectorization since nothing cleans up copied exit tests
581 that can now be simplified. CSE from the entry of the
582 region we copied till all loop exit blocks but not
583 entering the loop itself. */
584 for (unsigned i = 0; i < copied.length (); ++i)
585 {
586 edge entry = copied[i].first;
587 loop_p loop = copied[i].second;
588 auto_vec<edge> exit_edges = get_loop_exit_edges (loop);
589 bitmap exit_bbs = BITMAP_ALLOC (NULL);
590 for (unsigned j = 0; j < exit_edges.length (); ++j)
591 bitmap_set_bit (exit_bbs, exit_edges[j]->dest->index);
592 bitmap_set_bit (exit_bbs, loop->header->index);
593 do_rpo_vn (cfun, entry, exit_bbs);
594 BITMAP_FREE (exit_bbs);
595 }
596 }
597 free (bbs);
598 free (copied_bbs);
599
600 return changed ? TODO_cleanup_cfg : 0;
601 }
602
603 /* Initialize the loop structures we need, and finalize after. */
604
605 unsigned int
606 pass_ch::execute (function *fun)
607 {
608 loop_optimizer_init (LOOPS_HAVE_PREHEADERS
609 | LOOPS_HAVE_SIMPLE_LATCHES
610 | LOOPS_HAVE_RECORDED_EXITS);
611
612 unsigned int res = copy_headers (fun);
613
614 loop_optimizer_finalize ();
615 return res;
616 }
617
618 /* Assume an earlier phase has already initialized all the loop structures that
619 we need here (and perhaps others too), and that these will be finalized by
620 a later phase. */
621
622 unsigned int
623 pass_ch_vect::execute (function *fun)
624 {
625 return copy_headers (fun);
626 }
627
628 /* Apply header copying according to a very simple test of do-while shape. */
629
630 bool
631 pass_ch::process_loop_p (class loop *loop)
632 {
633 return !do_while_loop_p (loop);
634 }
635
636 /* Apply header-copying to loops where we might enable vectorization. */
637
638 bool
639 pass_ch_vect::process_loop_p (class loop *loop)
640 {
641 if (!flag_tree_loop_vectorize && !loop->force_vectorize)
642 return false;
643
644 if (loop->dont_vectorize)
645 return false;
646
647 /* The vectorizer won't handle anything with multiple exits, so skip. */
648 edge exit = single_exit (loop);
649 if (!exit)
650 return false;
651
652 if (!do_while_loop_p (loop))
653 return true;
654
655 return false;
656 }
657
658 } // anon namespace
659
660 gimple_opt_pass *
661 make_pass_ch_vect (gcc::context *ctxt)
662 {
663 return new pass_ch_vect (ctxt);
664 }
665
666 gimple_opt_pass *
667 make_pass_ch (gcc::context *ctxt)
668 {
669 return new pass_ch (ctxt);
670 }