1 /* Loop optimizations over tree-ssa.
2 Copyright (C) 2003-2016 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"
26 #include "tree-pass.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"
35 #include "tree-inline.h"
36 #include "tree-scalar-evolution.h"
37 #include "tree-vectorizer.h"
39 #include "diagnostic-core.h"
42 /* A pass making sure loops are fixed up. */
46 const pass_data pass_data_fix_loops
=
48 GIMPLE_PASS
, /* type */
49 "fix_loops", /* name */
50 OPTGROUP_LOOP
, /* optinfo_flags */
51 TV_TREE_LOOP
, /* tv_id */
52 PROP_cfg
, /* properties_required */
53 0, /* properties_provided */
54 0, /* properties_destroyed */
55 0, /* todo_flags_start */
56 0, /* todo_flags_finish */
59 class pass_fix_loops
: public gimple_opt_pass
62 pass_fix_loops (gcc::context
*ctxt
)
63 : gimple_opt_pass (pass_data_fix_loops
, ctxt
)
66 /* opt_pass methods: */
67 virtual bool gate (function
*) { return flag_tree_loop_optimize
; }
69 virtual unsigned int execute (function
*fn
);
70 }; // class pass_fix_loops
73 pass_fix_loops::execute (function
*)
75 if (loops_state_satisfies_p (LOOPS_NEED_FIXUP
))
77 calculate_dominance_info (CDI_DOMINATORS
);
78 fix_loop_structure (NULL
);
86 make_pass_fix_loops (gcc::context
*ctxt
)
88 return new pass_fix_loops (ctxt
);
92 /* Gate for loop pass group. The group is controlled by -ftree-loop-optimize
93 but we also avoid running it when the IL doesn't contain any loop. */
96 gate_loop (function
*fn
)
98 if (!flag_tree_loop_optimize
)
101 /* For -fdump-passes which runs before loop discovery print the
102 state of -ftree-loop-optimize. */
103 if (!loops_for_fn (fn
))
106 return number_of_loops (fn
) > 1;
109 /* The loop superpass. */
113 const pass_data pass_data_tree_loop
=
115 GIMPLE_PASS
, /* type */
117 OPTGROUP_LOOP
, /* optinfo_flags */
118 TV_TREE_LOOP
, /* tv_id */
119 PROP_cfg
, /* properties_required */
120 0, /* properties_provided */
121 0, /* properties_destroyed */
122 0, /* todo_flags_start */
123 0, /* todo_flags_finish */
126 class pass_tree_loop
: public gimple_opt_pass
129 pass_tree_loop (gcc::context
*ctxt
)
130 : gimple_opt_pass (pass_data_tree_loop
, ctxt
)
133 /* opt_pass methods: */
134 virtual bool gate (function
*fn
) { return gate_loop (fn
); }
136 }; // class pass_tree_loop
141 make_pass_tree_loop (gcc::context
*ctxt
)
143 return new pass_tree_loop (ctxt
);
146 /* Gate for oacc kernels pass group. */
149 gate_oacc_kernels (function
*fn
)
154 tree oacc_function_attr
= get_oacc_fn_attrib (fn
->decl
);
155 if (oacc_function_attr
== NULL_TREE
)
157 if (!oacc_fn_attrib_kernels_p (oacc_function_attr
))
161 FOR_EACH_LOOP (loop
, 0)
162 if (loop
->in_oacc_kernels_region
)
168 /* The oacc kernels superpass. */
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
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
200 make_pass_oacc_kernels (gcc::context
*ctxt
)
202 return new pass_oacc_kernels (ctxt
);
205 /* The ipa oacc superpass. */
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
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
*)
234 /* Don't bother doing anything if the program has errors. */
238 }; // class pass_ipa_oacc
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. */
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
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
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. */
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
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
314 make_pass_tree_no_loop (gcc::context
*ctxt
)
316 return new pass_tree_no_loop (ctxt
);
320 /* Loop optimizer initialization. */
324 const pass_data pass_data_tree_loop_init
=
326 GIMPLE_PASS
, /* type */
327 "loopinit", /* name */
328 OPTGROUP_LOOP
, /* optinfo_flags */
330 PROP_cfg
, /* properties_required */
331 0, /* properties_provided */
332 0, /* properties_destroyed */
333 0, /* todo_flags_start */
334 0, /* todo_flags_finish */
337 class pass_tree_loop_init
: public gimple_opt_pass
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
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
354 (loops_state_satisfies_p (LOOPS_NORMAL | LOOPS_HAVE_RECORDED_EXITS
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
);
369 make_pass_tree_loop_init (gcc::context
*ctxt
)
371 return new pass_tree_loop_init (ctxt
);
374 /* Loop autovectorization. */
378 const pass_data pass_data_vectorize
=
380 GIMPLE_PASS
, /* type */
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
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
409 pass_vectorize::execute (function
*fun
)
411 if (number_of_loops (fun
) <= 1)
414 return vectorize_loops ();
420 make_pass_vectorize (gcc::context
*ctxt
)
422 return new pass_vectorize (ctxt
);
425 /* Propagation of constants using scev. */
429 const pass_data pass_data_scev_cprop
=
431 GIMPLE_PASS
, /* type */
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 */
440 | TODO_update_ssa_only_virtuals
), /* todo_flags_finish */
443 class pass_scev_cprop
: public gimple_opt_pass
446 pass_scev_cprop (gcc::context
*ctxt
)
447 : gimple_opt_pass (pass_data_scev_cprop
, ctxt
)
450 /* opt_pass methods: */
451 virtual bool gate (function
*) { return flag_tree_scev_cprop
; }
452 virtual unsigned int execute (function
*) { return scev_const_prop (); }
454 }; // class pass_scev_cprop
459 make_pass_scev_cprop (gcc::context
*ctxt
)
461 return new pass_scev_cprop (ctxt
);
464 /* Record bounds on numbers of iterations of loops. */
468 const pass_data pass_data_record_bounds
=
470 GIMPLE_PASS
, /* type */
471 "*record_bounds", /* name */
472 OPTGROUP_NONE
, /* optinfo_flags */
473 TV_TREE_LOOP_BOUNDS
, /* tv_id */
474 ( PROP_cfg
| PROP_ssa
), /* properties_required */
475 0, /* properties_provided */
476 0, /* properties_destroyed */
477 0, /* todo_flags_start */
478 0, /* todo_flags_finish */
481 class pass_record_bounds
: public gimple_opt_pass
484 pass_record_bounds (gcc::context
*ctxt
)
485 : gimple_opt_pass (pass_data_record_bounds
, ctxt
)
488 /* opt_pass methods: */
489 virtual unsigned int execute (function
*);
491 }; // class pass_record_bounds
494 pass_record_bounds::execute (function
*fun
)
496 if (number_of_loops (fun
) <= 1)
499 estimate_numbers_of_iterations ();
507 make_pass_record_bounds (gcc::context
*ctxt
)
509 return new pass_record_bounds (ctxt
);
512 /* Induction variable optimizations. */
516 const pass_data pass_data_iv_optimize
=
518 GIMPLE_PASS
, /* type */
520 OPTGROUP_LOOP
, /* optinfo_flags */
521 TV_TREE_LOOP_IVOPTS
, /* tv_id */
522 ( PROP_cfg
| PROP_ssa
), /* properties_required */
523 0, /* properties_provided */
524 0, /* properties_destroyed */
525 0, /* todo_flags_start */
526 TODO_update_ssa
, /* todo_flags_finish */
529 class pass_iv_optimize
: public gimple_opt_pass
532 pass_iv_optimize (gcc::context
*ctxt
)
533 : gimple_opt_pass (pass_data_iv_optimize
, ctxt
)
536 /* opt_pass methods: */
537 virtual bool gate (function
*) { return flag_ivopts
!= 0; }
538 virtual unsigned int execute (function
*);
540 }; // class pass_iv_optimize
543 pass_iv_optimize::execute (function
*fun
)
545 if (number_of_loops (fun
) <= 1)
548 tree_ssa_iv_optimize ();
555 make_pass_iv_optimize (gcc::context
*ctxt
)
557 return new pass_iv_optimize (ctxt
);
560 /* Loop optimizer finalization. */
563 tree_ssa_loop_done (void)
565 free_numbers_of_iterations_estimates (cfun
);
567 loop_optimizer_finalize ();
573 const pass_data pass_data_tree_loop_done
=
575 GIMPLE_PASS
, /* type */
576 "loopdone", /* name */
577 OPTGROUP_LOOP
, /* optinfo_flags */
579 PROP_cfg
, /* properties_required */
580 0, /* properties_provided */
581 0, /* properties_destroyed */
582 0, /* todo_flags_start */
583 TODO_cleanup_cfg
, /* todo_flags_finish */
586 class pass_tree_loop_done
: public gimple_opt_pass
589 pass_tree_loop_done (gcc::context
*ctxt
)
590 : gimple_opt_pass (pass_data_tree_loop_done
, ctxt
)
593 /* opt_pass methods: */
594 virtual unsigned int execute (function
*) { return tree_ssa_loop_done (); }
596 }; // class pass_tree_loop_done
601 make_pass_tree_loop_done (gcc::context
*ctxt
)
603 return new pass_tree_loop_done (ctxt
);
606 /* Calls CBCK for each index in memory reference ADDR_P. There are two
607 kinds situations handled; in each of these cases, the memory reference
608 and DATA are passed to the callback:
610 Access to an array: ARRAY_{RANGE_}REF (base, index). In this case we also
611 pass the pointer to the index to the callback.
613 Pointer dereference: INDIRECT_REF (addr). In this case we also pass the
614 pointer to addr to the callback.
616 If the callback returns false, the whole search stops and false is returned.
617 Otherwise the function returns true after traversing through the whole
618 reference *ADDR_P. */
621 for_each_index (tree
*addr_p
, bool (*cbck
) (tree
, tree
*, void *), void *data
)
625 for (; ; addr_p
= nxt
)
627 switch (TREE_CODE (*addr_p
))
630 return cbck (*addr_p
, addr_p
, data
);
633 nxt
= &TREE_OPERAND (*addr_p
, 0);
634 return cbck (*addr_p
, nxt
, data
);
637 case VIEW_CONVERT_EXPR
:
640 nxt
= &TREE_OPERAND (*addr_p
, 0);
644 /* If the component has varying offset, it behaves like index
646 idx
= &TREE_OPERAND (*addr_p
, 2);
648 && !cbck (*addr_p
, idx
, data
))
651 nxt
= &TREE_OPERAND (*addr_p
, 0);
655 case ARRAY_RANGE_REF
:
656 nxt
= &TREE_OPERAND (*addr_p
, 0);
657 if (!cbck (*addr_p
, &TREE_OPERAND (*addr_p
, 1), data
))
675 gcc_assert (is_gimple_min_invariant (*addr_p
));
679 idx
= &TMR_BASE (*addr_p
);
681 && !cbck (*addr_p
, idx
, data
))
683 idx
= &TMR_INDEX (*addr_p
);
685 && !cbck (*addr_p
, idx
, data
))
687 idx
= &TMR_INDEX2 (*addr_p
);
689 && !cbck (*addr_p
, idx
, data
))
700 /* The name and the length of the currently generated variable
702 #define MAX_LSM_NAME_LENGTH 40
703 static char lsm_tmp_name
[MAX_LSM_NAME_LENGTH
+ 1];
704 static int lsm_tmp_name_length
;
706 /* Adds S to lsm_tmp_name. */
709 lsm_tmp_name_add (const char *s
)
711 int l
= strlen (s
) + lsm_tmp_name_length
;
712 if (l
> MAX_LSM_NAME_LENGTH
)
715 strcpy (lsm_tmp_name
+ lsm_tmp_name_length
, s
);
716 lsm_tmp_name_length
= l
;
719 /* Stores the name for temporary variable that replaces REF to
723 gen_lsm_tmp_name (tree ref
)
727 switch (TREE_CODE (ref
))
731 gen_lsm_tmp_name (TREE_OPERAND (ref
, 0));
732 lsm_tmp_name_add ("_");
736 gen_lsm_tmp_name (TREE_OPERAND (ref
, 0));
740 case VIEW_CONVERT_EXPR
:
741 case ARRAY_RANGE_REF
:
742 gen_lsm_tmp_name (TREE_OPERAND (ref
, 0));
746 gen_lsm_tmp_name (TREE_OPERAND (ref
, 0));
747 lsm_tmp_name_add ("_RE");
751 gen_lsm_tmp_name (TREE_OPERAND (ref
, 0));
752 lsm_tmp_name_add ("_IM");
756 gen_lsm_tmp_name (TREE_OPERAND (ref
, 0));
757 lsm_tmp_name_add ("_");
758 name
= get_name (TREE_OPERAND (ref
, 1));
761 lsm_tmp_name_add (name
);
765 gen_lsm_tmp_name (TREE_OPERAND (ref
, 0));
766 lsm_tmp_name_add ("_I");
774 name
= get_name (ref
);
777 lsm_tmp_name_add (name
);
781 lsm_tmp_name_add ("S");
785 lsm_tmp_name_add ("R");
795 /* Determines name for temporary variable that replaces REF.
796 The name is accumulated into the lsm_tmp_name variable.
797 N is added to the name of the temporary. */
800 get_lsm_tmp_name (tree ref
, unsigned n
, const char *suffix
)
804 lsm_tmp_name_length
= 0;
805 gen_lsm_tmp_name (ref
);
806 lsm_tmp_name_add ("_lsm");
811 lsm_tmp_name_add (ns
);
815 lsm_tmp_name_add (suffix
);
818 /* Computes an estimated number of insns in LOOP, weighted by WEIGHTS. */
821 tree_num_loop_insns (struct loop
*loop
, eni_weights
*weights
)
823 basic_block
*body
= get_loop_body (loop
);
824 gimple_stmt_iterator gsi
;
825 unsigned size
= 0, i
;
827 for (i
= 0; i
< loop
->num_nodes
; i
++)
828 for (gsi
= gsi_start_bb (body
[i
]); !gsi_end_p (gsi
); gsi_next (&gsi
))
829 size
+= estimate_num_insns (gsi_stmt (gsi
), weights
);