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 /* Gate for loop pass group. The group is controlled by -ftree-loop-optimize
47 but we also avoid running it when the IL doesn't contain any loop. */
50 gate_loop (function
*fn
)
52 if (!flag_tree_loop_optimize
)
55 /* For -fdump-passes which runs before loop discovery print the
56 state of -ftree-loop-optimize. */
57 if (!loops_for_fn (fn
))
60 /* Make sure to drop / re-discover loops when necessary. */
61 if (loops_state_satisfies_p (LOOPS_NEED_FIXUP
))
62 fix_loop_structure (NULL
);
63 return number_of_loops (fn
) > 1;
66 /* The loop superpass. */
70 const pass_data pass_data_tree_loop
=
72 GIMPLE_PASS
, /* type */
74 OPTGROUP_LOOP
, /* optinfo_flags */
75 TV_TREE_LOOP
, /* tv_id */
76 PROP_cfg
, /* properties_required */
77 0, /* properties_provided */
78 0, /* properties_destroyed */
79 0, /* todo_flags_start */
80 0, /* todo_flags_finish */
83 class pass_tree_loop
: public gimple_opt_pass
86 pass_tree_loop (gcc::context
*ctxt
)
87 : gimple_opt_pass (pass_data_tree_loop
, ctxt
)
90 /* opt_pass methods: */
91 virtual bool gate (function
*fn
) { return gate_loop (fn
); }
93 }; // class pass_tree_loop
98 make_pass_tree_loop (gcc::context
*ctxt
)
100 return new pass_tree_loop (ctxt
);
103 /* The no-loop superpass. */
107 const pass_data pass_data_tree_no_loop
=
109 GIMPLE_PASS
, /* type */
110 "no_loop", /* name */
111 OPTGROUP_NONE
, /* optinfo_flags */
112 TV_TREE_NOLOOP
, /* tv_id */
113 PROP_cfg
, /* properties_required */
114 0, /* properties_provided */
115 0, /* properties_destroyed */
116 0, /* todo_flags_start */
117 0, /* todo_flags_finish */
120 class pass_tree_no_loop
: public gimple_opt_pass
123 pass_tree_no_loop (gcc::context
*ctxt
)
124 : gimple_opt_pass (pass_data_tree_no_loop
, ctxt
)
127 /* opt_pass methods: */
128 virtual bool gate (function
*fn
) { return !gate_loop (fn
); }
130 }; // class pass_tree_no_loop
135 make_pass_tree_no_loop (gcc::context
*ctxt
)
137 return new pass_tree_no_loop (ctxt
);
141 /* Loop optimizer initialization. */
145 const pass_data pass_data_tree_loop_init
=
147 GIMPLE_PASS
, /* type */
148 "loopinit", /* name */
149 OPTGROUP_LOOP
, /* optinfo_flags */
151 PROP_cfg
, /* properties_required */
152 0, /* properties_provided */
153 0, /* properties_destroyed */
154 0, /* todo_flags_start */
155 0, /* todo_flags_finish */
158 class pass_tree_loop_init
: public gimple_opt_pass
161 pass_tree_loop_init (gcc::context
*ctxt
)
162 : gimple_opt_pass (pass_data_tree_loop_init
, ctxt
)
165 /* opt_pass methods: */
166 virtual unsigned int execute (function
*);
168 }; // class pass_tree_loop_init
171 pass_tree_loop_init::execute (function
*fun ATTRIBUTE_UNUSED
)
173 loop_optimizer_init (LOOPS_NORMAL
174 | LOOPS_HAVE_RECORDED_EXITS
);
175 rewrite_into_loop_closed_ssa (NULL
, TODO_update_ssa
);
177 /* We might discover new loops, e.g. when turning irreducible
178 regions into reducible. */
187 make_pass_tree_loop_init (gcc::context
*ctxt
)
189 return new pass_tree_loop_init (ctxt
);
192 /* Loop autovectorization. */
196 const pass_data pass_data_vectorize
=
198 GIMPLE_PASS
, /* type */
200 OPTGROUP_LOOP
| OPTGROUP_VEC
, /* optinfo_flags */
201 TV_TREE_VECTORIZATION
, /* tv_id */
202 ( PROP_cfg
| PROP_ssa
), /* properties_required */
203 0, /* properties_provided */
204 0, /* properties_destroyed */
205 0, /* todo_flags_start */
206 0, /* todo_flags_finish */
209 class pass_vectorize
: public gimple_opt_pass
212 pass_vectorize (gcc::context
*ctxt
)
213 : gimple_opt_pass (pass_data_vectorize
, ctxt
)
216 /* opt_pass methods: */
217 virtual bool gate (function
*fun
)
219 return flag_tree_loop_vectorize
|| fun
->has_force_vectorize_loops
;
222 virtual unsigned int execute (function
*);
224 }; // class pass_vectorize
227 pass_vectorize::execute (function
*fun
)
229 if (number_of_loops (fun
) <= 1)
232 return vectorize_loops ();
238 make_pass_vectorize (gcc::context
*ctxt
)
240 return new pass_vectorize (ctxt
);
243 /* Check the correctness of the data dependence analyzers. */
247 const pass_data pass_data_check_data_deps
=
249 GIMPLE_PASS
, /* type */
251 OPTGROUP_LOOP
, /* optinfo_flags */
252 TV_CHECK_DATA_DEPS
, /* tv_id */
253 ( PROP_cfg
| PROP_ssa
), /* properties_required */
254 0, /* properties_provided */
255 0, /* properties_destroyed */
256 0, /* todo_flags_start */
257 0, /* todo_flags_finish */
260 class pass_check_data_deps
: public gimple_opt_pass
263 pass_check_data_deps (gcc::context
*ctxt
)
264 : gimple_opt_pass (pass_data_check_data_deps
, ctxt
)
267 /* opt_pass methods: */
268 virtual bool gate (function
*) { return flag_check_data_deps
!= 0; }
269 virtual unsigned int execute (function
*);
271 }; // class pass_check_data_deps
274 pass_check_data_deps::execute (function
*fun
)
276 if (number_of_loops (fun
) <= 1)
279 tree_check_data_deps ();
286 make_pass_check_data_deps (gcc::context
*ctxt
)
288 return new pass_check_data_deps (ctxt
);
291 /* Propagation of constants using scev. */
295 const pass_data pass_data_scev_cprop
=
297 GIMPLE_PASS
, /* type */
299 OPTGROUP_LOOP
, /* optinfo_flags */
300 TV_SCEV_CONST
, /* tv_id */
301 ( PROP_cfg
| PROP_ssa
), /* properties_required */
302 0, /* properties_provided */
303 0, /* properties_destroyed */
304 0, /* todo_flags_start */
306 | TODO_update_ssa_only_virtuals
), /* todo_flags_finish */
309 class pass_scev_cprop
: public gimple_opt_pass
312 pass_scev_cprop (gcc::context
*ctxt
)
313 : gimple_opt_pass (pass_data_scev_cprop
, ctxt
)
316 /* opt_pass methods: */
317 virtual bool gate (function
*) { return flag_tree_scev_cprop
; }
318 virtual unsigned int execute (function
*) { return scev_const_prop (); }
320 }; // class pass_scev_cprop
325 make_pass_scev_cprop (gcc::context
*ctxt
)
327 return new pass_scev_cprop (ctxt
);
330 /* Record bounds on numbers of iterations of loops. */
334 const pass_data pass_data_record_bounds
=
336 GIMPLE_PASS
, /* type */
337 "*record_bounds", /* name */
338 OPTGROUP_NONE
, /* optinfo_flags */
339 TV_TREE_LOOP_BOUNDS
, /* tv_id */
340 ( PROP_cfg
| PROP_ssa
), /* properties_required */
341 0, /* properties_provided */
342 0, /* properties_destroyed */
343 0, /* todo_flags_start */
344 0, /* todo_flags_finish */
347 class pass_record_bounds
: public gimple_opt_pass
350 pass_record_bounds (gcc::context
*ctxt
)
351 : gimple_opt_pass (pass_data_record_bounds
, ctxt
)
354 /* opt_pass methods: */
355 virtual unsigned int execute (function
*);
357 }; // class pass_record_bounds
360 pass_record_bounds::execute (function
*fun
)
362 if (number_of_loops (fun
) <= 1)
365 estimate_numbers_of_iterations ();
373 make_pass_record_bounds (gcc::context
*ctxt
)
375 return new pass_record_bounds (ctxt
);
378 /* Induction variable optimizations. */
382 const pass_data pass_data_iv_optimize
=
384 GIMPLE_PASS
, /* type */
386 OPTGROUP_LOOP
, /* optinfo_flags */
387 TV_TREE_LOOP_IVOPTS
, /* tv_id */
388 ( PROP_cfg
| PROP_ssa
), /* properties_required */
389 0, /* properties_provided */
390 0, /* properties_destroyed */
391 0, /* todo_flags_start */
392 TODO_update_ssa
, /* todo_flags_finish */
395 class pass_iv_optimize
: public gimple_opt_pass
398 pass_iv_optimize (gcc::context
*ctxt
)
399 : gimple_opt_pass (pass_data_iv_optimize
, ctxt
)
402 /* opt_pass methods: */
403 virtual bool gate (function
*) { return flag_ivopts
!= 0; }
404 virtual unsigned int execute (function
*);
406 }; // class pass_iv_optimize
409 pass_iv_optimize::execute (function
*fun
)
411 if (number_of_loops (fun
) <= 1)
414 tree_ssa_iv_optimize ();
421 make_pass_iv_optimize (gcc::context
*ctxt
)
423 return new pass_iv_optimize (ctxt
);
426 /* Loop optimizer finalization. */
429 tree_ssa_loop_done (void)
431 free_numbers_of_iterations_estimates ();
433 loop_optimizer_finalize ();
439 const pass_data pass_data_tree_loop_done
=
441 GIMPLE_PASS
, /* type */
442 "loopdone", /* name */
443 OPTGROUP_LOOP
, /* optinfo_flags */
445 PROP_cfg
, /* properties_required */
446 0, /* properties_provided */
447 0, /* properties_destroyed */
448 0, /* todo_flags_start */
449 TODO_cleanup_cfg
, /* todo_flags_finish */
452 class pass_tree_loop_done
: public gimple_opt_pass
455 pass_tree_loop_done (gcc::context
*ctxt
)
456 : gimple_opt_pass (pass_data_tree_loop_done
, ctxt
)
459 /* opt_pass methods: */
460 virtual unsigned int execute (function
*) { return tree_ssa_loop_done (); }
462 }; // class pass_tree_loop_done
467 make_pass_tree_loop_done (gcc::context
*ctxt
)
469 return new pass_tree_loop_done (ctxt
);
472 /* Calls CBCK for each index in memory reference ADDR_P. There are two
473 kinds situations handled; in each of these cases, the memory reference
474 and DATA are passed to the callback:
476 Access to an array: ARRAY_{RANGE_}REF (base, index). In this case we also
477 pass the pointer to the index to the callback.
479 Pointer dereference: INDIRECT_REF (addr). In this case we also pass the
480 pointer to addr to the callback.
482 If the callback returns false, the whole search stops and false is returned.
483 Otherwise the function returns true after traversing through the whole
484 reference *ADDR_P. */
487 for_each_index (tree
*addr_p
, bool (*cbck
) (tree
, tree
*, void *), void *data
)
491 for (; ; addr_p
= nxt
)
493 switch (TREE_CODE (*addr_p
))
496 return cbck (*addr_p
, addr_p
, data
);
499 nxt
= &TREE_OPERAND (*addr_p
, 0);
500 return cbck (*addr_p
, nxt
, data
);
503 case VIEW_CONVERT_EXPR
:
506 nxt
= &TREE_OPERAND (*addr_p
, 0);
510 /* If the component has varying offset, it behaves like index
512 idx
= &TREE_OPERAND (*addr_p
, 2);
514 && !cbck (*addr_p
, idx
, data
))
517 nxt
= &TREE_OPERAND (*addr_p
, 0);
521 case ARRAY_RANGE_REF
:
522 nxt
= &TREE_OPERAND (*addr_p
, 0);
523 if (!cbck (*addr_p
, &TREE_OPERAND (*addr_p
, 1), data
))
541 gcc_assert (is_gimple_min_invariant (*addr_p
));
545 idx
= &TMR_BASE (*addr_p
);
547 && !cbck (*addr_p
, idx
, data
))
549 idx
= &TMR_INDEX (*addr_p
);
551 && !cbck (*addr_p
, idx
, data
))
553 idx
= &TMR_INDEX2 (*addr_p
);
555 && !cbck (*addr_p
, idx
, data
))
566 /* The name and the length of the currently generated variable
568 #define MAX_LSM_NAME_LENGTH 40
569 static char lsm_tmp_name
[MAX_LSM_NAME_LENGTH
+ 1];
570 static int lsm_tmp_name_length
;
572 /* Adds S to lsm_tmp_name. */
575 lsm_tmp_name_add (const char *s
)
577 int l
= strlen (s
) + lsm_tmp_name_length
;
578 if (l
> MAX_LSM_NAME_LENGTH
)
581 strcpy (lsm_tmp_name
+ lsm_tmp_name_length
, s
);
582 lsm_tmp_name_length
= l
;
585 /* Stores the name for temporary variable that replaces REF to
589 gen_lsm_tmp_name (tree ref
)
593 switch (TREE_CODE (ref
))
597 gen_lsm_tmp_name (TREE_OPERAND (ref
, 0));
598 lsm_tmp_name_add ("_");
602 gen_lsm_tmp_name (TREE_OPERAND (ref
, 0));
606 case VIEW_CONVERT_EXPR
:
607 case ARRAY_RANGE_REF
:
608 gen_lsm_tmp_name (TREE_OPERAND (ref
, 0));
612 gen_lsm_tmp_name (TREE_OPERAND (ref
, 0));
613 lsm_tmp_name_add ("_RE");
617 gen_lsm_tmp_name (TREE_OPERAND (ref
, 0));
618 lsm_tmp_name_add ("_IM");
622 gen_lsm_tmp_name (TREE_OPERAND (ref
, 0));
623 lsm_tmp_name_add ("_");
624 name
= get_name (TREE_OPERAND (ref
, 1));
627 lsm_tmp_name_add (name
);
631 gen_lsm_tmp_name (TREE_OPERAND (ref
, 0));
632 lsm_tmp_name_add ("_I");
638 name
= get_name (ref
);
641 lsm_tmp_name_add (name
);
645 lsm_tmp_name_add ("S");
649 lsm_tmp_name_add ("R");
661 /* Determines name for temporary variable that replaces REF.
662 The name is accumulated into the lsm_tmp_name variable.
663 N is added to the name of the temporary. */
666 get_lsm_tmp_name (tree ref
, unsigned n
, const char *suffix
)
670 lsm_tmp_name_length
= 0;
671 gen_lsm_tmp_name (ref
);
672 lsm_tmp_name_add ("_lsm");
677 lsm_tmp_name_add (ns
);
681 lsm_tmp_name_add (suffix
);
684 /* Computes an estimated number of insns in LOOP, weighted by WEIGHTS. */
687 tree_num_loop_insns (struct loop
*loop
, eni_weights
*weights
)
689 basic_block
*body
= get_loop_body (loop
);
690 gimple_stmt_iterator gsi
;
691 unsigned size
= 0, i
;
693 for (i
= 0; i
< loop
->num_nodes
; i
++)
694 for (gsi
= gsi_start_bb (body
[i
]); !gsi_end_p (gsi
); gsi_next (&gsi
))
695 size
+= estimate_num_insns (gsi_stmt (gsi
), weights
);