1 /* Loop optimizations over tree-ssa.
2 Copyright (C) 2003-2014 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 "basic-block.h"
27 #include "tree-ssa-alias.h"
28 #include "internal-fn.h"
29 #include "gimple-expr.h"
32 #include "gimple-iterator.h"
33 #include "tree-ssa-loop-ivopts.h"
34 #include "tree-ssa-loop-manip.h"
35 #include "tree-ssa-loop-niter.h"
36 #include "tree-ssa-loop.h"
37 #include "tree-pass.h"
40 #include "tree-inline.h"
41 #include "tree-scalar-evolution.h"
42 #include "diagnostic-core.h"
43 #include "tree-vectorizer.h"
46 /* A pass making sure loops are fixed up. */
50 const pass_data pass_data_fix_loops
=
52 GIMPLE_PASS
, /* type */
53 "fix_loops", /* name */
54 OPTGROUP_LOOP
, /* optinfo_flags */
55 TV_TREE_LOOP
, /* tv_id */
56 PROP_cfg
, /* properties_required */
57 0, /* properties_provided */
58 0, /* properties_destroyed */
59 0, /* todo_flags_start */
60 0, /* todo_flags_finish */
63 class pass_fix_loops
: public gimple_opt_pass
66 pass_fix_loops (gcc::context
*ctxt
)
67 : gimple_opt_pass (pass_data_fix_loops
, ctxt
)
70 /* opt_pass methods: */
71 virtual bool gate (function
*) { return flag_tree_loop_optimize
; }
73 virtual unsigned int execute (function
*fn
);
74 }; // class pass_fix_loops
77 pass_fix_loops::execute (function
*)
79 if (loops_state_satisfies_p (LOOPS_NEED_FIXUP
))
81 calculate_dominance_info (CDI_DOMINATORS
);
82 fix_loop_structure (NULL
);
90 make_pass_fix_loops (gcc::context
*ctxt
)
92 return new pass_fix_loops (ctxt
);
96 /* Gate for loop pass group. The group is controlled by -ftree-loop-optimize
97 but we also avoid running it when the IL doesn't contain any loop. */
100 gate_loop (function
*fn
)
102 if (!flag_tree_loop_optimize
)
105 /* For -fdump-passes which runs before loop discovery print the
106 state of -ftree-loop-optimize. */
107 if (!loops_for_fn (fn
))
110 return number_of_loops (fn
) > 1;
113 /* The loop superpass. */
117 const pass_data pass_data_tree_loop
=
119 GIMPLE_PASS
, /* type */
121 OPTGROUP_LOOP
, /* optinfo_flags */
122 TV_TREE_LOOP
, /* tv_id */
123 PROP_cfg
, /* properties_required */
124 0, /* properties_provided */
125 0, /* properties_destroyed */
126 0, /* todo_flags_start */
127 0, /* todo_flags_finish */
130 class pass_tree_loop
: public gimple_opt_pass
133 pass_tree_loop (gcc::context
*ctxt
)
134 : gimple_opt_pass (pass_data_tree_loop
, ctxt
)
137 /* opt_pass methods: */
138 virtual bool gate (function
*fn
) { return gate_loop (fn
); }
140 }; // class pass_tree_loop
145 make_pass_tree_loop (gcc::context
*ctxt
)
147 return new pass_tree_loop (ctxt
);
150 /* The no-loop superpass. */
154 const pass_data pass_data_tree_no_loop
=
156 GIMPLE_PASS
, /* type */
157 "no_loop", /* name */
158 OPTGROUP_NONE
, /* optinfo_flags */
159 TV_TREE_NOLOOP
, /* tv_id */
160 PROP_cfg
, /* properties_required */
161 0, /* properties_provided */
162 0, /* properties_destroyed */
163 0, /* todo_flags_start */
164 0, /* todo_flags_finish */
167 class pass_tree_no_loop
: public gimple_opt_pass
170 pass_tree_no_loop (gcc::context
*ctxt
)
171 : gimple_opt_pass (pass_data_tree_no_loop
, ctxt
)
174 /* opt_pass methods: */
175 virtual bool gate (function
*fn
) { return !gate_loop (fn
); }
177 }; // class pass_tree_no_loop
182 make_pass_tree_no_loop (gcc::context
*ctxt
)
184 return new pass_tree_no_loop (ctxt
);
188 /* Loop optimizer initialization. */
192 const pass_data pass_data_tree_loop_init
=
194 GIMPLE_PASS
, /* type */
195 "loopinit", /* name */
196 OPTGROUP_LOOP
, /* optinfo_flags */
198 PROP_cfg
, /* properties_required */
199 0, /* properties_provided */
200 0, /* properties_destroyed */
201 0, /* todo_flags_start */
202 0, /* todo_flags_finish */
205 class pass_tree_loop_init
: public gimple_opt_pass
208 pass_tree_loop_init (gcc::context
*ctxt
)
209 : gimple_opt_pass (pass_data_tree_loop_init
, ctxt
)
212 /* opt_pass methods: */
213 virtual unsigned int execute (function
*);
215 }; // class pass_tree_loop_init
218 pass_tree_loop_init::execute (function
*fun ATTRIBUTE_UNUSED
)
220 loop_optimizer_init (LOOPS_NORMAL
221 | LOOPS_HAVE_RECORDED_EXITS
);
222 rewrite_into_loop_closed_ssa (NULL
, TODO_update_ssa
);
224 /* We might discover new loops, e.g. when turning irreducible
225 regions into reducible. */
234 make_pass_tree_loop_init (gcc::context
*ctxt
)
236 return new pass_tree_loop_init (ctxt
);
239 /* Loop autovectorization. */
243 const pass_data pass_data_vectorize
=
245 GIMPLE_PASS
, /* type */
247 OPTGROUP_LOOP
| OPTGROUP_VEC
, /* optinfo_flags */
248 TV_TREE_VECTORIZATION
, /* tv_id */
249 ( PROP_cfg
| PROP_ssa
), /* properties_required */
250 0, /* properties_provided */
251 0, /* properties_destroyed */
252 0, /* todo_flags_start */
253 0, /* todo_flags_finish */
256 class pass_vectorize
: public gimple_opt_pass
259 pass_vectorize (gcc::context
*ctxt
)
260 : gimple_opt_pass (pass_data_vectorize
, ctxt
)
263 /* opt_pass methods: */
264 virtual bool gate (function
*fun
)
266 return flag_tree_loop_vectorize
|| fun
->has_force_vectorize_loops
;
269 virtual unsigned int execute (function
*);
271 }; // class pass_vectorize
274 pass_vectorize::execute (function
*fun
)
276 if (number_of_loops (fun
) <= 1)
279 return vectorize_loops ();
285 make_pass_vectorize (gcc::context
*ctxt
)
287 return new pass_vectorize (ctxt
);
290 /* Check the correctness of the data dependence analyzers. */
294 const pass_data pass_data_check_data_deps
=
296 GIMPLE_PASS
, /* type */
298 OPTGROUP_LOOP
, /* optinfo_flags */
299 TV_CHECK_DATA_DEPS
, /* tv_id */
300 ( PROP_cfg
| PROP_ssa
), /* properties_required */
301 0, /* properties_provided */
302 0, /* properties_destroyed */
303 0, /* todo_flags_start */
304 0, /* todo_flags_finish */
307 class pass_check_data_deps
: public gimple_opt_pass
310 pass_check_data_deps (gcc::context
*ctxt
)
311 : gimple_opt_pass (pass_data_check_data_deps
, ctxt
)
314 /* opt_pass methods: */
315 virtual bool gate (function
*) { return flag_check_data_deps
!= 0; }
316 virtual unsigned int execute (function
*);
318 }; // class pass_check_data_deps
321 pass_check_data_deps::execute (function
*fun
)
323 if (number_of_loops (fun
) <= 1)
326 tree_check_data_deps ();
333 make_pass_check_data_deps (gcc::context
*ctxt
)
335 return new pass_check_data_deps (ctxt
);
338 /* Propagation of constants using scev. */
342 const pass_data pass_data_scev_cprop
=
344 GIMPLE_PASS
, /* type */
346 OPTGROUP_LOOP
, /* optinfo_flags */
347 TV_SCEV_CONST
, /* tv_id */
348 ( PROP_cfg
| PROP_ssa
), /* properties_required */
349 0, /* properties_provided */
350 0, /* properties_destroyed */
351 0, /* todo_flags_start */
353 | TODO_update_ssa_only_virtuals
), /* todo_flags_finish */
356 class pass_scev_cprop
: public gimple_opt_pass
359 pass_scev_cprop (gcc::context
*ctxt
)
360 : gimple_opt_pass (pass_data_scev_cprop
, ctxt
)
363 /* opt_pass methods: */
364 virtual bool gate (function
*) { return flag_tree_scev_cprop
; }
365 virtual unsigned int execute (function
*) { return scev_const_prop (); }
367 }; // class pass_scev_cprop
372 make_pass_scev_cprop (gcc::context
*ctxt
)
374 return new pass_scev_cprop (ctxt
);
377 /* Record bounds on numbers of iterations of loops. */
381 const pass_data pass_data_record_bounds
=
383 GIMPLE_PASS
, /* type */
384 "*record_bounds", /* name */
385 OPTGROUP_NONE
, /* optinfo_flags */
386 TV_TREE_LOOP_BOUNDS
, /* tv_id */
387 ( PROP_cfg
| PROP_ssa
), /* properties_required */
388 0, /* properties_provided */
389 0, /* properties_destroyed */
390 0, /* todo_flags_start */
391 0, /* todo_flags_finish */
394 class pass_record_bounds
: public gimple_opt_pass
397 pass_record_bounds (gcc::context
*ctxt
)
398 : gimple_opt_pass (pass_data_record_bounds
, ctxt
)
401 /* opt_pass methods: */
402 virtual unsigned int execute (function
*);
404 }; // class pass_record_bounds
407 pass_record_bounds::execute (function
*fun
)
409 if (number_of_loops (fun
) <= 1)
412 estimate_numbers_of_iterations ();
420 make_pass_record_bounds (gcc::context
*ctxt
)
422 return new pass_record_bounds (ctxt
);
425 /* Induction variable optimizations. */
429 const pass_data pass_data_iv_optimize
=
431 GIMPLE_PASS
, /* type */
433 OPTGROUP_LOOP
, /* optinfo_flags */
434 TV_TREE_LOOP_IVOPTS
, /* tv_id */
435 ( PROP_cfg
| PROP_ssa
), /* properties_required */
436 0, /* properties_provided */
437 0, /* properties_destroyed */
438 0, /* todo_flags_start */
439 TODO_update_ssa
, /* todo_flags_finish */
442 class pass_iv_optimize
: public gimple_opt_pass
445 pass_iv_optimize (gcc::context
*ctxt
)
446 : gimple_opt_pass (pass_data_iv_optimize
, ctxt
)
449 /* opt_pass methods: */
450 virtual bool gate (function
*) { return flag_ivopts
!= 0; }
451 virtual unsigned int execute (function
*);
453 }; // class pass_iv_optimize
456 pass_iv_optimize::execute (function
*fun
)
458 if (number_of_loops (fun
) <= 1)
461 tree_ssa_iv_optimize ();
468 make_pass_iv_optimize (gcc::context
*ctxt
)
470 return new pass_iv_optimize (ctxt
);
473 /* Loop optimizer finalization. */
476 tree_ssa_loop_done (void)
478 free_numbers_of_iterations_estimates ();
480 loop_optimizer_finalize ();
486 const pass_data pass_data_tree_loop_done
=
488 GIMPLE_PASS
, /* type */
489 "loopdone", /* name */
490 OPTGROUP_LOOP
, /* optinfo_flags */
492 PROP_cfg
, /* properties_required */
493 0, /* properties_provided */
494 0, /* properties_destroyed */
495 0, /* todo_flags_start */
496 TODO_cleanup_cfg
, /* todo_flags_finish */
499 class pass_tree_loop_done
: public gimple_opt_pass
502 pass_tree_loop_done (gcc::context
*ctxt
)
503 : gimple_opt_pass (pass_data_tree_loop_done
, ctxt
)
506 /* opt_pass methods: */
507 virtual unsigned int execute (function
*) { return tree_ssa_loop_done (); }
509 }; // class pass_tree_loop_done
514 make_pass_tree_loop_done (gcc::context
*ctxt
)
516 return new pass_tree_loop_done (ctxt
);
519 /* Calls CBCK for each index in memory reference ADDR_P. There are two
520 kinds situations handled; in each of these cases, the memory reference
521 and DATA are passed to the callback:
523 Access to an array: ARRAY_{RANGE_}REF (base, index). In this case we also
524 pass the pointer to the index to the callback.
526 Pointer dereference: INDIRECT_REF (addr). In this case we also pass the
527 pointer to addr to the callback.
529 If the callback returns false, the whole search stops and false is returned.
530 Otherwise the function returns true after traversing through the whole
531 reference *ADDR_P. */
534 for_each_index (tree
*addr_p
, bool (*cbck
) (tree
, tree
*, void *), void *data
)
538 for (; ; addr_p
= nxt
)
540 switch (TREE_CODE (*addr_p
))
543 return cbck (*addr_p
, addr_p
, data
);
546 nxt
= &TREE_OPERAND (*addr_p
, 0);
547 return cbck (*addr_p
, nxt
, data
);
550 case VIEW_CONVERT_EXPR
:
553 nxt
= &TREE_OPERAND (*addr_p
, 0);
557 /* If the component has varying offset, it behaves like index
559 idx
= &TREE_OPERAND (*addr_p
, 2);
561 && !cbck (*addr_p
, idx
, data
))
564 nxt
= &TREE_OPERAND (*addr_p
, 0);
568 case ARRAY_RANGE_REF
:
569 nxt
= &TREE_OPERAND (*addr_p
, 0);
570 if (!cbck (*addr_p
, &TREE_OPERAND (*addr_p
, 1), data
))
588 gcc_assert (is_gimple_min_invariant (*addr_p
));
592 idx
= &TMR_BASE (*addr_p
);
594 && !cbck (*addr_p
, idx
, data
))
596 idx
= &TMR_INDEX (*addr_p
);
598 && !cbck (*addr_p
, idx
, data
))
600 idx
= &TMR_INDEX2 (*addr_p
);
602 && !cbck (*addr_p
, idx
, data
))
613 /* The name and the length of the currently generated variable
615 #define MAX_LSM_NAME_LENGTH 40
616 static char lsm_tmp_name
[MAX_LSM_NAME_LENGTH
+ 1];
617 static int lsm_tmp_name_length
;
619 /* Adds S to lsm_tmp_name. */
622 lsm_tmp_name_add (const char *s
)
624 int l
= strlen (s
) + lsm_tmp_name_length
;
625 if (l
> MAX_LSM_NAME_LENGTH
)
628 strcpy (lsm_tmp_name
+ lsm_tmp_name_length
, s
);
629 lsm_tmp_name_length
= l
;
632 /* Stores the name for temporary variable that replaces REF to
636 gen_lsm_tmp_name (tree ref
)
640 switch (TREE_CODE (ref
))
644 gen_lsm_tmp_name (TREE_OPERAND (ref
, 0));
645 lsm_tmp_name_add ("_");
649 gen_lsm_tmp_name (TREE_OPERAND (ref
, 0));
653 case VIEW_CONVERT_EXPR
:
654 case ARRAY_RANGE_REF
:
655 gen_lsm_tmp_name (TREE_OPERAND (ref
, 0));
659 gen_lsm_tmp_name (TREE_OPERAND (ref
, 0));
660 lsm_tmp_name_add ("_RE");
664 gen_lsm_tmp_name (TREE_OPERAND (ref
, 0));
665 lsm_tmp_name_add ("_IM");
669 gen_lsm_tmp_name (TREE_OPERAND (ref
, 0));
670 lsm_tmp_name_add ("_");
671 name
= get_name (TREE_OPERAND (ref
, 1));
674 lsm_tmp_name_add (name
);
678 gen_lsm_tmp_name (TREE_OPERAND (ref
, 0));
679 lsm_tmp_name_add ("_I");
685 name
= get_name (ref
);
688 lsm_tmp_name_add (name
);
692 lsm_tmp_name_add ("S");
696 lsm_tmp_name_add ("R");
708 /* Determines name for temporary variable that replaces REF.
709 The name is accumulated into the lsm_tmp_name variable.
710 N is added to the name of the temporary. */
713 get_lsm_tmp_name (tree ref
, unsigned n
, const char *suffix
)
717 lsm_tmp_name_length
= 0;
718 gen_lsm_tmp_name (ref
);
719 lsm_tmp_name_add ("_lsm");
724 lsm_tmp_name_add (ns
);
728 lsm_tmp_name_add (suffix
);
731 /* Computes an estimated number of insns in LOOP, weighted by WEIGHTS. */
734 tree_num_loop_insns (struct loop
*loop
, eni_weights
*weights
)
736 basic_block
*body
= get_loop_body (loop
);
737 gimple_stmt_iterator gsi
;
738 unsigned size
= 0, i
;
740 for (i
= 0; i
< loop
->num_nodes
; i
++)
741 for (gsi
= gsi_start_bb (body
[i
]); !gsi_end_p (gsi
); gsi_next (&gsi
))
742 size
+= estimate_num_insns (gsi_stmt (gsi
), weights
);