]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/tree-ssa-loop.c
2017-06-16 Richard Biener <rguenther@suse.de>
[thirdparty/gcc.git] / gcc / tree-ssa-loop.c
CommitLineData
4ee9c684 1/* Loop optimizations over tree-ssa.
aad93da1 2 Copyright (C) 2003-2017 Free Software Foundation, Inc.
48e1416a 3
4ee9c684 4This file is part of GCC.
48e1416a 5
4ee9c684 6GCC is free software; you can redistribute it and/or modify it
7under the terms of the GNU General Public License as published by the
8c4c00c1 8Free Software Foundation; either version 3, or (at your option) any
4ee9c684 9later version.
48e1416a 10
4ee9c684 11GCC is distributed in the hope that it will be useful, but WITHOUT
12ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14for more details.
48e1416a 15
4ee9c684 16You should have received a copy of the GNU General Public License
8c4c00c1 17along with GCC; see the file COPYING3. If not see
18<http://www.gnu.org/licenses/>. */
4ee9c684 19
20#include "config.h"
21#include "system.h"
22#include "coretypes.h"
9ef16211 23#include "backend.h"
4ee9c684 24#include "tree.h"
9ef16211 25#include "gimple.h"
7c29e30e 26#include "tree-pass.h"
ad7b10a2 27#include "memmodel.h"
7c29e30e 28#include "tm_p.h"
b20a8bb4 29#include "fold-const.h"
dcf1a1ec 30#include "gimple-iterator.h"
05d9c18a 31#include "tree-ssa-loop-ivopts.h"
32#include "tree-ssa-loop-manip.h"
33#include "tree-ssa-loop-niter.h"
073c1fd5 34#include "tree-ssa-loop.h"
4ee9c684 35#include "cfgloop.h"
4ee9c684 36#include "tree-inline.h"
c91e8223 37#include "tree-scalar-evolution.h"
10230637 38#include "tree-vectorizer.h"
4954efd4 39#include "omp-general.h"
f71e6ee5 40#include "diagnostic-core.h"
4ee9c684 41
ef3f2b6f 42
bf8e217d 43/* A pass making sure loops are fixed up. */
44
45namespace {
46
47const pass_data pass_data_fix_loops =
48{
49 GIMPLE_PASS, /* type */
50 "fix_loops", /* name */
51 OPTGROUP_LOOP, /* optinfo_flags */
52 TV_TREE_LOOP, /* tv_id */
53 PROP_cfg, /* properties_required */
54 0, /* properties_provided */
55 0, /* properties_destroyed */
56 0, /* todo_flags_start */
57 0, /* todo_flags_finish */
58};
59
60class pass_fix_loops : public gimple_opt_pass
61{
62public:
63 pass_fix_loops (gcc::context *ctxt)
64 : gimple_opt_pass (pass_data_fix_loops, ctxt)
65 {}
66
67 /* opt_pass methods: */
68 virtual bool gate (function *) { return flag_tree_loop_optimize; }
69
70 virtual unsigned int execute (function *fn);
71}; // class pass_fix_loops
72
73unsigned int
74pass_fix_loops::execute (function *)
75{
76 if (loops_state_satisfies_p (LOOPS_NEED_FIXUP))
77 {
78 calculate_dominance_info (CDI_DOMINATORS);
79 fix_loop_structure (NULL);
80 }
81 return 0;
82}
83
84} // anon namespace
85
86gimple_opt_pass *
87make_pass_fix_loops (gcc::context *ctxt)
88{
89 return new pass_fix_loops (ctxt);
90}
91
92
ef3f2b6f 93/* Gate for loop pass group. The group is controlled by -ftree-loop-optimize
94 but we also avoid running it when the IL doesn't contain any loop. */
95
96static bool
97gate_loop (function *fn)
98{
99 if (!flag_tree_loop_optimize)
100 return false;
101
102 /* For -fdump-passes which runs before loop discovery print the
103 state of -ftree-loop-optimize. */
104 if (!loops_for_fn (fn))
105 return true;
106
ef3f2b6f 107 return number_of_loops (fn) > 1;
108}
109
dcb9eccb 110/* The loop superpass. */
111
cbe8bda8 112namespace {
113
114const pass_data pass_data_tree_loop =
115{
116 GIMPLE_PASS, /* type */
117 "loop", /* name */
118 OPTGROUP_LOOP, /* optinfo_flags */
cbe8bda8 119 TV_TREE_LOOP, /* tv_id */
120 PROP_cfg, /* properties_required */
121 0, /* properties_provided */
122 0, /* properties_destroyed */
123 0, /* todo_flags_start */
8b88439e 124 0, /* todo_flags_finish */
dcb9eccb 125};
126
cbe8bda8 127class pass_tree_loop : public gimple_opt_pass
128{
129public:
9af5ce0c 130 pass_tree_loop (gcc::context *ctxt)
131 : gimple_opt_pass (pass_data_tree_loop, ctxt)
cbe8bda8 132 {}
133
134 /* opt_pass methods: */
ef3f2b6f 135 virtual bool gate (function *fn) { return gate_loop (fn); }
cbe8bda8 136
137}; // class pass_tree_loop
138
139} // anon namespace
140
141gimple_opt_pass *
142make_pass_tree_loop (gcc::context *ctxt)
143{
144 return new pass_tree_loop (ctxt);
145}
146
3abdee23 147/* Gate for oacc kernels pass group. */
148
149static bool
150gate_oacc_kernels (function *fn)
151{
3a37a410 152 if (!flag_openacc)
3abdee23 153 return false;
154
1d3ea8fc 155 if (!lookup_attribute ("oacc kernels", DECL_ATTRIBUTES (fn->decl)))
3abdee23 156 return false;
157
158 struct loop *loop;
159 FOR_EACH_LOOP (loop, 0)
160 if (loop->in_oacc_kernels_region)
161 return true;
162
163 return false;
164}
165
166/* The oacc kernels superpass. */
167
168namespace {
169
170const pass_data pass_data_oacc_kernels =
171{
172 GIMPLE_PASS, /* type */
173 "oacc_kernels", /* name */
174 OPTGROUP_LOOP, /* optinfo_flags */
175 TV_TREE_LOOP, /* tv_id */
176 PROP_cfg, /* properties_required */
177 0, /* properties_provided */
178 0, /* properties_destroyed */
179 0, /* todo_flags_start */
180 0, /* todo_flags_finish */
181};
182
183class pass_oacc_kernels : public gimple_opt_pass
184{
185public:
186 pass_oacc_kernels (gcc::context *ctxt)
187 : gimple_opt_pass (pass_data_oacc_kernels, ctxt)
188 {}
189
190 /* opt_pass methods: */
191 virtual bool gate (function *fn) { return gate_oacc_kernels (fn); }
192
193}; // class pass_oacc_kernels
194
195} // anon namespace
196
197gimple_opt_pass *
198make_pass_oacc_kernels (gcc::context *ctxt)
199{
200 return new pass_oacc_kernels (ctxt);
201}
202
f71e6ee5 203/* The ipa oacc superpass. */
204
3abdee23 205namespace {
206
f71e6ee5 207const pass_data pass_data_ipa_oacc =
3abdee23 208{
f71e6ee5 209 SIMPLE_IPA_PASS, /* type */
210 "ipa_oacc", /* name */
3abdee23 211 OPTGROUP_LOOP, /* optinfo_flags */
212 TV_TREE_LOOP, /* tv_id */
213 PROP_cfg, /* properties_required */
214 0, /* properties_provided */
215 0, /* properties_destroyed */
216 0, /* todo_flags_start */
217 0, /* todo_flags_finish */
218};
219
f71e6ee5 220class pass_ipa_oacc : public simple_ipa_opt_pass
3abdee23 221{
222public:
f71e6ee5 223 pass_ipa_oacc (gcc::context *ctxt)
224 : simple_ipa_opt_pass (pass_data_ipa_oacc, ctxt)
3abdee23 225 {}
226
227 /* opt_pass methods: */
f71e6ee5 228 virtual bool gate (function *)
229 {
230 return (optimize
f71e6ee5 231 && flag_openacc
3a37a410 232 /* Don't bother doing anything if the program has errors. */
233 && !seen_error ());
f71e6ee5 234 }
3abdee23 235
f71e6ee5 236}; // class pass_ipa_oacc
3abdee23 237
238} // anon namespace
239
f71e6ee5 240simple_ipa_opt_pass *
241make_pass_ipa_oacc (gcc::context *ctxt)
242{
243 return new pass_ipa_oacc (ctxt);
244}
245
246/* The ipa oacc kernels pass. */
247
248namespace {
249
250const pass_data pass_data_ipa_oacc_kernels =
251{
252 SIMPLE_IPA_PASS, /* type */
253 "ipa_oacc_kernels", /* name */
254 OPTGROUP_LOOP, /* optinfo_flags */
255 TV_TREE_LOOP, /* tv_id */
256 PROP_cfg, /* properties_required */
257 0, /* properties_provided */
258 0, /* properties_destroyed */
259 0, /* todo_flags_start */
260 0, /* todo_flags_finish */
261};
262
263class pass_ipa_oacc_kernels : public simple_ipa_opt_pass
264{
265public:
266 pass_ipa_oacc_kernels (gcc::context *ctxt)
267 : simple_ipa_opt_pass (pass_data_ipa_oacc_kernels, ctxt)
268 {}
269
270}; // class pass_ipa_oacc_kernels
271
272} // anon namespace
273
274simple_ipa_opt_pass *
275make_pass_ipa_oacc_kernels (gcc::context *ctxt)
3abdee23 276{
f71e6ee5 277 return new pass_ipa_oacc_kernels (ctxt);
3abdee23 278}
279
ef3f2b6f 280/* The no-loop superpass. */
281
282namespace {
283
284const pass_data pass_data_tree_no_loop =
285{
286 GIMPLE_PASS, /* type */
287 "no_loop", /* name */
288 OPTGROUP_NONE, /* optinfo_flags */
ef3f2b6f 289 TV_TREE_NOLOOP, /* tv_id */
290 PROP_cfg, /* properties_required */
291 0, /* properties_provided */
292 0, /* properties_destroyed */
293 0, /* todo_flags_start */
294 0, /* todo_flags_finish */
295};
296
297class pass_tree_no_loop : public gimple_opt_pass
298{
299public:
300 pass_tree_no_loop (gcc::context *ctxt)
301 : gimple_opt_pass (pass_data_tree_no_loop, ctxt)
302 {}
303
304 /* opt_pass methods: */
305 virtual bool gate (function *fn) { return !gate_loop (fn); }
306
307}; // class pass_tree_no_loop
308
309} // anon namespace
310
311gimple_opt_pass *
312make_pass_tree_no_loop (gcc::context *ctxt)
313{
314 return new pass_tree_no_loop (ctxt);
315}
316
317
dcb9eccb 318/* Loop optimizer initialization. */
319
cbe8bda8 320namespace {
321
322const pass_data pass_data_tree_loop_init =
323{
324 GIMPLE_PASS, /* type */
325 "loopinit", /* name */
326 OPTGROUP_LOOP, /* optinfo_flags */
cbe8bda8 327 TV_NONE, /* tv_id */
328 PROP_cfg, /* properties_required */
329 0, /* properties_provided */
330 0, /* properties_destroyed */
331 0, /* todo_flags_start */
332 0, /* todo_flags_finish */
dcb9eccb 333};
334
cbe8bda8 335class pass_tree_loop_init : public gimple_opt_pass
336{
337public:
9af5ce0c 338 pass_tree_loop_init (gcc::context *ctxt)
339 : gimple_opt_pass (pass_data_tree_loop_init, ctxt)
cbe8bda8 340 {}
341
342 /* opt_pass methods: */
65b0537f 343 virtual unsigned int execute (function *);
cbe8bda8 344
345}; // class pass_tree_loop_init
346
65b0537f 347unsigned int
76ce2a43 348pass_tree_loop_init::execute (function *fun ATTRIBUTE_UNUSED)
65b0537f 349{
9b6c9378 350 /* When processing a loop in the loop pipeline, we should be able to assert
351 that:
352 (loops_state_satisfies_p (LOOPS_NORMAL | LOOPS_HAVE_RECORDED_EXITS
353 | LOOP_CLOSED_SSA)
354 && scev_initialized_p ())
355 */
65b0537f 356 loop_optimizer_init (LOOPS_NORMAL
357 | LOOPS_HAVE_RECORDED_EXITS);
358 rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa);
65b0537f 359 scev_initialize ();
360
65b0537f 361 return 0;
362}
363
cbe8bda8 364} // anon namespace
365
366gimple_opt_pass *
367make_pass_tree_loop_init (gcc::context *ctxt)
368{
369 return new pass_tree_loop_init (ctxt);
370}
371
c91e8223 372/* Loop autovectorization. */
373
cbe8bda8 374namespace {
375
376const pass_data pass_data_vectorize =
377{
378 GIMPLE_PASS, /* type */
379 "vect", /* name */
380 OPTGROUP_LOOP | OPTGROUP_VEC, /* optinfo_flags */
cbe8bda8 381 TV_TREE_VECTORIZATION, /* tv_id */
382 ( PROP_cfg | PROP_ssa ), /* properties_required */
383 0, /* properties_provided */
384 0, /* properties_destroyed */
385 0, /* todo_flags_start */
386 0, /* todo_flags_finish */
c91e8223 387};
388
cbe8bda8 389class pass_vectorize : public gimple_opt_pass
390{
391public:
9af5ce0c 392 pass_vectorize (gcc::context *ctxt)
393 : gimple_opt_pass (pass_data_vectorize, ctxt)
cbe8bda8 394 {}
395
396 /* opt_pass methods: */
31315c24 397 virtual bool gate (function *fun)
398 {
399 return flag_tree_loop_vectorize || fun->has_force_vectorize_loops;
400 }
401
65b0537f 402 virtual unsigned int execute (function *);
cbe8bda8 403
404}; // class pass_vectorize
405
65b0537f 406unsigned int
407pass_vectorize::execute (function *fun)
408{
409 if (number_of_loops (fun) <= 1)
410 return 0;
411
412 return vectorize_loops ();
413}
414
cbe8bda8 415} // anon namespace
416
417gimple_opt_pass *
418make_pass_vectorize (gcc::context *ctxt)
419{
420 return new pass_vectorize (ctxt);
421}
422
10fec820 423/* Propagation of constants using scev. */
424
cbe8bda8 425namespace {
426
427const pass_data pass_data_scev_cprop =
428{
429 GIMPLE_PASS, /* type */
430 "sccp", /* name */
431 OPTGROUP_LOOP, /* optinfo_flags */
cbe8bda8 432 TV_SCEV_CONST, /* tv_id */
433 ( PROP_cfg | PROP_ssa ), /* properties_required */
434 0, /* properties_provided */
435 0, /* properties_destroyed */
436 0, /* todo_flags_start */
437 ( TODO_cleanup_cfg
438 | TODO_update_ssa_only_virtuals ), /* todo_flags_finish */
8feba661 439};
440
cbe8bda8 441class pass_scev_cprop : public gimple_opt_pass
442{
443public:
9af5ce0c 444 pass_scev_cprop (gcc::context *ctxt)
445 : gimple_opt_pass (pass_data_scev_cprop, ctxt)
cbe8bda8 446 {}
447
448 /* opt_pass methods: */
31315c24 449 virtual bool gate (function *) { return flag_tree_scev_cprop; }
65b0537f 450 virtual unsigned int execute (function *) { return scev_const_prop (); }
cbe8bda8 451
452}; // class pass_scev_cprop
453
454} // anon namespace
455
456gimple_opt_pass *
457make_pass_scev_cprop (gcc::context *ctxt)
458{
459 return new pass_scev_cprop (ctxt);
460}
461
dec41e98 462/* Induction variable optimizations. */
463
cbe8bda8 464namespace {
465
466const pass_data pass_data_iv_optimize =
467{
468 GIMPLE_PASS, /* type */
469 "ivopts", /* name */
470 OPTGROUP_LOOP, /* optinfo_flags */
cbe8bda8 471 TV_TREE_LOOP_IVOPTS, /* tv_id */
472 ( PROP_cfg | PROP_ssa ), /* properties_required */
473 0, /* properties_provided */
474 0, /* properties_destroyed */
475 0, /* todo_flags_start */
476 TODO_update_ssa, /* todo_flags_finish */
bb445479 477};
478
cbe8bda8 479class pass_iv_optimize : public gimple_opt_pass
480{
481public:
9af5ce0c 482 pass_iv_optimize (gcc::context *ctxt)
483 : gimple_opt_pass (pass_data_iv_optimize, ctxt)
cbe8bda8 484 {}
485
486 /* opt_pass methods: */
31315c24 487 virtual bool gate (function *) { return flag_ivopts != 0; }
65b0537f 488 virtual unsigned int execute (function *);
cbe8bda8 489
490}; // class pass_iv_optimize
491
65b0537f 492unsigned int
493pass_iv_optimize::execute (function *fun)
494{
495 if (number_of_loops (fun) <= 1)
496 return 0;
497
498 tree_ssa_iv_optimize ();
499 return 0;
500}
501
cbe8bda8 502} // anon namespace
503
504gimple_opt_pass *
505make_pass_iv_optimize (gcc::context *ctxt)
506{
507 return new pass_iv_optimize (ctxt);
508}
509
dcb9eccb 510/* Loop optimizer finalization. */
511
2a1990e9 512static unsigned int
dcb9eccb 513tree_ssa_loop_done (void)
514{
d4f078b5 515 free_numbers_of_iterations_estimates (cfun);
bb445479 516 scev_finalize ();
88e6f696 517 loop_optimizer_finalize ();
2a1990e9 518 return 0;
dcb9eccb 519}
48e1416a 520
cbe8bda8 521namespace {
522
523const pass_data pass_data_tree_loop_done =
524{
525 GIMPLE_PASS, /* type */
526 "loopdone", /* name */
527 OPTGROUP_LOOP, /* optinfo_flags */
cbe8bda8 528 TV_NONE, /* tv_id */
529 PROP_cfg, /* properties_required */
530 0, /* properties_provided */
531 0, /* properties_destroyed */
532 0, /* todo_flags_start */
8b88439e 533 TODO_cleanup_cfg, /* todo_flags_finish */
dcb9eccb 534};
cbe8bda8 535
536class pass_tree_loop_done : public gimple_opt_pass
537{
538public:
9af5ce0c 539 pass_tree_loop_done (gcc::context *ctxt)
540 : gimple_opt_pass (pass_data_tree_loop_done, ctxt)
cbe8bda8 541 {}
542
543 /* opt_pass methods: */
65b0537f 544 virtual unsigned int execute (function *) { return tree_ssa_loop_done (); }
cbe8bda8 545
546}; // class pass_tree_loop_done
547
548} // anon namespace
549
550gimple_opt_pass *
551make_pass_tree_loop_done (gcc::context *ctxt)
552{
553 return new pass_tree_loop_done (ctxt);
554}
f86b328b 555
556/* Calls CBCK for each index in memory reference ADDR_P. There are two
557 kinds situations handled; in each of these cases, the memory reference
558 and DATA are passed to the callback:
559
560 Access to an array: ARRAY_{RANGE_}REF (base, index). In this case we also
561 pass the pointer to the index to the callback.
562
563 Pointer dereference: INDIRECT_REF (addr). In this case we also pass the
564 pointer to addr to the callback.
565
566 If the callback returns false, the whole search stops and false is returned.
567 Otherwise the function returns true after traversing through the whole
568 reference *ADDR_P. */
569
570bool
571for_each_index (tree *addr_p, bool (*cbck) (tree, tree *, void *), void *data)
572{
573 tree *nxt, *idx;
574
575 for (; ; addr_p = nxt)
576 {
577 switch (TREE_CODE (*addr_p))
578 {
579 case SSA_NAME:
580 return cbck (*addr_p, addr_p, data);
581
582 case MEM_REF:
583 nxt = &TREE_OPERAND (*addr_p, 0);
584 return cbck (*addr_p, nxt, data);
585
586 case BIT_FIELD_REF:
587 case VIEW_CONVERT_EXPR:
588 case REALPART_EXPR:
589 case IMAGPART_EXPR:
590 nxt = &TREE_OPERAND (*addr_p, 0);
591 break;
592
593 case COMPONENT_REF:
594 /* If the component has varying offset, it behaves like index
595 as well. */
596 idx = &TREE_OPERAND (*addr_p, 2);
597 if (*idx
598 && !cbck (*addr_p, idx, data))
599 return false;
600
601 nxt = &TREE_OPERAND (*addr_p, 0);
602 break;
603
604 case ARRAY_REF:
605 case ARRAY_RANGE_REF:
606 nxt = &TREE_OPERAND (*addr_p, 0);
607 if (!cbck (*addr_p, &TREE_OPERAND (*addr_p, 1), data))
608 return false;
609 break;
610
611 case VAR_DECL:
612 case PARM_DECL:
613 case CONST_DECL:
614 case STRING_CST:
615 case RESULT_DECL:
616 case VECTOR_CST:
617 case COMPLEX_CST:
618 case INTEGER_CST:
619 case REAL_CST:
620 case FIXED_CST:
621 case CONSTRUCTOR:
622 return true;
623
624 case ADDR_EXPR:
625 gcc_assert (is_gimple_min_invariant (*addr_p));
626 return true;
627
628 case TARGET_MEM_REF:
629 idx = &TMR_BASE (*addr_p);
630 if (*idx
631 && !cbck (*addr_p, idx, data))
632 return false;
633 idx = &TMR_INDEX (*addr_p);
634 if (*idx
635 && !cbck (*addr_p, idx, data))
636 return false;
637 idx = &TMR_INDEX2 (*addr_p);
638 if (*idx
639 && !cbck (*addr_p, idx, data))
640 return false;
641 return true;
642
643 default:
644 gcc_unreachable ();
645 }
646 }
647}
648
649
650/* The name and the length of the currently generated variable
651 for lsm. */
652#define MAX_LSM_NAME_LENGTH 40
653static char lsm_tmp_name[MAX_LSM_NAME_LENGTH + 1];
654static int lsm_tmp_name_length;
655
656/* Adds S to lsm_tmp_name. */
657
658static void
659lsm_tmp_name_add (const char *s)
660{
661 int l = strlen (s) + lsm_tmp_name_length;
662 if (l > MAX_LSM_NAME_LENGTH)
663 return;
664
665 strcpy (lsm_tmp_name + lsm_tmp_name_length, s);
666 lsm_tmp_name_length = l;
667}
668
669/* Stores the name for temporary variable that replaces REF to
670 lsm_tmp_name. */
671
672static void
673gen_lsm_tmp_name (tree ref)
674{
675 const char *name;
676
677 switch (TREE_CODE (ref))
678 {
679 case MEM_REF:
680 case TARGET_MEM_REF:
681 gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
682 lsm_tmp_name_add ("_");
683 break;
684
685 case ADDR_EXPR:
686 gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
687 break;
688
689 case BIT_FIELD_REF:
690 case VIEW_CONVERT_EXPR:
691 case ARRAY_RANGE_REF:
692 gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
693 break;
694
695 case REALPART_EXPR:
696 gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
697 lsm_tmp_name_add ("_RE");
698 break;
699
700 case IMAGPART_EXPR:
701 gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
702 lsm_tmp_name_add ("_IM");
703 break;
704
705 case COMPONENT_REF:
706 gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
707 lsm_tmp_name_add ("_");
708 name = get_name (TREE_OPERAND (ref, 1));
709 if (!name)
710 name = "F";
711 lsm_tmp_name_add (name);
712 break;
713
714 case ARRAY_REF:
715 gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
716 lsm_tmp_name_add ("_I");
717 break;
718
719 case SSA_NAME:
720 case VAR_DECL:
721 case PARM_DECL:
69262824 722 case FUNCTION_DECL:
723 case LABEL_DECL:
f86b328b 724 name = get_name (ref);
725 if (!name)
726 name = "D";
727 lsm_tmp_name_add (name);
728 break;
729
730 case STRING_CST:
731 lsm_tmp_name_add ("S");
732 break;
733
734 case RESULT_DECL:
735 lsm_tmp_name_add ("R");
736 break;
737
738 case INTEGER_CST:
69262824 739 default:
f86b328b 740 /* Nothing. */
741 break;
f86b328b 742 }
743}
744
745/* Determines name for temporary variable that replaces REF.
746 The name is accumulated into the lsm_tmp_name variable.
747 N is added to the name of the temporary. */
748
749char *
750get_lsm_tmp_name (tree ref, unsigned n, const char *suffix)
751{
752 char ns[2];
753
754 lsm_tmp_name_length = 0;
755 gen_lsm_tmp_name (ref);
756 lsm_tmp_name_add ("_lsm");
757 if (n < 10)
758 {
759 ns[0] = '0' + n;
760 ns[1] = 0;
761 lsm_tmp_name_add (ns);
762 }
763 return lsm_tmp_name;
764 if (suffix != NULL)
765 lsm_tmp_name_add (suffix);
766}
767
768/* Computes an estimated number of insns in LOOP, weighted by WEIGHTS. */
769
770unsigned
771tree_num_loop_insns (struct loop *loop, eni_weights *weights)
772{
773 basic_block *body = get_loop_body (loop);
774 gimple_stmt_iterator gsi;
775 unsigned size = 0, i;
776
777 for (i = 0; i < loop->num_nodes; i++)
778 for (gsi = gsi_start_bb (body[i]); !gsi_end_p (gsi); gsi_next (&gsi))
779 size += estimate_num_insns (gsi_stmt (gsi), weights);
780 free (body);
781
782 return size;
783}
784
785
786