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
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
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/>. */
22 #include "coretypes.h"
27 #include "fold-const.h"
30 #include "hard-reg-set.h"
32 #include "dominance.h"
34 #include "basic-block.h"
35 #include "tree-ssa-alias.h"
36 #include "internal-fn.h"
37 #include "gimple-expr.h"
39 #include "gimple-iterator.h"
40 #include "tree-ssa-loop-ivopts.h"
41 #include "tree-ssa-loop-manip.h"
42 #include "tree-ssa-loop-niter.h"
43 #include "tree-ssa-loop.h"
44 #include "tree-pass.h"
47 #include "tree-inline.h"
48 #include "tree-scalar-evolution.h"
49 #include "diagnostic-core.h"
50 #include "tree-vectorizer.h"
53 /* A pass making sure loops are fixed up. */
57 const pass_data pass_data_fix_loops
=
59 GIMPLE_PASS
, /* type */
60 "fix_loops", /* name */
61 OPTGROUP_LOOP
, /* optinfo_flags */
62 TV_TREE_LOOP
, /* tv_id */
63 PROP_cfg
, /* properties_required */
64 0, /* properties_provided */
65 0, /* properties_destroyed */
66 0, /* todo_flags_start */
67 0, /* todo_flags_finish */
70 class pass_fix_loops
: public gimple_opt_pass
73 pass_fix_loops (gcc::context
*ctxt
)
74 : gimple_opt_pass (pass_data_fix_loops
, ctxt
)
77 /* opt_pass methods: */
78 virtual bool gate (function
*) { return flag_tree_loop_optimize
; }
80 virtual unsigned int execute (function
*fn
);
81 }; // class pass_fix_loops
84 pass_fix_loops::execute (function
*)
86 if (loops_state_satisfies_p (LOOPS_NEED_FIXUP
))
88 calculate_dominance_info (CDI_DOMINATORS
);
89 fix_loop_structure (NULL
);
97 make_pass_fix_loops (gcc::context
*ctxt
)
99 return new pass_fix_loops (ctxt
);
103 /* Gate for loop pass group. The group is controlled by -ftree-loop-optimize
104 but we also avoid running it when the IL doesn't contain any loop. */
107 gate_loop (function
*fn
)
109 if (!flag_tree_loop_optimize
)
112 /* For -fdump-passes which runs before loop discovery print the
113 state of -ftree-loop-optimize. */
114 if (!loops_for_fn (fn
))
117 return number_of_loops (fn
) > 1;
120 /* The loop superpass. */
124 const pass_data pass_data_tree_loop
=
126 GIMPLE_PASS
, /* type */
128 OPTGROUP_LOOP
, /* optinfo_flags */
129 TV_TREE_LOOP
, /* tv_id */
130 PROP_cfg
, /* properties_required */
131 0, /* properties_provided */
132 0, /* properties_destroyed */
133 0, /* todo_flags_start */
134 0, /* todo_flags_finish */
137 class pass_tree_loop
: public gimple_opt_pass
140 pass_tree_loop (gcc::context
*ctxt
)
141 : gimple_opt_pass (pass_data_tree_loop
, ctxt
)
144 /* opt_pass methods: */
145 virtual bool gate (function
*fn
) { return gate_loop (fn
); }
147 }; // class pass_tree_loop
152 make_pass_tree_loop (gcc::context
*ctxt
)
154 return new pass_tree_loop (ctxt
);
157 /* The no-loop superpass. */
161 const pass_data pass_data_tree_no_loop
=
163 GIMPLE_PASS
, /* type */
164 "no_loop", /* name */
165 OPTGROUP_NONE
, /* optinfo_flags */
166 TV_TREE_NOLOOP
, /* tv_id */
167 PROP_cfg
, /* properties_required */
168 0, /* properties_provided */
169 0, /* properties_destroyed */
170 0, /* todo_flags_start */
171 0, /* todo_flags_finish */
174 class pass_tree_no_loop
: public gimple_opt_pass
177 pass_tree_no_loop (gcc::context
*ctxt
)
178 : gimple_opt_pass (pass_data_tree_no_loop
, ctxt
)
181 /* opt_pass methods: */
182 virtual bool gate (function
*fn
) { return !gate_loop (fn
); }
184 }; // class pass_tree_no_loop
189 make_pass_tree_no_loop (gcc::context
*ctxt
)
191 return new pass_tree_no_loop (ctxt
);
195 /* Loop optimizer initialization. */
199 const pass_data pass_data_tree_loop_init
=
201 GIMPLE_PASS
, /* type */
202 "loopinit", /* name */
203 OPTGROUP_LOOP
, /* optinfo_flags */
205 PROP_cfg
, /* properties_required */
206 0, /* properties_provided */
207 0, /* properties_destroyed */
208 0, /* todo_flags_start */
209 0, /* todo_flags_finish */
212 class pass_tree_loop_init
: public gimple_opt_pass
215 pass_tree_loop_init (gcc::context
*ctxt
)
216 : gimple_opt_pass (pass_data_tree_loop_init
, ctxt
)
219 /* opt_pass methods: */
220 virtual unsigned int execute (function
*);
222 }; // class pass_tree_loop_init
225 pass_tree_loop_init::execute (function
*fun ATTRIBUTE_UNUSED
)
227 loop_optimizer_init (LOOPS_NORMAL
228 | LOOPS_HAVE_RECORDED_EXITS
);
229 rewrite_into_loop_closed_ssa (NULL
, TODO_update_ssa
);
231 /* We might discover new loops, e.g. when turning irreducible
232 regions into reducible. */
241 make_pass_tree_loop_init (gcc::context
*ctxt
)
243 return new pass_tree_loop_init (ctxt
);
246 /* Loop autovectorization. */
250 const pass_data pass_data_vectorize
=
252 GIMPLE_PASS
, /* type */
254 OPTGROUP_LOOP
| OPTGROUP_VEC
, /* optinfo_flags */
255 TV_TREE_VECTORIZATION
, /* tv_id */
256 ( PROP_cfg
| PROP_ssa
), /* properties_required */
257 0, /* properties_provided */
258 0, /* properties_destroyed */
259 0, /* todo_flags_start */
260 0, /* todo_flags_finish */
263 class pass_vectorize
: public gimple_opt_pass
266 pass_vectorize (gcc::context
*ctxt
)
267 : gimple_opt_pass (pass_data_vectorize
, ctxt
)
270 /* opt_pass methods: */
271 virtual bool gate (function
*fun
)
273 return flag_tree_loop_vectorize
|| fun
->has_force_vectorize_loops
;
276 virtual unsigned int execute (function
*);
278 }; // class pass_vectorize
281 pass_vectorize::execute (function
*fun
)
283 if (number_of_loops (fun
) <= 1)
286 return vectorize_loops ();
292 make_pass_vectorize (gcc::context
*ctxt
)
294 return new pass_vectorize (ctxt
);
297 /* Check the correctness of the data dependence analyzers. */
301 const pass_data pass_data_check_data_deps
=
303 GIMPLE_PASS
, /* type */
305 OPTGROUP_LOOP
, /* optinfo_flags */
306 TV_CHECK_DATA_DEPS
, /* tv_id */
307 ( PROP_cfg
| PROP_ssa
), /* properties_required */
308 0, /* properties_provided */
309 0, /* properties_destroyed */
310 0, /* todo_flags_start */
311 0, /* todo_flags_finish */
314 class pass_check_data_deps
: public gimple_opt_pass
317 pass_check_data_deps (gcc::context
*ctxt
)
318 : gimple_opt_pass (pass_data_check_data_deps
, ctxt
)
321 /* opt_pass methods: */
322 virtual bool gate (function
*) { return flag_check_data_deps
!= 0; }
323 virtual unsigned int execute (function
*);
325 }; // class pass_check_data_deps
328 pass_check_data_deps::execute (function
*fun
)
330 if (number_of_loops (fun
) <= 1)
333 tree_check_data_deps ();
340 make_pass_check_data_deps (gcc::context
*ctxt
)
342 return new pass_check_data_deps (ctxt
);
345 /* Propagation of constants using scev. */
349 const pass_data pass_data_scev_cprop
=
351 GIMPLE_PASS
, /* type */
353 OPTGROUP_LOOP
, /* optinfo_flags */
354 TV_SCEV_CONST
, /* tv_id */
355 ( PROP_cfg
| PROP_ssa
), /* properties_required */
356 0, /* properties_provided */
357 0, /* properties_destroyed */
358 0, /* todo_flags_start */
360 | TODO_update_ssa_only_virtuals
), /* todo_flags_finish */
363 class pass_scev_cprop
: public gimple_opt_pass
366 pass_scev_cprop (gcc::context
*ctxt
)
367 : gimple_opt_pass (pass_data_scev_cprop
, ctxt
)
370 /* opt_pass methods: */
371 virtual bool gate (function
*) { return flag_tree_scev_cprop
; }
372 virtual unsigned int execute (function
*) { return scev_const_prop (); }
374 }; // class pass_scev_cprop
379 make_pass_scev_cprop (gcc::context
*ctxt
)
381 return new pass_scev_cprop (ctxt
);
384 /* Record bounds on numbers of iterations of loops. */
388 const pass_data pass_data_record_bounds
=
390 GIMPLE_PASS
, /* type */
391 "*record_bounds", /* name */
392 OPTGROUP_NONE
, /* optinfo_flags */
393 TV_TREE_LOOP_BOUNDS
, /* tv_id */
394 ( PROP_cfg
| PROP_ssa
), /* properties_required */
395 0, /* properties_provided */
396 0, /* properties_destroyed */
397 0, /* todo_flags_start */
398 0, /* todo_flags_finish */
401 class pass_record_bounds
: public gimple_opt_pass
404 pass_record_bounds (gcc::context
*ctxt
)
405 : gimple_opt_pass (pass_data_record_bounds
, ctxt
)
408 /* opt_pass methods: */
409 virtual unsigned int execute (function
*);
411 }; // class pass_record_bounds
414 pass_record_bounds::execute (function
*fun
)
416 if (number_of_loops (fun
) <= 1)
419 estimate_numbers_of_iterations ();
427 make_pass_record_bounds (gcc::context
*ctxt
)
429 return new pass_record_bounds (ctxt
);
432 /* Induction variable optimizations. */
436 const pass_data pass_data_iv_optimize
=
438 GIMPLE_PASS
, /* type */
440 OPTGROUP_LOOP
, /* optinfo_flags */
441 TV_TREE_LOOP_IVOPTS
, /* tv_id */
442 ( PROP_cfg
| PROP_ssa
), /* properties_required */
443 0, /* properties_provided */
444 0, /* properties_destroyed */
445 0, /* todo_flags_start */
446 TODO_update_ssa
, /* todo_flags_finish */
449 class pass_iv_optimize
: public gimple_opt_pass
452 pass_iv_optimize (gcc::context
*ctxt
)
453 : gimple_opt_pass (pass_data_iv_optimize
, ctxt
)
456 /* opt_pass methods: */
457 virtual bool gate (function
*) { return flag_ivopts
!= 0; }
458 virtual unsigned int execute (function
*);
460 }; // class pass_iv_optimize
463 pass_iv_optimize::execute (function
*fun
)
465 if (number_of_loops (fun
) <= 1)
468 tree_ssa_iv_optimize ();
475 make_pass_iv_optimize (gcc::context
*ctxt
)
477 return new pass_iv_optimize (ctxt
);
480 /* Loop optimizer finalization. */
483 tree_ssa_loop_done (void)
485 free_numbers_of_iterations_estimates ();
487 loop_optimizer_finalize ();
493 const pass_data pass_data_tree_loop_done
=
495 GIMPLE_PASS
, /* type */
496 "loopdone", /* name */
497 OPTGROUP_LOOP
, /* optinfo_flags */
499 PROP_cfg
, /* properties_required */
500 0, /* properties_provided */
501 0, /* properties_destroyed */
502 0, /* todo_flags_start */
503 TODO_cleanup_cfg
, /* todo_flags_finish */
506 class pass_tree_loop_done
: public gimple_opt_pass
509 pass_tree_loop_done (gcc::context
*ctxt
)
510 : gimple_opt_pass (pass_data_tree_loop_done
, ctxt
)
513 /* opt_pass methods: */
514 virtual unsigned int execute (function
*) { return tree_ssa_loop_done (); }
516 }; // class pass_tree_loop_done
521 make_pass_tree_loop_done (gcc::context
*ctxt
)
523 return new pass_tree_loop_done (ctxt
);
526 /* Calls CBCK for each index in memory reference ADDR_P. There are two
527 kinds situations handled; in each of these cases, the memory reference
528 and DATA are passed to the callback:
530 Access to an array: ARRAY_{RANGE_}REF (base, index). In this case we also
531 pass the pointer to the index to the callback.
533 Pointer dereference: INDIRECT_REF (addr). In this case we also pass the
534 pointer to addr to the callback.
536 If the callback returns false, the whole search stops and false is returned.
537 Otherwise the function returns true after traversing through the whole
538 reference *ADDR_P. */
541 for_each_index (tree
*addr_p
, bool (*cbck
) (tree
, tree
*, void *), void *data
)
545 for (; ; addr_p
= nxt
)
547 switch (TREE_CODE (*addr_p
))
550 return cbck (*addr_p
, addr_p
, data
);
553 nxt
= &TREE_OPERAND (*addr_p
, 0);
554 return cbck (*addr_p
, nxt
, data
);
557 case VIEW_CONVERT_EXPR
:
560 nxt
= &TREE_OPERAND (*addr_p
, 0);
564 /* If the component has varying offset, it behaves like index
566 idx
= &TREE_OPERAND (*addr_p
, 2);
568 && !cbck (*addr_p
, idx
, data
))
571 nxt
= &TREE_OPERAND (*addr_p
, 0);
575 case ARRAY_RANGE_REF
:
576 nxt
= &TREE_OPERAND (*addr_p
, 0);
577 if (!cbck (*addr_p
, &TREE_OPERAND (*addr_p
, 1), data
))
595 gcc_assert (is_gimple_min_invariant (*addr_p
));
599 idx
= &TMR_BASE (*addr_p
);
601 && !cbck (*addr_p
, idx
, data
))
603 idx
= &TMR_INDEX (*addr_p
);
605 && !cbck (*addr_p
, idx
, data
))
607 idx
= &TMR_INDEX2 (*addr_p
);
609 && !cbck (*addr_p
, idx
, data
))
620 /* The name and the length of the currently generated variable
622 #define MAX_LSM_NAME_LENGTH 40
623 static char lsm_tmp_name
[MAX_LSM_NAME_LENGTH
+ 1];
624 static int lsm_tmp_name_length
;
626 /* Adds S to lsm_tmp_name. */
629 lsm_tmp_name_add (const char *s
)
631 int l
= strlen (s
) + lsm_tmp_name_length
;
632 if (l
> MAX_LSM_NAME_LENGTH
)
635 strcpy (lsm_tmp_name
+ lsm_tmp_name_length
, s
);
636 lsm_tmp_name_length
= l
;
639 /* Stores the name for temporary variable that replaces REF to
643 gen_lsm_tmp_name (tree ref
)
647 switch (TREE_CODE (ref
))
651 gen_lsm_tmp_name (TREE_OPERAND (ref
, 0));
652 lsm_tmp_name_add ("_");
656 gen_lsm_tmp_name (TREE_OPERAND (ref
, 0));
660 case VIEW_CONVERT_EXPR
:
661 case ARRAY_RANGE_REF
:
662 gen_lsm_tmp_name (TREE_OPERAND (ref
, 0));
666 gen_lsm_tmp_name (TREE_OPERAND (ref
, 0));
667 lsm_tmp_name_add ("_RE");
671 gen_lsm_tmp_name (TREE_OPERAND (ref
, 0));
672 lsm_tmp_name_add ("_IM");
676 gen_lsm_tmp_name (TREE_OPERAND (ref
, 0));
677 lsm_tmp_name_add ("_");
678 name
= get_name (TREE_OPERAND (ref
, 1));
681 lsm_tmp_name_add (name
);
685 gen_lsm_tmp_name (TREE_OPERAND (ref
, 0));
686 lsm_tmp_name_add ("_I");
692 name
= get_name (ref
);
695 lsm_tmp_name_add (name
);
699 lsm_tmp_name_add ("S");
703 lsm_tmp_name_add ("R");
715 /* Determines name for temporary variable that replaces REF.
716 The name is accumulated into the lsm_tmp_name variable.
717 N is added to the name of the temporary. */
720 get_lsm_tmp_name (tree ref
, unsigned n
, const char *suffix
)
724 lsm_tmp_name_length
= 0;
725 gen_lsm_tmp_name (ref
);
726 lsm_tmp_name_add ("_lsm");
731 lsm_tmp_name_add (ns
);
735 lsm_tmp_name_add (suffix
);
738 /* Computes an estimated number of insns in LOOP, weighted by WEIGHTS. */
741 tree_num_loop_insns (struct loop
*loop
, eni_weights
*weights
)
743 basic_block
*body
= get_loop_body (loop
);
744 gimple_stmt_iterator gsi
;
745 unsigned size
= 0, i
;
747 for (i
= 0; i
< loop
->num_nodes
; i
++)
748 for (gsi
= gsi_start_bb (body
[i
]); !gsi_end_p (gsi
); gsi_next (&gsi
))
749 size
+= estimate_num_insns (gsi_stmt (gsi
), weights
);