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