2015-11-09 Steve Ellcey <sellcey@imgtec.com>
[official-gcc.git] / gcc / tree-ssa-loop.c
blob8ecd140c22dfd145c61752350b6700e2db31e4b5
1 /* Loop optimizations over tree-ssa.
2 Copyright (C) 2003-2015 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 "tm_p.h"
28 #include "fold-const.h"
29 #include "gimple-iterator.h"
30 #include "tree-ssa-loop-ivopts.h"
31 #include "tree-ssa-loop-manip.h"
32 #include "tree-ssa-loop-niter.h"
33 #include "tree-ssa-loop.h"
34 #include "cfgloop.h"
35 #include "tree-inline.h"
36 #include "tree-scalar-evolution.h"
37 #include "tree-vectorizer.h"
40 /* A pass making sure loops are fixed up. */
42 namespace {
44 const pass_data pass_data_fix_loops =
46 GIMPLE_PASS, /* type */
47 "fix_loops", /* name */
48 OPTGROUP_LOOP, /* optinfo_flags */
49 TV_TREE_LOOP, /* tv_id */
50 PROP_cfg, /* properties_required */
51 0, /* properties_provided */
52 0, /* properties_destroyed */
53 0, /* todo_flags_start */
54 0, /* todo_flags_finish */
57 class pass_fix_loops : public gimple_opt_pass
59 public:
60 pass_fix_loops (gcc::context *ctxt)
61 : gimple_opt_pass (pass_data_fix_loops, ctxt)
64 /* opt_pass methods: */
65 virtual bool gate (function *) { return flag_tree_loop_optimize; }
67 virtual unsigned int execute (function *fn);
68 }; // class pass_fix_loops
70 unsigned int
71 pass_fix_loops::execute (function *)
73 if (loops_state_satisfies_p (LOOPS_NEED_FIXUP))
75 calculate_dominance_info (CDI_DOMINATORS);
76 fix_loop_structure (NULL);
78 return 0;
81 } // anon namespace
83 gimple_opt_pass *
84 make_pass_fix_loops (gcc::context *ctxt)
86 return new pass_fix_loops (ctxt);
90 /* Gate for loop pass group. The group is controlled by -ftree-loop-optimize
91 but we also avoid running it when the IL doesn't contain any loop. */
93 static bool
94 gate_loop (function *fn)
96 if (!flag_tree_loop_optimize)
97 return false;
99 /* For -fdump-passes which runs before loop discovery print the
100 state of -ftree-loop-optimize. */
101 if (!loops_for_fn (fn))
102 return true;
104 return number_of_loops (fn) > 1;
107 /* The loop superpass. */
109 namespace {
111 const pass_data pass_data_tree_loop =
113 GIMPLE_PASS, /* type */
114 "loop", /* name */
115 OPTGROUP_LOOP, /* optinfo_flags */
116 TV_TREE_LOOP, /* tv_id */
117 PROP_cfg, /* properties_required */
118 0, /* properties_provided */
119 0, /* properties_destroyed */
120 0, /* todo_flags_start */
121 0, /* todo_flags_finish */
124 class pass_tree_loop : public gimple_opt_pass
126 public:
127 pass_tree_loop (gcc::context *ctxt)
128 : gimple_opt_pass (pass_data_tree_loop, ctxt)
131 /* opt_pass methods: */
132 virtual bool gate (function *fn) { return gate_loop (fn); }
134 }; // class pass_tree_loop
136 } // anon namespace
138 gimple_opt_pass *
139 make_pass_tree_loop (gcc::context *ctxt)
141 return new pass_tree_loop (ctxt);
144 /* The no-loop superpass. */
146 namespace {
148 const pass_data pass_data_tree_no_loop =
150 GIMPLE_PASS, /* type */
151 "no_loop", /* name */
152 OPTGROUP_NONE, /* optinfo_flags */
153 TV_TREE_NOLOOP, /* tv_id */
154 PROP_cfg, /* properties_required */
155 0, /* properties_provided */
156 0, /* properties_destroyed */
157 0, /* todo_flags_start */
158 0, /* todo_flags_finish */
161 class pass_tree_no_loop : public gimple_opt_pass
163 public:
164 pass_tree_no_loop (gcc::context *ctxt)
165 : gimple_opt_pass (pass_data_tree_no_loop, ctxt)
168 /* opt_pass methods: */
169 virtual bool gate (function *fn) { return !gate_loop (fn); }
171 }; // class pass_tree_no_loop
173 } // anon namespace
175 gimple_opt_pass *
176 make_pass_tree_no_loop (gcc::context *ctxt)
178 return new pass_tree_no_loop (ctxt);
182 /* Loop optimizer initialization. */
184 namespace {
186 const pass_data pass_data_tree_loop_init =
188 GIMPLE_PASS, /* type */
189 "loopinit", /* name */
190 OPTGROUP_LOOP, /* optinfo_flags */
191 TV_NONE, /* tv_id */
192 PROP_cfg, /* properties_required */
193 0, /* properties_provided */
194 0, /* properties_destroyed */
195 0, /* todo_flags_start */
196 0, /* todo_flags_finish */
199 class pass_tree_loop_init : public gimple_opt_pass
201 public:
202 pass_tree_loop_init (gcc::context *ctxt)
203 : gimple_opt_pass (pass_data_tree_loop_init, ctxt)
206 /* opt_pass methods: */
207 virtual unsigned int execute (function *);
209 }; // class pass_tree_loop_init
211 unsigned int
212 pass_tree_loop_init::execute (function *fun ATTRIBUTE_UNUSED)
214 loop_optimizer_init (LOOPS_NORMAL
215 | LOOPS_HAVE_RECORDED_EXITS);
216 rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa);
218 /* We might discover new loops, e.g. when turning irreducible
219 regions into reducible. */
220 scev_initialize ();
222 return 0;
225 } // anon namespace
227 gimple_opt_pass *
228 make_pass_tree_loop_init (gcc::context *ctxt)
230 return new pass_tree_loop_init (ctxt);
233 /* Loop autovectorization. */
235 namespace {
237 const pass_data pass_data_vectorize =
239 GIMPLE_PASS, /* type */
240 "vect", /* name */
241 OPTGROUP_LOOP | OPTGROUP_VEC, /* optinfo_flags */
242 TV_TREE_VECTORIZATION, /* tv_id */
243 ( PROP_cfg | PROP_ssa ), /* properties_required */
244 0, /* properties_provided */
245 0, /* properties_destroyed */
246 0, /* todo_flags_start */
247 0, /* todo_flags_finish */
250 class pass_vectorize : public gimple_opt_pass
252 public:
253 pass_vectorize (gcc::context *ctxt)
254 : gimple_opt_pass (pass_data_vectorize, ctxt)
257 /* opt_pass methods: */
258 virtual bool gate (function *fun)
260 return flag_tree_loop_vectorize || fun->has_force_vectorize_loops;
263 virtual unsigned int execute (function *);
265 }; // class pass_vectorize
267 unsigned int
268 pass_vectorize::execute (function *fun)
270 if (number_of_loops (fun) <= 1)
271 return 0;
273 return vectorize_loops ();
276 } // anon namespace
278 gimple_opt_pass *
279 make_pass_vectorize (gcc::context *ctxt)
281 return new pass_vectorize (ctxt);
284 /* Propagation of constants using scev. */
286 namespace {
288 const pass_data pass_data_scev_cprop =
290 GIMPLE_PASS, /* type */
291 "sccp", /* name */
292 OPTGROUP_LOOP, /* optinfo_flags */
293 TV_SCEV_CONST, /* tv_id */
294 ( PROP_cfg | PROP_ssa ), /* properties_required */
295 0, /* properties_provided */
296 0, /* properties_destroyed */
297 0, /* todo_flags_start */
298 ( TODO_cleanup_cfg
299 | TODO_update_ssa_only_virtuals ), /* todo_flags_finish */
302 class pass_scev_cprop : public gimple_opt_pass
304 public:
305 pass_scev_cprop (gcc::context *ctxt)
306 : gimple_opt_pass (pass_data_scev_cprop, ctxt)
309 /* opt_pass methods: */
310 virtual bool gate (function *) { return flag_tree_scev_cprop; }
311 virtual unsigned int execute (function *) { return scev_const_prop (); }
313 }; // class pass_scev_cprop
315 } // anon namespace
317 gimple_opt_pass *
318 make_pass_scev_cprop (gcc::context *ctxt)
320 return new pass_scev_cprop (ctxt);
323 /* Record bounds on numbers of iterations of loops. */
325 namespace {
327 const pass_data pass_data_record_bounds =
329 GIMPLE_PASS, /* type */
330 "*record_bounds", /* name */
331 OPTGROUP_NONE, /* optinfo_flags */
332 TV_TREE_LOOP_BOUNDS, /* tv_id */
333 ( PROP_cfg | PROP_ssa ), /* properties_required */
334 0, /* properties_provided */
335 0, /* properties_destroyed */
336 0, /* todo_flags_start */
337 0, /* todo_flags_finish */
340 class pass_record_bounds : public gimple_opt_pass
342 public:
343 pass_record_bounds (gcc::context *ctxt)
344 : gimple_opt_pass (pass_data_record_bounds, ctxt)
347 /* opt_pass methods: */
348 virtual unsigned int execute (function *);
350 }; // class pass_record_bounds
352 unsigned int
353 pass_record_bounds::execute (function *fun)
355 if (number_of_loops (fun) <= 1)
356 return 0;
358 estimate_numbers_of_iterations ();
359 scev_reset ();
360 return 0;
363 } // anon namespace
365 gimple_opt_pass *
366 make_pass_record_bounds (gcc::context *ctxt)
368 return new pass_record_bounds (ctxt);
371 /* Induction variable optimizations. */
373 namespace {
375 const pass_data pass_data_iv_optimize =
377 GIMPLE_PASS, /* type */
378 "ivopts", /* name */
379 OPTGROUP_LOOP, /* optinfo_flags */
380 TV_TREE_LOOP_IVOPTS, /* tv_id */
381 ( PROP_cfg | PROP_ssa ), /* properties_required */
382 0, /* properties_provided */
383 0, /* properties_destroyed */
384 0, /* todo_flags_start */
385 TODO_update_ssa, /* todo_flags_finish */
388 class pass_iv_optimize : public gimple_opt_pass
390 public:
391 pass_iv_optimize (gcc::context *ctxt)
392 : gimple_opt_pass (pass_data_iv_optimize, ctxt)
395 /* opt_pass methods: */
396 virtual bool gate (function *) { return flag_ivopts != 0; }
397 virtual unsigned int execute (function *);
399 }; // class pass_iv_optimize
401 unsigned int
402 pass_iv_optimize::execute (function *fun)
404 if (number_of_loops (fun) <= 1)
405 return 0;
407 tree_ssa_iv_optimize ();
408 return 0;
411 } // anon namespace
413 gimple_opt_pass *
414 make_pass_iv_optimize (gcc::context *ctxt)
416 return new pass_iv_optimize (ctxt);
419 /* Loop optimizer finalization. */
421 static unsigned int
422 tree_ssa_loop_done (void)
424 free_numbers_of_iterations_estimates (cfun);
425 scev_finalize ();
426 loop_optimizer_finalize ();
427 return 0;
430 namespace {
432 const pass_data pass_data_tree_loop_done =
434 GIMPLE_PASS, /* type */
435 "loopdone", /* name */
436 OPTGROUP_LOOP, /* optinfo_flags */
437 TV_NONE, /* tv_id */
438 PROP_cfg, /* properties_required */
439 0, /* properties_provided */
440 0, /* properties_destroyed */
441 0, /* todo_flags_start */
442 TODO_cleanup_cfg, /* todo_flags_finish */
445 class pass_tree_loop_done : public gimple_opt_pass
447 public:
448 pass_tree_loop_done (gcc::context *ctxt)
449 : gimple_opt_pass (pass_data_tree_loop_done, ctxt)
452 /* opt_pass methods: */
453 virtual unsigned int execute (function *) { return tree_ssa_loop_done (); }
455 }; // class pass_tree_loop_done
457 } // anon namespace
459 gimple_opt_pass *
460 make_pass_tree_loop_done (gcc::context *ctxt)
462 return new pass_tree_loop_done (ctxt);
465 /* Calls CBCK for each index in memory reference ADDR_P. There are two
466 kinds situations handled; in each of these cases, the memory reference
467 and DATA are passed to the callback:
469 Access to an array: ARRAY_{RANGE_}REF (base, index). In this case we also
470 pass the pointer to the index to the callback.
472 Pointer dereference: INDIRECT_REF (addr). In this case we also pass the
473 pointer to addr to the callback.
475 If the callback returns false, the whole search stops and false is returned.
476 Otherwise the function returns true after traversing through the whole
477 reference *ADDR_P. */
479 bool
480 for_each_index (tree *addr_p, bool (*cbck) (tree, tree *, void *), void *data)
482 tree *nxt, *idx;
484 for (; ; addr_p = nxt)
486 switch (TREE_CODE (*addr_p))
488 case SSA_NAME:
489 return cbck (*addr_p, addr_p, data);
491 case MEM_REF:
492 nxt = &TREE_OPERAND (*addr_p, 0);
493 return cbck (*addr_p, nxt, data);
495 case BIT_FIELD_REF:
496 case VIEW_CONVERT_EXPR:
497 case REALPART_EXPR:
498 case IMAGPART_EXPR:
499 nxt = &TREE_OPERAND (*addr_p, 0);
500 break;
502 case COMPONENT_REF:
503 /* If the component has varying offset, it behaves like index
504 as well. */
505 idx = &TREE_OPERAND (*addr_p, 2);
506 if (*idx
507 && !cbck (*addr_p, idx, data))
508 return false;
510 nxt = &TREE_OPERAND (*addr_p, 0);
511 break;
513 case ARRAY_REF:
514 case ARRAY_RANGE_REF:
515 nxt = &TREE_OPERAND (*addr_p, 0);
516 if (!cbck (*addr_p, &TREE_OPERAND (*addr_p, 1), data))
517 return false;
518 break;
520 case VAR_DECL:
521 case PARM_DECL:
522 case CONST_DECL:
523 case STRING_CST:
524 case RESULT_DECL:
525 case VECTOR_CST:
526 case COMPLEX_CST:
527 case INTEGER_CST:
528 case REAL_CST:
529 case FIXED_CST:
530 case CONSTRUCTOR:
531 return true;
533 case ADDR_EXPR:
534 gcc_assert (is_gimple_min_invariant (*addr_p));
535 return true;
537 case TARGET_MEM_REF:
538 idx = &TMR_BASE (*addr_p);
539 if (*idx
540 && !cbck (*addr_p, idx, data))
541 return false;
542 idx = &TMR_INDEX (*addr_p);
543 if (*idx
544 && !cbck (*addr_p, idx, data))
545 return false;
546 idx = &TMR_INDEX2 (*addr_p);
547 if (*idx
548 && !cbck (*addr_p, idx, data))
549 return false;
550 return true;
552 default:
553 gcc_unreachable ();
559 /* The name and the length of the currently generated variable
560 for lsm. */
561 #define MAX_LSM_NAME_LENGTH 40
562 static char lsm_tmp_name[MAX_LSM_NAME_LENGTH + 1];
563 static int lsm_tmp_name_length;
565 /* Adds S to lsm_tmp_name. */
567 static void
568 lsm_tmp_name_add (const char *s)
570 int l = strlen (s) + lsm_tmp_name_length;
571 if (l > MAX_LSM_NAME_LENGTH)
572 return;
574 strcpy (lsm_tmp_name + lsm_tmp_name_length, s);
575 lsm_tmp_name_length = l;
578 /* Stores the name for temporary variable that replaces REF to
579 lsm_tmp_name. */
581 static void
582 gen_lsm_tmp_name (tree ref)
584 const char *name;
586 switch (TREE_CODE (ref))
588 case MEM_REF:
589 case TARGET_MEM_REF:
590 gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
591 lsm_tmp_name_add ("_");
592 break;
594 case ADDR_EXPR:
595 gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
596 break;
598 case BIT_FIELD_REF:
599 case VIEW_CONVERT_EXPR:
600 case ARRAY_RANGE_REF:
601 gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
602 break;
604 case REALPART_EXPR:
605 gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
606 lsm_tmp_name_add ("_RE");
607 break;
609 case IMAGPART_EXPR:
610 gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
611 lsm_tmp_name_add ("_IM");
612 break;
614 case COMPONENT_REF:
615 gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
616 lsm_tmp_name_add ("_");
617 name = get_name (TREE_OPERAND (ref, 1));
618 if (!name)
619 name = "F";
620 lsm_tmp_name_add (name);
621 break;
623 case ARRAY_REF:
624 gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
625 lsm_tmp_name_add ("_I");
626 break;
628 case SSA_NAME:
629 case VAR_DECL:
630 case PARM_DECL:
631 name = get_name (ref);
632 if (!name)
633 name = "D";
634 lsm_tmp_name_add (name);
635 break;
637 case STRING_CST:
638 lsm_tmp_name_add ("S");
639 break;
641 case RESULT_DECL:
642 lsm_tmp_name_add ("R");
643 break;
645 case INTEGER_CST:
646 /* Nothing. */
647 break;
649 default:
650 gcc_unreachable ();
654 /* Determines name for temporary variable that replaces REF.
655 The name is accumulated into the lsm_tmp_name variable.
656 N is added to the name of the temporary. */
658 char *
659 get_lsm_tmp_name (tree ref, unsigned n, const char *suffix)
661 char ns[2];
663 lsm_tmp_name_length = 0;
664 gen_lsm_tmp_name (ref);
665 lsm_tmp_name_add ("_lsm");
666 if (n < 10)
668 ns[0] = '0' + n;
669 ns[1] = 0;
670 lsm_tmp_name_add (ns);
672 return lsm_tmp_name;
673 if (suffix != NULL)
674 lsm_tmp_name_add (suffix);
677 /* Computes an estimated number of insns in LOOP, weighted by WEIGHTS. */
679 unsigned
680 tree_num_loop_insns (struct loop *loop, eni_weights *weights)
682 basic_block *body = get_loop_body (loop);
683 gimple_stmt_iterator gsi;
684 unsigned size = 0, i;
686 for (i = 0; i < loop->num_nodes; i++)
687 for (gsi = gsi_start_bb (body[i]); !gsi_end_p (gsi); gsi_next (&gsi))
688 size += estimate_num_insns (gsi_stmt (gsi), weights);
689 free (body);
691 return size;