]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/tree-ssa-loop.c
Split omp-low into multiple files
[thirdparty/gcc.git] / gcc / tree-ssa-loop.c
CommitLineData
6de9cd9a 1/* Loop optimizations over tree-ssa.
818ab71a 2 Copyright (C) 2003-2016 Free Software Foundation, Inc.
b8698a0f 3
6de9cd9a 4This file is part of GCC.
b8698a0f 5
6de9cd9a
DN
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
9dcd6f09 8Free Software Foundation; either version 3, or (at your option) any
6de9cd9a 9later version.
b8698a0f 10
6de9cd9a
DN
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.
b8698a0f 15
6de9cd9a 16You should have received a copy of the GNU General Public License
9dcd6f09
NC
17along with GCC; see the file COPYING3. If not see
18<http://www.gnu.org/licenses/>. */
6de9cd9a
DN
19
20#include "config.h"
21#include "system.h"
22#include "coretypes.h"
c7131fb2 23#include "backend.h"
6de9cd9a 24#include "tree.h"
c7131fb2 25#include "gimple.h"
957060b5 26#include "tree-pass.h"
4d0cdd0c 27#include "memmodel.h"
957060b5 28#include "tm_p.h"
40e23961 29#include "fold-const.h"
5be5c238 30#include "gimple-iterator.h"
e28030cf
AM
31#include "tree-ssa-loop-ivopts.h"
32#include "tree-ssa-loop-manip.h"
33#include "tree-ssa-loop-niter.h"
442b4905 34#include "tree-ssa-loop.h"
6de9cd9a 35#include "cfgloop.h"
6de9cd9a 36#include "tree-inline.h"
79fe1b3b 37#include "tree-scalar-evolution.h"
8ed77e22 38#include "tree-vectorizer.h"
629b3d75 39#include "omp-general.h"
597a8ab9 40#include "diagnostic-core.h"
6de9cd9a 41
e5d8bd8c 42
7d39012c
RB
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
e5d8bd8c
RB
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
e5d8bd8c
RB
107 return number_of_loops (fn) > 1;
108}
109
c66b6c66
ZD
110/* The loop superpass. */
111
27a4cd48
DM
112namespace {
113
114const pass_data pass_data_tree_loop =
115{
116 GIMPLE_PASS, /* type */
117 "loop", /* name */
118 OPTGROUP_LOOP, /* optinfo_flags */
27a4cd48
DM
119 TV_TREE_LOOP, /* tv_id */
120 PROP_cfg, /* properties_required */
121 0, /* properties_provided */
122 0, /* properties_destroyed */
123 0, /* todo_flags_start */
3bea341f 124 0, /* todo_flags_finish */
c66b6c66
ZD
125};
126
27a4cd48
DM
127class pass_tree_loop : public gimple_opt_pass
128{
129public:
c3284718
RS
130 pass_tree_loop (gcc::context *ctxt)
131 : gimple_opt_pass (pass_data_tree_loop, ctxt)
27a4cd48
DM
132 {}
133
134 /* opt_pass methods: */
e5d8bd8c 135 virtual bool gate (function *fn) { return gate_loop (fn); }
27a4cd48
DM
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
896522ee
TV
147/* Gate for oacc kernels pass group. */
148
149static bool
150gate_oacc_kernels (function *fn)
151{
f99c3557 152 if (!flag_openacc)
896522ee
TV
153 return false;
154
629b3d75 155 tree oacc_function_attr = oacc_get_fn_attrib (fn->decl);
896522ee
TV
156 if (oacc_function_attr == NULL_TREE)
157 return false;
f8393eb0 158 if (!oacc_fn_attrib_kernels_p (oacc_function_attr))
896522ee
TV
159 return false;
160
161 struct loop *loop;
162 FOR_EACH_LOOP (loop, 0)
163 if (loop->in_oacc_kernels_region)
164 return true;
165
166 return false;
167}
168
169/* The oacc kernels superpass. */
170
171namespace {
172
173const pass_data pass_data_oacc_kernels =
174{
175 GIMPLE_PASS, /* type */
176 "oacc_kernels", /* name */
177 OPTGROUP_LOOP, /* optinfo_flags */
178 TV_TREE_LOOP, /* tv_id */
179 PROP_cfg, /* properties_required */
180 0, /* properties_provided */
181 0, /* properties_destroyed */
182 0, /* todo_flags_start */
183 0, /* todo_flags_finish */
184};
185
186class pass_oacc_kernels : public gimple_opt_pass
187{
188public:
189 pass_oacc_kernels (gcc::context *ctxt)
190 : gimple_opt_pass (pass_data_oacc_kernels, ctxt)
191 {}
192
193 /* opt_pass methods: */
194 virtual bool gate (function *fn) { return gate_oacc_kernels (fn); }
195
196}; // class pass_oacc_kernels
197
198} // anon namespace
199
200gimple_opt_pass *
201make_pass_oacc_kernels (gcc::context *ctxt)
202{
203 return new pass_oacc_kernels (ctxt);
204}
205
597a8ab9
TV
206/* The ipa oacc superpass. */
207
896522ee
TV
208namespace {
209
597a8ab9 210const pass_data pass_data_ipa_oacc =
896522ee 211{
597a8ab9
TV
212 SIMPLE_IPA_PASS, /* type */
213 "ipa_oacc", /* name */
896522ee
TV
214 OPTGROUP_LOOP, /* optinfo_flags */
215 TV_TREE_LOOP, /* tv_id */
216 PROP_cfg, /* properties_required */
217 0, /* properties_provided */
218 0, /* properties_destroyed */
219 0, /* todo_flags_start */
220 0, /* todo_flags_finish */
221};
222
597a8ab9 223class pass_ipa_oacc : public simple_ipa_opt_pass
896522ee
TV
224{
225public:
597a8ab9
TV
226 pass_ipa_oacc (gcc::context *ctxt)
227 : simple_ipa_opt_pass (pass_data_ipa_oacc, ctxt)
896522ee
TV
228 {}
229
230 /* opt_pass methods: */
597a8ab9
TV
231 virtual bool gate (function *)
232 {
233 return (optimize
597a8ab9 234 && flag_openacc
f99c3557
TS
235 /* Don't bother doing anything if the program has errors. */
236 && !seen_error ());
597a8ab9 237 }
896522ee 238
597a8ab9 239}; // class pass_ipa_oacc
896522ee
TV
240
241} // anon namespace
242
597a8ab9
TV
243simple_ipa_opt_pass *
244make_pass_ipa_oacc (gcc::context *ctxt)
245{
246 return new pass_ipa_oacc (ctxt);
247}
248
249/* The ipa oacc kernels pass. */
250
251namespace {
252
253const pass_data pass_data_ipa_oacc_kernels =
254{
255 SIMPLE_IPA_PASS, /* type */
256 "ipa_oacc_kernels", /* name */
257 OPTGROUP_LOOP, /* optinfo_flags */
258 TV_TREE_LOOP, /* tv_id */
259 PROP_cfg, /* properties_required */
260 0, /* properties_provided */
261 0, /* properties_destroyed */
262 0, /* todo_flags_start */
263 0, /* todo_flags_finish */
264};
265
266class pass_ipa_oacc_kernels : public simple_ipa_opt_pass
267{
268public:
269 pass_ipa_oacc_kernels (gcc::context *ctxt)
270 : simple_ipa_opt_pass (pass_data_ipa_oacc_kernels, ctxt)
271 {}
272
273}; // class pass_ipa_oacc_kernels
274
275} // anon namespace
276
277simple_ipa_opt_pass *
278make_pass_ipa_oacc_kernels (gcc::context *ctxt)
896522ee 279{
597a8ab9 280 return new pass_ipa_oacc_kernels (ctxt);
896522ee
TV
281}
282
e5d8bd8c
RB
283/* The no-loop superpass. */
284
285namespace {
286
287const pass_data pass_data_tree_no_loop =
288{
289 GIMPLE_PASS, /* type */
290 "no_loop", /* name */
291 OPTGROUP_NONE, /* optinfo_flags */
e5d8bd8c
RB
292 TV_TREE_NOLOOP, /* tv_id */
293 PROP_cfg, /* properties_required */
294 0, /* properties_provided */
295 0, /* properties_destroyed */
296 0, /* todo_flags_start */
297 0, /* todo_flags_finish */
298};
299
300class pass_tree_no_loop : public gimple_opt_pass
301{
302public:
303 pass_tree_no_loop (gcc::context *ctxt)
304 : gimple_opt_pass (pass_data_tree_no_loop, ctxt)
305 {}
306
307 /* opt_pass methods: */
308 virtual bool gate (function *fn) { return !gate_loop (fn); }
309
310}; // class pass_tree_no_loop
311
312} // anon namespace
313
314gimple_opt_pass *
315make_pass_tree_no_loop (gcc::context *ctxt)
316{
317 return new pass_tree_no_loop (ctxt);
318}
319
320
c66b6c66
ZD
321/* Loop optimizer initialization. */
322
27a4cd48
DM
323namespace {
324
325const pass_data pass_data_tree_loop_init =
326{
327 GIMPLE_PASS, /* type */
328 "loopinit", /* name */
329 OPTGROUP_LOOP, /* optinfo_flags */
27a4cd48
DM
330 TV_NONE, /* tv_id */
331 PROP_cfg, /* properties_required */
332 0, /* properties_provided */
333 0, /* properties_destroyed */
334 0, /* todo_flags_start */
335 0, /* todo_flags_finish */
c66b6c66
ZD
336};
337
27a4cd48
DM
338class pass_tree_loop_init : public gimple_opt_pass
339{
340public:
c3284718
RS
341 pass_tree_loop_init (gcc::context *ctxt)
342 : gimple_opt_pass (pass_data_tree_loop_init, ctxt)
27a4cd48
DM
343 {}
344
345 /* opt_pass methods: */
be55bfe6 346 virtual unsigned int execute (function *);
27a4cd48
DM
347
348}; // class pass_tree_loop_init
349
be55bfe6 350unsigned int
3e455386 351pass_tree_loop_init::execute (function *fun ATTRIBUTE_UNUSED)
be55bfe6 352{
33c6daf4
TV
353 /* When processing a loop in the loop pipeline, we should be able to assert
354 that:
355 (loops_state_satisfies_p (LOOPS_NORMAL | LOOPS_HAVE_RECORDED_EXITS
356 | LOOP_CLOSED_SSA)
357 && scev_initialized_p ())
358 */
be55bfe6
TS
359 loop_optimizer_init (LOOPS_NORMAL
360 | LOOPS_HAVE_RECORDED_EXITS);
361 rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa);
be55bfe6
TS
362 scev_initialize ();
363
be55bfe6
TS
364 return 0;
365}
366
27a4cd48
DM
367} // anon namespace
368
369gimple_opt_pass *
370make_pass_tree_loop_init (gcc::context *ctxt)
371{
372 return new pass_tree_loop_init (ctxt);
373}
374
79fe1b3b
DN
375/* Loop autovectorization. */
376
27a4cd48
DM
377namespace {
378
379const pass_data pass_data_vectorize =
380{
381 GIMPLE_PASS, /* type */
382 "vect", /* name */
383 OPTGROUP_LOOP | OPTGROUP_VEC, /* optinfo_flags */
27a4cd48
DM
384 TV_TREE_VECTORIZATION, /* tv_id */
385 ( PROP_cfg | PROP_ssa ), /* properties_required */
386 0, /* properties_provided */
387 0, /* properties_destroyed */
388 0, /* todo_flags_start */
389 0, /* todo_flags_finish */
79fe1b3b
DN
390};
391
27a4cd48
DM
392class pass_vectorize : public gimple_opt_pass
393{
394public:
c3284718
RS
395 pass_vectorize (gcc::context *ctxt)
396 : gimple_opt_pass (pass_data_vectorize, ctxt)
27a4cd48
DM
397 {}
398
399 /* opt_pass methods: */
1a3d085c
TS
400 virtual bool gate (function *fun)
401 {
402 return flag_tree_loop_vectorize || fun->has_force_vectorize_loops;
403 }
404
be55bfe6 405 virtual unsigned int execute (function *);
27a4cd48
DM
406
407}; // class pass_vectorize
408
be55bfe6
TS
409unsigned int
410pass_vectorize::execute (function *fun)
411{
412 if (number_of_loops (fun) <= 1)
413 return 0;
414
415 return vectorize_loops ();
416}
417
27a4cd48
DM
418} // anon namespace
419
420gimple_opt_pass *
421make_pass_vectorize (gcc::context *ctxt)
422{
423 return new pass_vectorize (ctxt);
424}
425
684aaf29
ZD
426/* Propagation of constants using scev. */
427
27a4cd48
DM
428namespace {
429
430const pass_data pass_data_scev_cprop =
431{
432 GIMPLE_PASS, /* type */
433 "sccp", /* name */
434 OPTGROUP_LOOP, /* optinfo_flags */
27a4cd48
DM
435 TV_SCEV_CONST, /* tv_id */
436 ( PROP_cfg | PROP_ssa ), /* properties_required */
437 0, /* properties_provided */
438 0, /* properties_destroyed */
439 0, /* todo_flags_start */
440 ( TODO_cleanup_cfg
441 | TODO_update_ssa_only_virtuals ), /* todo_flags_finish */
b7eae7b8
ZD
442};
443
27a4cd48
DM
444class pass_scev_cprop : public gimple_opt_pass
445{
446public:
c3284718
RS
447 pass_scev_cprop (gcc::context *ctxt)
448 : gimple_opt_pass (pass_data_scev_cprop, ctxt)
27a4cd48
DM
449 {}
450
451 /* opt_pass methods: */
1a3d085c 452 virtual bool gate (function *) { return flag_tree_scev_cprop; }
be55bfe6 453 virtual unsigned int execute (function *) { return scev_const_prop (); }
27a4cd48
DM
454
455}; // class pass_scev_cprop
456
457} // anon namespace
458
459gimple_opt_pass *
460make_pass_scev_cprop (gcc::context *ctxt)
461{
462 return new pass_scev_cprop (ctxt);
463}
464
f3cd574f
ZD
465/* Record bounds on numbers of iterations of loops. */
466
27a4cd48
DM
467namespace {
468
469const pass_data pass_data_record_bounds =
470{
471 GIMPLE_PASS, /* type */
472 "*record_bounds", /* name */
473 OPTGROUP_NONE, /* optinfo_flags */
27a4cd48
DM
474 TV_TREE_LOOP_BOUNDS, /* tv_id */
475 ( PROP_cfg | PROP_ssa ), /* properties_required */
476 0, /* properties_provided */
477 0, /* properties_destroyed */
478 0, /* todo_flags_start */
479 0, /* todo_flags_finish */
f3cd574f
ZD
480};
481
27a4cd48
DM
482class pass_record_bounds : public gimple_opt_pass
483{
484public:
c3284718
RS
485 pass_record_bounds (gcc::context *ctxt)
486 : gimple_opt_pass (pass_data_record_bounds, ctxt)
27a4cd48
DM
487 {}
488
489 /* opt_pass methods: */
be55bfe6 490 virtual unsigned int execute (function *);
27a4cd48
DM
491
492}; // class pass_record_bounds
493
be55bfe6
TS
494unsigned int
495pass_record_bounds::execute (function *fun)
496{
497 if (number_of_loops (fun) <= 1)
498 return 0;
499
500 estimate_numbers_of_iterations ();
501 scev_reset ();
502 return 0;
503}
504
27a4cd48
DM
505} // anon namespace
506
507gimple_opt_pass *
508make_pass_record_bounds (gcc::context *ctxt)
509{
510 return new pass_record_bounds (ctxt);
511}
512
8b11a64c
ZD
513/* Induction variable optimizations. */
514
27a4cd48
DM
515namespace {
516
517const pass_data pass_data_iv_optimize =
518{
519 GIMPLE_PASS, /* type */
520 "ivopts", /* name */
521 OPTGROUP_LOOP, /* optinfo_flags */
27a4cd48
DM
522 TV_TREE_LOOP_IVOPTS, /* tv_id */
523 ( PROP_cfg | PROP_ssa ), /* properties_required */
524 0, /* properties_provided */
525 0, /* properties_destroyed */
526 0, /* todo_flags_start */
527 TODO_update_ssa, /* todo_flags_finish */
82b85a85
ZD
528};
529
27a4cd48
DM
530class pass_iv_optimize : public gimple_opt_pass
531{
532public:
c3284718
RS
533 pass_iv_optimize (gcc::context *ctxt)
534 : gimple_opt_pass (pass_data_iv_optimize, ctxt)
27a4cd48
DM
535 {}
536
537 /* opt_pass methods: */
1a3d085c 538 virtual bool gate (function *) { return flag_ivopts != 0; }
be55bfe6 539 virtual unsigned int execute (function *);
27a4cd48
DM
540
541}; // class pass_iv_optimize
542
be55bfe6
TS
543unsigned int
544pass_iv_optimize::execute (function *fun)
545{
546 if (number_of_loops (fun) <= 1)
547 return 0;
548
549 tree_ssa_iv_optimize ();
550 return 0;
551}
552
27a4cd48
DM
553} // anon namespace
554
555gimple_opt_pass *
556make_pass_iv_optimize (gcc::context *ctxt)
557{
558 return new pass_iv_optimize (ctxt);
559}
560
c66b6c66
ZD
561/* Loop optimizer finalization. */
562
c2924966 563static unsigned int
c66b6c66
ZD
564tree_ssa_loop_done (void)
565{
61183076 566 free_numbers_of_iterations_estimates (cfun);
82b85a85 567 scev_finalize ();
598ec7bd 568 loop_optimizer_finalize ();
c2924966 569 return 0;
c66b6c66 570}
b8698a0f 571
27a4cd48
DM
572namespace {
573
574const pass_data pass_data_tree_loop_done =
575{
576 GIMPLE_PASS, /* type */
577 "loopdone", /* name */
578 OPTGROUP_LOOP, /* optinfo_flags */
27a4cd48
DM
579 TV_NONE, /* tv_id */
580 PROP_cfg, /* properties_required */
581 0, /* properties_provided */
582 0, /* properties_destroyed */
583 0, /* todo_flags_start */
3bea341f 584 TODO_cleanup_cfg, /* todo_flags_finish */
c66b6c66 585};
27a4cd48
DM
586
587class pass_tree_loop_done : public gimple_opt_pass
588{
589public:
c3284718
RS
590 pass_tree_loop_done (gcc::context *ctxt)
591 : gimple_opt_pass (pass_data_tree_loop_done, ctxt)
27a4cd48
DM
592 {}
593
594 /* opt_pass methods: */
be55bfe6 595 virtual unsigned int execute (function *) { return tree_ssa_loop_done (); }
27a4cd48
DM
596
597}; // class pass_tree_loop_done
598
599} // anon namespace
600
601gimple_opt_pass *
602make_pass_tree_loop_done (gcc::context *ctxt)
603{
604 return new pass_tree_loop_done (ctxt);
605}
71343877
AM
606
607/* Calls CBCK for each index in memory reference ADDR_P. There are two
608 kinds situations handled; in each of these cases, the memory reference
609 and DATA are passed to the callback:
610
611 Access to an array: ARRAY_{RANGE_}REF (base, index). In this case we also
612 pass the pointer to the index to the callback.
613
614 Pointer dereference: INDIRECT_REF (addr). In this case we also pass the
615 pointer to addr to the callback.
616
617 If the callback returns false, the whole search stops and false is returned.
618 Otherwise the function returns true after traversing through the whole
619 reference *ADDR_P. */
620
621bool
622for_each_index (tree *addr_p, bool (*cbck) (tree, tree *, void *), void *data)
623{
624 tree *nxt, *idx;
625
626 for (; ; addr_p = nxt)
627 {
628 switch (TREE_CODE (*addr_p))
629 {
630 case SSA_NAME:
631 return cbck (*addr_p, addr_p, data);
632
633 case MEM_REF:
634 nxt = &TREE_OPERAND (*addr_p, 0);
635 return cbck (*addr_p, nxt, data);
636
637 case BIT_FIELD_REF:
638 case VIEW_CONVERT_EXPR:
639 case REALPART_EXPR:
640 case IMAGPART_EXPR:
641 nxt = &TREE_OPERAND (*addr_p, 0);
642 break;
643
644 case COMPONENT_REF:
645 /* If the component has varying offset, it behaves like index
646 as well. */
647 idx = &TREE_OPERAND (*addr_p, 2);
648 if (*idx
649 && !cbck (*addr_p, idx, data))
650 return false;
651
652 nxt = &TREE_OPERAND (*addr_p, 0);
653 break;
654
655 case ARRAY_REF:
656 case ARRAY_RANGE_REF:
657 nxt = &TREE_OPERAND (*addr_p, 0);
658 if (!cbck (*addr_p, &TREE_OPERAND (*addr_p, 1), data))
659 return false;
660 break;
661
662 case VAR_DECL:
663 case PARM_DECL:
664 case CONST_DECL:
665 case STRING_CST:
666 case RESULT_DECL:
667 case VECTOR_CST:
668 case COMPLEX_CST:
669 case INTEGER_CST:
670 case REAL_CST:
671 case FIXED_CST:
672 case CONSTRUCTOR:
673 return true;
674
675 case ADDR_EXPR:
676 gcc_assert (is_gimple_min_invariant (*addr_p));
677 return true;
678
679 case TARGET_MEM_REF:
680 idx = &TMR_BASE (*addr_p);
681 if (*idx
682 && !cbck (*addr_p, idx, data))
683 return false;
684 idx = &TMR_INDEX (*addr_p);
685 if (*idx
686 && !cbck (*addr_p, idx, data))
687 return false;
688 idx = &TMR_INDEX2 (*addr_p);
689 if (*idx
690 && !cbck (*addr_p, idx, data))
691 return false;
692 return true;
693
694 default:
695 gcc_unreachable ();
696 }
697 }
698}
699
700
701/* The name and the length of the currently generated variable
702 for lsm. */
703#define MAX_LSM_NAME_LENGTH 40
704static char lsm_tmp_name[MAX_LSM_NAME_LENGTH + 1];
705static int lsm_tmp_name_length;
706
707/* Adds S to lsm_tmp_name. */
708
709static void
710lsm_tmp_name_add (const char *s)
711{
712 int l = strlen (s) + lsm_tmp_name_length;
713 if (l > MAX_LSM_NAME_LENGTH)
714 return;
715
716 strcpy (lsm_tmp_name + lsm_tmp_name_length, s);
717 lsm_tmp_name_length = l;
718}
719
720/* Stores the name for temporary variable that replaces REF to
721 lsm_tmp_name. */
722
723static void
724gen_lsm_tmp_name (tree ref)
725{
726 const char *name;
727
728 switch (TREE_CODE (ref))
729 {
730 case MEM_REF:
731 case TARGET_MEM_REF:
732 gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
733 lsm_tmp_name_add ("_");
734 break;
735
736 case ADDR_EXPR:
737 gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
738 break;
739
740 case BIT_FIELD_REF:
741 case VIEW_CONVERT_EXPR:
742 case ARRAY_RANGE_REF:
743 gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
744 break;
745
746 case REALPART_EXPR:
747 gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
748 lsm_tmp_name_add ("_RE");
749 break;
750
751 case IMAGPART_EXPR:
752 gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
753 lsm_tmp_name_add ("_IM");
754 break;
755
756 case COMPONENT_REF:
757 gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
758 lsm_tmp_name_add ("_");
759 name = get_name (TREE_OPERAND (ref, 1));
760 if (!name)
761 name = "F";
762 lsm_tmp_name_add (name);
763 break;
764
765 case ARRAY_REF:
766 gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
767 lsm_tmp_name_add ("_I");
768 break;
769
770 case SSA_NAME:
771 case VAR_DECL:
772 case PARM_DECL:
02d472a2
JJ
773 case FUNCTION_DECL:
774 case LABEL_DECL:
71343877
AM
775 name = get_name (ref);
776 if (!name)
777 name = "D";
778 lsm_tmp_name_add (name);
779 break;
780
781 case STRING_CST:
782 lsm_tmp_name_add ("S");
783 break;
784
785 case RESULT_DECL:
786 lsm_tmp_name_add ("R");
787 break;
788
789 case INTEGER_CST:
02d472a2 790 default:
71343877
AM
791 /* Nothing. */
792 break;
71343877
AM
793 }
794}
795
796/* Determines name for temporary variable that replaces REF.
797 The name is accumulated into the lsm_tmp_name variable.
798 N is added to the name of the temporary. */
799
800char *
801get_lsm_tmp_name (tree ref, unsigned n, const char *suffix)
802{
803 char ns[2];
804
805 lsm_tmp_name_length = 0;
806 gen_lsm_tmp_name (ref);
807 lsm_tmp_name_add ("_lsm");
808 if (n < 10)
809 {
810 ns[0] = '0' + n;
811 ns[1] = 0;
812 lsm_tmp_name_add (ns);
813 }
814 return lsm_tmp_name;
815 if (suffix != NULL)
816 lsm_tmp_name_add (suffix);
817}
818
819/* Computes an estimated number of insns in LOOP, weighted by WEIGHTS. */
820
821unsigned
822tree_num_loop_insns (struct loop *loop, eni_weights *weights)
823{
824 basic_block *body = get_loop_body (loop);
825 gimple_stmt_iterator gsi;
826 unsigned size = 0, i;
827
828 for (i = 0; i < loop->num_nodes; i++)
829 for (gsi = gsi_start_bb (body[i]); !gsi_end_p (gsi); gsi_next (&gsi))
830 size += estimate_num_insns (gsi_stmt (gsi), weights);
831 free (body);
832
833 return size;
834}
835
836
837