1 /* Loop optimizations over tree-ssa.
2    Copyright (C) 2003-2021 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 "memmodel.h"
28 #include "tm_p.h"
29 #include "fold-const.h"
30 #include "gimple-iterator.h"
31 #include "tree-ssa-loop-ivopts.h"
32 #include "tree-ssa-loop-manip.h"
33 #include "tree-ssa-loop-niter.h"
34 #include "tree-ssa-loop.h"
35 #include "cfgloop.h"
36 #include "tree-inline.h"
37 #include "tree-scalar-evolution.h"
38 #include "tree-vectorizer.h"
39 #include "omp-general.h"
40 #include "diagnostic-core.h"
41 #include "stringpool.h"
42 #include "attribs.h"
43 
44 
45 /* A pass making sure loops are fixed up.  */
46 
47 namespace {
48 
49 const pass_data pass_data_fix_loops =
50 {
51   GIMPLE_PASS, /* type */
52   "fix_loops", /* name */
53   OPTGROUP_LOOP, /* optinfo_flags */
54   TV_TREE_LOOP, /* tv_id */
55   PROP_cfg, /* properties_required */
56   0, /* properties_provided */
57   0, /* properties_destroyed */
58   0, /* todo_flags_start */
59   0, /* todo_flags_finish */
60 };
61 
62 class pass_fix_loops : public gimple_opt_pass
63 {
64 public:
pass_fix_loops(gcc::context * ctxt)65   pass_fix_loops (gcc::context *ctxt)
66     : gimple_opt_pass (pass_data_fix_loops, ctxt)
67   {}
68 
69   /* opt_pass methods: */
gate(function *)70   virtual bool gate (function *) { return flag_tree_loop_optimize; }
71 
72   virtual unsigned int execute (function *fn);
73 }; // class pass_fix_loops
74 
75 unsigned int
execute(function *)76 pass_fix_loops::execute (function *)
77 {
78   if (loops_state_satisfies_p (LOOPS_NEED_FIXUP))
79     {
80       calculate_dominance_info (CDI_DOMINATORS);
81       fix_loop_structure (NULL);
82     }
83   return 0;
84 }
85 
86 } // anon namespace
87 
88 gimple_opt_pass *
make_pass_fix_loops(gcc::context * ctxt)89 make_pass_fix_loops (gcc::context *ctxt)
90 {
91   return new pass_fix_loops (ctxt);
92 }
93 
94 
95 /* Gate for loop pass group.  The group is controlled by -ftree-loop-optimize
96    but we also avoid running it when the IL doesn't contain any loop.  */
97 
98 static bool
gate_loop(function * fn)99 gate_loop (function *fn)
100 {
101   if (!flag_tree_loop_optimize)
102     return false;
103 
104   /* For -fdump-passes which runs before loop discovery print the
105      state of -ftree-loop-optimize.  */
106   if (!loops_for_fn (fn))
107     return true;
108 
109   return number_of_loops (fn) > 1;
110 }
111 
112 /* The loop superpass.  */
113 
114 namespace {
115 
116 const pass_data pass_data_tree_loop =
117 {
118   GIMPLE_PASS, /* type */
119   "loop", /* name */
120   OPTGROUP_LOOP, /* optinfo_flags */
121   TV_TREE_LOOP, /* tv_id */
122   PROP_cfg, /* properties_required */
123   0, /* properties_provided */
124   0, /* properties_destroyed */
125   0, /* todo_flags_start */
126   0, /* todo_flags_finish */
127 };
128 
129 class pass_tree_loop : public gimple_opt_pass
130 {
131 public:
pass_tree_loop(gcc::context * ctxt)132   pass_tree_loop (gcc::context *ctxt)
133     : gimple_opt_pass (pass_data_tree_loop, ctxt)
134   {}
135 
136   /* opt_pass methods: */
gate(function * fn)137   virtual bool gate (function *fn) { return gate_loop (fn); }
138 
139 }; // class pass_tree_loop
140 
141 } // anon namespace
142 
143 gimple_opt_pass *
make_pass_tree_loop(gcc::context * ctxt)144 make_pass_tree_loop (gcc::context *ctxt)
145 {
146   return new pass_tree_loop (ctxt);
147 }
148 
149 /* Gate for oacc kernels pass group.  */
150 
151 static bool
gate_oacc_kernels(function * fn)152 gate_oacc_kernels (function *fn)
153 {
154   if (!flag_openacc)
155     return false;
156 
157   if (!lookup_attribute ("oacc kernels", DECL_ATTRIBUTES (fn->decl)))
158     return false;
159 
160   class 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   TODO_update_address_taken, /* 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   0, /* todo_flags_finish */
440 };
441 
442 class pass_scev_cprop : public gimple_opt_pass
443 {
444 public:
pass_scev_cprop(gcc::context * ctxt)445   pass_scev_cprop (gcc::context *ctxt)
446     : gimple_opt_pass (pass_data_scev_cprop, ctxt)
447   {}
448 
449   /* opt_pass methods: */
gate(function *)450   virtual bool gate (function *) { return flag_tree_scev_cprop; }
451   virtual unsigned int execute (function *);
452 
453 }; // class pass_scev_cprop
454 
455 unsigned
execute(function *)456 pass_scev_cprop::execute (function *)
457 {
458   class loop *loop;
459   bool any = false;
460 
461   /* Perform final value replacement in loops, in case the replacement
462      expressions are cheap.  */
463   FOR_EACH_LOOP (loop, LI_FROM_INNERMOST)
464     any |= final_value_replacement_loop (loop);
465 
466   return any ? TODO_cleanup_cfg | TODO_update_ssa_only_virtuals : 0;
467 }
468 
469 } // anon namespace
470 
471 gimple_opt_pass *
make_pass_scev_cprop(gcc::context * ctxt)472 make_pass_scev_cprop (gcc::context *ctxt)
473 {
474   return new pass_scev_cprop (ctxt);
475 }
476 
477 /* Induction variable optimizations.  */
478 
479 namespace {
480 
481 const pass_data pass_data_iv_optimize =
482 {
483   GIMPLE_PASS, /* type */
484   "ivopts", /* name */
485   OPTGROUP_LOOP, /* optinfo_flags */
486   TV_TREE_LOOP_IVOPTS, /* tv_id */
487   ( PROP_cfg | PROP_ssa ), /* properties_required */
488   0, /* properties_provided */
489   0, /* properties_destroyed */
490   0, /* todo_flags_start */
491   TODO_update_ssa, /* todo_flags_finish */
492 };
493 
494 class pass_iv_optimize : public gimple_opt_pass
495 {
496 public:
pass_iv_optimize(gcc::context * ctxt)497   pass_iv_optimize (gcc::context *ctxt)
498     : gimple_opt_pass (pass_data_iv_optimize, ctxt)
499   {}
500 
501   /* opt_pass methods: */
gate(function *)502   virtual bool gate (function *) { return flag_ivopts != 0; }
503   virtual unsigned int execute (function *);
504 
505 }; // class pass_iv_optimize
506 
507 unsigned int
execute(function * fun)508 pass_iv_optimize::execute (function *fun)
509 {
510   if (number_of_loops (fun) <= 1)
511     return 0;
512 
513   tree_ssa_iv_optimize ();
514   return 0;
515 }
516 
517 } // anon namespace
518 
519 gimple_opt_pass *
make_pass_iv_optimize(gcc::context * ctxt)520 make_pass_iv_optimize (gcc::context *ctxt)
521 {
522   return new pass_iv_optimize (ctxt);
523 }
524 
525 /* Loop optimizer finalization.  */
526 
527 static unsigned int
tree_ssa_loop_done(void)528 tree_ssa_loop_done (void)
529 {
530   free_numbers_of_iterations_estimates (cfun);
531   scev_finalize ();
532   loop_optimizer_finalize (cfun, true);
533   return 0;
534 }
535 
536 namespace {
537 
538 const pass_data pass_data_tree_loop_done =
539 {
540   GIMPLE_PASS, /* type */
541   "loopdone", /* name */
542   OPTGROUP_LOOP, /* optinfo_flags */
543   TV_NONE, /* tv_id */
544   PROP_cfg, /* properties_required */
545   0, /* properties_provided */
546   0, /* properties_destroyed */
547   0, /* todo_flags_start */
548   TODO_cleanup_cfg, /* todo_flags_finish */
549 };
550 
551 class pass_tree_loop_done : public gimple_opt_pass
552 {
553 public:
pass_tree_loop_done(gcc::context * ctxt)554   pass_tree_loop_done (gcc::context *ctxt)
555     : gimple_opt_pass (pass_data_tree_loop_done, ctxt)
556   {}
557 
558   /* opt_pass methods: */
execute(function *)559   virtual unsigned int execute (function *) { return tree_ssa_loop_done (); }
560 
561 }; // class pass_tree_loop_done
562 
563 } // anon namespace
564 
565 gimple_opt_pass *
make_pass_tree_loop_done(gcc::context * ctxt)566 make_pass_tree_loop_done (gcc::context *ctxt)
567 {
568   return new pass_tree_loop_done (ctxt);
569 }
570 
571 /* Calls CBCK for each index in memory reference ADDR_P.  There are two
572    kinds situations handled; in each of these cases, the memory reference
573    and DATA are passed to the callback:
574 
575    Access to an array: ARRAY_{RANGE_}REF (base, index).  In this case we also
576    pass the pointer to the index to the callback.
577 
578    Pointer dereference: INDIRECT_REF (addr).  In this case we also pass the
579    pointer to addr to the callback.
580 
581    If the callback returns false, the whole search stops and false is returned.
582    Otherwise the function returns true after traversing through the whole
583    reference *ADDR_P.  */
584 
585 bool
for_each_index(tree * addr_p,bool (* cbck)(tree,tree *,void *),void * data)586 for_each_index (tree *addr_p, bool (*cbck) (tree, tree *, void *), void *data)
587 {
588   tree *nxt, *idx;
589 
590   for (; ; addr_p = nxt)
591     {
592       switch (TREE_CODE (*addr_p))
593 	{
594 	case SSA_NAME:
595 	  return cbck (*addr_p, addr_p, data);
596 
597 	case MEM_REF:
598 	  nxt = &TREE_OPERAND (*addr_p, 0);
599 	  return cbck (*addr_p, nxt, data);
600 
601 	case BIT_FIELD_REF:
602 	case VIEW_CONVERT_EXPR:
603 	case REALPART_EXPR:
604 	case IMAGPART_EXPR:
605 	  nxt = &TREE_OPERAND (*addr_p, 0);
606 	  break;
607 
608 	case COMPONENT_REF:
609 	  /* If the component has varying offset, it behaves like index
610 	     as well.  */
611 	  idx = &TREE_OPERAND (*addr_p, 2);
612 	  if (*idx
613 	      && !cbck (*addr_p, idx, data))
614 	    return false;
615 
616 	  nxt = &TREE_OPERAND (*addr_p, 0);
617 	  break;
618 
619 	case ARRAY_REF:
620 	case ARRAY_RANGE_REF:
621 	  nxt = &TREE_OPERAND (*addr_p, 0);
622 	  if (!cbck (*addr_p, &TREE_OPERAND (*addr_p, 1), data))
623 	    return false;
624 	  break;
625 
626 	case CONSTRUCTOR:
627 	  return true;
628 
629 	case ADDR_EXPR:
630 	  gcc_assert (is_gimple_min_invariant (*addr_p));
631 	  return true;
632 
633 	case TARGET_MEM_REF:
634 	  idx = &TMR_BASE (*addr_p);
635 	  if (*idx
636 	      && !cbck (*addr_p, idx, data))
637 	    return false;
638 	  idx = &TMR_INDEX (*addr_p);
639 	  if (*idx
640 	      && !cbck (*addr_p, idx, data))
641 	    return false;
642 	  idx = &TMR_INDEX2 (*addr_p);
643 	  if (*idx
644 	      && !cbck (*addr_p, idx, data))
645 	    return false;
646 	  return true;
647 
648 	default:
649 	  if (DECL_P (*addr_p)
650 	      || CONSTANT_CLASS_P (*addr_p))
651 	    return true;
652     	  gcc_unreachable ();
653 	}
654     }
655 }
656 
657 
658 /* The name and the length of the currently generated variable
659    for lsm.  */
660 #define MAX_LSM_NAME_LENGTH 40
661 static char lsm_tmp_name[MAX_LSM_NAME_LENGTH + 1];
662 static int lsm_tmp_name_length;
663 
664 /* Adds S to lsm_tmp_name.  */
665 
666 static void
lsm_tmp_name_add(const char * s)667 lsm_tmp_name_add (const char *s)
668 {
669   int l = strlen (s) + lsm_tmp_name_length;
670   if (l > MAX_LSM_NAME_LENGTH)
671     return;
672 
673   strcpy (lsm_tmp_name + lsm_tmp_name_length, s);
674   lsm_tmp_name_length = l;
675 }
676 
677 /* Stores the name for temporary variable that replaces REF to
678    lsm_tmp_name.  */
679 
680 static void
gen_lsm_tmp_name(tree ref)681 gen_lsm_tmp_name (tree ref)
682 {
683   const char *name;
684 
685   switch (TREE_CODE (ref))
686     {
687     case MEM_REF:
688     case TARGET_MEM_REF:
689       gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
690       lsm_tmp_name_add ("_");
691       break;
692 
693     case ADDR_EXPR:
694       gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
695       break;
696 
697     case BIT_FIELD_REF:
698     case VIEW_CONVERT_EXPR:
699     case ARRAY_RANGE_REF:
700       gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
701       break;
702 
703     case REALPART_EXPR:
704       gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
705       lsm_tmp_name_add ("_RE");
706       break;
707 
708     case IMAGPART_EXPR:
709       gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
710       lsm_tmp_name_add ("_IM");
711       break;
712 
713     case COMPONENT_REF:
714       gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
715       lsm_tmp_name_add ("_");
716       name = get_name (TREE_OPERAND (ref, 1));
717       if (!name)
718 	name = "F";
719       lsm_tmp_name_add (name);
720       break;
721 
722     case ARRAY_REF:
723       gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
724       lsm_tmp_name_add ("_I");
725       break;
726 
727     case SSA_NAME:
728     case VAR_DECL:
729     case PARM_DECL:
730     case FUNCTION_DECL:
731     case LABEL_DECL:
732       name = get_name (ref);
733       if (!name)
734 	name = "D";
735       lsm_tmp_name_add (name);
736       break;
737 
738     case STRING_CST:
739       lsm_tmp_name_add ("S");
740       break;
741 
742     case RESULT_DECL:
743       lsm_tmp_name_add ("R");
744       break;
745 
746     case INTEGER_CST:
747     default:
748       /* Nothing.  */
749       break;
750     }
751 }
752 
753 /* Determines name for temporary variable that replaces REF.
754    The name is accumulated into the lsm_tmp_name variable.
755    N is added to the name of the temporary.  */
756 
757 char *
get_lsm_tmp_name(tree ref,unsigned n,const char * suffix)758 get_lsm_tmp_name (tree ref, unsigned n, const char *suffix)
759 {
760   char ns[2];
761 
762   lsm_tmp_name_length = 0;
763   gen_lsm_tmp_name (ref);
764   lsm_tmp_name_add ("_lsm");
765   if (n < 10)
766     {
767       ns[0] = '0' + n;
768       ns[1] = 0;
769       lsm_tmp_name_add (ns);
770     }
771   if (suffix != NULL)
772     lsm_tmp_name_add (suffix);
773   return lsm_tmp_name;
774 }
775 
776 /* Computes an estimated number of insns in LOOP, weighted by WEIGHTS.  */
777 
778 unsigned
tree_num_loop_insns(class loop * loop,eni_weights * weights)779 tree_num_loop_insns (class loop *loop, eni_weights *weights)
780 {
781   basic_block *body = get_loop_body (loop);
782   gimple_stmt_iterator gsi;
783   unsigned size = 0, i;
784 
785   for (i = 0; i < loop->num_nodes; i++)
786     for (gsi = gsi_start_bb (body[i]); !gsi_end_p (gsi); gsi_next (&gsi))
787       size += estimate_num_insns (gsi_stmt (gsi), weights);
788   free (body);
789 
790   return size;
791 }
792 
793 
794 
795