[Ada] Crash on Loop_Entry for while_loop involving substrings
[official-gcc.git] / gcc / tree-ssa-loop.c
blobfc9f08363ce206564e3600321c1471392da3a3a9
1 /* Loop optimizations over tree-ssa.
2 Copyright (C) 2003-2019 Free Software Foundation, Inc.
4 This file is part of GCC.
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.
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.
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/>. */
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 "memmodel.h"
28 #include "tm_p.h"
29 #include "fold-const.h"
30 #include "gimple-iterator.h"
31 #include "tree-ssa-loop-ivopts.h"
32 #include "tree-ssa-loop-manip.h"
33 #include "tree-ssa-loop-niter.h"
34 #include "tree-ssa-loop.h"
35 #include "cfgloop.h"
36 #include "tree-inline.h"
37 #include "tree-scalar-evolution.h"
38 #include "tree-vectorizer.h"
39 #include "omp-general.h"
40 #include "diagnostic-core.h"
41 #include "stringpool.h"
42 #include "attribs.h"
45 /* A pass making sure loops are fixed up. */
47 namespace {
49 const pass_data pass_data_fix_loops =
51 GIMPLE_PASS, /* type */
52 "fix_loops", /* name */
53 OPTGROUP_LOOP, /* optinfo_flags */
54 TV_TREE_LOOP, /* tv_id */
55 PROP_cfg, /* properties_required */
56 0, /* properties_provided */
57 0, /* properties_destroyed */
58 0, /* todo_flags_start */
59 0, /* todo_flags_finish */
62 class pass_fix_loops : public gimple_opt_pass
64 public:
65 pass_fix_loops (gcc::context *ctxt)
66 : gimple_opt_pass (pass_data_fix_loops, ctxt)
69 /* opt_pass methods: */
70 virtual bool gate (function *) { return flag_tree_loop_optimize; }
72 virtual unsigned int execute (function *fn);
73 }; // class pass_fix_loops
75 unsigned int
76 pass_fix_loops::execute (function *)
78 if (loops_state_satisfies_p (LOOPS_NEED_FIXUP))
80 calculate_dominance_info (CDI_DOMINATORS);
81 fix_loop_structure (NULL);
83 return 0;
86 } // anon namespace
88 gimple_opt_pass *
89 make_pass_fix_loops (gcc::context *ctxt)
91 return new pass_fix_loops (ctxt);
95 /* Gate for loop pass group. The group is controlled by -ftree-loop-optimize
96 but we also avoid running it when the IL doesn't contain any loop. */
98 static bool
99 gate_loop (function *fn)
101 if (!flag_tree_loop_optimize)
102 return false;
104 /* For -fdump-passes which runs before loop discovery print the
105 state of -ftree-loop-optimize. */
106 if (!loops_for_fn (fn))
107 return true;
109 return number_of_loops (fn) > 1;
112 /* The loop superpass. */
114 namespace {
116 const pass_data pass_data_tree_loop =
118 GIMPLE_PASS, /* type */
119 "loop", /* name */
120 OPTGROUP_LOOP, /* optinfo_flags */
121 TV_TREE_LOOP, /* tv_id */
122 PROP_cfg, /* properties_required */
123 0, /* properties_provided */
124 0, /* properties_destroyed */
125 0, /* todo_flags_start */
126 0, /* todo_flags_finish */
129 class pass_tree_loop : public gimple_opt_pass
131 public:
132 pass_tree_loop (gcc::context *ctxt)
133 : gimple_opt_pass (pass_data_tree_loop, ctxt)
136 /* opt_pass methods: */
137 virtual bool gate (function *fn) { return gate_loop (fn); }
139 }; // class pass_tree_loop
141 } // anon namespace
143 gimple_opt_pass *
144 make_pass_tree_loop (gcc::context *ctxt)
146 return new pass_tree_loop (ctxt);
149 /* Gate for oacc kernels pass group. */
151 static bool
152 gate_oacc_kernels (function *fn)
154 if (!flag_openacc)
155 return false;
157 if (!lookup_attribute ("oacc kernels", DECL_ATTRIBUTES (fn->decl)))
158 return false;
160 class loop *loop;
161 FOR_EACH_LOOP (loop, 0)
162 if (loop->in_oacc_kernels_region)
163 return true;
165 return false;
168 /* The oacc kernels superpass. */
170 namespace {
172 const pass_data pass_data_oacc_kernels =
174 GIMPLE_PASS, /* type */
175 "oacc_kernels", /* name */
176 OPTGROUP_LOOP, /* optinfo_flags */
177 TV_TREE_LOOP, /* tv_id */
178 PROP_cfg, /* properties_required */
179 0, /* properties_provided */
180 0, /* properties_destroyed */
181 0, /* todo_flags_start */
182 0, /* todo_flags_finish */
185 class pass_oacc_kernels : public gimple_opt_pass
187 public:
188 pass_oacc_kernels (gcc::context *ctxt)
189 : gimple_opt_pass (pass_data_oacc_kernels, ctxt)
192 /* opt_pass methods: */
193 virtual bool gate (function *fn) { return gate_oacc_kernels (fn); }
195 }; // class pass_oacc_kernels
197 } // anon namespace
199 gimple_opt_pass *
200 make_pass_oacc_kernels (gcc::context *ctxt)
202 return new pass_oacc_kernels (ctxt);
205 /* The ipa oacc superpass. */
207 namespace {
209 const pass_data pass_data_ipa_oacc =
211 SIMPLE_IPA_PASS, /* type */
212 "ipa_oacc", /* name */
213 OPTGROUP_LOOP, /* optinfo_flags */
214 TV_TREE_LOOP, /* tv_id */
215 PROP_cfg, /* properties_required */
216 0, /* properties_provided */
217 0, /* properties_destroyed */
218 0, /* todo_flags_start */
219 0, /* todo_flags_finish */
222 class pass_ipa_oacc : public simple_ipa_opt_pass
224 public:
225 pass_ipa_oacc (gcc::context *ctxt)
226 : simple_ipa_opt_pass (pass_data_ipa_oacc, ctxt)
229 /* opt_pass methods: */
230 virtual bool gate (function *)
232 return (optimize
233 && flag_openacc
234 /* Don't bother doing anything if the program has errors. */
235 && !seen_error ());
238 }; // class pass_ipa_oacc
240 } // anon namespace
242 simple_ipa_opt_pass *
243 make_pass_ipa_oacc (gcc::context *ctxt)
245 return new pass_ipa_oacc (ctxt);
248 /* The ipa oacc kernels pass. */
250 namespace {
252 const pass_data pass_data_ipa_oacc_kernels =
254 SIMPLE_IPA_PASS, /* type */
255 "ipa_oacc_kernels", /* name */
256 OPTGROUP_LOOP, /* optinfo_flags */
257 TV_TREE_LOOP, /* tv_id */
258 PROP_cfg, /* properties_required */
259 0, /* properties_provided */
260 0, /* properties_destroyed */
261 0, /* todo_flags_start */
262 0, /* todo_flags_finish */
265 class pass_ipa_oacc_kernels : public simple_ipa_opt_pass
267 public:
268 pass_ipa_oacc_kernels (gcc::context *ctxt)
269 : simple_ipa_opt_pass (pass_data_ipa_oacc_kernels, ctxt)
272 }; // class pass_ipa_oacc_kernels
274 } // anon namespace
276 simple_ipa_opt_pass *
277 make_pass_ipa_oacc_kernels (gcc::context *ctxt)
279 return new pass_ipa_oacc_kernels (ctxt);
282 /* The no-loop superpass. */
284 namespace {
286 const pass_data pass_data_tree_no_loop =
288 GIMPLE_PASS, /* type */
289 "no_loop", /* name */
290 OPTGROUP_NONE, /* optinfo_flags */
291 TV_TREE_NOLOOP, /* tv_id */
292 PROP_cfg, /* properties_required */
293 0, /* properties_provided */
294 0, /* properties_destroyed */
295 0, /* todo_flags_start */
296 0, /* todo_flags_finish */
299 class pass_tree_no_loop : public gimple_opt_pass
301 public:
302 pass_tree_no_loop (gcc::context *ctxt)
303 : gimple_opt_pass (pass_data_tree_no_loop, ctxt)
306 /* opt_pass methods: */
307 virtual bool gate (function *fn) { return !gate_loop (fn); }
309 }; // class pass_tree_no_loop
311 } // anon namespace
313 gimple_opt_pass *
314 make_pass_tree_no_loop (gcc::context *ctxt)
316 return new pass_tree_no_loop (ctxt);
320 /* Loop optimizer initialization. */
322 namespace {
324 const pass_data pass_data_tree_loop_init =
326 GIMPLE_PASS, /* type */
327 "loopinit", /* name */
328 OPTGROUP_LOOP, /* optinfo_flags */
329 TV_NONE, /* tv_id */
330 PROP_cfg, /* properties_required */
331 0, /* properties_provided */
332 0, /* properties_destroyed */
333 TODO_update_address_taken, /* todo_flags_start */
334 0, /* todo_flags_finish */
337 class pass_tree_loop_init : public gimple_opt_pass
339 public:
340 pass_tree_loop_init (gcc::context *ctxt)
341 : gimple_opt_pass (pass_data_tree_loop_init, ctxt)
344 /* opt_pass methods: */
345 virtual unsigned int execute (function *);
347 }; // class pass_tree_loop_init
349 unsigned int
350 pass_tree_loop_init::execute (function *fun ATTRIBUTE_UNUSED)
352 /* When processing a loop in the loop pipeline, we should be able to assert
353 that:
354 (loops_state_satisfies_p (LOOPS_NORMAL | LOOPS_HAVE_RECORDED_EXITS
355 | LOOP_CLOSED_SSA)
356 && scev_initialized_p ())
358 loop_optimizer_init (LOOPS_NORMAL
359 | LOOPS_HAVE_RECORDED_EXITS);
360 rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa);
361 scev_initialize ();
363 return 0;
366 } // anon namespace
368 gimple_opt_pass *
369 make_pass_tree_loop_init (gcc::context *ctxt)
371 return new pass_tree_loop_init (ctxt);
374 /* Loop autovectorization. */
376 namespace {
378 const pass_data pass_data_vectorize =
380 GIMPLE_PASS, /* type */
381 "vect", /* name */
382 OPTGROUP_LOOP | OPTGROUP_VEC, /* optinfo_flags */
383 TV_TREE_VECTORIZATION, /* tv_id */
384 ( PROP_cfg | PROP_ssa ), /* properties_required */
385 0, /* properties_provided */
386 0, /* properties_destroyed */
387 0, /* todo_flags_start */
388 0, /* todo_flags_finish */
391 class pass_vectorize : public gimple_opt_pass
393 public:
394 pass_vectorize (gcc::context *ctxt)
395 : gimple_opt_pass (pass_data_vectorize, ctxt)
398 /* opt_pass methods: */
399 virtual bool gate (function *fun)
401 return flag_tree_loop_vectorize || fun->has_force_vectorize_loops;
404 virtual unsigned int execute (function *);
406 }; // class pass_vectorize
408 unsigned int
409 pass_vectorize::execute (function *fun)
411 if (number_of_loops (fun) <= 1)
412 return 0;
414 return vectorize_loops ();
417 } // anon namespace
419 gimple_opt_pass *
420 make_pass_vectorize (gcc::context *ctxt)
422 return new pass_vectorize (ctxt);
425 /* Propagation of constants using scev. */
427 namespace {
429 const pass_data pass_data_scev_cprop =
431 GIMPLE_PASS, /* type */
432 "sccp", /* name */
433 OPTGROUP_LOOP, /* optinfo_flags */
434 TV_SCEV_CONST, /* tv_id */
435 ( PROP_cfg | PROP_ssa ), /* properties_required */
436 0, /* properties_provided */
437 0, /* properties_destroyed */
438 0, /* todo_flags_start */
439 0, /* todo_flags_finish */
442 class pass_scev_cprop : public gimple_opt_pass
444 public:
445 pass_scev_cprop (gcc::context *ctxt)
446 : gimple_opt_pass (pass_data_scev_cprop, ctxt)
449 /* opt_pass methods: */
450 virtual bool gate (function *) { return flag_tree_scev_cprop; }
451 virtual unsigned int execute (function *);
453 }; // class pass_scev_cprop
455 unsigned
456 pass_scev_cprop::execute (function *)
458 class loop *loop;
459 bool any = false;
461 /* Perform final value replacement in loops, in case the replacement
462 expressions are cheap. */
463 FOR_EACH_LOOP (loop, LI_FROM_INNERMOST)
464 any |= final_value_replacement_loop (loop);
466 return any ? TODO_cleanup_cfg | TODO_update_ssa_only_virtuals : 0;
469 } // anon namespace
471 gimple_opt_pass *
472 make_pass_scev_cprop (gcc::context *ctxt)
474 return new pass_scev_cprop (ctxt);
477 /* Induction variable optimizations. */
479 namespace {
481 const pass_data pass_data_iv_optimize =
483 GIMPLE_PASS, /* type */
484 "ivopts", /* name */
485 OPTGROUP_LOOP, /* optinfo_flags */
486 TV_TREE_LOOP_IVOPTS, /* tv_id */
487 ( PROP_cfg | PROP_ssa ), /* properties_required */
488 0, /* properties_provided */
489 0, /* properties_destroyed */
490 0, /* todo_flags_start */
491 TODO_update_ssa, /* todo_flags_finish */
494 class pass_iv_optimize : public gimple_opt_pass
496 public:
497 pass_iv_optimize (gcc::context *ctxt)
498 : gimple_opt_pass (pass_data_iv_optimize, ctxt)
501 /* opt_pass methods: */
502 virtual bool gate (function *) { return flag_ivopts != 0; }
503 virtual unsigned int execute (function *);
505 }; // class pass_iv_optimize
507 unsigned int
508 pass_iv_optimize::execute (function *fun)
510 if (number_of_loops (fun) <= 1)
511 return 0;
513 tree_ssa_iv_optimize ();
514 return 0;
517 } // anon namespace
519 gimple_opt_pass *
520 make_pass_iv_optimize (gcc::context *ctxt)
522 return new pass_iv_optimize (ctxt);
525 /* Loop optimizer finalization. */
527 static unsigned int
528 tree_ssa_loop_done (void)
530 free_numbers_of_iterations_estimates (cfun);
531 scev_finalize ();
532 loop_optimizer_finalize ();
533 return 0;
536 namespace {
538 const pass_data pass_data_tree_loop_done =
540 GIMPLE_PASS, /* type */
541 "loopdone", /* name */
542 OPTGROUP_LOOP, /* optinfo_flags */
543 TV_NONE, /* tv_id */
544 PROP_cfg, /* properties_required */
545 0, /* properties_provided */
546 0, /* properties_destroyed */
547 0, /* todo_flags_start */
548 TODO_cleanup_cfg, /* todo_flags_finish */
551 class pass_tree_loop_done : public gimple_opt_pass
553 public:
554 pass_tree_loop_done (gcc::context *ctxt)
555 : gimple_opt_pass (pass_data_tree_loop_done, ctxt)
558 /* opt_pass methods: */
559 virtual unsigned int execute (function *) { return tree_ssa_loop_done (); }
561 }; // class pass_tree_loop_done
563 } // anon namespace
565 gimple_opt_pass *
566 make_pass_tree_loop_done (gcc::context *ctxt)
568 return new pass_tree_loop_done (ctxt);
571 /* Calls CBCK for each index in memory reference ADDR_P. There are two
572 kinds situations handled; in each of these cases, the memory reference
573 and DATA are passed to the callback:
575 Access to an array: ARRAY_{RANGE_}REF (base, index). In this case we also
576 pass the pointer to the index to the callback.
578 Pointer dereference: INDIRECT_REF (addr). In this case we also pass the
579 pointer to addr to the callback.
581 If the callback returns false, the whole search stops and false is returned.
582 Otherwise the function returns true after traversing through the whole
583 reference *ADDR_P. */
585 bool
586 for_each_index (tree *addr_p, bool (*cbck) (tree, tree *, void *), void *data)
588 tree *nxt, *idx;
590 for (; ; addr_p = nxt)
592 switch (TREE_CODE (*addr_p))
594 case SSA_NAME:
595 return cbck (*addr_p, addr_p, data);
597 case MEM_REF:
598 nxt = &TREE_OPERAND (*addr_p, 0);
599 return cbck (*addr_p, nxt, data);
601 case BIT_FIELD_REF:
602 case VIEW_CONVERT_EXPR:
603 case REALPART_EXPR:
604 case IMAGPART_EXPR:
605 nxt = &TREE_OPERAND (*addr_p, 0);
606 break;
608 case COMPONENT_REF:
609 /* If the component has varying offset, it behaves like index
610 as well. */
611 idx = &TREE_OPERAND (*addr_p, 2);
612 if (*idx
613 && !cbck (*addr_p, idx, data))
614 return false;
616 nxt = &TREE_OPERAND (*addr_p, 0);
617 break;
619 case ARRAY_REF:
620 case ARRAY_RANGE_REF:
621 nxt = &TREE_OPERAND (*addr_p, 0);
622 if (!cbck (*addr_p, &TREE_OPERAND (*addr_p, 1), data))
623 return false;
624 break;
626 case CONSTRUCTOR:
627 return true;
629 case ADDR_EXPR:
630 gcc_assert (is_gimple_min_invariant (*addr_p));
631 return true;
633 case TARGET_MEM_REF:
634 idx = &TMR_BASE (*addr_p);
635 if (*idx
636 && !cbck (*addr_p, idx, data))
637 return false;
638 idx = &TMR_INDEX (*addr_p);
639 if (*idx
640 && !cbck (*addr_p, idx, data))
641 return false;
642 idx = &TMR_INDEX2 (*addr_p);
643 if (*idx
644 && !cbck (*addr_p, idx, data))
645 return false;
646 return true;
648 default:
649 if (DECL_P (*addr_p)
650 || CONSTANT_CLASS_P (*addr_p))
651 return true;
652 gcc_unreachable ();
658 /* The name and the length of the currently generated variable
659 for lsm. */
660 #define MAX_LSM_NAME_LENGTH 40
661 static char lsm_tmp_name[MAX_LSM_NAME_LENGTH + 1];
662 static int lsm_tmp_name_length;
664 /* Adds S to lsm_tmp_name. */
666 static void
667 lsm_tmp_name_add (const char *s)
669 int l = strlen (s) + lsm_tmp_name_length;
670 if (l > MAX_LSM_NAME_LENGTH)
671 return;
673 strcpy (lsm_tmp_name + lsm_tmp_name_length, s);
674 lsm_tmp_name_length = l;
677 /* Stores the name for temporary variable that replaces REF to
678 lsm_tmp_name. */
680 static void
681 gen_lsm_tmp_name (tree ref)
683 const char *name;
685 switch (TREE_CODE (ref))
687 case MEM_REF:
688 case TARGET_MEM_REF:
689 gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
690 lsm_tmp_name_add ("_");
691 break;
693 case ADDR_EXPR:
694 gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
695 break;
697 case BIT_FIELD_REF:
698 case VIEW_CONVERT_EXPR:
699 case ARRAY_RANGE_REF:
700 gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
701 break;
703 case REALPART_EXPR:
704 gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
705 lsm_tmp_name_add ("_RE");
706 break;
708 case IMAGPART_EXPR:
709 gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
710 lsm_tmp_name_add ("_IM");
711 break;
713 case COMPONENT_REF:
714 gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
715 lsm_tmp_name_add ("_");
716 name = get_name (TREE_OPERAND (ref, 1));
717 if (!name)
718 name = "F";
719 lsm_tmp_name_add (name);
720 break;
722 case ARRAY_REF:
723 gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
724 lsm_tmp_name_add ("_I");
725 break;
727 case SSA_NAME:
728 case VAR_DECL:
729 case PARM_DECL:
730 case FUNCTION_DECL:
731 case LABEL_DECL:
732 name = get_name (ref);
733 if (!name)
734 name = "D";
735 lsm_tmp_name_add (name);
736 break;
738 case STRING_CST:
739 lsm_tmp_name_add ("S");
740 break;
742 case RESULT_DECL:
743 lsm_tmp_name_add ("R");
744 break;
746 case INTEGER_CST:
747 default:
748 /* Nothing. */
749 break;
753 /* Determines name for temporary variable that replaces REF.
754 The name is accumulated into the lsm_tmp_name variable.
755 N is added to the name of the temporary. */
757 char *
758 get_lsm_tmp_name (tree ref, unsigned n, const char *suffix)
760 char ns[2];
762 lsm_tmp_name_length = 0;
763 gen_lsm_tmp_name (ref);
764 lsm_tmp_name_add ("_lsm");
765 if (n < 10)
767 ns[0] = '0' + n;
768 ns[1] = 0;
769 lsm_tmp_name_add (ns);
771 if (suffix != NULL)
772 lsm_tmp_name_add (suffix);
773 return lsm_tmp_name;
776 /* Computes an estimated number of insns in LOOP, weighted by WEIGHTS. */
778 unsigned
779 tree_num_loop_insns (class loop *loop, eni_weights *weights)
781 basic_block *body = get_loop_body (loop);
782 gimple_stmt_iterator gsi;
783 unsigned size = 0, i;
785 for (i = 0; i < loop->num_nodes; i++)
786 for (gsi = gsi_start_bb (body[i]); !gsi_end_p (gsi); gsi_next (&gsi))
787 size += estimate_num_insns (gsi_stmt (gsi), weights);
788 free (body);
790 return size;