OSDN Git Service

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