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"
45 /* The loop superpass. */
49 const pass_data pass_data_tree_loop
=
51 GIMPLE_PASS
, /* type */
53 OPTGROUP_LOOP
, /* optinfo_flags */
54 false, /* has_execute */
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 TODO_verify_ssa
, /* todo_flags_finish */
63 class pass_tree_loop
: public gimple_opt_pass
66 pass_tree_loop (gcc::context
*ctxt
)
67 : gimple_opt_pass (pass_data_tree_loop
, ctxt
)
70 /* opt_pass methods: */
71 virtual bool gate (function
*) { return flag_tree_loop_optimize
!= 0; }
73 }; // class pass_tree_loop
78 make_pass_tree_loop (gcc::context
*ctxt
)
80 return new pass_tree_loop (ctxt
);
83 /* Loop optimizer initialization. */
87 const pass_data pass_data_tree_loop_init
=
89 GIMPLE_PASS
, /* type */
90 "loopinit", /* name */
91 OPTGROUP_LOOP
, /* optinfo_flags */
92 true, /* has_execute */
94 PROP_cfg
, /* properties_required */
95 0, /* properties_provided */
96 0, /* properties_destroyed */
97 0, /* todo_flags_start */
98 0, /* todo_flags_finish */
101 class pass_tree_loop_init
: public gimple_opt_pass
104 pass_tree_loop_init (gcc::context
*ctxt
)
105 : gimple_opt_pass (pass_data_tree_loop_init
, ctxt
)
108 /* opt_pass methods: */
109 virtual unsigned int execute (function
*);
111 }; // class pass_tree_loop_init
114 pass_tree_loop_init::execute (function
*fun
)
116 loop_optimizer_init (LOOPS_NORMAL
117 | LOOPS_HAVE_RECORDED_EXITS
);
118 rewrite_into_loop_closed_ssa (NULL
, TODO_update_ssa
);
120 /* We might discover new loops, e.g. when turning irreducible
121 regions into reducible. */
124 if (number_of_loops (fun
) <= 1)
133 make_pass_tree_loop_init (gcc::context
*ctxt
)
135 return new pass_tree_loop_init (ctxt
);
138 /* Loop autovectorization. */
142 const pass_data pass_data_vectorize
=
144 GIMPLE_PASS
, /* type */
146 OPTGROUP_LOOP
| OPTGROUP_VEC
, /* optinfo_flags */
147 true, /* has_execute */
148 TV_TREE_VECTORIZATION
, /* tv_id */
149 ( PROP_cfg
| PROP_ssa
), /* properties_required */
150 0, /* properties_provided */
151 0, /* properties_destroyed */
152 0, /* todo_flags_start */
153 0, /* todo_flags_finish */
156 class pass_vectorize
: public gimple_opt_pass
159 pass_vectorize (gcc::context
*ctxt
)
160 : gimple_opt_pass (pass_data_vectorize
, ctxt
)
163 /* opt_pass methods: */
164 virtual bool gate (function
*fun
)
166 return flag_tree_loop_vectorize
|| fun
->has_force_vectorize_loops
;
169 virtual unsigned int execute (function
*);
171 }; // class pass_vectorize
174 pass_vectorize::execute (function
*fun
)
176 if (number_of_loops (fun
) <= 1)
179 return vectorize_loops ();
185 make_pass_vectorize (gcc::context
*ctxt
)
187 return new pass_vectorize (ctxt
);
190 /* Check the correctness of the data dependence analyzers. */
194 const pass_data pass_data_check_data_deps
=
196 GIMPLE_PASS
, /* type */
198 OPTGROUP_LOOP
, /* optinfo_flags */
199 true, /* has_execute */
200 TV_CHECK_DATA_DEPS
, /* tv_id */
201 ( PROP_cfg
| PROP_ssa
), /* properties_required */
202 0, /* properties_provided */
203 0, /* properties_destroyed */
204 0, /* todo_flags_start */
205 0, /* todo_flags_finish */
208 class pass_check_data_deps
: public gimple_opt_pass
211 pass_check_data_deps (gcc::context
*ctxt
)
212 : gimple_opt_pass (pass_data_check_data_deps
, ctxt
)
215 /* opt_pass methods: */
216 virtual bool gate (function
*) { return flag_check_data_deps
!= 0; }
217 virtual unsigned int execute (function
*);
219 }; // class pass_check_data_deps
222 pass_check_data_deps::execute (function
*fun
)
224 if (number_of_loops (fun
) <= 1)
227 tree_check_data_deps ();
234 make_pass_check_data_deps (gcc::context
*ctxt
)
236 return new pass_check_data_deps (ctxt
);
239 /* Propagation of constants using scev. */
243 const pass_data pass_data_scev_cprop
=
245 GIMPLE_PASS
, /* type */
247 OPTGROUP_LOOP
, /* optinfo_flags */
248 true, /* has_execute */
249 TV_SCEV_CONST
, /* tv_id */
250 ( PROP_cfg
| PROP_ssa
), /* properties_required */
251 0, /* properties_provided */
252 0, /* properties_destroyed */
253 0, /* todo_flags_start */
255 | TODO_update_ssa_only_virtuals
), /* todo_flags_finish */
258 class pass_scev_cprop
: public gimple_opt_pass
261 pass_scev_cprop (gcc::context
*ctxt
)
262 : gimple_opt_pass (pass_data_scev_cprop
, ctxt
)
265 /* opt_pass methods: */
266 virtual bool gate (function
*) { return flag_tree_scev_cprop
; }
267 virtual unsigned int execute (function
*) { return scev_const_prop (); }
269 }; // class pass_scev_cprop
274 make_pass_scev_cprop (gcc::context
*ctxt
)
276 return new pass_scev_cprop (ctxt
);
279 /* Record bounds on numbers of iterations of loops. */
283 const pass_data pass_data_record_bounds
=
285 GIMPLE_PASS
, /* type */
286 "*record_bounds", /* name */
287 OPTGROUP_NONE
, /* optinfo_flags */
288 true, /* has_execute */
289 TV_TREE_LOOP_BOUNDS
, /* tv_id */
290 ( PROP_cfg
| PROP_ssa
), /* properties_required */
291 0, /* properties_provided */
292 0, /* properties_destroyed */
293 0, /* todo_flags_start */
294 0, /* todo_flags_finish */
297 class pass_record_bounds
: public gimple_opt_pass
300 pass_record_bounds (gcc::context
*ctxt
)
301 : gimple_opt_pass (pass_data_record_bounds
, ctxt
)
304 /* opt_pass methods: */
305 virtual unsigned int execute (function
*);
307 }; // class pass_record_bounds
310 pass_record_bounds::execute (function
*fun
)
312 if (number_of_loops (fun
) <= 1)
315 estimate_numbers_of_iterations ();
323 make_pass_record_bounds (gcc::context
*ctxt
)
325 return new pass_record_bounds (ctxt
);
328 /* Induction variable optimizations. */
332 const pass_data pass_data_iv_optimize
=
334 GIMPLE_PASS
, /* type */
336 OPTGROUP_LOOP
, /* optinfo_flags */
337 true, /* has_execute */
338 TV_TREE_LOOP_IVOPTS
, /* tv_id */
339 ( PROP_cfg
| PROP_ssa
), /* properties_required */
340 0, /* properties_provided */
341 0, /* properties_destroyed */
342 0, /* todo_flags_start */
343 TODO_update_ssa
, /* todo_flags_finish */
346 class pass_iv_optimize
: public gimple_opt_pass
349 pass_iv_optimize (gcc::context
*ctxt
)
350 : gimple_opt_pass (pass_data_iv_optimize
, ctxt
)
353 /* opt_pass methods: */
354 virtual bool gate (function
*) { return flag_ivopts
!= 0; }
355 virtual unsigned int execute (function
*);
357 }; // class pass_iv_optimize
360 pass_iv_optimize::execute (function
*fun
)
362 if (number_of_loops (fun
) <= 1)
365 tree_ssa_iv_optimize ();
372 make_pass_iv_optimize (gcc::context
*ctxt
)
374 return new pass_iv_optimize (ctxt
);
377 /* Loop optimizer finalization. */
380 tree_ssa_loop_done (void)
382 free_numbers_of_iterations_estimates ();
384 loop_optimizer_finalize ();
390 const pass_data pass_data_tree_loop_done
=
392 GIMPLE_PASS
, /* type */
393 "loopdone", /* name */
394 OPTGROUP_LOOP
, /* optinfo_flags */
395 true, /* has_execute */
397 PROP_cfg
, /* properties_required */
398 0, /* properties_provided */
399 0, /* properties_destroyed */
400 0, /* todo_flags_start */
401 ( TODO_cleanup_cfg
| TODO_verify_flow
), /* todo_flags_finish */
404 class pass_tree_loop_done
: public gimple_opt_pass
407 pass_tree_loop_done (gcc::context
*ctxt
)
408 : gimple_opt_pass (pass_data_tree_loop_done
, ctxt
)
411 /* opt_pass methods: */
412 virtual unsigned int execute (function
*) { return tree_ssa_loop_done (); }
414 }; // class pass_tree_loop_done
419 make_pass_tree_loop_done (gcc::context
*ctxt
)
421 return new pass_tree_loop_done (ctxt
);
424 /* Calls CBCK for each index in memory reference ADDR_P. There are two
425 kinds situations handled; in each of these cases, the memory reference
426 and DATA are passed to the callback:
428 Access to an array: ARRAY_{RANGE_}REF (base, index). In this case we also
429 pass the pointer to the index to the callback.
431 Pointer dereference: INDIRECT_REF (addr). In this case we also pass the
432 pointer to addr to the callback.
434 If the callback returns false, the whole search stops and false is returned.
435 Otherwise the function returns true after traversing through the whole
436 reference *ADDR_P. */
439 for_each_index (tree
*addr_p
, bool (*cbck
) (tree
, tree
*, void *), void *data
)
443 for (; ; addr_p
= nxt
)
445 switch (TREE_CODE (*addr_p
))
448 return cbck (*addr_p
, addr_p
, data
);
451 nxt
= &TREE_OPERAND (*addr_p
, 0);
452 return cbck (*addr_p
, nxt
, data
);
455 case VIEW_CONVERT_EXPR
:
458 nxt
= &TREE_OPERAND (*addr_p
, 0);
462 /* If the component has varying offset, it behaves like index
464 idx
= &TREE_OPERAND (*addr_p
, 2);
466 && !cbck (*addr_p
, idx
, data
))
469 nxt
= &TREE_OPERAND (*addr_p
, 0);
473 case ARRAY_RANGE_REF
:
474 nxt
= &TREE_OPERAND (*addr_p
, 0);
475 if (!cbck (*addr_p
, &TREE_OPERAND (*addr_p
, 1), data
))
493 gcc_assert (is_gimple_min_invariant (*addr_p
));
497 idx
= &TMR_BASE (*addr_p
);
499 && !cbck (*addr_p
, idx
, data
))
501 idx
= &TMR_INDEX (*addr_p
);
503 && !cbck (*addr_p
, idx
, data
))
505 idx
= &TMR_INDEX2 (*addr_p
);
507 && !cbck (*addr_p
, idx
, data
))
518 /* The name and the length of the currently generated variable
520 #define MAX_LSM_NAME_LENGTH 40
521 static char lsm_tmp_name
[MAX_LSM_NAME_LENGTH
+ 1];
522 static int lsm_tmp_name_length
;
524 /* Adds S to lsm_tmp_name. */
527 lsm_tmp_name_add (const char *s
)
529 int l
= strlen (s
) + lsm_tmp_name_length
;
530 if (l
> MAX_LSM_NAME_LENGTH
)
533 strcpy (lsm_tmp_name
+ lsm_tmp_name_length
, s
);
534 lsm_tmp_name_length
= l
;
537 /* Stores the name for temporary variable that replaces REF to
541 gen_lsm_tmp_name (tree ref
)
545 switch (TREE_CODE (ref
))
549 gen_lsm_tmp_name (TREE_OPERAND (ref
, 0));
550 lsm_tmp_name_add ("_");
554 gen_lsm_tmp_name (TREE_OPERAND (ref
, 0));
558 case VIEW_CONVERT_EXPR
:
559 case ARRAY_RANGE_REF
:
560 gen_lsm_tmp_name (TREE_OPERAND (ref
, 0));
564 gen_lsm_tmp_name (TREE_OPERAND (ref
, 0));
565 lsm_tmp_name_add ("_RE");
569 gen_lsm_tmp_name (TREE_OPERAND (ref
, 0));
570 lsm_tmp_name_add ("_IM");
574 gen_lsm_tmp_name (TREE_OPERAND (ref
, 0));
575 lsm_tmp_name_add ("_");
576 name
= get_name (TREE_OPERAND (ref
, 1));
579 lsm_tmp_name_add (name
);
583 gen_lsm_tmp_name (TREE_OPERAND (ref
, 0));
584 lsm_tmp_name_add ("_I");
590 name
= get_name (ref
);
593 lsm_tmp_name_add (name
);
597 lsm_tmp_name_add ("S");
601 lsm_tmp_name_add ("R");
613 /* Determines name for temporary variable that replaces REF.
614 The name is accumulated into the lsm_tmp_name variable.
615 N is added to the name of the temporary. */
618 get_lsm_tmp_name (tree ref
, unsigned n
, const char *suffix
)
622 lsm_tmp_name_length
= 0;
623 gen_lsm_tmp_name (ref
);
624 lsm_tmp_name_add ("_lsm");
629 lsm_tmp_name_add (ns
);
633 lsm_tmp_name_add (suffix
);
636 /* Computes an estimated number of insns in LOOP, weighted by WEIGHTS. */
639 tree_num_loop_insns (struct loop
*loop
, eni_weights
*weights
)
641 basic_block
*body
= get_loop_body (loop
);
642 gimple_stmt_iterator gsi
;
643 unsigned size
= 0, i
;
645 for (i
= 0; i
< loop
->num_nodes
; i
++)
646 for (gsi
= gsi_start_bb (body
[i
]); !gsi_end_p (gsi
); gsi_next (&gsi
))
647 size
+= estimate_num_insns (gsi_stmt (gsi
), weights
);