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"
28 #include "fold-const.h"
31 #include "hard-reg-set.h"
34 #include "dominance.h"
36 #include "basic-block.h"
37 #include "tree-ssa-alias.h"
38 #include "internal-fn.h"
39 #include "gimple-expr.h"
42 #include "gimple-iterator.h"
43 #include "tree-ssa-loop-ivopts.h"
44 #include "tree-ssa-loop-manip.h"
45 #include "tree-ssa-loop-niter.h"
46 #include "tree-ssa-loop.h"
47 #include "tree-pass.h"
50 #include "tree-inline.h"
51 #include "tree-scalar-evolution.h"
52 #include "diagnostic-core.h"
53 #include "tree-vectorizer.h"
56 /* A pass making sure loops are fixed up. */
60 const pass_data pass_data_fix_loops
=
62 GIMPLE_PASS
, /* type */
63 "fix_loops", /* name */
64 OPTGROUP_LOOP
, /* optinfo_flags */
65 TV_TREE_LOOP
, /* tv_id */
66 PROP_cfg
, /* properties_required */
67 0, /* properties_provided */
68 0, /* properties_destroyed */
69 0, /* todo_flags_start */
70 0, /* todo_flags_finish */
73 class pass_fix_loops
: public gimple_opt_pass
76 pass_fix_loops (gcc::context
*ctxt
)
77 : gimple_opt_pass (pass_data_fix_loops
, ctxt
)
80 /* opt_pass methods: */
81 virtual bool gate (function
*) { return flag_tree_loop_optimize
; }
83 virtual unsigned int execute (function
*fn
);
84 }; // class pass_fix_loops
87 pass_fix_loops::execute (function
*)
89 if (loops_state_satisfies_p (LOOPS_NEED_FIXUP
))
91 calculate_dominance_info (CDI_DOMINATORS
);
92 fix_loop_structure (NULL
);
100 make_pass_fix_loops (gcc::context
*ctxt
)
102 return new pass_fix_loops (ctxt
);
106 /* Gate for loop pass group. The group is controlled by -ftree-loop-optimize
107 but we also avoid running it when the IL doesn't contain any loop. */
110 gate_loop (function
*fn
)
112 if (!flag_tree_loop_optimize
)
115 /* For -fdump-passes which runs before loop discovery print the
116 state of -ftree-loop-optimize. */
117 if (!loops_for_fn (fn
))
120 return number_of_loops (fn
) > 1;
123 /* The loop superpass. */
127 const pass_data pass_data_tree_loop
=
129 GIMPLE_PASS
, /* type */
131 OPTGROUP_LOOP
, /* optinfo_flags */
132 TV_TREE_LOOP
, /* tv_id */
133 PROP_cfg
, /* properties_required */
134 0, /* properties_provided */
135 0, /* properties_destroyed */
136 0, /* todo_flags_start */
137 0, /* todo_flags_finish */
140 class pass_tree_loop
: public gimple_opt_pass
143 pass_tree_loop (gcc::context
*ctxt
)
144 : gimple_opt_pass (pass_data_tree_loop
, ctxt
)
147 /* opt_pass methods: */
148 virtual bool gate (function
*fn
) { return gate_loop (fn
); }
150 }; // class pass_tree_loop
155 make_pass_tree_loop (gcc::context
*ctxt
)
157 return new pass_tree_loop (ctxt
);
160 /* The no-loop superpass. */
164 const pass_data pass_data_tree_no_loop
=
166 GIMPLE_PASS
, /* type */
167 "no_loop", /* name */
168 OPTGROUP_NONE
, /* optinfo_flags */
169 TV_TREE_NOLOOP
, /* tv_id */
170 PROP_cfg
, /* properties_required */
171 0, /* properties_provided */
172 0, /* properties_destroyed */
173 0, /* todo_flags_start */
174 0, /* todo_flags_finish */
177 class pass_tree_no_loop
: public gimple_opt_pass
180 pass_tree_no_loop (gcc::context
*ctxt
)
181 : gimple_opt_pass (pass_data_tree_no_loop
, ctxt
)
184 /* opt_pass methods: */
185 virtual bool gate (function
*fn
) { return !gate_loop (fn
); }
187 }; // class pass_tree_no_loop
192 make_pass_tree_no_loop (gcc::context
*ctxt
)
194 return new pass_tree_no_loop (ctxt
);
198 /* Loop optimizer initialization. */
202 const pass_data pass_data_tree_loop_init
=
204 GIMPLE_PASS
, /* type */
205 "loopinit", /* name */
206 OPTGROUP_LOOP
, /* optinfo_flags */
208 PROP_cfg
, /* properties_required */
209 0, /* properties_provided */
210 0, /* properties_destroyed */
211 0, /* todo_flags_start */
212 0, /* todo_flags_finish */
215 class pass_tree_loop_init
: public gimple_opt_pass
218 pass_tree_loop_init (gcc::context
*ctxt
)
219 : gimple_opt_pass (pass_data_tree_loop_init
, ctxt
)
222 /* opt_pass methods: */
223 virtual unsigned int execute (function
*);
225 }; // class pass_tree_loop_init
228 pass_tree_loop_init::execute (function
*fun ATTRIBUTE_UNUSED
)
230 loop_optimizer_init (LOOPS_NORMAL
231 | LOOPS_HAVE_RECORDED_EXITS
);
232 rewrite_into_loop_closed_ssa (NULL
, TODO_update_ssa
);
234 /* We might discover new loops, e.g. when turning irreducible
235 regions into reducible. */
244 make_pass_tree_loop_init (gcc::context
*ctxt
)
246 return new pass_tree_loop_init (ctxt
);
249 /* Loop autovectorization. */
253 const pass_data pass_data_vectorize
=
255 GIMPLE_PASS
, /* type */
257 OPTGROUP_LOOP
| OPTGROUP_VEC
, /* optinfo_flags */
258 TV_TREE_VECTORIZATION
, /* tv_id */
259 ( PROP_cfg
| PROP_ssa
), /* properties_required */
260 0, /* properties_provided */
261 0, /* properties_destroyed */
262 0, /* todo_flags_start */
263 0, /* todo_flags_finish */
266 class pass_vectorize
: public gimple_opt_pass
269 pass_vectorize (gcc::context
*ctxt
)
270 : gimple_opt_pass (pass_data_vectorize
, ctxt
)
273 /* opt_pass methods: */
274 virtual bool gate (function
*fun
)
276 return flag_tree_loop_vectorize
|| fun
->has_force_vectorize_loops
;
279 virtual unsigned int execute (function
*);
281 }; // class pass_vectorize
284 pass_vectorize::execute (function
*fun
)
286 if (number_of_loops (fun
) <= 1)
289 return vectorize_loops ();
295 make_pass_vectorize (gcc::context
*ctxt
)
297 return new pass_vectorize (ctxt
);
300 /* Check the correctness of the data dependence analyzers. */
304 const pass_data pass_data_check_data_deps
=
306 GIMPLE_PASS
, /* type */
308 OPTGROUP_LOOP
, /* optinfo_flags */
309 TV_CHECK_DATA_DEPS
, /* tv_id */
310 ( PROP_cfg
| PROP_ssa
), /* properties_required */
311 0, /* properties_provided */
312 0, /* properties_destroyed */
313 0, /* todo_flags_start */
314 0, /* todo_flags_finish */
317 class pass_check_data_deps
: public gimple_opt_pass
320 pass_check_data_deps (gcc::context
*ctxt
)
321 : gimple_opt_pass (pass_data_check_data_deps
, ctxt
)
324 /* opt_pass methods: */
325 virtual bool gate (function
*) { return flag_check_data_deps
!= 0; }
326 virtual unsigned int execute (function
*);
328 }; // class pass_check_data_deps
331 pass_check_data_deps::execute (function
*fun
)
333 if (number_of_loops (fun
) <= 1)
336 tree_check_data_deps ();
343 make_pass_check_data_deps (gcc::context
*ctxt
)
345 return new pass_check_data_deps (ctxt
);
348 /* Propagation of constants using scev. */
352 const pass_data pass_data_scev_cprop
=
354 GIMPLE_PASS
, /* type */
356 OPTGROUP_LOOP
, /* optinfo_flags */
357 TV_SCEV_CONST
, /* tv_id */
358 ( PROP_cfg
| PROP_ssa
), /* properties_required */
359 0, /* properties_provided */
360 0, /* properties_destroyed */
361 0, /* todo_flags_start */
363 | TODO_update_ssa_only_virtuals
), /* todo_flags_finish */
366 class pass_scev_cprop
: public gimple_opt_pass
369 pass_scev_cprop (gcc::context
*ctxt
)
370 : gimple_opt_pass (pass_data_scev_cprop
, ctxt
)
373 /* opt_pass methods: */
374 virtual bool gate (function
*) { return flag_tree_scev_cprop
; }
375 virtual unsigned int execute (function
*) { return scev_const_prop (); }
377 }; // class pass_scev_cprop
382 make_pass_scev_cprop (gcc::context
*ctxt
)
384 return new pass_scev_cprop (ctxt
);
387 /* Record bounds on numbers of iterations of loops. */
391 const pass_data pass_data_record_bounds
=
393 GIMPLE_PASS
, /* type */
394 "*record_bounds", /* name */
395 OPTGROUP_NONE
, /* optinfo_flags */
396 TV_TREE_LOOP_BOUNDS
, /* tv_id */
397 ( PROP_cfg
| PROP_ssa
), /* properties_required */
398 0, /* properties_provided */
399 0, /* properties_destroyed */
400 0, /* todo_flags_start */
401 0, /* todo_flags_finish */
404 class pass_record_bounds
: public gimple_opt_pass
407 pass_record_bounds (gcc::context
*ctxt
)
408 : gimple_opt_pass (pass_data_record_bounds
, ctxt
)
411 /* opt_pass methods: */
412 virtual unsigned int execute (function
*);
414 }; // class pass_record_bounds
417 pass_record_bounds::execute (function
*fun
)
419 if (number_of_loops (fun
) <= 1)
422 estimate_numbers_of_iterations ();
430 make_pass_record_bounds (gcc::context
*ctxt
)
432 return new pass_record_bounds (ctxt
);
435 /* Induction variable optimizations. */
439 const pass_data pass_data_iv_optimize
=
441 GIMPLE_PASS
, /* type */
443 OPTGROUP_LOOP
, /* optinfo_flags */
444 TV_TREE_LOOP_IVOPTS
, /* tv_id */
445 ( PROP_cfg
| PROP_ssa
), /* properties_required */
446 0, /* properties_provided */
447 0, /* properties_destroyed */
448 0, /* todo_flags_start */
449 TODO_update_ssa
, /* todo_flags_finish */
452 class pass_iv_optimize
: public gimple_opt_pass
455 pass_iv_optimize (gcc::context
*ctxt
)
456 : gimple_opt_pass (pass_data_iv_optimize
, ctxt
)
459 /* opt_pass methods: */
460 virtual bool gate (function
*) { return flag_ivopts
!= 0; }
461 virtual unsigned int execute (function
*);
463 }; // class pass_iv_optimize
466 pass_iv_optimize::execute (function
*fun
)
468 if (number_of_loops (fun
) <= 1)
471 tree_ssa_iv_optimize ();
478 make_pass_iv_optimize (gcc::context
*ctxt
)
480 return new pass_iv_optimize (ctxt
);
483 /* Loop optimizer finalization. */
486 tree_ssa_loop_done (void)
488 free_numbers_of_iterations_estimates ();
490 loop_optimizer_finalize ();
496 const pass_data pass_data_tree_loop_done
=
498 GIMPLE_PASS
, /* type */
499 "loopdone", /* name */
500 OPTGROUP_LOOP
, /* optinfo_flags */
502 PROP_cfg
, /* properties_required */
503 0, /* properties_provided */
504 0, /* properties_destroyed */
505 0, /* todo_flags_start */
506 TODO_cleanup_cfg
, /* todo_flags_finish */
509 class pass_tree_loop_done
: public gimple_opt_pass
512 pass_tree_loop_done (gcc::context
*ctxt
)
513 : gimple_opt_pass (pass_data_tree_loop_done
, ctxt
)
516 /* opt_pass methods: */
517 virtual unsigned int execute (function
*) { return tree_ssa_loop_done (); }
519 }; // class pass_tree_loop_done
524 make_pass_tree_loop_done (gcc::context
*ctxt
)
526 return new pass_tree_loop_done (ctxt
);
529 /* Calls CBCK for each index in memory reference ADDR_P. There are two
530 kinds situations handled; in each of these cases, the memory reference
531 and DATA are passed to the callback:
533 Access to an array: ARRAY_{RANGE_}REF (base, index). In this case we also
534 pass the pointer to the index to the callback.
536 Pointer dereference: INDIRECT_REF (addr). In this case we also pass the
537 pointer to addr to the callback.
539 If the callback returns false, the whole search stops and false is returned.
540 Otherwise the function returns true after traversing through the whole
541 reference *ADDR_P. */
544 for_each_index (tree
*addr_p
, bool (*cbck
) (tree
, tree
*, void *), void *data
)
548 for (; ; addr_p
= nxt
)
550 switch (TREE_CODE (*addr_p
))
553 return cbck (*addr_p
, addr_p
, data
);
556 nxt
= &TREE_OPERAND (*addr_p
, 0);
557 return cbck (*addr_p
, nxt
, data
);
560 case VIEW_CONVERT_EXPR
:
563 nxt
= &TREE_OPERAND (*addr_p
, 0);
567 /* If the component has varying offset, it behaves like index
569 idx
= &TREE_OPERAND (*addr_p
, 2);
571 && !cbck (*addr_p
, idx
, data
))
574 nxt
= &TREE_OPERAND (*addr_p
, 0);
578 case ARRAY_RANGE_REF
:
579 nxt
= &TREE_OPERAND (*addr_p
, 0);
580 if (!cbck (*addr_p
, &TREE_OPERAND (*addr_p
, 1), data
))
598 gcc_assert (is_gimple_min_invariant (*addr_p
));
602 idx
= &TMR_BASE (*addr_p
);
604 && !cbck (*addr_p
, idx
, data
))
606 idx
= &TMR_INDEX (*addr_p
);
608 && !cbck (*addr_p
, idx
, data
))
610 idx
= &TMR_INDEX2 (*addr_p
);
612 && !cbck (*addr_p
, idx
, data
))
623 /* The name and the length of the currently generated variable
625 #define MAX_LSM_NAME_LENGTH 40
626 static char lsm_tmp_name
[MAX_LSM_NAME_LENGTH
+ 1];
627 static int lsm_tmp_name_length
;
629 /* Adds S to lsm_tmp_name. */
632 lsm_tmp_name_add (const char *s
)
634 int l
= strlen (s
) + lsm_tmp_name_length
;
635 if (l
> MAX_LSM_NAME_LENGTH
)
638 strcpy (lsm_tmp_name
+ lsm_tmp_name_length
, s
);
639 lsm_tmp_name_length
= l
;
642 /* Stores the name for temporary variable that replaces REF to
646 gen_lsm_tmp_name (tree ref
)
650 switch (TREE_CODE (ref
))
654 gen_lsm_tmp_name (TREE_OPERAND (ref
, 0));
655 lsm_tmp_name_add ("_");
659 gen_lsm_tmp_name (TREE_OPERAND (ref
, 0));
663 case VIEW_CONVERT_EXPR
:
664 case ARRAY_RANGE_REF
:
665 gen_lsm_tmp_name (TREE_OPERAND (ref
, 0));
669 gen_lsm_tmp_name (TREE_OPERAND (ref
, 0));
670 lsm_tmp_name_add ("_RE");
674 gen_lsm_tmp_name (TREE_OPERAND (ref
, 0));
675 lsm_tmp_name_add ("_IM");
679 gen_lsm_tmp_name (TREE_OPERAND (ref
, 0));
680 lsm_tmp_name_add ("_");
681 name
= get_name (TREE_OPERAND (ref
, 1));
684 lsm_tmp_name_add (name
);
688 gen_lsm_tmp_name (TREE_OPERAND (ref
, 0));
689 lsm_tmp_name_add ("_I");
695 name
= get_name (ref
);
698 lsm_tmp_name_add (name
);
702 lsm_tmp_name_add ("S");
706 lsm_tmp_name_add ("R");
718 /* Determines name for temporary variable that replaces REF.
719 The name is accumulated into the lsm_tmp_name variable.
720 N is added to the name of the temporary. */
723 get_lsm_tmp_name (tree ref
, unsigned n
, const char *suffix
)
727 lsm_tmp_name_length
= 0;
728 gen_lsm_tmp_name (ref
);
729 lsm_tmp_name_add ("_lsm");
734 lsm_tmp_name_add (ns
);
738 lsm_tmp_name_add (suffix
);
741 /* Computes an estimated number of insns in LOOP, weighted by WEIGHTS. */
744 tree_num_loop_insns (struct loop
*loop
, eni_weights
*weights
)
746 basic_block
*body
= get_loop_body (loop
);
747 gimple_stmt_iterator gsi
;
748 unsigned size
= 0, i
;
750 for (i
= 0; i
< loop
->num_nodes
; i
++)
751 for (gsi
= gsi_start_bb (body
[i
]); !gsi_end_p (gsi
); gsi_next (&gsi
))
752 size
+= estimate_num_insns (gsi_stmt (gsi
), weights
);