Line data Source code
1 : /* Loop optimizations over tree-ssa.
2 : Copyright (C) 2003-2026 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 "gimple-range.h"
32 : #include "tree-ssa-loop-ivopts.h"
33 : #include "tree-ssa-loop-manip.h"
34 : #include "tree-ssa-loop-niter.h"
35 : #include "tree-ssa-loop.h"
36 : #include "cfgloop.h"
37 : #include "tree-inline.h"
38 : #include "tree-scalar-evolution.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:
65 285722 : pass_fix_loops (gcc::context *ctxt)
66 571444 : : gimple_opt_pass (pass_data_fix_loops, ctxt)
67 : {}
68 :
69 : /* opt_pass methods: */
70 1041484 : bool gate (function *) final override { return flag_tree_loop_optimize; }
71 :
72 : unsigned int execute (function *fn) final override;
73 : }; // class pass_fix_loops
74 :
75 : unsigned int
76 1041416 : pass_fix_loops::execute (function *)
77 : {
78 1041416 : if (loops_state_satisfies_p (LOOPS_NEED_FIXUP))
79 : {
80 13 : calculate_dominance_info (CDI_DOMINATORS);
81 13 : fix_loop_structure (NULL);
82 : }
83 1041416 : return 0;
84 : }
85 :
86 : } // anon namespace
87 :
88 : gimple_opt_pass *
89 285722 : make_pass_fix_loops (gcc::context *ctxt)
90 : {
91 285722 : 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
99 2082968 : gate_loop (function *fn)
100 : {
101 2082968 : 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 2082896 : if (!loops_for_fn (fn))
107 : return true;
108 :
109 4165772 : 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:
132 285722 : pass_tree_loop (gcc::context *ctxt)
133 571444 : : gimple_opt_pass (pass_data_tree_loop, ctxt)
134 : {}
135 :
136 : /* opt_pass methods: */
137 1041484 : bool gate (function *fn) final override { return gate_loop (fn); }
138 :
139 : }; // class pass_tree_loop
140 :
141 : } // anon namespace
142 :
143 : gimple_opt_pass *
144 285722 : make_pass_tree_loop (gcc::context *ctxt)
145 : {
146 285722 : return new pass_tree_loop (ctxt);
147 : }
148 :
149 : /* Gate for oacc kernels pass group. */
150 :
151 : static bool
152 12014 : gate_oacc_kernels (function *fn)
153 : {
154 12014 : if (!flag_openacc)
155 : return false;
156 :
157 12009 : if (!lookup_attribute ("oacc kernels", DECL_ATTRIBUTES (fn->decl)))
158 : return false;
159 :
160 4614 : for (auto loop : loops_list (cfun, 0))
161 1858 : if (loop->in_oacc_kernels_region)
162 1033 : return true;
163 :
164 230 : return false;
165 : }
166 :
167 : /* The oacc kernels superpass. */
168 :
169 : namespace {
170 :
171 : const pass_data pass_data_oacc_kernels =
172 : {
173 : GIMPLE_PASS, /* type */
174 : "oacc_kernels", /* name */
175 : OPTGROUP_LOOP, /* optinfo_flags */
176 : TV_TREE_LOOP, /* tv_id */
177 : PROP_cfg, /* properties_required */
178 : 0, /* properties_provided */
179 : 0, /* properties_destroyed */
180 : 0, /* todo_flags_start */
181 : 0, /* todo_flags_finish */
182 : };
183 :
184 : class pass_oacc_kernels : public gimple_opt_pass
185 : {
186 : public:
187 285722 : pass_oacc_kernels (gcc::context *ctxt)
188 571444 : : gimple_opt_pass (pass_data_oacc_kernels, ctxt)
189 : {}
190 :
191 : /* opt_pass methods: */
192 12014 : bool gate (function *fn) final override { return gate_oacc_kernels (fn); }
193 :
194 : }; // class pass_oacc_kernels
195 :
196 : } // anon namespace
197 :
198 : gimple_opt_pass *
199 285722 : make_pass_oacc_kernels (gcc::context *ctxt)
200 : {
201 285722 : return new pass_oacc_kernels (ctxt);
202 : }
203 :
204 : /* The ipa oacc superpass. */
205 :
206 : namespace {
207 :
208 : const pass_data pass_data_ipa_oacc =
209 : {
210 : SIMPLE_IPA_PASS, /* type */
211 : "ipa_oacc", /* name */
212 : OPTGROUP_LOOP, /* optinfo_flags */
213 : TV_TREE_LOOP, /* tv_id */
214 : PROP_cfg, /* properties_required */
215 : 0, /* properties_provided */
216 : 0, /* properties_destroyed */
217 : 0, /* todo_flags_start */
218 : 0, /* todo_flags_finish */
219 : };
220 :
221 : class pass_ipa_oacc : public simple_ipa_opt_pass
222 : {
223 : public:
224 285722 : pass_ipa_oacc (gcc::context *ctxt)
225 571444 : : simple_ipa_opt_pass (pass_data_ipa_oacc, ctxt)
226 : {}
227 :
228 : /* opt_pass methods: */
229 229960 : bool gate (function *) final override
230 : {
231 229960 : return (optimize
232 148719 : && flag_openacc
233 : /* Don't bother doing anything if the program has errors. */
234 231986 : && !seen_error ());
235 : }
236 :
237 : }; // class pass_ipa_oacc
238 :
239 : } // anon namespace
240 :
241 : simple_ipa_opt_pass *
242 285722 : make_pass_ipa_oacc (gcc::context *ctxt)
243 : {
244 285722 : return new pass_ipa_oacc (ctxt);
245 : }
246 :
247 : /* The ipa oacc kernels pass. */
248 :
249 : namespace {
250 :
251 : const pass_data pass_data_ipa_oacc_kernels =
252 : {
253 : SIMPLE_IPA_PASS, /* type */
254 : "ipa_oacc_kernels", /* name */
255 : OPTGROUP_LOOP, /* optinfo_flags */
256 : TV_TREE_LOOP, /* tv_id */
257 : PROP_cfg, /* properties_required */
258 : 0, /* properties_provided */
259 : 0, /* properties_destroyed */
260 : 0, /* todo_flags_start */
261 : 0, /* todo_flags_finish */
262 : };
263 :
264 : class pass_ipa_oacc_kernels : public simple_ipa_opt_pass
265 : {
266 : public:
267 285722 : pass_ipa_oacc_kernels (gcc::context *ctxt)
268 571444 : : simple_ipa_opt_pass (pass_data_ipa_oacc_kernels, ctxt)
269 : {}
270 :
271 : }; // class pass_ipa_oacc_kernels
272 :
273 : } // anon namespace
274 :
275 : simple_ipa_opt_pass *
276 285722 : make_pass_ipa_oacc_kernels (gcc::context *ctxt)
277 : {
278 285722 : return new pass_ipa_oacc_kernels (ctxt);
279 : }
280 :
281 : /* The no-loop superpass. */
282 :
283 : namespace {
284 :
285 : const pass_data pass_data_tree_no_loop =
286 : {
287 : GIMPLE_PASS, /* type */
288 : "no_loop", /* name */
289 : OPTGROUP_NONE, /* optinfo_flags */
290 : TV_TREE_NOLOOP, /* tv_id */
291 : PROP_cfg, /* properties_required */
292 : 0, /* properties_provided */
293 : 0, /* properties_destroyed */
294 : 0, /* todo_flags_start */
295 : 0, /* todo_flags_finish */
296 : };
297 :
298 : class pass_tree_no_loop : public gimple_opt_pass
299 : {
300 : public:
301 285722 : pass_tree_no_loop (gcc::context *ctxt)
302 571444 : : gimple_opt_pass (pass_data_tree_no_loop, ctxt)
303 : {}
304 :
305 : /* opt_pass methods: */
306 1041484 : bool gate (function *fn) final override { return !gate_loop (fn); }
307 :
308 : }; // class pass_tree_no_loop
309 :
310 : } // anon namespace
311 :
312 : gimple_opt_pass *
313 285722 : make_pass_tree_no_loop (gcc::context *ctxt)
314 : {
315 285722 : return new pass_tree_no_loop (ctxt);
316 : }
317 :
318 :
319 : /* Loop optimizer initialization. */
320 :
321 : namespace {
322 :
323 : const pass_data pass_data_tree_loop_init =
324 : {
325 : GIMPLE_PASS, /* type */
326 : "loopinit", /* name */
327 : OPTGROUP_LOOP, /* optinfo_flags */
328 : TV_NONE, /* tv_id */
329 : PROP_cfg, /* properties_required */
330 : 0, /* properties_provided */
331 : 0, /* properties_destroyed */
332 : TODO_update_address_taken, /* todo_flags_start */
333 : 0, /* todo_flags_finish */
334 : };
335 :
336 : class pass_tree_loop_init : public gimple_opt_pass
337 : {
338 : public:
339 285722 : pass_tree_loop_init (gcc::context *ctxt)
340 571444 : : gimple_opt_pass (pass_data_tree_loop_init, ctxt)
341 : {}
342 :
343 : /* opt_pass methods: */
344 : unsigned int execute (function *) final override;
345 :
346 : }; // class pass_tree_loop_init
347 :
348 : unsigned int
349 241452 : pass_tree_loop_init::execute (function *fun ATTRIBUTE_UNUSED)
350 : {
351 : /* When processing a loop in the loop pipeline, we should be able to assert
352 : that:
353 : (loops_state_satisfies_p (LOOPS_NORMAL | LOOPS_HAVE_RECORDED_EXITS
354 : | LOOP_CLOSED_SSA)
355 : && scev_initialized_p ())
356 : */
357 241452 : loop_optimizer_init (LOOPS_NORMAL
358 : | LOOPS_HAVE_RECORDED_EXITS);
359 241452 : rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa);
360 241452 : scev_initialize ();
361 :
362 241452 : return 0;
363 : }
364 :
365 : } // anon namespace
366 :
367 : gimple_opt_pass *
368 285722 : make_pass_tree_loop_init (gcc::context *ctxt)
369 : {
370 285722 : return new pass_tree_loop_init (ctxt);
371 : }
372 :
373 : /* Propagation of constants using scev. */
374 :
375 : namespace {
376 :
377 : const pass_data pass_data_scev_cprop =
378 : {
379 : GIMPLE_PASS, /* type */
380 : "sccp", /* name */
381 : OPTGROUP_LOOP, /* optinfo_flags */
382 : TV_SCEV_CONST, /* tv_id */
383 : ( PROP_cfg | PROP_ssa ), /* properties_required */
384 : 0, /* properties_provided */
385 : 0, /* properties_destroyed */
386 : 0, /* todo_flags_start */
387 : 0, /* todo_flags_finish */
388 : };
389 :
390 : class pass_scev_cprop : public gimple_opt_pass
391 : {
392 : public:
393 285722 : pass_scev_cprop (gcc::context *ctxt)
394 571444 : : gimple_opt_pass (pass_data_scev_cprop, ctxt)
395 : {}
396 :
397 : /* opt_pass methods: */
398 241458 : bool gate (function *) final override { return flag_tree_scev_cprop; }
399 : unsigned int execute (function *) final override;
400 :
401 : }; // class pass_scev_cprop
402 :
403 : unsigned
404 241116 : pass_scev_cprop::execute (function *)
405 : {
406 241116 : bool any = false;
407 :
408 241116 : enable_ranger (cfun);
409 :
410 : /* Perform final value replacement in loops, in case the replacement
411 : expressions are cheap. */
412 1409729 : for (auto loop : loops_list (cfun, LI_FROM_INNERMOST))
413 686381 : any |= final_value_replacement_loop (loop);
414 :
415 241116 : disable_ranger (cfun);
416 :
417 241116 : return any ? TODO_cleanup_cfg | TODO_update_ssa_only_virtuals : 0;
418 : }
419 :
420 : } // anon namespace
421 :
422 : gimple_opt_pass *
423 285722 : make_pass_scev_cprop (gcc::context *ctxt)
424 : {
425 285722 : return new pass_scev_cprop (ctxt);
426 : }
427 :
428 : /* Induction variable optimizations. */
429 :
430 : namespace {
431 :
432 : const pass_data pass_data_iv_optimize =
433 : {
434 : GIMPLE_PASS, /* type */
435 : "ivopts", /* name */
436 : OPTGROUP_LOOP, /* optinfo_flags */
437 : TV_TREE_LOOP_IVOPTS, /* tv_id */
438 : ( PROP_cfg | PROP_ssa ), /* properties_required */
439 : 0, /* properties_provided */
440 : 0, /* properties_destroyed */
441 : 0, /* todo_flags_start */
442 : TODO_update_ssa, /* todo_flags_finish */
443 : };
444 :
445 : class pass_iv_optimize : public gimple_opt_pass
446 : {
447 : public:
448 285722 : pass_iv_optimize (gcc::context *ctxt)
449 571444 : : gimple_opt_pass (pass_data_iv_optimize, ctxt)
450 : {}
451 :
452 : /* opt_pass methods: */
453 241458 : bool gate (function *) final override { return flag_ivopts != 0; }
454 : unsigned int execute (function *) final override;
455 :
456 : }; // class pass_iv_optimize
457 :
458 : unsigned int
459 241428 : pass_iv_optimize::execute (function *fun)
460 : {
461 482856 : if (number_of_loops (fun) <= 1)
462 : return 0;
463 :
464 241428 : tree_ssa_iv_optimize ();
465 241428 : return 0;
466 : }
467 :
468 : } // anon namespace
469 :
470 : gimple_opt_pass *
471 285722 : make_pass_iv_optimize (gcc::context *ctxt)
472 : {
473 285722 : return new pass_iv_optimize (ctxt);
474 : }
475 :
476 : /* Loop optimizer finalization. */
477 :
478 : static unsigned int
479 241453 : tree_ssa_loop_done (void)
480 : {
481 241453 : free_numbers_of_iterations_estimates (cfun);
482 241453 : scev_finalize ();
483 241453 : loop_optimizer_finalize (cfun, true);
484 241453 : return 0;
485 : }
486 :
487 : namespace {
488 :
489 : const pass_data pass_data_tree_loop_done =
490 : {
491 : GIMPLE_PASS, /* type */
492 : "loopdone", /* name */
493 : OPTGROUP_LOOP, /* optinfo_flags */
494 : TV_NONE, /* tv_id */
495 : PROP_cfg, /* properties_required */
496 : PROP_loop_opts_done, /* properties_provided */
497 : 0, /* properties_destroyed */
498 : 0, /* todo_flags_start */
499 : TODO_cleanup_cfg, /* todo_flags_finish */
500 : };
501 :
502 : class pass_tree_loop_done : public gimple_opt_pass
503 : {
504 : public:
505 285722 : pass_tree_loop_done (gcc::context *ctxt)
506 571444 : : gimple_opt_pass (pass_data_tree_loop_done, ctxt)
507 : {}
508 :
509 : /* opt_pass methods: */
510 241453 : unsigned int execute (function *) final override
511 : {
512 241453 : return tree_ssa_loop_done ();
513 : }
514 :
515 : }; // class pass_tree_loop_done
516 :
517 : } // anon namespace
518 :
519 : gimple_opt_pass *
520 285722 : make_pass_tree_loop_done (gcc::context *ctxt)
521 : {
522 285722 : return new pass_tree_loop_done (ctxt);
523 : }
524 :
525 : /* Calls CBCK for each index in memory reference ADDR_P. There are two
526 : kinds situations handled; in each of these cases, the memory reference
527 : and DATA are passed to the callback:
528 :
529 : Access to an array: ARRAY_{RANGE_}REF (base, index). In this case we also
530 : pass the pointer to the index to the callback.
531 :
532 : Pointer dereference: INDIRECT_REF (addr). In this case we also pass the
533 : pointer to addr to the callback.
534 :
535 : If the callback returns false, the whole search stops and false is returned.
536 : Otherwise the function returns true after traversing through the whole
537 : reference *ADDR_P. */
538 :
539 : bool
540 45848400 : for_each_index (tree *addr_p, bool (*cbck) (tree, tree *, void *), void *data)
541 : {
542 83242008 : tree *nxt, *idx;
543 :
544 83242008 : for (; ; addr_p = nxt)
545 : {
546 83242008 : switch (TREE_CODE (*addr_p))
547 : {
548 1480376 : case SSA_NAME:
549 1480376 : return cbck (*addr_p, addr_p, data);
550 :
551 27610647 : case MEM_REF:
552 27610647 : nxt = &TREE_OPERAND (*addr_p, 0);
553 27610647 : return cbck (*addr_p, nxt, data);
554 :
555 2834763 : case BIT_FIELD_REF:
556 2834763 : case VIEW_CONVERT_EXPR:
557 2834763 : case REALPART_EXPR:
558 2834763 : case IMAGPART_EXPR:
559 2834763 : nxt = &TREE_OPERAND (*addr_p, 0);
560 2834763 : break;
561 :
562 23626843 : case COMPONENT_REF:
563 : /* If the component has varying offset, it behaves like index
564 : as well. */
565 23626843 : idx = &TREE_OPERAND (*addr_p, 2);
566 23626843 : if (*idx
567 23626843 : && !cbck (*addr_p, idx, data))
568 : return false;
569 :
570 23626836 : nxt = &TREE_OPERAND (*addr_p, 0);
571 23626836 : break;
572 :
573 11832833 : case ARRAY_REF:
574 11832833 : case ARRAY_RANGE_REF:
575 11832833 : nxt = &TREE_OPERAND (*addr_p, 0);
576 11832833 : if (!cbck (*addr_p, &TREE_OPERAND (*addr_p, 1), data))
577 : return false;
578 : break;
579 :
580 : case CONSTRUCTOR:
581 : return true;
582 :
583 2333 : case ADDR_EXPR:
584 2333 : gcc_assert (is_gimple_min_invariant (*addr_p));
585 : return true;
586 :
587 2103771 : case TARGET_MEM_REF:
588 2103771 : idx = &TMR_BASE (*addr_p);
589 2103771 : if (*idx
590 2103771 : && !cbck (*addr_p, idx, data))
591 : return false;
592 1702478 : idx = &TMR_INDEX (*addr_p);
593 1702478 : if (*idx
594 1702478 : && !cbck (*addr_p, idx, data))
595 : return false;
596 1507228 : idx = &TMR_INDEX2 (*addr_p);
597 1507228 : if (*idx
598 1507228 : && !cbck (*addr_p, idx, data))
599 : return false;
600 : return true;
601 :
602 13750442 : default:
603 13750442 : if (DECL_P (*addr_p)
604 610 : || CONSTANT_CLASS_P (*addr_p))
605 : return true;
606 0 : gcc_unreachable ();
607 : }
608 : }
609 : }
610 :
611 :
612 : /* The name and the length of the currently generated variable
613 : for lsm. */
614 : #define MAX_LSM_NAME_LENGTH 40
615 : static char lsm_tmp_name[MAX_LSM_NAME_LENGTH + 1];
616 : static int lsm_tmp_name_length;
617 :
618 : /* Adds S to lsm_tmp_name. */
619 :
620 : static void
621 216585 : lsm_tmp_name_add (const char *s)
622 : {
623 216585 : int l = strlen (s) + lsm_tmp_name_length;
624 216585 : if (l > MAX_LSM_NAME_LENGTH)
625 : return;
626 :
627 216388 : strcpy (lsm_tmp_name + lsm_tmp_name_length, s);
628 216388 : lsm_tmp_name_length = l;
629 : }
630 :
631 : /* Stores the name for temporary variable that replaces REF to
632 : lsm_tmp_name. */
633 :
634 : static void
635 117544 : gen_lsm_tmp_name (tree ref)
636 : {
637 127852 : const char *name;
638 :
639 127852 : switch (TREE_CODE (ref))
640 : {
641 23751 : case MEM_REF:
642 23751 : case TARGET_MEM_REF:
643 23751 : gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
644 23751 : lsm_tmp_name_add ("_");
645 23751 : break;
646 :
647 10305 : case ADDR_EXPR:
648 10305 : gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
649 10305 : break;
650 :
651 3 : case BIT_FIELD_REF:
652 3 : case VIEW_CONVERT_EXPR:
653 3 : case ARRAY_RANGE_REF:
654 3 : gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
655 3 : break;
656 :
657 141 : case REALPART_EXPR:
658 141 : gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
659 141 : lsm_tmp_name_add ("_RE");
660 141 : break;
661 :
662 120 : case IMAGPART_EXPR:
663 120 : gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
664 120 : lsm_tmp_name_add ("_IM");
665 120 : break;
666 :
667 9565 : case COMPONENT_REF:
668 9565 : gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
669 9565 : lsm_tmp_name_add ("_");
670 9565 : name = get_name (TREE_OPERAND (ref, 1));
671 9565 : if (!name)
672 91 : name = "F";
673 9565 : lsm_tmp_name_add (name);
674 9565 : break;
675 :
676 21877 : case ARRAY_REF:
677 21877 : gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
678 21877 : lsm_tmp_name_add ("_I");
679 21877 : break;
680 :
681 61988 : case SSA_NAME:
682 61988 : case VAR_DECL:
683 61988 : case PARM_DECL:
684 61988 : case FUNCTION_DECL:
685 61988 : case LABEL_DECL:
686 61988 : name = get_name (ref);
687 61988 : if (!name)
688 14599 : name = "D";
689 61988 : lsm_tmp_name_add (name);
690 61988 : break;
691 :
692 6 : case STRING_CST:
693 6 : lsm_tmp_name_add ("S");
694 6 : break;
695 :
696 92 : case RESULT_DECL:
697 92 : lsm_tmp_name_add ("R");
698 92 : break;
699 :
700 : case INTEGER_CST:
701 : default:
702 : /* Nothing. */
703 : break;
704 : }
705 117544 : }
706 :
707 : /* Determines name for temporary variable that replaces REF.
708 : The name is accumulated into the lsm_tmp_name variable.
709 : N is added to the name of the temporary. */
710 :
711 : char *
712 62090 : get_lsm_tmp_name (tree ref, unsigned n, const char *suffix)
713 : {
714 62090 : char ns[2];
715 :
716 62090 : lsm_tmp_name_length = 0;
717 62090 : gen_lsm_tmp_name (ref);
718 62090 : lsm_tmp_name_add ("_lsm");
719 62090 : if (n < 10)
720 : {
721 19778 : ns[0] = '0' + n;
722 19778 : ns[1] = 0;
723 19778 : lsm_tmp_name_add (ns);
724 : }
725 62090 : if (suffix != NULL)
726 7612 : lsm_tmp_name_add (suffix);
727 62090 : return lsm_tmp_name;
728 : }
729 :
730 : /* Computes an estimated number of insns in LOOP, weighted by WEIGHTS. */
731 :
732 : unsigned
733 1098 : tree_num_loop_insns (class loop *loop, eni_weights *weights)
734 : {
735 1098 : basic_block *body = get_loop_body (loop);
736 1098 : gimple_stmt_iterator gsi;
737 1098 : unsigned size = 0, i;
738 :
739 6006 : for (i = 0; i < loop->num_nodes; i++)
740 31162 : for (gsi = gsi_start_bb (body[i]); !gsi_end_p (gsi); gsi_next (&gsi))
741 23542 : size += estimate_num_insns (gsi_stmt (gsi), weights);
742 1098 : free (body);
743 :
744 1098 : return size;
745 : }
746 :
747 :
748 :
|