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 "double-int.h"
34 #include "fold-const.h"
37 #include "hard-reg-set.h"
40 #include "dominance.h"
42 #include "basic-block.h"
43 #include "tree-ssa-alias.h"
44 #include "internal-fn.h"
45 #include "gimple-expr.h"
48 #include "gimple-iterator.h"
49 #include "tree-ssa-loop-ivopts.h"
50 #include "tree-ssa-loop-manip.h"
51 #include "tree-ssa-loop-niter.h"
52 #include "tree-ssa-loop.h"
53 #include "tree-pass.h"
56 #include "tree-inline.h"
57 #include "tree-scalar-evolution.h"
58 #include "diagnostic-core.h"
59 #include "tree-vectorizer.h"
62 /* A pass making sure loops are fixed up. */
66 const pass_data pass_data_fix_loops
=
68 GIMPLE_PASS
, /* type */
69 "fix_loops", /* name */
70 OPTGROUP_LOOP
, /* optinfo_flags */
71 TV_TREE_LOOP
, /* tv_id */
72 PROP_cfg
, /* properties_required */
73 0, /* properties_provided */
74 0, /* properties_destroyed */
75 0, /* todo_flags_start */
76 0, /* todo_flags_finish */
79 class pass_fix_loops
: public gimple_opt_pass
82 pass_fix_loops (gcc::context
*ctxt
)
83 : gimple_opt_pass (pass_data_fix_loops
, ctxt
)
86 /* opt_pass methods: */
87 virtual bool gate (function
*) { return flag_tree_loop_optimize
; }
89 virtual unsigned int execute (function
*fn
);
90 }; // class pass_fix_loops
93 pass_fix_loops::execute (function
*)
95 if (loops_state_satisfies_p (LOOPS_NEED_FIXUP
))
97 calculate_dominance_info (CDI_DOMINATORS
);
98 fix_loop_structure (NULL
);
106 make_pass_fix_loops (gcc::context
*ctxt
)
108 return new pass_fix_loops (ctxt
);
112 /* Gate for loop pass group. The group is controlled by -ftree-loop-optimize
113 but we also avoid running it when the IL doesn't contain any loop. */
116 gate_loop (function
*fn
)
118 if (!flag_tree_loop_optimize
)
121 /* For -fdump-passes which runs before loop discovery print the
122 state of -ftree-loop-optimize. */
123 if (!loops_for_fn (fn
))
126 return number_of_loops (fn
) > 1;
129 /* The loop superpass. */
133 const pass_data pass_data_tree_loop
=
135 GIMPLE_PASS
, /* type */
137 OPTGROUP_LOOP
, /* optinfo_flags */
138 TV_TREE_LOOP
, /* tv_id */
139 PROP_cfg
, /* properties_required */
140 0, /* properties_provided */
141 0, /* properties_destroyed */
142 0, /* todo_flags_start */
143 0, /* todo_flags_finish */
146 class pass_tree_loop
: public gimple_opt_pass
149 pass_tree_loop (gcc::context
*ctxt
)
150 : gimple_opt_pass (pass_data_tree_loop
, ctxt
)
153 /* opt_pass methods: */
154 virtual bool gate (function
*fn
) { return gate_loop (fn
); }
156 }; // class pass_tree_loop
161 make_pass_tree_loop (gcc::context
*ctxt
)
163 return new pass_tree_loop (ctxt
);
166 /* The no-loop superpass. */
170 const pass_data pass_data_tree_no_loop
=
172 GIMPLE_PASS
, /* type */
173 "no_loop", /* name */
174 OPTGROUP_NONE
, /* optinfo_flags */
175 TV_TREE_NOLOOP
, /* 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_tree_no_loop
: public gimple_opt_pass
186 pass_tree_no_loop (gcc::context
*ctxt
)
187 : gimple_opt_pass (pass_data_tree_no_loop
, ctxt
)
190 /* opt_pass methods: */
191 virtual bool gate (function
*fn
) { return !gate_loop (fn
); }
193 }; // class pass_tree_no_loop
198 make_pass_tree_no_loop (gcc::context
*ctxt
)
200 return new pass_tree_no_loop (ctxt
);
204 /* Loop optimizer initialization. */
208 const pass_data pass_data_tree_loop_init
=
210 GIMPLE_PASS
, /* type */
211 "loopinit", /* name */
212 OPTGROUP_LOOP
, /* optinfo_flags */
214 PROP_cfg
, /* properties_required */
215 0, /* properties_provided */
216 0, /* properties_destroyed */
217 0, /* todo_flags_start */
218 0, /* todo_flags_finish */
221 class pass_tree_loop_init
: public gimple_opt_pass
224 pass_tree_loop_init (gcc::context
*ctxt
)
225 : gimple_opt_pass (pass_data_tree_loop_init
, ctxt
)
228 /* opt_pass methods: */
229 virtual unsigned int execute (function
*);
231 }; // class pass_tree_loop_init
234 pass_tree_loop_init::execute (function
*fun ATTRIBUTE_UNUSED
)
236 loop_optimizer_init (LOOPS_NORMAL
237 | LOOPS_HAVE_RECORDED_EXITS
);
238 rewrite_into_loop_closed_ssa (NULL
, TODO_update_ssa
);
240 /* We might discover new loops, e.g. when turning irreducible
241 regions into reducible. */
250 make_pass_tree_loop_init (gcc::context
*ctxt
)
252 return new pass_tree_loop_init (ctxt
);
255 /* Loop autovectorization. */
259 const pass_data pass_data_vectorize
=
261 GIMPLE_PASS
, /* type */
263 OPTGROUP_LOOP
| OPTGROUP_VEC
, /* optinfo_flags */
264 TV_TREE_VECTORIZATION
, /* tv_id */
265 ( PROP_cfg
| PROP_ssa
), /* properties_required */
266 0, /* properties_provided */
267 0, /* properties_destroyed */
268 0, /* todo_flags_start */
269 0, /* todo_flags_finish */
272 class pass_vectorize
: public gimple_opt_pass
275 pass_vectorize (gcc::context
*ctxt
)
276 : gimple_opt_pass (pass_data_vectorize
, ctxt
)
279 /* opt_pass methods: */
280 virtual bool gate (function
*fun
)
282 return flag_tree_loop_vectorize
|| fun
->has_force_vectorize_loops
;
285 virtual unsigned int execute (function
*);
287 }; // class pass_vectorize
290 pass_vectorize::execute (function
*fun
)
292 if (number_of_loops (fun
) <= 1)
295 return vectorize_loops ();
301 make_pass_vectorize (gcc::context
*ctxt
)
303 return new pass_vectorize (ctxt
);
306 /* Check the correctness of the data dependence analyzers. */
310 const pass_data pass_data_check_data_deps
=
312 GIMPLE_PASS
, /* type */
314 OPTGROUP_LOOP
, /* optinfo_flags */
315 TV_CHECK_DATA_DEPS
, /* tv_id */
316 ( PROP_cfg
| PROP_ssa
), /* properties_required */
317 0, /* properties_provided */
318 0, /* properties_destroyed */
319 0, /* todo_flags_start */
320 0, /* todo_flags_finish */
323 class pass_check_data_deps
: public gimple_opt_pass
326 pass_check_data_deps (gcc::context
*ctxt
)
327 : gimple_opt_pass (pass_data_check_data_deps
, ctxt
)
330 /* opt_pass methods: */
331 virtual bool gate (function
*) { return flag_check_data_deps
!= 0; }
332 virtual unsigned int execute (function
*);
334 }; // class pass_check_data_deps
337 pass_check_data_deps::execute (function
*fun
)
339 if (number_of_loops (fun
) <= 1)
342 tree_check_data_deps ();
349 make_pass_check_data_deps (gcc::context
*ctxt
)
351 return new pass_check_data_deps (ctxt
);
354 /* Propagation of constants using scev. */
358 const pass_data pass_data_scev_cprop
=
360 GIMPLE_PASS
, /* type */
362 OPTGROUP_LOOP
, /* optinfo_flags */
363 TV_SCEV_CONST
, /* tv_id */
364 ( PROP_cfg
| PROP_ssa
), /* properties_required */
365 0, /* properties_provided */
366 0, /* properties_destroyed */
367 0, /* todo_flags_start */
369 | TODO_update_ssa_only_virtuals
), /* todo_flags_finish */
372 class pass_scev_cprop
: public gimple_opt_pass
375 pass_scev_cprop (gcc::context
*ctxt
)
376 : gimple_opt_pass (pass_data_scev_cprop
, ctxt
)
379 /* opt_pass methods: */
380 virtual bool gate (function
*) { return flag_tree_scev_cprop
; }
381 virtual unsigned int execute (function
*) { return scev_const_prop (); }
383 }; // class pass_scev_cprop
388 make_pass_scev_cprop (gcc::context
*ctxt
)
390 return new pass_scev_cprop (ctxt
);
393 /* Record bounds on numbers of iterations of loops. */
397 const pass_data pass_data_record_bounds
=
399 GIMPLE_PASS
, /* type */
400 "*record_bounds", /* name */
401 OPTGROUP_NONE
, /* optinfo_flags */
402 TV_TREE_LOOP_BOUNDS
, /* tv_id */
403 ( PROP_cfg
| PROP_ssa
), /* properties_required */
404 0, /* properties_provided */
405 0, /* properties_destroyed */
406 0, /* todo_flags_start */
407 0, /* todo_flags_finish */
410 class pass_record_bounds
: public gimple_opt_pass
413 pass_record_bounds (gcc::context
*ctxt
)
414 : gimple_opt_pass (pass_data_record_bounds
, ctxt
)
417 /* opt_pass methods: */
418 virtual unsigned int execute (function
*);
420 }; // class pass_record_bounds
423 pass_record_bounds::execute (function
*fun
)
425 if (number_of_loops (fun
) <= 1)
428 estimate_numbers_of_iterations ();
436 make_pass_record_bounds (gcc::context
*ctxt
)
438 return new pass_record_bounds (ctxt
);
441 /* Induction variable optimizations. */
445 const pass_data pass_data_iv_optimize
=
447 GIMPLE_PASS
, /* type */
449 OPTGROUP_LOOP
, /* optinfo_flags */
450 TV_TREE_LOOP_IVOPTS
, /* tv_id */
451 ( PROP_cfg
| PROP_ssa
), /* properties_required */
452 0, /* properties_provided */
453 0, /* properties_destroyed */
454 0, /* todo_flags_start */
455 TODO_update_ssa
, /* todo_flags_finish */
458 class pass_iv_optimize
: public gimple_opt_pass
461 pass_iv_optimize (gcc::context
*ctxt
)
462 : gimple_opt_pass (pass_data_iv_optimize
, ctxt
)
465 /* opt_pass methods: */
466 virtual bool gate (function
*) { return flag_ivopts
!= 0; }
467 virtual unsigned int execute (function
*);
469 }; // class pass_iv_optimize
472 pass_iv_optimize::execute (function
*fun
)
474 if (number_of_loops (fun
) <= 1)
477 tree_ssa_iv_optimize ();
484 make_pass_iv_optimize (gcc::context
*ctxt
)
486 return new pass_iv_optimize (ctxt
);
489 /* Loop optimizer finalization. */
492 tree_ssa_loop_done (void)
494 free_numbers_of_iterations_estimates ();
496 loop_optimizer_finalize ();
502 const pass_data pass_data_tree_loop_done
=
504 GIMPLE_PASS
, /* type */
505 "loopdone", /* name */
506 OPTGROUP_LOOP
, /* optinfo_flags */
508 PROP_cfg
, /* properties_required */
509 0, /* properties_provided */
510 0, /* properties_destroyed */
511 0, /* todo_flags_start */
512 TODO_cleanup_cfg
, /* todo_flags_finish */
515 class pass_tree_loop_done
: public gimple_opt_pass
518 pass_tree_loop_done (gcc::context
*ctxt
)
519 : gimple_opt_pass (pass_data_tree_loop_done
, ctxt
)
522 /* opt_pass methods: */
523 virtual unsigned int execute (function
*) { return tree_ssa_loop_done (); }
525 }; // class pass_tree_loop_done
530 make_pass_tree_loop_done (gcc::context
*ctxt
)
532 return new pass_tree_loop_done (ctxt
);
535 /* Calls CBCK for each index in memory reference ADDR_P. There are two
536 kinds situations handled; in each of these cases, the memory reference
537 and DATA are passed to the callback:
539 Access to an array: ARRAY_{RANGE_}REF (base, index). In this case we also
540 pass the pointer to the index to the callback.
542 Pointer dereference: INDIRECT_REF (addr). In this case we also pass the
543 pointer to addr to the callback.
545 If the callback returns false, the whole search stops and false is returned.
546 Otherwise the function returns true after traversing through the whole
547 reference *ADDR_P. */
550 for_each_index (tree
*addr_p
, bool (*cbck
) (tree
, tree
*, void *), void *data
)
554 for (; ; addr_p
= nxt
)
556 switch (TREE_CODE (*addr_p
))
559 return cbck (*addr_p
, addr_p
, data
);
562 nxt
= &TREE_OPERAND (*addr_p
, 0);
563 return cbck (*addr_p
, nxt
, data
);
566 case VIEW_CONVERT_EXPR
:
569 nxt
= &TREE_OPERAND (*addr_p
, 0);
573 /* If the component has varying offset, it behaves like index
575 idx
= &TREE_OPERAND (*addr_p
, 2);
577 && !cbck (*addr_p
, idx
, data
))
580 nxt
= &TREE_OPERAND (*addr_p
, 0);
584 case ARRAY_RANGE_REF
:
585 nxt
= &TREE_OPERAND (*addr_p
, 0);
586 if (!cbck (*addr_p
, &TREE_OPERAND (*addr_p
, 1), data
))
604 gcc_assert (is_gimple_min_invariant (*addr_p
));
608 idx
= &TMR_BASE (*addr_p
);
610 && !cbck (*addr_p
, idx
, data
))
612 idx
= &TMR_INDEX (*addr_p
);
614 && !cbck (*addr_p
, idx
, data
))
616 idx
= &TMR_INDEX2 (*addr_p
);
618 && !cbck (*addr_p
, idx
, data
))
629 /* The name and the length of the currently generated variable
631 #define MAX_LSM_NAME_LENGTH 40
632 static char lsm_tmp_name
[MAX_LSM_NAME_LENGTH
+ 1];
633 static int lsm_tmp_name_length
;
635 /* Adds S to lsm_tmp_name. */
638 lsm_tmp_name_add (const char *s
)
640 int l
= strlen (s
) + lsm_tmp_name_length
;
641 if (l
> MAX_LSM_NAME_LENGTH
)
644 strcpy (lsm_tmp_name
+ lsm_tmp_name_length
, s
);
645 lsm_tmp_name_length
= l
;
648 /* Stores the name for temporary variable that replaces REF to
652 gen_lsm_tmp_name (tree ref
)
656 switch (TREE_CODE (ref
))
660 gen_lsm_tmp_name (TREE_OPERAND (ref
, 0));
661 lsm_tmp_name_add ("_");
665 gen_lsm_tmp_name (TREE_OPERAND (ref
, 0));
669 case VIEW_CONVERT_EXPR
:
670 case ARRAY_RANGE_REF
:
671 gen_lsm_tmp_name (TREE_OPERAND (ref
, 0));
675 gen_lsm_tmp_name (TREE_OPERAND (ref
, 0));
676 lsm_tmp_name_add ("_RE");
680 gen_lsm_tmp_name (TREE_OPERAND (ref
, 0));
681 lsm_tmp_name_add ("_IM");
685 gen_lsm_tmp_name (TREE_OPERAND (ref
, 0));
686 lsm_tmp_name_add ("_");
687 name
= get_name (TREE_OPERAND (ref
, 1));
690 lsm_tmp_name_add (name
);
694 gen_lsm_tmp_name (TREE_OPERAND (ref
, 0));
695 lsm_tmp_name_add ("_I");
701 name
= get_name (ref
);
704 lsm_tmp_name_add (name
);
708 lsm_tmp_name_add ("S");
712 lsm_tmp_name_add ("R");
724 /* Determines name for temporary variable that replaces REF.
725 The name is accumulated into the lsm_tmp_name variable.
726 N is added to the name of the temporary. */
729 get_lsm_tmp_name (tree ref
, unsigned n
, const char *suffix
)
733 lsm_tmp_name_length
= 0;
734 gen_lsm_tmp_name (ref
);
735 lsm_tmp_name_add ("_lsm");
740 lsm_tmp_name_add (ns
);
744 lsm_tmp_name_add (suffix
);
747 /* Computes an estimated number of insns in LOOP, weighted by WEIGHTS. */
750 tree_num_loop_insns (struct loop
*loop
, eni_weights
*weights
)
752 basic_block
*body
= get_loop_body (loop
);
753 gimple_stmt_iterator gsi
;
754 unsigned size
= 0, i
;
756 for (i
= 0; i
< loop
->num_nodes
; i
++)
757 for (gsi
= gsi_start_bb (body
[i
]); !gsi_end_p (gsi
); gsi_next (&gsi
))
758 size
+= estimate_num_insns (gsi_stmt (gsi
), weights
);