1 /* Loop optimizations over tree-ssa.
2 Copyright (C) 2003-2017 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"
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"
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"
43 /* A pass making sure loops are fixed up. */
47 const pass_data pass_data_fix_loops
=
49 GIMPLE_PASS
, /* type */
50 "fix_loops", /* name */
51 OPTGROUP_LOOP
, /* optinfo_flags */
52 TV_TREE_LOOP
, /* tv_id */
53 PROP_cfg
, /* properties_required */
54 0, /* properties_provided */
55 0, /* properties_destroyed */
56 0, /* todo_flags_start */
57 0, /* todo_flags_finish */
60 class pass_fix_loops
: public gimple_opt_pass
63 pass_fix_loops (gcc::context
*ctxt
)
64 : gimple_opt_pass (pass_data_fix_loops
, ctxt
)
67 /* opt_pass methods: */
68 virtual bool gate (function
*) { return flag_tree_loop_optimize
; }
70 virtual unsigned int execute (function
*fn
);
71 }; // class pass_fix_loops
74 pass_fix_loops::execute (function
*)
76 if (loops_state_satisfies_p (LOOPS_NEED_FIXUP
))
78 calculate_dominance_info (CDI_DOMINATORS
);
79 fix_loop_structure (NULL
);
87 make_pass_fix_loops (gcc::context
*ctxt
)
89 return new pass_fix_loops (ctxt
);
93 /* Gate for loop pass group. The group is controlled by -ftree-loop-optimize
94 but we also avoid running it when the IL doesn't contain any loop. */
97 gate_loop (function
*fn
)
99 if (!flag_tree_loop_optimize
)
102 /* For -fdump-passes which runs before loop discovery print the
103 state of -ftree-loop-optimize. */
104 if (!loops_for_fn (fn
))
107 return number_of_loops (fn
) > 1;
110 /* The loop superpass. */
114 const pass_data pass_data_tree_loop
=
116 GIMPLE_PASS
, /* type */
118 OPTGROUP_LOOP
, /* optinfo_flags */
119 TV_TREE_LOOP
, /* tv_id */
120 PROP_cfg
, /* properties_required */
121 0, /* properties_provided */
122 0, /* properties_destroyed */
123 0, /* todo_flags_start */
124 0, /* todo_flags_finish */
127 class pass_tree_loop
: public gimple_opt_pass
130 pass_tree_loop (gcc::context
*ctxt
)
131 : gimple_opt_pass (pass_data_tree_loop
, ctxt
)
134 /* opt_pass methods: */
135 virtual bool gate (function
*fn
) { return gate_loop (fn
); }
137 }; // class pass_tree_loop
142 make_pass_tree_loop (gcc::context
*ctxt
)
144 return new pass_tree_loop (ctxt
);
147 /* Gate for oacc kernels pass group. */
150 gate_oacc_kernels (function
*fn
)
155 if (!lookup_attribute ("oacc kernels", DECL_ATTRIBUTES (fn
->decl
)))
159 FOR_EACH_LOOP (loop
, 0)
160 if (loop
->in_oacc_kernels_region
)
166 /* The oacc kernels superpass. */
170 const pass_data pass_data_oacc_kernels
=
172 GIMPLE_PASS
, /* type */
173 "oacc_kernels", /* name */
174 OPTGROUP_LOOP
, /* optinfo_flags */
175 TV_TREE_LOOP
, /* tv_id */
176 PROP_cfg
, /* properties_required */
177 0, /* properties_provided */
178 0, /* properties_destroyed */
179 0, /* todo_flags_start */
180 0, /* todo_flags_finish */
183 class pass_oacc_kernels
: public gimple_opt_pass
186 pass_oacc_kernels (gcc::context
*ctxt
)
187 : gimple_opt_pass (pass_data_oacc_kernels
, ctxt
)
190 /* opt_pass methods: */
191 virtual bool gate (function
*fn
) { return gate_oacc_kernels (fn
); }
193 }; // class pass_oacc_kernels
198 make_pass_oacc_kernels (gcc::context
*ctxt
)
200 return new pass_oacc_kernels (ctxt
);
203 /* The ipa oacc superpass. */
207 const pass_data pass_data_ipa_oacc
=
209 SIMPLE_IPA_PASS
, /* type */
210 "ipa_oacc", /* name */
211 OPTGROUP_LOOP
, /* optinfo_flags */
212 TV_TREE_LOOP
, /* tv_id */
213 PROP_cfg
, /* properties_required */
214 0, /* properties_provided */
215 0, /* properties_destroyed */
216 0, /* todo_flags_start */
217 0, /* todo_flags_finish */
220 class pass_ipa_oacc
: public simple_ipa_opt_pass
223 pass_ipa_oacc (gcc::context
*ctxt
)
224 : simple_ipa_opt_pass (pass_data_ipa_oacc
, ctxt
)
227 /* opt_pass methods: */
228 virtual bool gate (function
*)
232 /* Don't bother doing anything if the program has errors. */
236 }; // class pass_ipa_oacc
240 simple_ipa_opt_pass
*
241 make_pass_ipa_oacc (gcc::context
*ctxt
)
243 return new pass_ipa_oacc (ctxt
);
246 /* The ipa oacc kernels pass. */
250 const pass_data pass_data_ipa_oacc_kernels
=
252 SIMPLE_IPA_PASS
, /* type */
253 "ipa_oacc_kernels", /* name */
254 OPTGROUP_LOOP
, /* optinfo_flags */
255 TV_TREE_LOOP
, /* tv_id */
256 PROP_cfg
, /* properties_required */
257 0, /* properties_provided */
258 0, /* properties_destroyed */
259 0, /* todo_flags_start */
260 0, /* todo_flags_finish */
263 class pass_ipa_oacc_kernels
: public simple_ipa_opt_pass
266 pass_ipa_oacc_kernels (gcc::context
*ctxt
)
267 : simple_ipa_opt_pass (pass_data_ipa_oacc_kernels
, ctxt
)
270 }; // class pass_ipa_oacc_kernels
274 simple_ipa_opt_pass
*
275 make_pass_ipa_oacc_kernels (gcc::context
*ctxt
)
277 return new pass_ipa_oacc_kernels (ctxt
);
280 /* The no-loop superpass. */
284 const pass_data pass_data_tree_no_loop
=
286 GIMPLE_PASS
, /* type */
287 "no_loop", /* name */
288 OPTGROUP_NONE
, /* optinfo_flags */
289 TV_TREE_NOLOOP
, /* tv_id */
290 PROP_cfg
, /* properties_required */
291 0, /* properties_provided */
292 0, /* properties_destroyed */
293 0, /* todo_flags_start */
294 0, /* todo_flags_finish */
297 class pass_tree_no_loop
: public gimple_opt_pass
300 pass_tree_no_loop (gcc::context
*ctxt
)
301 : gimple_opt_pass (pass_data_tree_no_loop
, ctxt
)
304 /* opt_pass methods: */
305 virtual bool gate (function
*fn
) { return !gate_loop (fn
); }
307 }; // class pass_tree_no_loop
312 make_pass_tree_no_loop (gcc::context
*ctxt
)
314 return new pass_tree_no_loop (ctxt
);
318 /* Loop optimizer initialization. */
322 const pass_data pass_data_tree_loop_init
=
324 GIMPLE_PASS
, /* type */
325 "loopinit", /* name */
326 OPTGROUP_LOOP
, /* optinfo_flags */
328 PROP_cfg
, /* properties_required */
329 0, /* properties_provided */
330 0, /* properties_destroyed */
331 0, /* todo_flags_start */
332 0, /* todo_flags_finish */
335 class pass_tree_loop_init
: public gimple_opt_pass
338 pass_tree_loop_init (gcc::context
*ctxt
)
339 : gimple_opt_pass (pass_data_tree_loop_init
, ctxt
)
342 /* opt_pass methods: */
343 virtual unsigned int execute (function
*);
345 }; // class pass_tree_loop_init
348 pass_tree_loop_init::execute (function
*fun ATTRIBUTE_UNUSED
)
350 /* When processing a loop in the loop pipeline, we should be able to assert
352 (loops_state_satisfies_p (LOOPS_NORMAL | LOOPS_HAVE_RECORDED_EXITS
354 && scev_initialized_p ())
356 loop_optimizer_init (LOOPS_NORMAL
357 | LOOPS_HAVE_RECORDED_EXITS
);
358 rewrite_into_loop_closed_ssa (NULL
, TODO_update_ssa
);
367 make_pass_tree_loop_init (gcc::context
*ctxt
)
369 return new pass_tree_loop_init (ctxt
);
372 /* Loop autovectorization. */
376 const pass_data pass_data_vectorize
=
378 GIMPLE_PASS
, /* type */
380 OPTGROUP_LOOP
| OPTGROUP_VEC
, /* optinfo_flags */
381 TV_TREE_VECTORIZATION
, /* tv_id */
382 ( PROP_cfg
| PROP_ssa
), /* properties_required */
383 0, /* properties_provided */
384 0, /* properties_destroyed */
385 0, /* todo_flags_start */
386 0, /* todo_flags_finish */
389 class pass_vectorize
: public gimple_opt_pass
392 pass_vectorize (gcc::context
*ctxt
)
393 : gimple_opt_pass (pass_data_vectorize
, ctxt
)
396 /* opt_pass methods: */
397 virtual bool gate (function
*fun
)
399 return flag_tree_loop_vectorize
|| fun
->has_force_vectorize_loops
;
402 virtual unsigned int execute (function
*);
404 }; // class pass_vectorize
407 pass_vectorize::execute (function
*fun
)
409 if (number_of_loops (fun
) <= 1)
412 return vectorize_loops ();
418 make_pass_vectorize (gcc::context
*ctxt
)
420 return new pass_vectorize (ctxt
);
423 /* Propagation of constants using scev. */
427 const pass_data pass_data_scev_cprop
=
429 GIMPLE_PASS
, /* type */
431 OPTGROUP_LOOP
, /* optinfo_flags */
432 TV_SCEV_CONST
, /* tv_id */
433 ( PROP_cfg
| PROP_ssa
), /* properties_required */
434 0, /* properties_provided */
435 0, /* properties_destroyed */
436 0, /* todo_flags_start */
438 | TODO_update_ssa_only_virtuals
), /* todo_flags_finish */
441 class pass_scev_cprop
: public gimple_opt_pass
444 pass_scev_cprop (gcc::context
*ctxt
)
445 : gimple_opt_pass (pass_data_scev_cprop
, ctxt
)
448 /* opt_pass methods: */
449 virtual bool gate (function
*) { return flag_tree_scev_cprop
; }
450 virtual unsigned int execute (function
*) { return scev_const_prop (); }
452 }; // class pass_scev_cprop
457 make_pass_scev_cprop (gcc::context
*ctxt
)
459 return new pass_scev_cprop (ctxt
);
462 /* Induction variable optimizations. */
466 const pass_data pass_data_iv_optimize
=
468 GIMPLE_PASS
, /* type */
470 OPTGROUP_LOOP
, /* optinfo_flags */
471 TV_TREE_LOOP_IVOPTS
, /* tv_id */
472 ( PROP_cfg
| PROP_ssa
), /* properties_required */
473 0, /* properties_provided */
474 0, /* properties_destroyed */
475 0, /* todo_flags_start */
476 TODO_update_ssa
, /* todo_flags_finish */
479 class pass_iv_optimize
: public gimple_opt_pass
482 pass_iv_optimize (gcc::context
*ctxt
)
483 : gimple_opt_pass (pass_data_iv_optimize
, ctxt
)
486 /* opt_pass methods: */
487 virtual bool gate (function
*) { return flag_ivopts
!= 0; }
488 virtual unsigned int execute (function
*);
490 }; // class pass_iv_optimize
493 pass_iv_optimize::execute (function
*fun
)
495 if (number_of_loops (fun
) <= 1)
498 tree_ssa_iv_optimize ();
505 make_pass_iv_optimize (gcc::context
*ctxt
)
507 return new pass_iv_optimize (ctxt
);
510 /* Loop optimizer finalization. */
513 tree_ssa_loop_done (void)
515 free_numbers_of_iterations_estimates (cfun
);
517 loop_optimizer_finalize ();
523 const pass_data pass_data_tree_loop_done
=
525 GIMPLE_PASS
, /* type */
526 "loopdone", /* name */
527 OPTGROUP_LOOP
, /* optinfo_flags */
529 PROP_cfg
, /* properties_required */
530 0, /* properties_provided */
531 0, /* properties_destroyed */
532 0, /* todo_flags_start */
533 TODO_cleanup_cfg
, /* todo_flags_finish */
536 class pass_tree_loop_done
: public gimple_opt_pass
539 pass_tree_loop_done (gcc::context
*ctxt
)
540 : gimple_opt_pass (pass_data_tree_loop_done
, ctxt
)
543 /* opt_pass methods: */
544 virtual unsigned int execute (function
*) { return tree_ssa_loop_done (); }
546 }; // class pass_tree_loop_done
551 make_pass_tree_loop_done (gcc::context
*ctxt
)
553 return new pass_tree_loop_done (ctxt
);
556 /* Calls CBCK for each index in memory reference ADDR_P. There are two
557 kinds situations handled; in each of these cases, the memory reference
558 and DATA are passed to the callback:
560 Access to an array: ARRAY_{RANGE_}REF (base, index). In this case we also
561 pass the pointer to the index to the callback.
563 Pointer dereference: INDIRECT_REF (addr). In this case we also pass the
564 pointer to addr to the callback.
566 If the callback returns false, the whole search stops and false is returned.
567 Otherwise the function returns true after traversing through the whole
568 reference *ADDR_P. */
571 for_each_index (tree
*addr_p
, bool (*cbck
) (tree
, tree
*, void *), void *data
)
575 for (; ; addr_p
= nxt
)
577 switch (TREE_CODE (*addr_p
))
580 return cbck (*addr_p
, addr_p
, data
);
583 nxt
= &TREE_OPERAND (*addr_p
, 0);
584 return cbck (*addr_p
, nxt
, data
);
587 case VIEW_CONVERT_EXPR
:
590 nxt
= &TREE_OPERAND (*addr_p
, 0);
594 /* If the component has varying offset, it behaves like index
596 idx
= &TREE_OPERAND (*addr_p
, 2);
598 && !cbck (*addr_p
, idx
, data
))
601 nxt
= &TREE_OPERAND (*addr_p
, 0);
605 case ARRAY_RANGE_REF
:
606 nxt
= &TREE_OPERAND (*addr_p
, 0);
607 if (!cbck (*addr_p
, &TREE_OPERAND (*addr_p
, 1), data
))
625 gcc_assert (is_gimple_min_invariant (*addr_p
));
629 idx
= &TMR_BASE (*addr_p
);
631 && !cbck (*addr_p
, idx
, data
))
633 idx
= &TMR_INDEX (*addr_p
);
635 && !cbck (*addr_p
, idx
, data
))
637 idx
= &TMR_INDEX2 (*addr_p
);
639 && !cbck (*addr_p
, idx
, data
))
650 /* The name and the length of the currently generated variable
652 #define MAX_LSM_NAME_LENGTH 40
653 static char lsm_tmp_name
[MAX_LSM_NAME_LENGTH
+ 1];
654 static int lsm_tmp_name_length
;
656 /* Adds S to lsm_tmp_name. */
659 lsm_tmp_name_add (const char *s
)
661 int l
= strlen (s
) + lsm_tmp_name_length
;
662 if (l
> MAX_LSM_NAME_LENGTH
)
665 strcpy (lsm_tmp_name
+ lsm_tmp_name_length
, s
);
666 lsm_tmp_name_length
= l
;
669 /* Stores the name for temporary variable that replaces REF to
673 gen_lsm_tmp_name (tree ref
)
677 switch (TREE_CODE (ref
))
681 gen_lsm_tmp_name (TREE_OPERAND (ref
, 0));
682 lsm_tmp_name_add ("_");
686 gen_lsm_tmp_name (TREE_OPERAND (ref
, 0));
690 case VIEW_CONVERT_EXPR
:
691 case ARRAY_RANGE_REF
:
692 gen_lsm_tmp_name (TREE_OPERAND (ref
, 0));
696 gen_lsm_tmp_name (TREE_OPERAND (ref
, 0));
697 lsm_tmp_name_add ("_RE");
701 gen_lsm_tmp_name (TREE_OPERAND (ref
, 0));
702 lsm_tmp_name_add ("_IM");
706 gen_lsm_tmp_name (TREE_OPERAND (ref
, 0));
707 lsm_tmp_name_add ("_");
708 name
= get_name (TREE_OPERAND (ref
, 1));
711 lsm_tmp_name_add (name
);
715 gen_lsm_tmp_name (TREE_OPERAND (ref
, 0));
716 lsm_tmp_name_add ("_I");
724 name
= get_name (ref
);
727 lsm_tmp_name_add (name
);
731 lsm_tmp_name_add ("S");
735 lsm_tmp_name_add ("R");
745 /* Determines name for temporary variable that replaces REF.
746 The name is accumulated into the lsm_tmp_name variable.
747 N is added to the name of the temporary. */
750 get_lsm_tmp_name (tree ref
, unsigned n
, const char *suffix
)
754 lsm_tmp_name_length
= 0;
755 gen_lsm_tmp_name (ref
);
756 lsm_tmp_name_add ("_lsm");
761 lsm_tmp_name_add (ns
);
765 lsm_tmp_name_add (suffix
);
768 /* Computes an estimated number of insns in LOOP, weighted by WEIGHTS. */
771 tree_num_loop_insns (struct loop
*loop
, eni_weights
*weights
)
773 basic_block
*body
= get_loop_body (loop
);
774 gimple_stmt_iterator gsi
;
775 unsigned size
= 0, i
;
777 for (i
= 0; i
< loop
->num_nodes
; i
++)
778 for (gsi
= gsi_start_bb (body
[i
]); !gsi_end_p (gsi
); gsi_next (&gsi
))
779 size
+= estimate_num_insns (gsi_stmt (gsi
), weights
);