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"
26 #include "hard-reg-set.h"
28 #include "fold-const.h"
30 #include "internal-fn.h"
31 #include "gimple-iterator.h"
32 #include "tree-ssa-loop-ivopts.h"
33 #include "tree-ssa-loop-manip.h"
34 #include "tree-ssa-loop-niter.h"
35 #include "tree-ssa-loop.h"
36 #include "tree-pass.h"
39 #include "tree-inline.h"
40 #include "tree-scalar-evolution.h"
41 #include "diagnostic-core.h"
42 #include "tree-vectorizer.h"
45 /* A pass making sure loops are fixed up. */
49 const pass_data pass_data_fix_loops
=
51 GIMPLE_PASS
, /* type */
52 "fix_loops", /* name */
53 OPTGROUP_LOOP
, /* optinfo_flags */
54 TV_TREE_LOOP
, /* tv_id */
55 PROP_cfg
, /* properties_required */
56 0, /* properties_provided */
57 0, /* properties_destroyed */
58 0, /* todo_flags_start */
59 0, /* todo_flags_finish */
62 class pass_fix_loops
: public gimple_opt_pass
65 pass_fix_loops (gcc::context
*ctxt
)
66 : gimple_opt_pass (pass_data_fix_loops
, ctxt
)
69 /* opt_pass methods: */
70 virtual bool gate (function
*) { return flag_tree_loop_optimize
; }
72 virtual unsigned int execute (function
*fn
);
73 }; // class pass_fix_loops
76 pass_fix_loops::execute (function
*)
78 if (loops_state_satisfies_p (LOOPS_NEED_FIXUP
))
80 calculate_dominance_info (CDI_DOMINATORS
);
81 fix_loop_structure (NULL
);
89 make_pass_fix_loops (gcc::context
*ctxt
)
91 return new pass_fix_loops (ctxt
);
95 /* Gate for loop pass group. The group is controlled by -ftree-loop-optimize
96 but we also avoid running it when the IL doesn't contain any loop. */
99 gate_loop (function
*fn
)
101 if (!flag_tree_loop_optimize
)
104 /* For -fdump-passes which runs before loop discovery print the
105 state of -ftree-loop-optimize. */
106 if (!loops_for_fn (fn
))
109 return number_of_loops (fn
) > 1;
112 /* The loop superpass. */
116 const pass_data pass_data_tree_loop
=
118 GIMPLE_PASS
, /* type */
120 OPTGROUP_LOOP
, /* optinfo_flags */
121 TV_TREE_LOOP
, /* tv_id */
122 PROP_cfg
, /* properties_required */
123 0, /* properties_provided */
124 0, /* properties_destroyed */
125 0, /* todo_flags_start */
126 0, /* todo_flags_finish */
129 class pass_tree_loop
: public gimple_opt_pass
132 pass_tree_loop (gcc::context
*ctxt
)
133 : gimple_opt_pass (pass_data_tree_loop
, ctxt
)
136 /* opt_pass methods: */
137 virtual bool gate (function
*fn
) { return gate_loop (fn
); }
139 }; // class pass_tree_loop
144 make_pass_tree_loop (gcc::context
*ctxt
)
146 return new pass_tree_loop (ctxt
);
149 /* The no-loop superpass. */
153 const pass_data pass_data_tree_no_loop
=
155 GIMPLE_PASS
, /* type */
156 "no_loop", /* name */
157 OPTGROUP_NONE
, /* optinfo_flags */
158 TV_TREE_NOLOOP
, /* tv_id */
159 PROP_cfg
, /* properties_required */
160 0, /* properties_provided */
161 0, /* properties_destroyed */
162 0, /* todo_flags_start */
163 0, /* todo_flags_finish */
166 class pass_tree_no_loop
: public gimple_opt_pass
169 pass_tree_no_loop (gcc::context
*ctxt
)
170 : gimple_opt_pass (pass_data_tree_no_loop
, ctxt
)
173 /* opt_pass methods: */
174 virtual bool gate (function
*fn
) { return !gate_loop (fn
); }
176 }; // class pass_tree_no_loop
181 make_pass_tree_no_loop (gcc::context
*ctxt
)
183 return new pass_tree_no_loop (ctxt
);
187 /* Loop optimizer initialization. */
191 const pass_data pass_data_tree_loop_init
=
193 GIMPLE_PASS
, /* type */
194 "loopinit", /* name */
195 OPTGROUP_LOOP
, /* optinfo_flags */
197 PROP_cfg
, /* properties_required */
198 0, /* properties_provided */
199 0, /* properties_destroyed */
200 0, /* todo_flags_start */
201 0, /* todo_flags_finish */
204 class pass_tree_loop_init
: public gimple_opt_pass
207 pass_tree_loop_init (gcc::context
*ctxt
)
208 : gimple_opt_pass (pass_data_tree_loop_init
, ctxt
)
211 /* opt_pass methods: */
212 virtual unsigned int execute (function
*);
214 }; // class pass_tree_loop_init
217 pass_tree_loop_init::execute (function
*fun ATTRIBUTE_UNUSED
)
219 loop_optimizer_init (LOOPS_NORMAL
220 | LOOPS_HAVE_RECORDED_EXITS
);
221 rewrite_into_loop_closed_ssa (NULL
, TODO_update_ssa
);
223 /* We might discover new loops, e.g. when turning irreducible
224 regions into reducible. */
233 make_pass_tree_loop_init (gcc::context
*ctxt
)
235 return new pass_tree_loop_init (ctxt
);
238 /* Loop autovectorization. */
242 const pass_data pass_data_vectorize
=
244 GIMPLE_PASS
, /* type */
246 OPTGROUP_LOOP
| OPTGROUP_VEC
, /* optinfo_flags */
247 TV_TREE_VECTORIZATION
, /* tv_id */
248 ( PROP_cfg
| PROP_ssa
), /* properties_required */
249 0, /* properties_provided */
250 0, /* properties_destroyed */
251 0, /* todo_flags_start */
252 0, /* todo_flags_finish */
255 class pass_vectorize
: public gimple_opt_pass
258 pass_vectorize (gcc::context
*ctxt
)
259 : gimple_opt_pass (pass_data_vectorize
, ctxt
)
262 /* opt_pass methods: */
263 virtual bool gate (function
*fun
)
265 return flag_tree_loop_vectorize
|| fun
->has_force_vectorize_loops
;
268 virtual unsigned int execute (function
*);
270 }; // class pass_vectorize
273 pass_vectorize::execute (function
*fun
)
275 if (number_of_loops (fun
) <= 1)
278 return vectorize_loops ();
284 make_pass_vectorize (gcc::context
*ctxt
)
286 return new pass_vectorize (ctxt
);
289 /* Propagation of constants using scev. */
293 const pass_data pass_data_scev_cprop
=
295 GIMPLE_PASS
, /* type */
297 OPTGROUP_LOOP
, /* optinfo_flags */
298 TV_SCEV_CONST
, /* tv_id */
299 ( PROP_cfg
| PROP_ssa
), /* properties_required */
300 0, /* properties_provided */
301 0, /* properties_destroyed */
302 0, /* todo_flags_start */
304 | TODO_update_ssa_only_virtuals
), /* todo_flags_finish */
307 class pass_scev_cprop
: public gimple_opt_pass
310 pass_scev_cprop (gcc::context
*ctxt
)
311 : gimple_opt_pass (pass_data_scev_cprop
, ctxt
)
314 /* opt_pass methods: */
315 virtual bool gate (function
*) { return flag_tree_scev_cprop
; }
316 virtual unsigned int execute (function
*) { return scev_const_prop (); }
318 }; // class pass_scev_cprop
323 make_pass_scev_cprop (gcc::context
*ctxt
)
325 return new pass_scev_cprop (ctxt
);
328 /* Record bounds on numbers of iterations of loops. */
332 const pass_data pass_data_record_bounds
=
334 GIMPLE_PASS
, /* type */
335 "*record_bounds", /* name */
336 OPTGROUP_NONE
, /* optinfo_flags */
337 TV_TREE_LOOP_BOUNDS
, /* tv_id */
338 ( PROP_cfg
| PROP_ssa
), /* properties_required */
339 0, /* properties_provided */
340 0, /* properties_destroyed */
341 0, /* todo_flags_start */
342 0, /* todo_flags_finish */
345 class pass_record_bounds
: public gimple_opt_pass
348 pass_record_bounds (gcc::context
*ctxt
)
349 : gimple_opt_pass (pass_data_record_bounds
, ctxt
)
352 /* opt_pass methods: */
353 virtual unsigned int execute (function
*);
355 }; // class pass_record_bounds
358 pass_record_bounds::execute (function
*fun
)
360 if (number_of_loops (fun
) <= 1)
363 estimate_numbers_of_iterations ();
371 make_pass_record_bounds (gcc::context
*ctxt
)
373 return new pass_record_bounds (ctxt
);
376 /* Induction variable optimizations. */
380 const pass_data pass_data_iv_optimize
=
382 GIMPLE_PASS
, /* type */
384 OPTGROUP_LOOP
, /* optinfo_flags */
385 TV_TREE_LOOP_IVOPTS
, /* tv_id */
386 ( PROP_cfg
| PROP_ssa
), /* properties_required */
387 0, /* properties_provided */
388 0, /* properties_destroyed */
389 0, /* todo_flags_start */
390 TODO_update_ssa
, /* todo_flags_finish */
393 class pass_iv_optimize
: public gimple_opt_pass
396 pass_iv_optimize (gcc::context
*ctxt
)
397 : gimple_opt_pass (pass_data_iv_optimize
, ctxt
)
400 /* opt_pass methods: */
401 virtual bool gate (function
*) { return flag_ivopts
!= 0; }
402 virtual unsigned int execute (function
*);
404 }; // class pass_iv_optimize
407 pass_iv_optimize::execute (function
*fun
)
409 if (number_of_loops (fun
) <= 1)
412 tree_ssa_iv_optimize ();
419 make_pass_iv_optimize (gcc::context
*ctxt
)
421 return new pass_iv_optimize (ctxt
);
424 /* Loop optimizer finalization. */
427 tree_ssa_loop_done (void)
429 free_numbers_of_iterations_estimates (cfun
);
431 loop_optimizer_finalize ();
437 const pass_data pass_data_tree_loop_done
=
439 GIMPLE_PASS
, /* type */
440 "loopdone", /* name */
441 OPTGROUP_LOOP
, /* optinfo_flags */
443 PROP_cfg
, /* properties_required */
444 0, /* properties_provided */
445 0, /* properties_destroyed */
446 0, /* todo_flags_start */
447 TODO_cleanup_cfg
, /* todo_flags_finish */
450 class pass_tree_loop_done
: public gimple_opt_pass
453 pass_tree_loop_done (gcc::context
*ctxt
)
454 : gimple_opt_pass (pass_data_tree_loop_done
, ctxt
)
457 /* opt_pass methods: */
458 virtual unsigned int execute (function
*) { return tree_ssa_loop_done (); }
460 }; // class pass_tree_loop_done
465 make_pass_tree_loop_done (gcc::context
*ctxt
)
467 return new pass_tree_loop_done (ctxt
);
470 /* Calls CBCK for each index in memory reference ADDR_P. There are two
471 kinds situations handled; in each of these cases, the memory reference
472 and DATA are passed to the callback:
474 Access to an array: ARRAY_{RANGE_}REF (base, index). In this case we also
475 pass the pointer to the index to the callback.
477 Pointer dereference: INDIRECT_REF (addr). In this case we also pass the
478 pointer to addr to the callback.
480 If the callback returns false, the whole search stops and false is returned.
481 Otherwise the function returns true after traversing through the whole
482 reference *ADDR_P. */
485 for_each_index (tree
*addr_p
, bool (*cbck
) (tree
, tree
*, void *), void *data
)
489 for (; ; addr_p
= nxt
)
491 switch (TREE_CODE (*addr_p
))
494 return cbck (*addr_p
, addr_p
, data
);
497 nxt
= &TREE_OPERAND (*addr_p
, 0);
498 return cbck (*addr_p
, nxt
, data
);
501 case VIEW_CONVERT_EXPR
:
504 nxt
= &TREE_OPERAND (*addr_p
, 0);
508 /* If the component has varying offset, it behaves like index
510 idx
= &TREE_OPERAND (*addr_p
, 2);
512 && !cbck (*addr_p
, idx
, data
))
515 nxt
= &TREE_OPERAND (*addr_p
, 0);
519 case ARRAY_RANGE_REF
:
520 nxt
= &TREE_OPERAND (*addr_p
, 0);
521 if (!cbck (*addr_p
, &TREE_OPERAND (*addr_p
, 1), data
))
539 gcc_assert (is_gimple_min_invariant (*addr_p
));
543 idx
= &TMR_BASE (*addr_p
);
545 && !cbck (*addr_p
, idx
, data
))
547 idx
= &TMR_INDEX (*addr_p
);
549 && !cbck (*addr_p
, idx
, data
))
551 idx
= &TMR_INDEX2 (*addr_p
);
553 && !cbck (*addr_p
, idx
, data
))
564 /* The name and the length of the currently generated variable
566 #define MAX_LSM_NAME_LENGTH 40
567 static char lsm_tmp_name
[MAX_LSM_NAME_LENGTH
+ 1];
568 static int lsm_tmp_name_length
;
570 /* Adds S to lsm_tmp_name. */
573 lsm_tmp_name_add (const char *s
)
575 int l
= strlen (s
) + lsm_tmp_name_length
;
576 if (l
> MAX_LSM_NAME_LENGTH
)
579 strcpy (lsm_tmp_name
+ lsm_tmp_name_length
, s
);
580 lsm_tmp_name_length
= l
;
583 /* Stores the name for temporary variable that replaces REF to
587 gen_lsm_tmp_name (tree ref
)
591 switch (TREE_CODE (ref
))
595 gen_lsm_tmp_name (TREE_OPERAND (ref
, 0));
596 lsm_tmp_name_add ("_");
600 gen_lsm_tmp_name (TREE_OPERAND (ref
, 0));
604 case VIEW_CONVERT_EXPR
:
605 case ARRAY_RANGE_REF
:
606 gen_lsm_tmp_name (TREE_OPERAND (ref
, 0));
610 gen_lsm_tmp_name (TREE_OPERAND (ref
, 0));
611 lsm_tmp_name_add ("_RE");
615 gen_lsm_tmp_name (TREE_OPERAND (ref
, 0));
616 lsm_tmp_name_add ("_IM");
620 gen_lsm_tmp_name (TREE_OPERAND (ref
, 0));
621 lsm_tmp_name_add ("_");
622 name
= get_name (TREE_OPERAND (ref
, 1));
625 lsm_tmp_name_add (name
);
629 gen_lsm_tmp_name (TREE_OPERAND (ref
, 0));
630 lsm_tmp_name_add ("_I");
636 name
= get_name (ref
);
639 lsm_tmp_name_add (name
);
643 lsm_tmp_name_add ("S");
647 lsm_tmp_name_add ("R");
659 /* Determines name for temporary variable that replaces REF.
660 The name is accumulated into the lsm_tmp_name variable.
661 N is added to the name of the temporary. */
664 get_lsm_tmp_name (tree ref
, unsigned n
, const char *suffix
)
668 lsm_tmp_name_length
= 0;
669 gen_lsm_tmp_name (ref
);
670 lsm_tmp_name_add ("_lsm");
675 lsm_tmp_name_add (ns
);
679 lsm_tmp_name_add (suffix
);
682 /* Computes an estimated number of insns in LOOP, weighted by WEIGHTS. */
685 tree_num_loop_insns (struct loop
*loop
, eni_weights
*weights
)
687 basic_block
*body
= get_loop_body (loop
);
688 gimple_stmt_iterator gsi
;
689 unsigned size
= 0, i
;
691 for (i
= 0; i
< loop
->num_nodes
; i
++)
692 for (gsi
= gsi_start_bb (body
[i
]); !gsi_end_p (gsi
); gsi_next (&gsi
))
693 size
+= estimate_num_insns (gsi_stmt (gsi
), weights
);