1 /* Data flow functions for trees.
2 Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
3 Contributed by Diego Novillo <dnovillo@redhat.com>
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to
19 the Free Software Foundation, 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA. */
21
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "hashtab.h"
27 #include "pointer-set.h"
28 #include "tree.h"
29 #include "rtl.h"
30 #include "tm_p.h"
31 #include "hard-reg-set.h"
32 #include "basic-block.h"
33 #include "output.h"
34 #include "timevar.h"
35 #include "expr.h"
36 #include "ggc.h"
37 #include "langhooks.h"
38 #include "flags.h"
39 #include "function.h"
40 #include "diagnostic.h"
41 #include "tree-dump.h"
42 #include "tree-gimple.h"
43 #include "tree-flow.h"
44 #include "tree-inline.h"
45 #include "tree-pass.h"
46 #include "convert.h"
47 #include "params.h"
48 #include "cgraph.h"
49
50 /* Build and maintain data flow information for trees. */
51
52 /* Counters used to display DFA and SSA statistics. */
53 struct dfa_stats_d
54 {
55 long num_stmt_anns;
56 long num_var_anns;
57 long num_defs;
58 long num_uses;
59 long num_phis;
60 long num_phi_args;
61 int max_num_phi_args;
62 long num_v_may_defs;
63 long num_vuses;
64 long num_v_must_defs;
65 };
66
67
68 /* Local functions. */
69 static void collect_dfa_stats (struct dfa_stats_d *);
70 static tree collect_dfa_stats_r (tree *, int *, void *);
71 static tree find_vars_r (tree *, int *, void *);
72 static void add_referenced_var (tree, bool);
73
74
75 /* Global declarations. */
76
77 /* Array of all variables referenced in the function. */
78 htab_t referenced_vars;
79 /* List of referenced variables with duplicate UID's. */
VEC(tree,gc)80 VEC(tree,gc) *referenced_vars_dup_list;
81
82
83 /*---------------------------------------------------------------------------
84 Dataflow analysis (DFA) routines
85 ---------------------------------------------------------------------------*/
86 /* Find all the variables referenced in the function. This function
87 builds the global arrays REFERENCED_VARS and CALL_CLOBBERED_VARS.
88
89 Note that this function does not look for statement operands, it simply
90 determines what variables are referenced in the program and detects
91 various attributes for each variable used by alias analysis and the
92 optimizer. */
93
94 static void
95 find_referenced_vars (void)
96 {
97 basic_block bb;
98 block_stmt_iterator si;
99
100 gcc_assert (VEC_length (tree, referenced_vars_dup_list) == 0);
101 FOR_EACH_BB (bb)
102 for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
103 {
104 tree *stmt_p = bsi_stmt_ptr (si);
105 walk_tree (stmt_p, find_vars_r, NULL, NULL);
106 }
107
108 }
109
110 struct tree_opt_pass pass_referenced_vars =
111 {
112 NULL, /* name */
113 NULL, /* gate */
114 find_referenced_vars, /* execute */
115 NULL, /* sub */
116 NULL, /* next */
117 0, /* static_pass_number */
118 TV_FIND_REFERENCED_VARS, /* tv_id */
119 PROP_gimple_leh | PROP_cfg, /* properties_required */
120 PROP_referenced_vars, /* properties_provided */
121 0, /* properties_destroyed */
122 0, /* todo_flags_start */
123 0, /* todo_flags_finish */
124 0 /* letter */
125 };
126
127
128 /*---------------------------------------------------------------------------
129 Manage annotations
130 ---------------------------------------------------------------------------*/
131 /* Create a new annotation for a _DECL node T. */
132
133 var_ann_t
create_var_ann(tree t)134 create_var_ann (tree t)
135 {
136 var_ann_t ann;
137
138 gcc_assert (t);
139 gcc_assert (DECL_P (t));
140 gcc_assert (!t->common.ann || t->common.ann->common.type == VAR_ANN);
141
142 ann = ggc_alloc (sizeof (*ann));
143 memset ((void *) ann, 0, sizeof (*ann));
144
145 ann->common.type = VAR_ANN;
146
147 t->common.ann = (tree_ann_t) ann;
148
149 return ann;
150 }
151
152
153 /* Create a new annotation for a statement node T. */
154
155 stmt_ann_t
create_stmt_ann(tree t)156 create_stmt_ann (tree t)
157 {
158 stmt_ann_t ann;
159
160 gcc_assert (is_gimple_stmt (t));
161 gcc_assert (!t->common.ann || t->common.ann->common.type == STMT_ANN);
162
163 ann = ggc_alloc (sizeof (*ann));
164 memset ((void *) ann, 0, sizeof (*ann));
165
166 ann->common.type = STMT_ANN;
167
168 /* Since we just created the annotation, mark the statement modified. */
169 ann->modified = true;
170
171 t->common.ann = (tree_ann_t) ann;
172
173 return ann;
174 }
175
176 /* Create a new annotation for a tree T. */
177
178 tree_ann_t
create_tree_ann(tree t)179 create_tree_ann (tree t)
180 {
181 tree_ann_t ann;
182
183 gcc_assert (t);
184 gcc_assert (!t->common.ann || t->common.ann->common.type == TREE_ANN_COMMON);
185
186 ann = ggc_alloc (sizeof (*ann));
187 memset ((void *) ann, 0, sizeof (*ann));
188
189 ann->common.type = TREE_ANN_COMMON;
190 t->common.ann = ann;
191
192 return ann;
193 }
194
195 /* Build a temporary. Make sure and register it to be renamed. */
196
197 tree
make_rename_temp(tree type,const char * prefix)198 make_rename_temp (tree type, const char *prefix)
199 {
200 tree t = create_tmp_var (type, prefix);
201
202 if (TREE_CODE (type) == COMPLEX_TYPE)
203 DECL_COMPLEX_GIMPLE_REG_P (t) = 1;
204
205 if (referenced_vars)
206 {
207 add_referenced_tmp_var (t);
208 mark_sym_for_renaming (t);
209 }
210
211 return t;
212 }
213
214
215
216 /*---------------------------------------------------------------------------
217 Debugging functions
218 ---------------------------------------------------------------------------*/
219 /* Dump the list of all the referenced variables in the current function to
220 FILE. */
221
222 void
dump_referenced_vars(FILE * file)223 dump_referenced_vars (FILE *file)
224 {
225 tree var;
226 referenced_var_iterator rvi;
227
228 fprintf (file, "\nReferenced variables in %s: %u\n\n",
229 get_name (current_function_decl), (unsigned) num_referenced_vars);
230
231 FOR_EACH_REFERENCED_VAR (var, rvi)
232 {
233 fprintf (file, "Variable: ");
234 dump_variable (file, var);
235 fprintf (file, "\n");
236 }
237 }
238
239
240 /* Dump the list of all the referenced variables to stderr. */
241
242 void
debug_referenced_vars(void)243 debug_referenced_vars (void)
244 {
245 dump_referenced_vars (stderr);
246 }
247
248
249 /* Dump sub-variables for VAR to FILE. */
250
251 void
dump_subvars_for(FILE * file,tree var)252 dump_subvars_for (FILE *file, tree var)
253 {
254 subvar_t sv = get_subvars_for_var (var);
255
256 if (!sv)
257 return;
258
259 fprintf (file, "{ ");
260
261 for (; sv; sv = sv->next)
262 {
263 print_generic_expr (file, sv->var, dump_flags);
264 fprintf (file, " ");
265 }
266
267 fprintf (file, "}");
268 }
269
270
271 /* Dumb sub-variables for VAR to stderr. */
272
273 void
debug_subvars_for(tree var)274 debug_subvars_for (tree var)
275 {
276 dump_subvars_for (stderr, var);
277 }
278
279
280 /* Dump variable VAR and its may-aliases to FILE. */
281
282 void
dump_variable(FILE * file,tree var)283 dump_variable (FILE *file, tree var)
284 {
285 var_ann_t ann;
286
287 if (TREE_CODE (var) == SSA_NAME)
288 {
289 if (POINTER_TYPE_P (TREE_TYPE (var)))
290 dump_points_to_info_for (file, var);
291 var = SSA_NAME_VAR (var);
292 }
293
294 if (var == NULL_TREE)
295 {
296 fprintf (file, "<nil>");
297 return;
298 }
299
300 print_generic_expr (file, var, dump_flags);
301
302 ann = var_ann (var);
303
304 fprintf (file, ", UID %u", (unsigned) DECL_UID (var));
305
306 fprintf (file, ", ");
307 print_generic_expr (file, TREE_TYPE (var), dump_flags);
308
309 if (ann && ann->type_mem_tag)
310 {
311 fprintf (file, ", type memory tag: ");
312 print_generic_expr (file, ann->type_mem_tag, dump_flags);
313 }
314
315 if (ann && ann->is_alias_tag)
316 fprintf (file, ", is an alias tag");
317
318 if (TREE_ADDRESSABLE (var))
319 fprintf (file, ", is addressable");
320
321 if (is_global_var (var))
322 fprintf (file, ", is global");
323
324 if (TREE_THIS_VOLATILE (var))
325 fprintf (file, ", is volatile");
326
327 if (is_call_clobbered (var))
328 fprintf (file, ", call clobbered");
329
330 if (default_def (var))
331 {
332 fprintf (file, ", default def: ");
333 print_generic_expr (file, default_def (var), dump_flags);
334 }
335
336 if (may_aliases (var))
337 {
338 fprintf (file, ", may aliases: ");
339 dump_may_aliases_for (file, var);
340 }
341
342 if (get_subvars_for_var (var))
343 {
344 fprintf (file, ", sub-vars: ");
345 dump_subvars_for (file, var);
346 }
347
348 fprintf (file, "\n");
349 }
350
351
352 /* Dump variable VAR and its may-aliases to stderr. */
353
354 void
debug_variable(tree var)355 debug_variable (tree var)
356 {
357 dump_variable (stderr, var);
358 }
359
360
361 /* Dump various DFA statistics to FILE. */
362
363 void
dump_dfa_stats(FILE * file)364 dump_dfa_stats (FILE *file)
365 {
366 struct dfa_stats_d dfa_stats;
367
368 unsigned long size, total = 0;
369 const char * const fmt_str = "%-30s%-13s%12s\n";
370 const char * const fmt_str_1 = "%-30s%13lu%11lu%c\n";
371 const char * const fmt_str_3 = "%-43s%11lu%c\n";
372 const char *funcname
373 = lang_hooks.decl_printable_name (current_function_decl, 2);
374
375 collect_dfa_stats (&dfa_stats);
376
377 fprintf (file, "\nDFA Statistics for %s\n\n", funcname);
378
379 fprintf (file, "---------------------------------------------------------\n");
380 fprintf (file, fmt_str, "", " Number of ", "Memory");
381 fprintf (file, fmt_str, "", " instances ", "used ");
382 fprintf (file, "---------------------------------------------------------\n");
383
384 size = num_referenced_vars * sizeof (tree);
385 total += size;
386 fprintf (file, fmt_str_1, "Referenced variables", (unsigned long)num_referenced_vars,
387 SCALE (size), LABEL (size));
388
389 size = dfa_stats.num_stmt_anns * sizeof (struct stmt_ann_d);
390 total += size;
391 fprintf (file, fmt_str_1, "Statements annotated", dfa_stats.num_stmt_anns,
392 SCALE (size), LABEL (size));
393
394 size = dfa_stats.num_var_anns * sizeof (struct var_ann_d);
395 total += size;
396 fprintf (file, fmt_str_1, "Variables annotated", dfa_stats.num_var_anns,
397 SCALE (size), LABEL (size));
398
399 size = dfa_stats.num_uses * sizeof (tree *);
400 total += size;
401 fprintf (file, fmt_str_1, "USE operands", dfa_stats.num_uses,
402 SCALE (size), LABEL (size));
403
404 size = dfa_stats.num_defs * sizeof (tree *);
405 total += size;
406 fprintf (file, fmt_str_1, "DEF operands", dfa_stats.num_defs,
407 SCALE (size), LABEL (size));
408
409 size = dfa_stats.num_vuses * sizeof (tree *);
410 total += size;
411 fprintf (file, fmt_str_1, "VUSE operands", dfa_stats.num_vuses,
412 SCALE (size), LABEL (size));
413
414 size = dfa_stats.num_v_may_defs * sizeof (tree *);
415 total += size;
416 fprintf (file, fmt_str_1, "V_MAY_DEF operands", dfa_stats.num_v_may_defs,
417 SCALE (size), LABEL (size));
418
419 size = dfa_stats.num_v_must_defs * sizeof (tree *);
420 total += size;
421 fprintf (file, fmt_str_1, "V_MUST_DEF operands", dfa_stats.num_v_must_defs,
422 SCALE (size), LABEL (size));
423
424 size = dfa_stats.num_phis * sizeof (struct tree_phi_node);
425 total += size;
426 fprintf (file, fmt_str_1, "PHI nodes", dfa_stats.num_phis,
427 SCALE (size), LABEL (size));
428
429 size = dfa_stats.num_phi_args * sizeof (struct phi_arg_d);
430 total += size;
431 fprintf (file, fmt_str_1, "PHI arguments", dfa_stats.num_phi_args,
432 SCALE (size), LABEL (size));
433
434 fprintf (file, "---------------------------------------------------------\n");
435 fprintf (file, fmt_str_3, "Total memory used by DFA/SSA data", SCALE (total),
436 LABEL (total));
437 fprintf (file, "---------------------------------------------------------\n");
438 fprintf (file, "\n");
439
440 if (dfa_stats.num_phis)
441 fprintf (file, "Average number of arguments per PHI node: %.1f (max: %d)\n",
442 (float) dfa_stats.num_phi_args / (float) dfa_stats.num_phis,
443 dfa_stats.max_num_phi_args);
444
445 fprintf (file, "\n");
446 }
447
448
449 /* Dump DFA statistics on stderr. */
450
451 void
debug_dfa_stats(void)452 debug_dfa_stats (void)
453 {
454 dump_dfa_stats (stderr);
455 }
456
457
458 /* Collect DFA statistics and store them in the structure pointed to by
459 DFA_STATS_P. */
460
461 static void
collect_dfa_stats(struct dfa_stats_d * dfa_stats_p)462 collect_dfa_stats (struct dfa_stats_d *dfa_stats_p)
463 {
464 struct pointer_set_t *pset;
465 basic_block bb;
466 block_stmt_iterator i;
467
468 gcc_assert (dfa_stats_p);
469
470 memset ((void *)dfa_stats_p, 0, sizeof (struct dfa_stats_d));
471
472 /* Walk all the trees in the function counting references. Start at
473 basic block 0, but don't stop at block boundaries. */
474 pset = pointer_set_create ();
475
476 for (i = bsi_start (BASIC_BLOCK (0)); !bsi_end_p (i); bsi_next (&i))
477 walk_tree (bsi_stmt_ptr (i), collect_dfa_stats_r, (void *) dfa_stats_p,
478 pset);
479
480 pointer_set_destroy (pset);
481
482 FOR_EACH_BB (bb)
483 {
484 tree phi;
485 for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
486 {
487 dfa_stats_p->num_phis++;
488 dfa_stats_p->num_phi_args += PHI_NUM_ARGS (phi);
489 if (PHI_NUM_ARGS (phi) > dfa_stats_p->max_num_phi_args)
490 dfa_stats_p->max_num_phi_args = PHI_NUM_ARGS (phi);
491 }
492 }
493 }
494
495
496 /* Callback for walk_tree to collect DFA statistics for a tree and its
497 children. */
498
499 static tree
collect_dfa_stats_r(tree * tp,int * walk_subtrees ATTRIBUTE_UNUSED,void * data)500 collect_dfa_stats_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
501 void *data)
502 {
503 tree t = *tp;
504 struct dfa_stats_d *dfa_stats_p = (struct dfa_stats_d *)data;
505
506 if (t->common.ann)
507 {
508 switch (ann_type (t->common.ann))
509 {
510 case STMT_ANN:
511 {
512 dfa_stats_p->num_stmt_anns++;
513 dfa_stats_p->num_defs += NUM_SSA_OPERANDS (t, SSA_OP_DEF);
514 dfa_stats_p->num_uses += NUM_SSA_OPERANDS (t, SSA_OP_USE);
515 dfa_stats_p->num_v_may_defs += NUM_SSA_OPERANDS (t, SSA_OP_VMAYDEF);
516 dfa_stats_p->num_vuses += NUM_SSA_OPERANDS (t, SSA_OP_VUSE);
517 dfa_stats_p->num_v_must_defs +=
518 NUM_SSA_OPERANDS (t, SSA_OP_VMUSTDEF);
519 break;
520 }
521
522 case VAR_ANN:
523 dfa_stats_p->num_var_anns++;
524 break;
525
526 default:
527 break;
528 }
529 }
530
531 return NULL;
532 }
533
534
535 /*---------------------------------------------------------------------------
536 Miscellaneous helpers
537 ---------------------------------------------------------------------------*/
538 /* Callback for walk_tree. Used to collect variables referenced in
539 the function. */
540
541 static tree
find_vars_r(tree * tp,int * walk_subtrees,void * data ATTRIBUTE_UNUSED)542 find_vars_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
543 {
544 /* If T is a regular variable that the optimizers are interested
545 in, add it to the list of variables. */
546 if (SSA_VAR_P (*tp))
547 add_referenced_var (*tp, false);
548
549 /* Type, _DECL and constant nodes have no interesting children.
550 Ignore them. */
551 else if (IS_TYPE_OR_DECL_P (*tp) || CONSTANT_CLASS_P (*tp))
552 *walk_subtrees = 0;
553
554 return NULL_TREE;
555 }
556
557
558 /* Lookup UID in the referenced_vars hashtable and return the associated
559 variable or NULL if it is not there. */
560
561 tree
referenced_var_lookup_if_exists(unsigned int uid)562 referenced_var_lookup_if_exists (unsigned int uid)
563 {
564 struct int_tree_map *h, in;
565 in.uid = uid;
566 h = htab_find_with_hash (referenced_vars, &in, uid);
567 if (h)
568 return h->to;
569 return NULL_TREE;
570 }
571
572 /* Lookup UID in the referenced_vars hashtable and return the associated
573 variable. */
574
575 tree
referenced_var_lookup(unsigned int uid)576 referenced_var_lookup (unsigned int uid)
577 {
578 struct int_tree_map *h, in;
579 in.uid = uid;
580 h = htab_find_with_hash (referenced_vars, &in, uid);
581 gcc_assert (h || uid == 0);
582 if (h)
583 return h->to;
584 return NULL_TREE;
585 }
586
587 /* Insert the pair UID, TO into the referenced_vars hashtable. */
588
589 static void
referenced_var_insert(unsigned int uid,tree to)590 referenced_var_insert (unsigned int uid, tree to)
591 {
592 struct int_tree_map *h;
593 void **loc;
594
595 h = ggc_alloc (sizeof (struct int_tree_map));
596 h->uid = uid;
597 h->to = to;
598 loc = htab_find_slot_with_hash (referenced_vars, h, uid, INSERT);
599 /* This assert can only trigger if a variable with the same UID has been
600 inserted already. */
601 gcc_assert ((*(struct int_tree_map **)loc) == NULL);
602 *(struct int_tree_map **) loc = h;
603 }
604
605 /* Add VAR to the list of dereferenced variables.
606
607 WALK_STATE contains a hash table used to avoid adding the same
608 variable more than once. Note that this function assumes that
609 VAR is a valid SSA variable. If WALK_STATE is NULL, no
610 duplicate checking is done. */
611
612 static void
add_referenced_var(tree var,bool always)613 add_referenced_var (tree var, bool always)
614 {
615 var_ann_t v_ann;
616 tree dup = referenced_var_lookup_if_exists (DECL_UID (var));
617
618 v_ann = get_var_ann (var);
619 gcc_assert (DECL_P (var));
620
621 /* PRs 26757 and 27793. Maintain a list of duplicate variable pointers
622 with the same DECL_UID. There isn't usually very many.
623 TODO. Once the C++ front end doesn't create duplicate DECL UID's, this
624 code can be removed. */
625 if (dup && dup != var)
626 {
627 unsigned u;
628 tree t = NULL_TREE;
629
630 for (u = 0; u < VEC_length (tree, referenced_vars_dup_list); u++)
631 {
632 t = VEC_index (tree, referenced_vars_dup_list, u);
633 if (t == var)
634 break;
635 }
636 if (t != var)
637 VEC_safe_push (tree, gc, referenced_vars_dup_list, var);
638 }
639
640 if (always || dup == NULL_TREE)
641 {
642 /* This is the first time we find this variable, add it to the
643 REFERENCED_VARS array and annotate it with attributes that are
644 intrinsic to the variable. */
645
646 referenced_var_insert (DECL_UID (var), var);
647
648 /* Global variables are always call-clobbered. */
649 if (is_global_var (var))
650 mark_call_clobbered (var);
651
652 /* Scan DECL_INITIAL for pointer variables as they may contain
653 address arithmetic referencing the address of other
654 variables. */
655 if (DECL_INITIAL (var)
656 /* Initializers of external variables are not useful to the
657 optimizers. */
658 && !DECL_EXTERNAL (var)
659 /* It's not necessary to walk the initial value of non-constant
660 variables because it cannot be propagated by the
661 optimizers. */
662 && (TREE_CONSTANT (var) || TREE_READONLY (var)))
663 walk_tree (&DECL_INITIAL (var), find_vars_r, NULL, 0);
664 }
665 }
666
667
668 /* Return the virtual variable associated to the non-scalar variable VAR. */
669
670 tree
get_virtual_var(tree var)671 get_virtual_var (tree var)
672 {
673 STRIP_NOPS (var);
674
675 if (TREE_CODE (var) == SSA_NAME)
676 var = SSA_NAME_VAR (var);
677
678 while (TREE_CODE (var) == REALPART_EXPR || TREE_CODE (var) == IMAGPART_EXPR
679 || handled_component_p (var))
680 var = TREE_OPERAND (var, 0);
681
682 /* Treating GIMPLE registers as virtual variables makes no sense.
683 Also complain if we couldn't extract a _DECL out of the original
684 expression. */
685 gcc_assert (SSA_VAR_P (var));
686 gcc_assert (!is_gimple_reg (var));
687
688 return var;
689 }
690
691 /* Add a temporary variable to REFERENCED_VARS. This is similar to
692 add_referenced_var, but is used by passes that need to add new temps to
693 the REFERENCED_VARS array after the program has been scanned for
694 variables. The variable will just receive a new UID and be added
695 to the REFERENCED_VARS array without checking for duplicates. */
696
697 void
add_referenced_tmp_var(tree var)698 add_referenced_tmp_var (tree var)
699 {
700 add_referenced_var (var, true);
701 }
702
703
704 /* Mark all the non-SSA variables found in STMT's operands to be
705 processed by update_ssa. */
706
707 void
mark_new_vars_to_rename(tree stmt)708 mark_new_vars_to_rename (tree stmt)
709 {
710 ssa_op_iter iter;
711 tree val;
712 bitmap vars_in_vops_to_rename;
713 bool found_exposed_symbol = false;
714 int v_may_defs_before, v_may_defs_after;
715 int v_must_defs_before, v_must_defs_after;
716
717 if (TREE_CODE (stmt) == PHI_NODE)
718 return;
719
720 vars_in_vops_to_rename = BITMAP_ALLOC (NULL);
721
722 /* Before re-scanning the statement for operands, mark the existing
723 virtual operands to be renamed again. We do this because when new
724 symbols are exposed, the virtual operands that were here before due to
725 aliasing will probably be removed by the call to get_stmt_operand.
726 Therefore, we need to flag them to be renamed beforehand.
727
728 We flag them in a separate bitmap because we don't really want to
729 rename them if there are not any newly exposed symbols in the
730 statement operands. */
731 v_may_defs_before = NUM_SSA_OPERANDS (stmt, SSA_OP_VMAYDEF);
732 v_must_defs_before = NUM_SSA_OPERANDS (stmt, SSA_OP_VMUSTDEF);
733
734 FOR_EACH_SSA_TREE_OPERAND (val, stmt, iter,
735 SSA_OP_VMAYDEF | SSA_OP_VUSE | SSA_OP_VMUSTDEF)
736 {
737 if (!DECL_P (val))
738 val = SSA_NAME_VAR (val);
739 bitmap_set_bit (vars_in_vops_to_rename, DECL_UID (val));
740 }
741
742 /* Now force an operand re-scan on the statement and mark any newly
743 exposed variables. */
744 update_stmt (stmt);
745
746 v_may_defs_after = NUM_SSA_OPERANDS (stmt, SSA_OP_VMAYDEF);
747 v_must_defs_after = NUM_SSA_OPERANDS (stmt, SSA_OP_VMUSTDEF);
748
749 FOR_EACH_SSA_TREE_OPERAND (val, stmt, iter, SSA_OP_ALL_OPERANDS)
750 if (DECL_P (val))
751 {
752 found_exposed_symbol = true;
753 mark_sym_for_renaming (val);
754 }
755
756 /* If we found any newly exposed symbols, or if there are fewer VDEF
757 operands in the statement, add the variables we had set in
758 VARS_IN_VOPS_TO_RENAME to VARS_TO_RENAME. We need to check for
759 vanishing VDEFs because in those cases, the names that were formerly
760 generated by this statement are not going to be available anymore. */
761 if (found_exposed_symbol
762 || v_may_defs_before > v_may_defs_after
763 || v_must_defs_before > v_must_defs_after)
764 mark_set_for_renaming (vars_in_vops_to_rename);
765
766 BITMAP_FREE (vars_in_vops_to_rename);
767 }
768
769 /* Find all variables within the gimplified statement that were not previously
770 visible to the function and add them to the referenced variables list. */
771
772 static tree
find_new_referenced_vars_1(tree * tp,int * walk_subtrees,void * data ATTRIBUTE_UNUSED)773 find_new_referenced_vars_1 (tree *tp, int *walk_subtrees,
774 void *data ATTRIBUTE_UNUSED)
775 {
776 tree t = *tp;
777
778 if (TREE_CODE (t) == VAR_DECL && !var_ann (t))
779 {
780 add_referenced_tmp_var (t);
781 mark_sym_for_renaming (t);
782 }
783
784 if (IS_TYPE_OR_DECL_P (t))
785 *walk_subtrees = 0;
786
787 return NULL;
788 }
789
790 void
find_new_referenced_vars(tree * stmt_p)791 find_new_referenced_vars (tree *stmt_p)
792 {
793 walk_tree (stmt_p, find_new_referenced_vars_1, NULL, NULL);
794 }
795
796
797 /* If REF is a COMPONENT_REF for a structure that can have sub-variables, and
798 we know where REF is accessing, return the variable in REF that has the
799 sub-variables. If the return value is not NULL, POFFSET will be the
800 offset, in bits, of REF inside the return value, and PSIZE will be the
801 size, in bits, of REF inside the return value. */
802
803 tree
okay_component_ref_for_subvars(tree ref,unsigned HOST_WIDE_INT * poffset,unsigned HOST_WIDE_INT * psize)804 okay_component_ref_for_subvars (tree ref, unsigned HOST_WIDE_INT *poffset,
805 unsigned HOST_WIDE_INT *psize)
806 {
807 tree result = NULL;
808 HOST_WIDE_INT bitsize;
809 HOST_WIDE_INT bitpos;
810 tree offset;
811 enum machine_mode mode;
812 int unsignedp;
813 int volatilep;
814
815 gcc_assert (!SSA_VAR_P (ref));
816 *poffset = 0;
817 *psize = (unsigned int) -1;
818
819 if (ref_contains_array_ref (ref))
820 return result;
821 ref = get_inner_reference (ref, &bitsize, &bitpos, &offset, &mode,
822 &unsignedp, &volatilep, false);
823 if (TREE_CODE (ref) == INDIRECT_REF)
824 return result;
825 else if (offset == NULL && bitsize != -1 && SSA_VAR_P (ref))
826 {
827 *poffset = bitpos;
828 *psize = bitsize;
829 if (get_subvars_for_var (ref) != NULL)
830 return ref;
831 }
832 else if (SSA_VAR_P (ref))
833 {
834 if (get_subvars_for_var (ref) != NULL)
835 return ref;
836 }
837 return NULL_TREE;
838 }
839