Branch data Line data Source code
1 : : /* Loop optimizations over tree-ssa.
2 : : Copyright (C) 2003-2025 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 : 289302 : pass_fix_loops (gcc::context *ctxt)
66 : 578604 : : gimple_opt_pass (pass_data_fix_loops, ctxt)
67 : : {}
68 : :
69 : : /* opt_pass methods: */
70 : 1041410 : 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 : 1041344 : pass_fix_loops::execute (function *)
77 : : {
78 : 1041344 : if (loops_state_satisfies_p (LOOPS_NEED_FIXUP))
79 : : {
80 : 13 : calculate_dominance_info (CDI_DOMINATORS);
81 : 13 : fix_loop_structure (NULL);
82 : : }
83 : 1041344 : return 0;
84 : : }
85 : :
86 : : } // anon namespace
87 : :
88 : : gimple_opt_pass *
89 : 289302 : make_pass_fix_loops (gcc::context *ctxt)
90 : : {
91 : 289302 : 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 : 2082820 : gate_loop (function *fn)
100 : : {
101 : 2082820 : 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 : 2082748 : if (!loops_for_fn (fn))
107 : : return true;
108 : :
109 : 4165476 : 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 : 289302 : pass_tree_loop (gcc::context *ctxt)
133 : 578604 : : gimple_opt_pass (pass_data_tree_loop, ctxt)
134 : : {}
135 : :
136 : : /* opt_pass methods: */
137 : 1041410 : 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 : 289302 : make_pass_tree_loop (gcc::context *ctxt)
145 : : {
146 : 289302 : return new pass_tree_loop (ctxt);
147 : : }
148 : :
149 : : /* Gate for oacc kernels pass group. */
150 : :
151 : : static bool
152 : 11842 : gate_oacc_kernels (function *fn)
153 : : {
154 : 11842 : if (!flag_openacc)
155 : : return false;
156 : :
157 : 11837 : 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 : 289302 : pass_oacc_kernels (gcc::context *ctxt)
188 : 578604 : : gimple_opt_pass (pass_data_oacc_kernels, ctxt)
189 : : {}
190 : :
191 : : /* opt_pass methods: */
192 : 11842 : 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 : 289302 : make_pass_oacc_kernels (gcc::context *ctxt)
200 : : {
201 : 289302 : 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 : 289302 : pass_ipa_oacc (gcc::context *ctxt)
225 : 578604 : : simple_ipa_opt_pass (pass_data_ipa_oacc, ctxt)
226 : : {}
227 : :
228 : : /* opt_pass methods: */
229 : 231591 : bool gate (function *) final override
230 : : {
231 : 231591 : return (optimize
232 : 148286 : && flag_openacc
233 : : /* Don't bother doing anything if the program has errors. */
234 : 233617 : && !seen_error ());
235 : : }
236 : :
237 : : }; // class pass_ipa_oacc
238 : :
239 : : } // anon namespace
240 : :
241 : : simple_ipa_opt_pass *
242 : 289302 : make_pass_ipa_oacc (gcc::context *ctxt)
243 : : {
244 : 289302 : 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 : 289302 : pass_ipa_oacc_kernels (gcc::context *ctxt)
268 : 578604 : : 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 : 289302 : make_pass_ipa_oacc_kernels (gcc::context *ctxt)
277 : : {
278 : 289302 : 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 : 289302 : pass_tree_no_loop (gcc::context *ctxt)
302 : 578604 : : gimple_opt_pass (pass_data_tree_no_loop, ctxt)
303 : : {}
304 : :
305 : : /* opt_pass methods: */
306 : 1041410 : 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 : 289302 : make_pass_tree_no_loop (gcc::context *ctxt)
314 : : {
315 : 289302 : 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 : 289302 : pass_tree_loop_init (gcc::context *ctxt)
340 : 578604 : : 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 : 242651 : 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 : 242651 : loop_optimizer_init (LOOPS_NORMAL
358 : : | LOOPS_HAVE_RECORDED_EXITS);
359 : 242651 : rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa);
360 : 242651 : scev_initialize ();
361 : :
362 : 242651 : return 0;
363 : : }
364 : :
365 : : } // anon namespace
366 : :
367 : : gimple_opt_pass *
368 : 289302 : make_pass_tree_loop_init (gcc::context *ctxt)
369 : : {
370 : 289302 : 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 : 289302 : pass_scev_cprop (gcc::context *ctxt)
394 : 578604 : : gimple_opt_pass (pass_data_scev_cprop, ctxt)
395 : : {}
396 : :
397 : : /* opt_pass methods: */
398 : 242657 : 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 : 242459 : pass_scev_cprop::execute (function *)
405 : : {
406 : 242459 : bool any = false;
407 : :
408 : 242459 : enable_ranger (cfun);
409 : :
410 : : /* Perform final value replacement in loops, in case the replacement
411 : : expressions are cheap. */
412 : 1424381 : for (auto loop : loops_list (cfun, LI_FROM_INNERMOST))
413 : 697004 : any |= final_value_replacement_loop (loop);
414 : :
415 : 242459 : disable_ranger (cfun);
416 : :
417 : 242459 : return any ? TODO_cleanup_cfg | TODO_update_ssa_only_virtuals : 0;
418 : : }
419 : :
420 : : } // anon namespace
421 : :
422 : : gimple_opt_pass *
423 : 289302 : make_pass_scev_cprop (gcc::context *ctxt)
424 : : {
425 : 289302 : 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 : 289302 : pass_iv_optimize (gcc::context *ctxt)
449 : 578604 : : gimple_opt_pass (pass_data_iv_optimize, ctxt)
450 : : {}
451 : :
452 : : /* opt_pass methods: */
453 : 242657 : 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 : 242627 : pass_iv_optimize::execute (function *fun)
460 : : {
461 : 485254 : if (number_of_loops (fun) <= 1)
462 : : return 0;
463 : :
464 : 242627 : tree_ssa_iv_optimize ();
465 : 242627 : return 0;
466 : : }
467 : :
468 : : } // anon namespace
469 : :
470 : : gimple_opt_pass *
471 : 289302 : make_pass_iv_optimize (gcc::context *ctxt)
472 : : {
473 : 289302 : return new pass_iv_optimize (ctxt);
474 : : }
475 : :
476 : : /* Loop optimizer finalization. */
477 : :
478 : : static unsigned int
479 : 242652 : tree_ssa_loop_done (void)
480 : : {
481 : 242652 : free_numbers_of_iterations_estimates (cfun);
482 : 242652 : scev_finalize ();
483 : 242652 : loop_optimizer_finalize (cfun, true);
484 : 242652 : 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 : 289302 : pass_tree_loop_done (gcc::context *ctxt)
506 : 578604 : : gimple_opt_pass (pass_data_tree_loop_done, ctxt)
507 : : {}
508 : :
509 : : /* opt_pass methods: */
510 : 242652 : unsigned int execute (function *) final override
511 : : {
512 : 242652 : return tree_ssa_loop_done ();
513 : : }
514 : :
515 : : }; // class pass_tree_loop_done
516 : :
517 : : } // anon namespace
518 : :
519 : : gimple_opt_pass *
520 : 289302 : make_pass_tree_loop_done (gcc::context *ctxt)
521 : : {
522 : 289302 : 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 : 45972036 : for_each_index (tree *addr_p, bool (*cbck) (tree, tree *, void *), void *data)
541 : : {
542 : 82806754 : tree *nxt, *idx;
543 : :
544 : 82806754 : for (; ; addr_p = nxt)
545 : : {
546 : 82806754 : switch (TREE_CODE (*addr_p))
547 : : {
548 : 1498280 : case SSA_NAME:
549 : 1498280 : return cbck (*addr_p, addr_p, data);
550 : :
551 : 27562745 : case MEM_REF:
552 : 27562745 : nxt = &TREE_OPERAND (*addr_p, 0);
553 : 27562745 : return cbck (*addr_p, nxt, data);
554 : :
555 : 2867749 : case BIT_FIELD_REF:
556 : 2867749 : case VIEW_CONVERT_EXPR:
557 : 2867749 : case REALPART_EXPR:
558 : 2867749 : case IMAGPART_EXPR:
559 : 2867749 : nxt = &TREE_OPERAND (*addr_p, 0);
560 : 2867749 : break;
561 : :
562 : 23194711 : case COMPONENT_REF:
563 : : /* If the component has varying offset, it behaves like index
564 : : as well. */
565 : 23194711 : idx = &TREE_OPERAND (*addr_p, 2);
566 : 23194711 : if (*idx
567 : 23194711 : && !cbck (*addr_p, idx, data))
568 : : return false;
569 : :
570 : 23194704 : nxt = &TREE_OPERAND (*addr_p, 0);
571 : 23194704 : break;
572 : :
573 : 11671349 : case ARRAY_REF:
574 : 11671349 : case ARRAY_RANGE_REF:
575 : 11671349 : nxt = &TREE_OPERAND (*addr_p, 0);
576 : 11671349 : if (!cbck (*addr_p, &TREE_OPERAND (*addr_p, 1), data))
577 : : return false;
578 : : break;
579 : :
580 : : case CONSTRUCTOR:
581 : : return true;
582 : :
583 : 3360 : case ADDR_EXPR:
584 : 3360 : gcc_assert (is_gimple_min_invariant (*addr_p));
585 : : return true;
586 : :
587 : 2111633 : case TARGET_MEM_REF:
588 : 2111633 : idx = &TMR_BASE (*addr_p);
589 : 2111633 : if (*idx
590 : 2111633 : && !cbck (*addr_p, idx, data))
591 : : return false;
592 : 1709847 : idx = &TMR_INDEX (*addr_p);
593 : 1709847 : if (*idx
594 : 1709847 : && !cbck (*addr_p, idx, data))
595 : : return false;
596 : 1512741 : idx = &TMR_INDEX2 (*addr_p);
597 : 1512741 : if (*idx
598 : 1512741 : && !cbck (*addr_p, idx, data))
599 : : return false;
600 : : return true;
601 : :
602 : 13896927 : default:
603 : 13896927 : if (DECL_P (*addr_p)
604 : 934 : || 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 : 219909 : lsm_tmp_name_add (const char *s)
622 : : {
623 : 219909 : int l = strlen (s) + lsm_tmp_name_length;
624 : 219909 : if (l > MAX_LSM_NAME_LENGTH)
625 : : return;
626 : :
627 : 219729 : strcpy (lsm_tmp_name + lsm_tmp_name_length, s);
628 : 219729 : 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 : 119562 : gen_lsm_tmp_name (tree ref)
636 : : {
637 : 129900 : const char *name;
638 : :
639 : 129900 : switch (TREE_CODE (ref))
640 : : {
641 : 23251 : case MEM_REF:
642 : 23251 : case TARGET_MEM_REF:
643 : 23251 : gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
644 : 23251 : lsm_tmp_name_add ("_");
645 : 23251 : break;
646 : :
647 : 10335 : case ADDR_EXPR:
648 : 10335 : gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
649 : 10335 : 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 : 9985 : case COMPONENT_REF:
668 : 9985 : gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
669 : 9985 : lsm_tmp_name_add ("_");
670 : 9985 : name = get_name (TREE_OPERAND (ref, 1));
671 : 9985 : if (!name)
672 : 102 : name = "F";
673 : 9985 : lsm_tmp_name_add (name);
674 : 9985 : break;
675 : :
676 : 22902 : case ARRAY_REF:
677 : 22902 : gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
678 : 22902 : lsm_tmp_name_add ("_I");
679 : 22902 : break;
680 : :
681 : 63061 : case SSA_NAME:
682 : 63061 : case VAR_DECL:
683 : 63061 : case PARM_DECL:
684 : 63061 : case FUNCTION_DECL:
685 : 63061 : case LABEL_DECL:
686 : 63061 : name = get_name (ref);
687 : 63061 : if (!name)
688 : 14613 : name = "D";
689 : 63061 : lsm_tmp_name_add (name);
690 : 63061 : 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 : 119562 : }
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 : 63163 : get_lsm_tmp_name (tree ref, unsigned n, const char *suffix)
713 : : {
714 : 63163 : char ns[2];
715 : :
716 : 63163 : lsm_tmp_name_length = 0;
717 : 63163 : gen_lsm_tmp_name (ref);
718 : 63163 : lsm_tmp_name_add ("_lsm");
719 : 63163 : if (n < 10)
720 : : {
721 : 19156 : ns[0] = '0' + n;
722 : 19156 : ns[1] = 0;
723 : 19156 : lsm_tmp_name_add (ns);
724 : : }
725 : 63163 : if (suffix != NULL)
726 : 8047 : lsm_tmp_name_add (suffix);
727 : 63163 : return lsm_tmp_name;
728 : : }
729 : :
730 : : /* Computes an estimated number of insns in LOOP, weighted by WEIGHTS. */
731 : :
732 : : unsigned
733 : 1036 : tree_num_loop_insns (class loop *loop, eni_weights *weights)
734 : : {
735 : 1036 : basic_block *body = get_loop_body (loop);
736 : 1036 : gimple_stmt_iterator gsi;
737 : 1036 : unsigned size = 0, i;
738 : :
739 : 5766 : for (i = 0; i < loop->num_nodes; i++)
740 : 30214 : for (gsi = gsi_start_bb (body[i]); !gsi_end_p (gsi); gsi_next (&gsi))
741 : 22826 : size += estimate_num_insns (gsi_stmt (gsi), weights);
742 : 1036 : free (body);
743 : :
744 : 1036 : return size;
745 : : }
746 : :
747 : :
748 : :
|