2015-11-22 Jerry DeLisle <jvdelisle@gcc.gnu.org>
[official-gcc.git] / gcc / tree-ssa-loop.c
blobafdef1217885b484e0735bf17c77f138ca1e648b
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 /* When processing a loop in the loop pipeline, we should be able to assert
215 that:
216 (loops_state_satisfies_p (LOOPS_NORMAL | LOOPS_HAVE_RECORDED_EXITS
217 | LOOP_CLOSED_SSA)
218 && scev_initialized_p ())
220 loop_optimizer_init (LOOPS_NORMAL
221 | LOOPS_HAVE_RECORDED_EXITS);
222 rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa);
223 scev_initialize ();
225 return 0;
228 } // anon namespace
230 gimple_opt_pass *
231 make_pass_tree_loop_init (gcc::context *ctxt)
233 return new pass_tree_loop_init (ctxt);
236 /* Loop autovectorization. */
238 namespace {
240 const pass_data pass_data_vectorize =
242 GIMPLE_PASS, /* type */
243 "vect", /* name */
244 OPTGROUP_LOOP | OPTGROUP_VEC, /* optinfo_flags */
245 TV_TREE_VECTORIZATION, /* tv_id */
246 ( PROP_cfg | PROP_ssa ), /* properties_required */
247 0, /* properties_provided */
248 0, /* properties_destroyed */
249 0, /* todo_flags_start */
250 0, /* todo_flags_finish */
253 class pass_vectorize : public gimple_opt_pass
255 public:
256 pass_vectorize (gcc::context *ctxt)
257 : gimple_opt_pass (pass_data_vectorize, ctxt)
260 /* opt_pass methods: */
261 virtual bool gate (function *fun)
263 return flag_tree_loop_vectorize || fun->has_force_vectorize_loops;
266 virtual unsigned int execute (function *);
268 }; // class pass_vectorize
270 unsigned int
271 pass_vectorize::execute (function *fun)
273 if (number_of_loops (fun) <= 1)
274 return 0;
276 return vectorize_loops ();
279 } // anon namespace
281 gimple_opt_pass *
282 make_pass_vectorize (gcc::context *ctxt)
284 return new pass_vectorize (ctxt);
287 /* Propagation of constants using scev. */
289 namespace {
291 const pass_data pass_data_scev_cprop =
293 GIMPLE_PASS, /* type */
294 "sccp", /* name */
295 OPTGROUP_LOOP, /* optinfo_flags */
296 TV_SCEV_CONST, /* tv_id */
297 ( PROP_cfg | PROP_ssa ), /* properties_required */
298 0, /* properties_provided */
299 0, /* properties_destroyed */
300 0, /* todo_flags_start */
301 ( TODO_cleanup_cfg
302 | TODO_update_ssa_only_virtuals ), /* todo_flags_finish */
305 class pass_scev_cprop : public gimple_opt_pass
307 public:
308 pass_scev_cprop (gcc::context *ctxt)
309 : gimple_opt_pass (pass_data_scev_cprop, ctxt)
312 /* opt_pass methods: */
313 virtual bool gate (function *) { return flag_tree_scev_cprop; }
314 virtual unsigned int execute (function *) { return scev_const_prop (); }
316 }; // class pass_scev_cprop
318 } // anon namespace
320 gimple_opt_pass *
321 make_pass_scev_cprop (gcc::context *ctxt)
323 return new pass_scev_cprop (ctxt);
326 /* Record bounds on numbers of iterations of loops. */
328 namespace {
330 const pass_data pass_data_record_bounds =
332 GIMPLE_PASS, /* type */
333 "*record_bounds", /* name */
334 OPTGROUP_NONE, /* optinfo_flags */
335 TV_TREE_LOOP_BOUNDS, /* tv_id */
336 ( PROP_cfg | PROP_ssa ), /* properties_required */
337 0, /* properties_provided */
338 0, /* properties_destroyed */
339 0, /* todo_flags_start */
340 0, /* todo_flags_finish */
343 class pass_record_bounds : public gimple_opt_pass
345 public:
346 pass_record_bounds (gcc::context *ctxt)
347 : gimple_opt_pass (pass_data_record_bounds, ctxt)
350 /* opt_pass methods: */
351 virtual unsigned int execute (function *);
353 }; // class pass_record_bounds
355 unsigned int
356 pass_record_bounds::execute (function *fun)
358 if (number_of_loops (fun) <= 1)
359 return 0;
361 estimate_numbers_of_iterations ();
362 scev_reset ();
363 return 0;
366 } // anon namespace
368 gimple_opt_pass *
369 make_pass_record_bounds (gcc::context *ctxt)
371 return new pass_record_bounds (ctxt);
374 /* Induction variable optimizations. */
376 namespace {
378 const pass_data pass_data_iv_optimize =
380 GIMPLE_PASS, /* type */
381 "ivopts", /* name */
382 OPTGROUP_LOOP, /* optinfo_flags */
383 TV_TREE_LOOP_IVOPTS, /* tv_id */
384 ( PROP_cfg | PROP_ssa ), /* properties_required */
385 0, /* properties_provided */
386 0, /* properties_destroyed */
387 0, /* todo_flags_start */
388 TODO_update_ssa, /* todo_flags_finish */
391 class pass_iv_optimize : public gimple_opt_pass
393 public:
394 pass_iv_optimize (gcc::context *ctxt)
395 : gimple_opt_pass (pass_data_iv_optimize, ctxt)
398 /* opt_pass methods: */
399 virtual bool gate (function *) { return flag_ivopts != 0; }
400 virtual unsigned int execute (function *);
402 }; // class pass_iv_optimize
404 unsigned int
405 pass_iv_optimize::execute (function *fun)
407 if (number_of_loops (fun) <= 1)
408 return 0;
410 tree_ssa_iv_optimize ();
411 return 0;
414 } // anon namespace
416 gimple_opt_pass *
417 make_pass_iv_optimize (gcc::context *ctxt)
419 return new pass_iv_optimize (ctxt);
422 /* Loop optimizer finalization. */
424 static unsigned int
425 tree_ssa_loop_done (void)
427 free_numbers_of_iterations_estimates (cfun);
428 scev_finalize ();
429 loop_optimizer_finalize ();
430 return 0;
433 namespace {
435 const pass_data pass_data_tree_loop_done =
437 GIMPLE_PASS, /* type */
438 "loopdone", /* name */
439 OPTGROUP_LOOP, /* optinfo_flags */
440 TV_NONE, /* tv_id */
441 PROP_cfg, /* properties_required */
442 0, /* properties_provided */
443 0, /* properties_destroyed */
444 0, /* todo_flags_start */
445 TODO_cleanup_cfg, /* todo_flags_finish */
448 class pass_tree_loop_done : public gimple_opt_pass
450 public:
451 pass_tree_loop_done (gcc::context *ctxt)
452 : gimple_opt_pass (pass_data_tree_loop_done, ctxt)
455 /* opt_pass methods: */
456 virtual unsigned int execute (function *) { return tree_ssa_loop_done (); }
458 }; // class pass_tree_loop_done
460 } // anon namespace
462 gimple_opt_pass *
463 make_pass_tree_loop_done (gcc::context *ctxt)
465 return new pass_tree_loop_done (ctxt);
468 /* Calls CBCK for each index in memory reference ADDR_P. There are two
469 kinds situations handled; in each of these cases, the memory reference
470 and DATA are passed to the callback:
472 Access to an array: ARRAY_{RANGE_}REF (base, index). In this case we also
473 pass the pointer to the index to the callback.
475 Pointer dereference: INDIRECT_REF (addr). In this case we also pass the
476 pointer to addr to the callback.
478 If the callback returns false, the whole search stops and false is returned.
479 Otherwise the function returns true after traversing through the whole
480 reference *ADDR_P. */
482 bool
483 for_each_index (tree *addr_p, bool (*cbck) (tree, tree *, void *), void *data)
485 tree *nxt, *idx;
487 for (; ; addr_p = nxt)
489 switch (TREE_CODE (*addr_p))
491 case SSA_NAME:
492 return cbck (*addr_p, addr_p, data);
494 case MEM_REF:
495 nxt = &TREE_OPERAND (*addr_p, 0);
496 return cbck (*addr_p, nxt, data);
498 case BIT_FIELD_REF:
499 case VIEW_CONVERT_EXPR:
500 case REALPART_EXPR:
501 case IMAGPART_EXPR:
502 nxt = &TREE_OPERAND (*addr_p, 0);
503 break;
505 case COMPONENT_REF:
506 /* If the component has varying offset, it behaves like index
507 as well. */
508 idx = &TREE_OPERAND (*addr_p, 2);
509 if (*idx
510 && !cbck (*addr_p, idx, data))
511 return false;
513 nxt = &TREE_OPERAND (*addr_p, 0);
514 break;
516 case ARRAY_REF:
517 case ARRAY_RANGE_REF:
518 nxt = &TREE_OPERAND (*addr_p, 0);
519 if (!cbck (*addr_p, &TREE_OPERAND (*addr_p, 1), data))
520 return false;
521 break;
523 case VAR_DECL:
524 case PARM_DECL:
525 case CONST_DECL:
526 case STRING_CST:
527 case RESULT_DECL:
528 case VECTOR_CST:
529 case COMPLEX_CST:
530 case INTEGER_CST:
531 case REAL_CST:
532 case FIXED_CST:
533 case CONSTRUCTOR:
534 return true;
536 case ADDR_EXPR:
537 gcc_assert (is_gimple_min_invariant (*addr_p));
538 return true;
540 case TARGET_MEM_REF:
541 idx = &TMR_BASE (*addr_p);
542 if (*idx
543 && !cbck (*addr_p, idx, data))
544 return false;
545 idx = &TMR_INDEX (*addr_p);
546 if (*idx
547 && !cbck (*addr_p, idx, data))
548 return false;
549 idx = &TMR_INDEX2 (*addr_p);
550 if (*idx
551 && !cbck (*addr_p, idx, data))
552 return false;
553 return true;
555 default:
556 gcc_unreachable ();
562 /* The name and the length of the currently generated variable
563 for lsm. */
564 #define MAX_LSM_NAME_LENGTH 40
565 static char lsm_tmp_name[MAX_LSM_NAME_LENGTH + 1];
566 static int lsm_tmp_name_length;
568 /* Adds S to lsm_tmp_name. */
570 static void
571 lsm_tmp_name_add (const char *s)
573 int l = strlen (s) + lsm_tmp_name_length;
574 if (l > MAX_LSM_NAME_LENGTH)
575 return;
577 strcpy (lsm_tmp_name + lsm_tmp_name_length, s);
578 lsm_tmp_name_length = l;
581 /* Stores the name for temporary variable that replaces REF to
582 lsm_tmp_name. */
584 static void
585 gen_lsm_tmp_name (tree ref)
587 const char *name;
589 switch (TREE_CODE (ref))
591 case MEM_REF:
592 case TARGET_MEM_REF:
593 gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
594 lsm_tmp_name_add ("_");
595 break;
597 case ADDR_EXPR:
598 gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
599 break;
601 case BIT_FIELD_REF:
602 case VIEW_CONVERT_EXPR:
603 case ARRAY_RANGE_REF:
604 gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
605 break;
607 case REALPART_EXPR:
608 gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
609 lsm_tmp_name_add ("_RE");
610 break;
612 case IMAGPART_EXPR:
613 gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
614 lsm_tmp_name_add ("_IM");
615 break;
617 case COMPONENT_REF:
618 gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
619 lsm_tmp_name_add ("_");
620 name = get_name (TREE_OPERAND (ref, 1));
621 if (!name)
622 name = "F";
623 lsm_tmp_name_add (name);
624 break;
626 case ARRAY_REF:
627 gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
628 lsm_tmp_name_add ("_I");
629 break;
631 case SSA_NAME:
632 case VAR_DECL:
633 case PARM_DECL:
634 name = get_name (ref);
635 if (!name)
636 name = "D";
637 lsm_tmp_name_add (name);
638 break;
640 case STRING_CST:
641 lsm_tmp_name_add ("S");
642 break;
644 case RESULT_DECL:
645 lsm_tmp_name_add ("R");
646 break;
648 case INTEGER_CST:
649 /* Nothing. */
650 break;
652 default:
653 gcc_unreachable ();
657 /* Determines name for temporary variable that replaces REF.
658 The name is accumulated into the lsm_tmp_name variable.
659 N is added to the name of the temporary. */
661 char *
662 get_lsm_tmp_name (tree ref, unsigned n, const char *suffix)
664 char ns[2];
666 lsm_tmp_name_length = 0;
667 gen_lsm_tmp_name (ref);
668 lsm_tmp_name_add ("_lsm");
669 if (n < 10)
671 ns[0] = '0' + n;
672 ns[1] = 0;
673 lsm_tmp_name_add (ns);
675 return lsm_tmp_name;
676 if (suffix != NULL)
677 lsm_tmp_name_add (suffix);
680 /* Computes an estimated number of insns in LOOP, weighted by WEIGHTS. */
682 unsigned
683 tree_num_loop_insns (struct loop *loop, eni_weights *weights)
685 basic_block *body = get_loop_body (loop);
686 gimple_stmt_iterator gsi;
687 unsigned size = 0, i;
689 for (i = 0; i < loop->num_nodes; i++)
690 for (gsi = gsi_start_bb (body[i]); !gsi_end_p (gsi); gsi_next (&gsi))
691 size += estimate_num_insns (gsi_stmt (gsi), weights);
692 free (body);
694 return size;