xref: /dflybsd-src/contrib/gcc-4.7/gcc/tree-dfa.c (revision 0a8dc9fc45f4d0b236341a473fac4a486375f60c)
1e4b17023SJohn Marino /* Data flow functions for trees.
2e4b17023SJohn Marino    Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010
3e4b17023SJohn Marino    Free Software Foundation, Inc.
4e4b17023SJohn Marino    Contributed by Diego Novillo <dnovillo@redhat.com>
5e4b17023SJohn Marino 
6e4b17023SJohn Marino This file is part of GCC.
7e4b17023SJohn Marino 
8e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify
9e4b17023SJohn Marino it under the terms of the GNU General Public License as published by
10e4b17023SJohn Marino the Free Software Foundation; either version 3, or (at your option)
11e4b17023SJohn Marino any later version.
12e4b17023SJohn Marino 
13e4b17023SJohn Marino GCC is distributed in the hope that it will be useful,
14e4b17023SJohn Marino but WITHOUT ANY WARRANTY; without even the implied warranty of
15e4b17023SJohn Marino MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16e4b17023SJohn Marino GNU General Public License for more details.
17e4b17023SJohn Marino 
18e4b17023SJohn Marino You should have received a copy of the GNU General Public License
19e4b17023SJohn Marino along with GCC; see the file COPYING3.  If not see
20e4b17023SJohn Marino <http://www.gnu.org/licenses/>.  */
21e4b17023SJohn Marino 
22e4b17023SJohn Marino #include "config.h"
23e4b17023SJohn Marino #include "system.h"
24e4b17023SJohn Marino #include "coretypes.h"
25e4b17023SJohn Marino #include "tm.h"
26e4b17023SJohn Marino #include "hashtab.h"
27e4b17023SJohn Marino #include "pointer-set.h"
28e4b17023SJohn Marino #include "tree.h"
29e4b17023SJohn Marino #include "tm_p.h"
30e4b17023SJohn Marino #include "basic-block.h"
31e4b17023SJohn Marino #include "output.h"
32e4b17023SJohn Marino #include "timevar.h"
33e4b17023SJohn Marino #include "ggc.h"
34e4b17023SJohn Marino #include "langhooks.h"
35e4b17023SJohn Marino #include "flags.h"
36e4b17023SJohn Marino #include "function.h"
37e4b17023SJohn Marino #include "tree-pretty-print.h"
38e4b17023SJohn Marino #include "tree-dump.h"
39e4b17023SJohn Marino #include "gimple.h"
40e4b17023SJohn Marino #include "tree-flow.h"
41e4b17023SJohn Marino #include "tree-inline.h"
42e4b17023SJohn Marino #include "tree-pass.h"
43e4b17023SJohn Marino #include "convert.h"
44e4b17023SJohn Marino #include "params.h"
45e4b17023SJohn Marino #include "cgraph.h"
46e4b17023SJohn Marino 
47e4b17023SJohn Marino /* Build and maintain data flow information for trees.  */
48e4b17023SJohn Marino 
49e4b17023SJohn Marino /* Counters used to display DFA and SSA statistics.  */
50e4b17023SJohn Marino struct dfa_stats_d
51e4b17023SJohn Marino {
52e4b17023SJohn Marino   long num_var_anns;
53e4b17023SJohn Marino   long num_defs;
54e4b17023SJohn Marino   long num_uses;
55e4b17023SJohn Marino   long num_phis;
56e4b17023SJohn Marino   long num_phi_args;
57e4b17023SJohn Marino   size_t max_num_phi_args;
58e4b17023SJohn Marino   long num_vdefs;
59e4b17023SJohn Marino   long num_vuses;
60e4b17023SJohn Marino };
61e4b17023SJohn Marino 
62e4b17023SJohn Marino 
63e4b17023SJohn Marino /* Local functions.  */
64e4b17023SJohn Marino static void collect_dfa_stats (struct dfa_stats_d *);
65e4b17023SJohn Marino static tree find_vars_r (tree *, int *, void *);
66e4b17023SJohn Marino 
67e4b17023SJohn Marino 
68e4b17023SJohn Marino /*---------------------------------------------------------------------------
69e4b17023SJohn Marino 			Dataflow analysis (DFA) routines
70e4b17023SJohn Marino ---------------------------------------------------------------------------*/
71e4b17023SJohn Marino /* Find all the variables referenced in the function.  This function
72e4b17023SJohn Marino    builds the global arrays REFERENCED_VARS and CALL_CLOBBERED_VARS.
73e4b17023SJohn Marino 
74e4b17023SJohn Marino    Note that this function does not look for statement operands, it simply
75e4b17023SJohn Marino    determines what variables are referenced in the program and detects
76e4b17023SJohn Marino    various attributes for each variable used by alias analysis and the
77e4b17023SJohn Marino    optimizer.  */
78e4b17023SJohn Marino 
79e4b17023SJohn Marino static unsigned int
find_referenced_vars(void)80e4b17023SJohn Marino find_referenced_vars (void)
81e4b17023SJohn Marino {
82e4b17023SJohn Marino   basic_block bb;
83e4b17023SJohn Marino   gimple_stmt_iterator si;
84e4b17023SJohn Marino 
85e4b17023SJohn Marino   FOR_EACH_BB (bb)
86e4b17023SJohn Marino     {
87e4b17023SJohn Marino       for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
88e4b17023SJohn Marino 	{
89e4b17023SJohn Marino 	  gimple stmt = gsi_stmt (si);
90e4b17023SJohn Marino 	  if (is_gimple_debug (stmt))
91e4b17023SJohn Marino 	    continue;
92e4b17023SJohn Marino 	  find_referenced_vars_in (gsi_stmt (si));
93e4b17023SJohn Marino 	}
94e4b17023SJohn Marino 
95e4b17023SJohn Marino       for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si))
96e4b17023SJohn Marino 	find_referenced_vars_in (gsi_stmt (si));
97e4b17023SJohn Marino     }
98e4b17023SJohn Marino 
99e4b17023SJohn Marino   return 0;
100e4b17023SJohn Marino }
101e4b17023SJohn Marino 
102e4b17023SJohn Marino struct gimple_opt_pass pass_referenced_vars =
103e4b17023SJohn Marino {
104e4b17023SJohn Marino  {
105e4b17023SJohn Marino   GIMPLE_PASS,
106e4b17023SJohn Marino   "*referenced_vars",			/* name */
107e4b17023SJohn Marino   NULL,					/* gate */
108e4b17023SJohn Marino   find_referenced_vars,			/* execute */
109e4b17023SJohn Marino   NULL,					/* sub */
110e4b17023SJohn Marino   NULL,					/* next */
111e4b17023SJohn Marino   0,					/* static_pass_number */
112e4b17023SJohn Marino   TV_FIND_REFERENCED_VARS,		/* tv_id */
113e4b17023SJohn Marino   PROP_gimple_leh | PROP_cfg,		/* properties_required */
114e4b17023SJohn Marino   PROP_referenced_vars,			/* properties_provided */
115e4b17023SJohn Marino   0,					/* properties_destroyed */
116e4b17023SJohn Marino   0,                     		/* todo_flags_start */
117e4b17023SJohn Marino   0                                     /* todo_flags_finish */
118e4b17023SJohn Marino  }
119e4b17023SJohn Marino };
120e4b17023SJohn Marino 
121e4b17023SJohn Marino 
122e4b17023SJohn Marino /*---------------------------------------------------------------------------
123e4b17023SJohn Marino 			    Manage annotations
124e4b17023SJohn Marino ---------------------------------------------------------------------------*/
125e4b17023SJohn Marino /* Create a new annotation for a _DECL node T.  */
126e4b17023SJohn Marino 
127e4b17023SJohn Marino var_ann_t
create_var_ann(tree t)128e4b17023SJohn Marino create_var_ann (tree t)
129e4b17023SJohn Marino {
130e4b17023SJohn Marino   var_ann_t ann;
131e4b17023SJohn Marino 
132e4b17023SJohn Marino   gcc_assert (t);
133e4b17023SJohn Marino   gcc_assert (TREE_CODE (t) == VAR_DECL
134e4b17023SJohn Marino 	      || TREE_CODE (t) == PARM_DECL
135e4b17023SJohn Marino 	      || TREE_CODE (t) == RESULT_DECL);
136e4b17023SJohn Marino 
137e4b17023SJohn Marino   ann = ggc_alloc_cleared_var_ann_d ();
138e4b17023SJohn Marino   *DECL_VAR_ANN_PTR (t) = ann;
139e4b17023SJohn Marino 
140e4b17023SJohn Marino   return ann;
141e4b17023SJohn Marino }
142e4b17023SJohn Marino 
143e4b17023SJohn Marino /* Renumber all of the gimple stmt uids.  */
144e4b17023SJohn Marino 
145e4b17023SJohn Marino void
renumber_gimple_stmt_uids(void)146e4b17023SJohn Marino renumber_gimple_stmt_uids (void)
147e4b17023SJohn Marino {
148e4b17023SJohn Marino   basic_block bb;
149e4b17023SJohn Marino 
150e4b17023SJohn Marino   set_gimple_stmt_max_uid (cfun, 0);
151e4b17023SJohn Marino   FOR_ALL_BB (bb)
152e4b17023SJohn Marino     {
153e4b17023SJohn Marino       gimple_stmt_iterator bsi;
154e4b17023SJohn Marino       for (bsi = gsi_start_phis (bb); !gsi_end_p (bsi); gsi_next (&bsi))
155e4b17023SJohn Marino 	{
156e4b17023SJohn Marino 	  gimple stmt = gsi_stmt (bsi);
157e4b17023SJohn Marino 	  gimple_set_uid (stmt, inc_gimple_stmt_max_uid (cfun));
158e4b17023SJohn Marino 	}
159e4b17023SJohn Marino       for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
160e4b17023SJohn Marino 	{
161e4b17023SJohn Marino 	  gimple stmt = gsi_stmt (bsi);
162e4b17023SJohn Marino 	  gimple_set_uid (stmt, inc_gimple_stmt_max_uid (cfun));
163e4b17023SJohn Marino 	}
164e4b17023SJohn Marino     }
165e4b17023SJohn Marino }
166e4b17023SJohn Marino 
167e4b17023SJohn Marino /* Like renumber_gimple_stmt_uids, but only do work on the basic blocks
168e4b17023SJohn Marino    in BLOCKS, of which there are N_BLOCKS.  Also renumbers PHIs.  */
169e4b17023SJohn Marino 
170e4b17023SJohn Marino void
renumber_gimple_stmt_uids_in_blocks(basic_block * blocks,int n_blocks)171e4b17023SJohn Marino renumber_gimple_stmt_uids_in_blocks (basic_block *blocks, int n_blocks)
172e4b17023SJohn Marino {
173e4b17023SJohn Marino   int i;
174e4b17023SJohn Marino 
175e4b17023SJohn Marino   set_gimple_stmt_max_uid (cfun, 0);
176e4b17023SJohn Marino   for (i = 0; i < n_blocks; i++)
177e4b17023SJohn Marino     {
178e4b17023SJohn Marino       basic_block bb = blocks[i];
179e4b17023SJohn Marino       gimple_stmt_iterator bsi;
180e4b17023SJohn Marino       for (bsi = gsi_start_phis (bb); !gsi_end_p (bsi); gsi_next (&bsi))
181e4b17023SJohn Marino 	{
182e4b17023SJohn Marino 	  gimple stmt = gsi_stmt (bsi);
183e4b17023SJohn Marino 	  gimple_set_uid (stmt, inc_gimple_stmt_max_uid (cfun));
184e4b17023SJohn Marino 	}
185e4b17023SJohn Marino       for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
186e4b17023SJohn Marino 	{
187e4b17023SJohn Marino 	  gimple stmt = gsi_stmt (bsi);
188e4b17023SJohn Marino 	  gimple_set_uid (stmt, inc_gimple_stmt_max_uid (cfun));
189e4b17023SJohn Marino 	}
190e4b17023SJohn Marino     }
191e4b17023SJohn Marino }
192e4b17023SJohn Marino 
193e4b17023SJohn Marino /* Build a temporary.  Make sure and register it to be renamed.  */
194e4b17023SJohn Marino 
195e4b17023SJohn Marino tree
make_rename_temp(tree type,const char * prefix)196e4b17023SJohn Marino make_rename_temp (tree type, const char *prefix)
197e4b17023SJohn Marino {
198e4b17023SJohn Marino   tree t = create_tmp_reg (type, prefix);
199e4b17023SJohn Marino 
200e4b17023SJohn Marino   if (gimple_referenced_vars (cfun))
201e4b17023SJohn Marino     {
202e4b17023SJohn Marino       add_referenced_var (t);
203e4b17023SJohn Marino       mark_sym_for_renaming (t);
204e4b17023SJohn Marino     }
205e4b17023SJohn Marino 
206e4b17023SJohn Marino   return t;
207e4b17023SJohn Marino }
208e4b17023SJohn Marino 
209e4b17023SJohn Marino 
210e4b17023SJohn Marino 
211e4b17023SJohn Marino /*---------------------------------------------------------------------------
212e4b17023SJohn Marino 			      Debugging functions
213e4b17023SJohn Marino ---------------------------------------------------------------------------*/
214e4b17023SJohn Marino /* Dump the list of all the referenced variables in the current function to
215e4b17023SJohn Marino    FILE.  */
216e4b17023SJohn Marino 
217e4b17023SJohn Marino void
dump_referenced_vars(FILE * file)218e4b17023SJohn Marino dump_referenced_vars (FILE *file)
219e4b17023SJohn Marino {
220e4b17023SJohn Marino   tree var;
221e4b17023SJohn Marino   referenced_var_iterator rvi;
222e4b17023SJohn Marino 
223e4b17023SJohn Marino   fprintf (file, "\nReferenced variables in %s: %u\n\n",
224e4b17023SJohn Marino 	   get_name (current_function_decl), (unsigned) num_referenced_vars);
225e4b17023SJohn Marino 
226e4b17023SJohn Marino   FOR_EACH_REFERENCED_VAR (cfun, var, rvi)
227e4b17023SJohn Marino     {
228e4b17023SJohn Marino       fprintf (file, "Variable: ");
229e4b17023SJohn Marino       dump_variable (file, var);
230e4b17023SJohn Marino     }
231e4b17023SJohn Marino 
232e4b17023SJohn Marino   fprintf (file, "\n");
233e4b17023SJohn Marino }
234e4b17023SJohn Marino 
235e4b17023SJohn Marino 
236e4b17023SJohn Marino /* Dump the list of all the referenced variables to stderr.  */
237e4b17023SJohn Marino 
238e4b17023SJohn Marino DEBUG_FUNCTION void
debug_referenced_vars(void)239e4b17023SJohn Marino debug_referenced_vars (void)
240e4b17023SJohn Marino {
241e4b17023SJohn Marino   dump_referenced_vars (stderr);
242e4b17023SJohn Marino }
243e4b17023SJohn Marino 
244e4b17023SJohn Marino 
245e4b17023SJohn Marino /* Dump variable VAR and its may-aliases to FILE.  */
246e4b17023SJohn Marino 
247e4b17023SJohn Marino void
dump_variable(FILE * file,tree var)248e4b17023SJohn Marino dump_variable (FILE *file, tree var)
249e4b17023SJohn Marino {
250e4b17023SJohn Marino   if (TREE_CODE (var) == SSA_NAME)
251e4b17023SJohn Marino     {
252e4b17023SJohn Marino       if (POINTER_TYPE_P (TREE_TYPE (var)))
253e4b17023SJohn Marino 	dump_points_to_info_for (file, var);
254e4b17023SJohn Marino       var = SSA_NAME_VAR (var);
255e4b17023SJohn Marino     }
256e4b17023SJohn Marino 
257e4b17023SJohn Marino   if (var == NULL_TREE)
258e4b17023SJohn Marino     {
259e4b17023SJohn Marino       fprintf (file, "<nil>");
260e4b17023SJohn Marino       return;
261e4b17023SJohn Marino     }
262e4b17023SJohn Marino 
263e4b17023SJohn Marino   print_generic_expr (file, var, dump_flags);
264e4b17023SJohn Marino 
265e4b17023SJohn Marino   fprintf (file, ", UID D.%u", (unsigned) DECL_UID (var));
266e4b17023SJohn Marino   if (DECL_PT_UID (var) != DECL_UID (var))
267e4b17023SJohn Marino     fprintf (file, ", PT-UID D.%u", (unsigned) DECL_PT_UID (var));
268e4b17023SJohn Marino 
269e4b17023SJohn Marino   fprintf (file, ", ");
270e4b17023SJohn Marino   print_generic_expr (file, TREE_TYPE (var), dump_flags);
271e4b17023SJohn Marino 
272e4b17023SJohn Marino   if (TREE_ADDRESSABLE (var))
273e4b17023SJohn Marino     fprintf (file, ", is addressable");
274e4b17023SJohn Marino 
275e4b17023SJohn Marino   if (is_global_var (var))
276e4b17023SJohn Marino     fprintf (file, ", is global");
277e4b17023SJohn Marino 
278e4b17023SJohn Marino   if (TREE_THIS_VOLATILE (var))
279e4b17023SJohn Marino     fprintf (file, ", is volatile");
280e4b17023SJohn Marino 
281e4b17023SJohn Marino   if (cfun && gimple_default_def (cfun, var))
282e4b17023SJohn Marino     {
283e4b17023SJohn Marino       fprintf (file, ", default def: ");
284e4b17023SJohn Marino       print_generic_expr (file, gimple_default_def (cfun, var), dump_flags);
285e4b17023SJohn Marino     }
286e4b17023SJohn Marino 
287e4b17023SJohn Marino   if (DECL_INITIAL (var))
288e4b17023SJohn Marino     {
289e4b17023SJohn Marino       fprintf (file, ", initial: ");
290e4b17023SJohn Marino       print_generic_expr (file, DECL_INITIAL (var), dump_flags);
291e4b17023SJohn Marino     }
292e4b17023SJohn Marino 
293e4b17023SJohn Marino   fprintf (file, "\n");
294e4b17023SJohn Marino }
295e4b17023SJohn Marino 
296e4b17023SJohn Marino 
297e4b17023SJohn Marino /* Dump variable VAR and its may-aliases to stderr.  */
298e4b17023SJohn Marino 
299e4b17023SJohn Marino DEBUG_FUNCTION void
debug_variable(tree var)300e4b17023SJohn Marino debug_variable (tree var)
301e4b17023SJohn Marino {
302e4b17023SJohn Marino   dump_variable (stderr, var);
303e4b17023SJohn Marino }
304e4b17023SJohn Marino 
305e4b17023SJohn Marino 
306e4b17023SJohn Marino /* Dump various DFA statistics to FILE.  */
307e4b17023SJohn Marino 
308e4b17023SJohn Marino void
dump_dfa_stats(FILE * file)309e4b17023SJohn Marino dump_dfa_stats (FILE *file)
310e4b17023SJohn Marino {
311e4b17023SJohn Marino   struct dfa_stats_d dfa_stats;
312e4b17023SJohn Marino 
313e4b17023SJohn Marino   unsigned long size, total = 0;
314e4b17023SJohn Marino   const char * const fmt_str   = "%-30s%-13s%12s\n";
315e4b17023SJohn Marino   const char * const fmt_str_1 = "%-30s%13lu%11lu%c\n";
316e4b17023SJohn Marino   const char * const fmt_str_3 = "%-43s%11lu%c\n";
317e4b17023SJohn Marino   const char *funcname
318e4b17023SJohn Marino     = lang_hooks.decl_printable_name (current_function_decl, 2);
319e4b17023SJohn Marino 
320e4b17023SJohn Marino   collect_dfa_stats (&dfa_stats);
321e4b17023SJohn Marino 
322e4b17023SJohn Marino   fprintf (file, "\nDFA Statistics for %s\n\n", funcname);
323e4b17023SJohn Marino 
324e4b17023SJohn Marino   fprintf (file, "---------------------------------------------------------\n");
325e4b17023SJohn Marino   fprintf (file, fmt_str, "", "  Number of  ", "Memory");
326e4b17023SJohn Marino   fprintf (file, fmt_str, "", "  instances  ", "used ");
327e4b17023SJohn Marino   fprintf (file, "---------------------------------------------------------\n");
328e4b17023SJohn Marino 
329e4b17023SJohn Marino   size = num_referenced_vars * sizeof (tree);
330e4b17023SJohn Marino   total += size;
331e4b17023SJohn Marino   fprintf (file, fmt_str_1, "Referenced variables", (unsigned long)num_referenced_vars,
332e4b17023SJohn Marino 	   SCALE (size), LABEL (size));
333e4b17023SJohn Marino 
334e4b17023SJohn Marino   size = dfa_stats.num_var_anns * sizeof (struct var_ann_d);
335e4b17023SJohn Marino   total += size;
336e4b17023SJohn Marino   fprintf (file, fmt_str_1, "Variables annotated", dfa_stats.num_var_anns,
337e4b17023SJohn Marino 	   SCALE (size), LABEL (size));
338e4b17023SJohn Marino 
339e4b17023SJohn Marino   size = dfa_stats.num_uses * sizeof (tree *);
340e4b17023SJohn Marino   total += size;
341e4b17023SJohn Marino   fprintf (file, fmt_str_1, "USE operands", dfa_stats.num_uses,
342e4b17023SJohn Marino 	   SCALE (size), LABEL (size));
343e4b17023SJohn Marino 
344e4b17023SJohn Marino   size = dfa_stats.num_defs * sizeof (tree *);
345e4b17023SJohn Marino   total += size;
346e4b17023SJohn Marino   fprintf (file, fmt_str_1, "DEF operands", dfa_stats.num_defs,
347e4b17023SJohn Marino 	   SCALE (size), LABEL (size));
348e4b17023SJohn Marino 
349e4b17023SJohn Marino   size = dfa_stats.num_vuses * sizeof (tree *);
350e4b17023SJohn Marino   total += size;
351e4b17023SJohn Marino   fprintf (file, fmt_str_1, "VUSE operands", dfa_stats.num_vuses,
352e4b17023SJohn Marino 	   SCALE (size), LABEL (size));
353e4b17023SJohn Marino 
354e4b17023SJohn Marino   size = dfa_stats.num_vdefs * sizeof (tree *);
355e4b17023SJohn Marino   total += size;
356e4b17023SJohn Marino   fprintf (file, fmt_str_1, "VDEF operands", dfa_stats.num_vdefs,
357e4b17023SJohn Marino 	   SCALE (size), LABEL (size));
358e4b17023SJohn Marino 
359e4b17023SJohn Marino   size = dfa_stats.num_phis * sizeof (struct gimple_statement_phi);
360e4b17023SJohn Marino   total += size;
361e4b17023SJohn Marino   fprintf (file, fmt_str_1, "PHI nodes", dfa_stats.num_phis,
362e4b17023SJohn Marino 	   SCALE (size), LABEL (size));
363e4b17023SJohn Marino 
364e4b17023SJohn Marino   size = dfa_stats.num_phi_args * sizeof (struct phi_arg_d);
365e4b17023SJohn Marino   total += size;
366e4b17023SJohn Marino   fprintf (file, fmt_str_1, "PHI arguments", dfa_stats.num_phi_args,
367e4b17023SJohn Marino  	   SCALE (size), LABEL (size));
368e4b17023SJohn Marino 
369e4b17023SJohn Marino   fprintf (file, "---------------------------------------------------------\n");
370e4b17023SJohn Marino   fprintf (file, fmt_str_3, "Total memory used by DFA/SSA data", SCALE (total),
371e4b17023SJohn Marino 	   LABEL (total));
372e4b17023SJohn Marino   fprintf (file, "---------------------------------------------------------\n");
373e4b17023SJohn Marino   fprintf (file, "\n");
374e4b17023SJohn Marino 
375e4b17023SJohn Marino   if (dfa_stats.num_phis)
376e4b17023SJohn Marino     fprintf (file, "Average number of arguments per PHI node: %.1f (max: %ld)\n",
377e4b17023SJohn Marino 	     (float) dfa_stats.num_phi_args / (float) dfa_stats.num_phis,
378e4b17023SJohn Marino 	     (long) dfa_stats.max_num_phi_args);
379e4b17023SJohn Marino 
380e4b17023SJohn Marino   fprintf (file, "\n");
381e4b17023SJohn Marino }
382e4b17023SJohn Marino 
383e4b17023SJohn Marino 
384e4b17023SJohn Marino /* Dump DFA statistics on stderr.  */
385e4b17023SJohn Marino 
386e4b17023SJohn Marino DEBUG_FUNCTION void
debug_dfa_stats(void)387e4b17023SJohn Marino debug_dfa_stats (void)
388e4b17023SJohn Marino {
389e4b17023SJohn Marino   dump_dfa_stats (stderr);
390e4b17023SJohn Marino }
391e4b17023SJohn Marino 
392e4b17023SJohn Marino 
393e4b17023SJohn Marino /* Collect DFA statistics and store them in the structure pointed to by
394e4b17023SJohn Marino    DFA_STATS_P.  */
395e4b17023SJohn Marino 
396e4b17023SJohn Marino static void
collect_dfa_stats(struct dfa_stats_d * dfa_stats_p ATTRIBUTE_UNUSED)397e4b17023SJohn Marino collect_dfa_stats (struct dfa_stats_d *dfa_stats_p ATTRIBUTE_UNUSED)
398e4b17023SJohn Marino {
399e4b17023SJohn Marino   basic_block bb;
400e4b17023SJohn Marino   referenced_var_iterator vi;
401e4b17023SJohn Marino   tree var;
402e4b17023SJohn Marino 
403e4b17023SJohn Marino   gcc_assert (dfa_stats_p);
404e4b17023SJohn Marino 
405e4b17023SJohn Marino   memset ((void *)dfa_stats_p, 0, sizeof (struct dfa_stats_d));
406e4b17023SJohn Marino 
407e4b17023SJohn Marino   /* Count all the variable annotations.  */
408e4b17023SJohn Marino   FOR_EACH_REFERENCED_VAR (cfun, var, vi)
409e4b17023SJohn Marino     if (var_ann (var))
410e4b17023SJohn Marino       dfa_stats_p->num_var_anns++;
411e4b17023SJohn Marino 
412e4b17023SJohn Marino   /* Walk all the statements in the function counting references.  */
413e4b17023SJohn Marino   FOR_EACH_BB (bb)
414e4b17023SJohn Marino     {
415e4b17023SJohn Marino       gimple_stmt_iterator si;
416e4b17023SJohn Marino 
417e4b17023SJohn Marino       for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si))
418e4b17023SJohn Marino 	{
419e4b17023SJohn Marino 	  gimple phi = gsi_stmt (si);
420e4b17023SJohn Marino 	  dfa_stats_p->num_phis++;
421e4b17023SJohn Marino 	  dfa_stats_p->num_phi_args += gimple_phi_num_args (phi);
422e4b17023SJohn Marino 	  if (gimple_phi_num_args (phi) > dfa_stats_p->max_num_phi_args)
423e4b17023SJohn Marino 	    dfa_stats_p->max_num_phi_args = gimple_phi_num_args (phi);
424e4b17023SJohn Marino 	}
425e4b17023SJohn Marino 
426e4b17023SJohn Marino       for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
427e4b17023SJohn Marino 	{
428e4b17023SJohn Marino 	  gimple stmt = gsi_stmt (si);
429e4b17023SJohn Marino 	  dfa_stats_p->num_defs += NUM_SSA_OPERANDS (stmt, SSA_OP_DEF);
430e4b17023SJohn Marino 	  dfa_stats_p->num_uses += NUM_SSA_OPERANDS (stmt, SSA_OP_USE);
431e4b17023SJohn Marino 	  dfa_stats_p->num_vdefs += gimple_vdef (stmt) ? 1 : 0;
432e4b17023SJohn Marino 	  dfa_stats_p->num_vuses += gimple_vuse (stmt) ? 1 : 0;
433e4b17023SJohn Marino 	}
434e4b17023SJohn Marino     }
435e4b17023SJohn Marino }
436e4b17023SJohn Marino 
437e4b17023SJohn Marino 
438e4b17023SJohn Marino /*---------------------------------------------------------------------------
439e4b17023SJohn Marino 			     Miscellaneous helpers
440e4b17023SJohn Marino ---------------------------------------------------------------------------*/
441e4b17023SJohn Marino /* Callback for walk_tree.  Used to collect variables referenced in
442e4b17023SJohn Marino    the function.  */
443e4b17023SJohn Marino 
444e4b17023SJohn Marino static tree
find_vars_r(tree * tp,int * walk_subtrees,void * data ATTRIBUTE_UNUSED)445e4b17023SJohn Marino find_vars_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
446e4b17023SJohn Marino {
447e4b17023SJohn Marino   /* If we are reading the lto info back in, we need to rescan the
448e4b17023SJohn Marino      referenced vars.  */
449e4b17023SJohn Marino   if (TREE_CODE (*tp) == SSA_NAME)
450e4b17023SJohn Marino     add_referenced_var (SSA_NAME_VAR (*tp));
451e4b17023SJohn Marino 
452e4b17023SJohn Marino   /* If T is a regular variable that the optimizers are interested
453e4b17023SJohn Marino      in, add it to the list of variables.  */
454e4b17023SJohn Marino   else if (SSA_VAR_P (*tp))
455e4b17023SJohn Marino     add_referenced_var (*tp);
456e4b17023SJohn Marino 
457e4b17023SJohn Marino   /* Type, _DECL and constant nodes have no interesting children.
458e4b17023SJohn Marino      Ignore them.  */
459e4b17023SJohn Marino   else if (IS_TYPE_OR_DECL_P (*tp) || CONSTANT_CLASS_P (*tp))
460e4b17023SJohn Marino     *walk_subtrees = 0;
461e4b17023SJohn Marino 
462e4b17023SJohn Marino   return NULL_TREE;
463e4b17023SJohn Marino }
464e4b17023SJohn Marino 
465e4b17023SJohn Marino /* Find referenced variables in STMT.  In contrast with
466e4b17023SJohn Marino    find_new_referenced_vars, this function will not mark newly found
467e4b17023SJohn Marino    variables for renaming.  */
468e4b17023SJohn Marino 
469e4b17023SJohn Marino void
find_referenced_vars_in(gimple stmt)470e4b17023SJohn Marino find_referenced_vars_in (gimple stmt)
471e4b17023SJohn Marino {
472e4b17023SJohn Marino   size_t i;
473e4b17023SJohn Marino 
474e4b17023SJohn Marino   if (gimple_code (stmt) != GIMPLE_PHI)
475e4b17023SJohn Marino     {
476e4b17023SJohn Marino       for (i = 0; i < gimple_num_ops (stmt); i++)
477e4b17023SJohn Marino 	walk_tree (gimple_op_ptr (stmt, i), find_vars_r, NULL, NULL);
478e4b17023SJohn Marino     }
479e4b17023SJohn Marino   else
480e4b17023SJohn Marino     {
481e4b17023SJohn Marino       walk_tree (gimple_phi_result_ptr (stmt), find_vars_r, NULL, NULL);
482e4b17023SJohn Marino 
483e4b17023SJohn Marino       for (i = 0; i < gimple_phi_num_args (stmt); i++)
484e4b17023SJohn Marino 	{
485e4b17023SJohn Marino 	  tree arg = gimple_phi_arg_def (stmt, i);
486e4b17023SJohn Marino 	  walk_tree (&arg, find_vars_r, NULL, NULL);
487e4b17023SJohn Marino 	}
488e4b17023SJohn Marino     }
489e4b17023SJohn Marino }
490e4b17023SJohn Marino 
491e4b17023SJohn Marino 
492e4b17023SJohn Marino /* Lookup UID in the referenced_vars hashtable and return the associated
493e4b17023SJohn Marino    variable.  */
494e4b17023SJohn Marino 
495e4b17023SJohn Marino tree
referenced_var_lookup(struct function * fn,unsigned int uid)496e4b17023SJohn Marino referenced_var_lookup (struct function *fn, unsigned int uid)
497e4b17023SJohn Marino {
498e4b17023SJohn Marino   tree h;
499e4b17023SJohn Marino   struct tree_decl_minimal in;
500e4b17023SJohn Marino   in.uid = uid;
501e4b17023SJohn Marino   h = (tree) htab_find_with_hash (gimple_referenced_vars (fn), &in, uid);
502e4b17023SJohn Marino   return h;
503e4b17023SJohn Marino }
504e4b17023SJohn Marino 
505e4b17023SJohn Marino /* Check if TO is in the referenced_vars hash table and insert it if not.
506e4b17023SJohn Marino    Return true if it required insertion.  */
507e4b17023SJohn Marino 
508e4b17023SJohn Marino bool
referenced_var_check_and_insert(tree to)509e4b17023SJohn Marino referenced_var_check_and_insert (tree to)
510e4b17023SJohn Marino {
511e4b17023SJohn Marino   tree h, *loc;
512e4b17023SJohn Marino   struct tree_decl_minimal in;
513e4b17023SJohn Marino   unsigned int uid = DECL_UID (to);
514e4b17023SJohn Marino 
515e4b17023SJohn Marino   in.uid = uid;
516e4b17023SJohn Marino   h = (tree) htab_find_with_hash (gimple_referenced_vars (cfun), &in, uid);
517e4b17023SJohn Marino   if (h)
518e4b17023SJohn Marino     {
519e4b17023SJohn Marino       /* DECL_UID has already been entered in the table.  Verify that it is
520e4b17023SJohn Marino 	 the same entry as TO.  See PR 27793.  */
521e4b17023SJohn Marino       gcc_assert (h == to);
522e4b17023SJohn Marino       return false;
523e4b17023SJohn Marino     }
524e4b17023SJohn Marino 
525e4b17023SJohn Marino   loc = (tree *) htab_find_slot_with_hash (gimple_referenced_vars (cfun),
526e4b17023SJohn Marino 					   &in, uid, INSERT);
527e4b17023SJohn Marino   *loc = to;
528e4b17023SJohn Marino   return true;
529e4b17023SJohn Marino }
530e4b17023SJohn Marino 
531e4b17023SJohn Marino /* Lookup VAR UID in the default_defs hashtable and return the associated
532e4b17023SJohn Marino    variable.  */
533e4b17023SJohn Marino 
534e4b17023SJohn Marino tree
gimple_default_def(struct function * fn,tree var)535e4b17023SJohn Marino gimple_default_def (struct function *fn, tree var)
536e4b17023SJohn Marino {
537e4b17023SJohn Marino   struct tree_decl_minimal ind;
538e4b17023SJohn Marino   struct tree_ssa_name in;
539e4b17023SJohn Marino   gcc_assert (SSA_VAR_P (var));
540e4b17023SJohn Marino   in.var = (tree)&ind;
541e4b17023SJohn Marino   ind.uid = DECL_UID (var);
542e4b17023SJohn Marino   return (tree) htab_find_with_hash (DEFAULT_DEFS (fn), &in, DECL_UID (var));
543e4b17023SJohn Marino }
544e4b17023SJohn Marino 
545e4b17023SJohn Marino /* Insert the pair VAR's UID, DEF into the default_defs hashtable.  */
546e4b17023SJohn Marino 
547e4b17023SJohn Marino void
set_default_def(tree var,tree def)548e4b17023SJohn Marino set_default_def (tree var, tree def)
549e4b17023SJohn Marino {
550e4b17023SJohn Marino   struct tree_decl_minimal ind;
551e4b17023SJohn Marino   struct tree_ssa_name in;
552e4b17023SJohn Marino   void **loc;
553e4b17023SJohn Marino 
554e4b17023SJohn Marino   gcc_assert (SSA_VAR_P (var));
555e4b17023SJohn Marino   in.var = (tree)&ind;
556e4b17023SJohn Marino   ind.uid = DECL_UID (var);
557e4b17023SJohn Marino   if (!def)
558e4b17023SJohn Marino     {
559e4b17023SJohn Marino       loc = htab_find_slot_with_hash (DEFAULT_DEFS (cfun), &in,
560e4b17023SJohn Marino             DECL_UID (var), INSERT);
561e4b17023SJohn Marino       gcc_assert (*loc);
562e4b17023SJohn Marino       htab_remove_elt (DEFAULT_DEFS (cfun), *loc);
563e4b17023SJohn Marino       return;
564e4b17023SJohn Marino     }
565e4b17023SJohn Marino   gcc_assert (TREE_CODE (def) == SSA_NAME && SSA_NAME_VAR (def) == var);
566e4b17023SJohn Marino   loc = htab_find_slot_with_hash (DEFAULT_DEFS (cfun), &in,
567e4b17023SJohn Marino                                   DECL_UID (var), INSERT);
568e4b17023SJohn Marino 
569e4b17023SJohn Marino   /* Default definition might be changed by tail call optimization.  */
570e4b17023SJohn Marino   if (*loc)
571e4b17023SJohn Marino     SSA_NAME_IS_DEFAULT_DEF (*(tree *) loc) = false;
572e4b17023SJohn Marino   *(tree *) loc = def;
573e4b17023SJohn Marino 
574e4b17023SJohn Marino    /* Mark DEF as the default definition for VAR.  */
575e4b17023SJohn Marino    SSA_NAME_IS_DEFAULT_DEF (def) = true;
576e4b17023SJohn Marino }
577e4b17023SJohn Marino 
578e4b17023SJohn Marino /* Add VAR to the list of referenced variables if it isn't already there.  */
579e4b17023SJohn Marino 
580e4b17023SJohn Marino bool
add_referenced_var(tree var)581e4b17023SJohn Marino add_referenced_var (tree var)
582e4b17023SJohn Marino {
583e4b17023SJohn Marino   gcc_assert (DECL_P (var));
584e4b17023SJohn Marino   if (!*DECL_VAR_ANN_PTR (var))
585e4b17023SJohn Marino     create_var_ann (var);
586e4b17023SJohn Marino 
587e4b17023SJohn Marino   /* Insert VAR into the referenced_vars hash table if it isn't present.  */
588e4b17023SJohn Marino   if (referenced_var_check_and_insert (var))
589e4b17023SJohn Marino     {
590e4b17023SJohn Marino       /* Scan DECL_INITIAL for pointer variables as they may contain
591e4b17023SJohn Marino 	 address arithmetic referencing the address of other
592e4b17023SJohn Marino 	 variables.  As we are only interested in directly referenced
593e4b17023SJohn Marino 	 globals or referenced locals restrict this to initializers
594e4b17023SJohn Marino 	 than can refer to local variables.  */
595e4b17023SJohn Marino       if (DECL_INITIAL (var)
596e4b17023SJohn Marino           && DECL_CONTEXT (var) == current_function_decl)
597e4b17023SJohn Marino       	walk_tree (&DECL_INITIAL (var), find_vars_r, NULL, 0);
598e4b17023SJohn Marino 
599e4b17023SJohn Marino       return true;
600e4b17023SJohn Marino     }
601e4b17023SJohn Marino 
602e4b17023SJohn Marino   return false;
603e4b17023SJohn Marino }
604e4b17023SJohn Marino 
605e4b17023SJohn Marino /* Remove VAR from the list.  */
606e4b17023SJohn Marino 
607e4b17023SJohn Marino void
remove_referenced_var(tree var)608e4b17023SJohn Marino remove_referenced_var (tree var)
609e4b17023SJohn Marino {
610e4b17023SJohn Marino   var_ann_t v_ann;
611e4b17023SJohn Marino   struct tree_decl_minimal in;
612e4b17023SJohn Marino   void **loc;
613e4b17023SJohn Marino   unsigned int uid = DECL_UID (var);
614e4b17023SJohn Marino 
615e4b17023SJohn Marino   /* Preserve var_anns of globals.  */
616e4b17023SJohn Marino   if (!is_global_var (var)
617e4b17023SJohn Marino       && (v_ann = var_ann (var)))
618e4b17023SJohn Marino     {
619e4b17023SJohn Marino       ggc_free (v_ann);
620e4b17023SJohn Marino       *DECL_VAR_ANN_PTR (var) = NULL;
621e4b17023SJohn Marino     }
622e4b17023SJohn Marino   gcc_assert (DECL_P (var));
623e4b17023SJohn Marino   in.uid = uid;
624e4b17023SJohn Marino   loc = htab_find_slot_with_hash (gimple_referenced_vars (cfun), &in, uid,
625e4b17023SJohn Marino 				  NO_INSERT);
626e4b17023SJohn Marino   htab_clear_slot (gimple_referenced_vars (cfun), loc);
627e4b17023SJohn Marino }
628e4b17023SJohn Marino 
629e4b17023SJohn Marino 
630e4b17023SJohn Marino /* Return the virtual variable associated to the non-scalar variable VAR.  */
631e4b17023SJohn Marino 
632e4b17023SJohn Marino tree
get_virtual_var(tree var)633e4b17023SJohn Marino get_virtual_var (tree var)
634e4b17023SJohn Marino {
635e4b17023SJohn Marino   STRIP_NOPS (var);
636e4b17023SJohn Marino 
637e4b17023SJohn Marino   if (TREE_CODE (var) == SSA_NAME)
638e4b17023SJohn Marino     var = SSA_NAME_VAR (var);
639e4b17023SJohn Marino 
640e4b17023SJohn Marino   while (TREE_CODE (var) == REALPART_EXPR || TREE_CODE (var) == IMAGPART_EXPR
641e4b17023SJohn Marino 	 || handled_component_p (var))
642e4b17023SJohn Marino     var = TREE_OPERAND (var, 0);
643e4b17023SJohn Marino 
644e4b17023SJohn Marino   /* Treating GIMPLE registers as virtual variables makes no sense.
645e4b17023SJohn Marino      Also complain if we couldn't extract a _DECL out of the original
646e4b17023SJohn Marino      expression.  */
647e4b17023SJohn Marino   gcc_assert (SSA_VAR_P (var));
648e4b17023SJohn Marino   gcc_assert (!is_gimple_reg (var));
649e4b17023SJohn Marino 
650e4b17023SJohn Marino   return var;
651e4b17023SJohn Marino }
652e4b17023SJohn Marino 
653e4b17023SJohn Marino /* Mark all the naked symbols in STMT for SSA renaming.  */
654e4b17023SJohn Marino 
655e4b17023SJohn Marino void
mark_symbols_for_renaming(gimple stmt)656e4b17023SJohn Marino mark_symbols_for_renaming (gimple stmt)
657e4b17023SJohn Marino {
658e4b17023SJohn Marino   tree op;
659e4b17023SJohn Marino   ssa_op_iter iter;
660e4b17023SJohn Marino 
661e4b17023SJohn Marino   update_stmt (stmt);
662e4b17023SJohn Marino 
663e4b17023SJohn Marino   /* Mark all the operands for renaming.  */
664e4b17023SJohn Marino   FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_ALL_OPERANDS)
665e4b17023SJohn Marino     if (DECL_P (op))
666e4b17023SJohn Marino       mark_sym_for_renaming (op);
667e4b17023SJohn Marino }
668e4b17023SJohn Marino 
669e4b17023SJohn Marino 
670e4b17023SJohn Marino /* Find all variables within the gimplified statement that were not
671e4b17023SJohn Marino    previously visible to the function and add them to the referenced
672e4b17023SJohn Marino    variables list.  */
673e4b17023SJohn Marino 
674e4b17023SJohn Marino static tree
find_new_referenced_vars_1(tree * tp,int * walk_subtrees,void * data ATTRIBUTE_UNUSED)675e4b17023SJohn Marino find_new_referenced_vars_1 (tree *tp, int *walk_subtrees,
676e4b17023SJohn Marino 			    void *data ATTRIBUTE_UNUSED)
677e4b17023SJohn Marino {
678e4b17023SJohn Marino   tree t = *tp;
679e4b17023SJohn Marino 
680e4b17023SJohn Marino   if (TREE_CODE (t) == VAR_DECL && !var_ann (t))
681e4b17023SJohn Marino     {
682e4b17023SJohn Marino       add_referenced_var (t);
683e4b17023SJohn Marino       mark_sym_for_renaming (t);
684e4b17023SJohn Marino     }
685e4b17023SJohn Marino 
686e4b17023SJohn Marino   if (IS_TYPE_OR_DECL_P (t))
687e4b17023SJohn Marino     *walk_subtrees = 0;
688e4b17023SJohn Marino 
689e4b17023SJohn Marino   return NULL;
690e4b17023SJohn Marino }
691e4b17023SJohn Marino 
692e4b17023SJohn Marino 
693e4b17023SJohn Marino /* Find any new referenced variables in STMT.  */
694e4b17023SJohn Marino 
695e4b17023SJohn Marino void
find_new_referenced_vars(gimple stmt)696e4b17023SJohn Marino find_new_referenced_vars (gimple stmt)
697e4b17023SJohn Marino {
698e4b17023SJohn Marino   walk_gimple_op (stmt, find_new_referenced_vars_1, NULL);
699e4b17023SJohn Marino }
700e4b17023SJohn Marino 
701e4b17023SJohn Marino 
702e4b17023SJohn Marino /* If EXP is a handled component reference for a structure, return the
703e4b17023SJohn Marino    base variable.  The access range is delimited by bit positions *POFFSET and
704e4b17023SJohn Marino    *POFFSET + *PMAX_SIZE.  The access size is *PSIZE bits.  If either
705e4b17023SJohn Marino    *PSIZE or *PMAX_SIZE is -1, they could not be determined.  If *PSIZE
706e4b17023SJohn Marino    and *PMAX_SIZE are equal, the access is non-variable.  */
707e4b17023SJohn Marino 
708e4b17023SJohn Marino tree
get_ref_base_and_extent(tree exp,HOST_WIDE_INT * poffset,HOST_WIDE_INT * psize,HOST_WIDE_INT * pmax_size)709e4b17023SJohn Marino get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset,
710e4b17023SJohn Marino 			 HOST_WIDE_INT *psize,
711e4b17023SJohn Marino 			 HOST_WIDE_INT *pmax_size)
712e4b17023SJohn Marino {
713e4b17023SJohn Marino   HOST_WIDE_INT bitsize = -1;
714e4b17023SJohn Marino   HOST_WIDE_INT maxsize = -1;
715e4b17023SJohn Marino   tree size_tree = NULL_TREE;
716*95d28233SJohn Marino   double_int bit_offset = double_int_zero;
717*95d28233SJohn Marino   HOST_WIDE_INT hbit_offset;
718e4b17023SJohn Marino   bool seen_variable_array_ref = false;
719e4b17023SJohn Marino 
720e4b17023SJohn Marino   /* First get the final access size from just the outermost expression.  */
721e4b17023SJohn Marino   if (TREE_CODE (exp) == COMPONENT_REF)
722e4b17023SJohn Marino     size_tree = DECL_SIZE (TREE_OPERAND (exp, 1));
723e4b17023SJohn Marino   else if (TREE_CODE (exp) == BIT_FIELD_REF)
724e4b17023SJohn Marino     size_tree = TREE_OPERAND (exp, 1);
725e4b17023SJohn Marino   else if (!VOID_TYPE_P (TREE_TYPE (exp)))
726e4b17023SJohn Marino     {
727e4b17023SJohn Marino       enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
728e4b17023SJohn Marino       if (mode == BLKmode)
729e4b17023SJohn Marino 	size_tree = TYPE_SIZE (TREE_TYPE (exp));
730e4b17023SJohn Marino       else
731e4b17023SJohn Marino 	bitsize = GET_MODE_BITSIZE (mode);
732e4b17023SJohn Marino     }
733e4b17023SJohn Marino   if (size_tree != NULL_TREE)
734e4b17023SJohn Marino     {
735e4b17023SJohn Marino       if (! host_integerp (size_tree, 1))
736e4b17023SJohn Marino 	bitsize = -1;
737e4b17023SJohn Marino       else
738e4b17023SJohn Marino 	bitsize = TREE_INT_CST_LOW (size_tree);
739e4b17023SJohn Marino     }
740e4b17023SJohn Marino 
741e4b17023SJohn Marino   /* Initially, maxsize is the same as the accessed element size.
742e4b17023SJohn Marino      In the following it will only grow (or become -1).  */
743e4b17023SJohn Marino   maxsize = bitsize;
744e4b17023SJohn Marino 
745e4b17023SJohn Marino   /* Compute cumulative bit-offset for nested component-refs and array-refs,
746e4b17023SJohn Marino      and find the ultimate containing object.  */
747e4b17023SJohn Marino   while (1)
748e4b17023SJohn Marino     {
749e4b17023SJohn Marino       switch (TREE_CODE (exp))
750e4b17023SJohn Marino 	{
751e4b17023SJohn Marino 	case BIT_FIELD_REF:
752*95d28233SJohn Marino 	  bit_offset
753*95d28233SJohn Marino 	    = double_int_add (bit_offset,
754*95d28233SJohn Marino 			      tree_to_double_int (TREE_OPERAND (exp, 2)));
755e4b17023SJohn Marino 	  break;
756e4b17023SJohn Marino 
757e4b17023SJohn Marino 	case COMPONENT_REF:
758e4b17023SJohn Marino 	  {
759e4b17023SJohn Marino 	    tree field = TREE_OPERAND (exp, 1);
760e4b17023SJohn Marino 	    tree this_offset = component_ref_field_offset (exp);
761e4b17023SJohn Marino 
762*95d28233SJohn Marino 	    if (this_offset && TREE_CODE (this_offset) == INTEGER_CST)
763e4b17023SJohn Marino 	      {
764*95d28233SJohn Marino 		double_int doffset = tree_to_double_int (this_offset);
765*95d28233SJohn Marino 		doffset = double_int_lshift (doffset,
766*95d28233SJohn Marino 					     BITS_PER_UNIT == 8
767*95d28233SJohn Marino 					     ? 3 : exact_log2 (BITS_PER_UNIT),
768*95d28233SJohn Marino 					     HOST_BITS_PER_DOUBLE_INT, true);
769*95d28233SJohn Marino 		doffset = double_int_add (doffset,
770*95d28233SJohn Marino 					  tree_to_double_int
771*95d28233SJohn Marino 					  (DECL_FIELD_BIT_OFFSET (field)));
772*95d28233SJohn Marino 		bit_offset = double_int_add (bit_offset, doffset);
773e4b17023SJohn Marino 
774e4b17023SJohn Marino 		/* If we had seen a variable array ref already and we just
775e4b17023SJohn Marino 		   referenced the last field of a struct or a union member
776e4b17023SJohn Marino 		   then we have to adjust maxsize by the padding at the end
777e4b17023SJohn Marino 		   of our field.  */
778*95d28233SJohn Marino 		if (seen_variable_array_ref && maxsize != -1)
779e4b17023SJohn Marino 		  {
780e4b17023SJohn Marino 		    tree stype = TREE_TYPE (TREE_OPERAND (exp, 0));
781e4b17023SJohn Marino 		    tree next = DECL_CHAIN (field);
782e4b17023SJohn Marino 		    while (next && TREE_CODE (next) != FIELD_DECL)
783e4b17023SJohn Marino 		      next = DECL_CHAIN (next);
784e4b17023SJohn Marino 		    if (!next
785e4b17023SJohn Marino 			|| TREE_CODE (stype) != RECORD_TYPE)
786e4b17023SJohn Marino 		      {
787e4b17023SJohn Marino 			tree fsize = DECL_SIZE_UNIT (field);
788e4b17023SJohn Marino 			tree ssize = TYPE_SIZE_UNIT (stype);
789e4b17023SJohn Marino 			if (host_integerp (fsize, 0)
790*95d28233SJohn Marino 			    && host_integerp (ssize, 0)
791*95d28233SJohn Marino 			    && double_int_fits_in_shwi_p (doffset))
792e4b17023SJohn Marino 			  maxsize += ((TREE_INT_CST_LOW (ssize)
793e4b17023SJohn Marino 				       - TREE_INT_CST_LOW (fsize))
794*95d28233SJohn Marino 				      * BITS_PER_UNIT
795*95d28233SJohn Marino 					- double_int_to_shwi (doffset));
796e4b17023SJohn Marino 			else
797e4b17023SJohn Marino 			  maxsize = -1;
798e4b17023SJohn Marino 		      }
799e4b17023SJohn Marino 		  }
800e4b17023SJohn Marino 	      }
801e4b17023SJohn Marino 	    else
802e4b17023SJohn Marino 	      {
803e4b17023SJohn Marino 		tree csize = TYPE_SIZE (TREE_TYPE (TREE_OPERAND (exp, 0)));
804e4b17023SJohn Marino 		/* We need to adjust maxsize to the whole structure bitsize.
805e4b17023SJohn Marino 		   But we can subtract any constant offset seen so far,
806e4b17023SJohn Marino 		   because that would get us out of the structure otherwise.  */
807*95d28233SJohn Marino 		if (maxsize != -1
808*95d28233SJohn Marino 		    && csize
809*95d28233SJohn Marino 		    && host_integerp (csize, 1)
810*95d28233SJohn Marino 		    && double_int_fits_in_shwi_p (bit_offset))
811*95d28233SJohn Marino 		  maxsize = TREE_INT_CST_LOW (csize)
812*95d28233SJohn Marino 			    - double_int_to_shwi (bit_offset);
813e4b17023SJohn Marino 		else
814e4b17023SJohn Marino 		  maxsize = -1;
815e4b17023SJohn Marino 	      }
816e4b17023SJohn Marino 	  }
817e4b17023SJohn Marino 	  break;
818e4b17023SJohn Marino 
819e4b17023SJohn Marino 	case ARRAY_REF:
820e4b17023SJohn Marino 	case ARRAY_RANGE_REF:
821e4b17023SJohn Marino 	  {
822e4b17023SJohn Marino 	    tree index = TREE_OPERAND (exp, 1);
823e4b17023SJohn Marino 	    tree low_bound, unit_size;
824e4b17023SJohn Marino 
825e4b17023SJohn Marino 	    /* If the resulting bit-offset is constant, track it.  */
826e4b17023SJohn Marino 	    if (TREE_CODE (index) == INTEGER_CST
827e4b17023SJohn Marino 		&& (low_bound = array_ref_low_bound (exp),
828*95d28233SJohn Marino 		    TREE_CODE (low_bound) == INTEGER_CST)
829e4b17023SJohn Marino 		&& (unit_size = array_ref_element_size (exp),
830*95d28233SJohn Marino 		    TREE_CODE (unit_size) == INTEGER_CST))
831e4b17023SJohn Marino 	      {
832*95d28233SJohn Marino 		double_int doffset
833*95d28233SJohn Marino 		  = double_int_sext
834*95d28233SJohn Marino 		    (double_int_sub (TREE_INT_CST (index),
835*95d28233SJohn Marino 				     TREE_INT_CST (low_bound)),
836*95d28233SJohn Marino 		     TYPE_PRECISION (TREE_TYPE (index)));
837*95d28233SJohn Marino 		doffset = double_int_mul (doffset,
838*95d28233SJohn Marino 					  tree_to_double_int (unit_size));
839*95d28233SJohn Marino 		doffset = double_int_lshift (doffset,
840*95d28233SJohn Marino 					     BITS_PER_UNIT == 8
841*95d28233SJohn Marino 					     ? 3 : exact_log2 (BITS_PER_UNIT),
842*95d28233SJohn Marino 					     HOST_BITS_PER_DOUBLE_INT, true);
843*95d28233SJohn Marino 		bit_offset = double_int_add (bit_offset, doffset);
844e4b17023SJohn Marino 
845e4b17023SJohn Marino 		/* An array ref with a constant index up in the structure
846e4b17023SJohn Marino 		   hierarchy will constrain the size of any variable array ref
847e4b17023SJohn Marino 		   lower in the access hierarchy.  */
848e4b17023SJohn Marino 		seen_variable_array_ref = false;
849e4b17023SJohn Marino 	      }
850e4b17023SJohn Marino 	    else
851e4b17023SJohn Marino 	      {
852e4b17023SJohn Marino 		tree asize = TYPE_SIZE (TREE_TYPE (TREE_OPERAND (exp, 0)));
853e4b17023SJohn Marino 		/* We need to adjust maxsize to the whole array bitsize.
854e4b17023SJohn Marino 		   But we can subtract any constant offset seen so far,
855e4b17023SJohn Marino 		   because that would get us outside of the array otherwise.  */
856*95d28233SJohn Marino 		if (maxsize != -1
857*95d28233SJohn Marino 		    && asize
858*95d28233SJohn Marino 		    && host_integerp (asize, 1)
859*95d28233SJohn Marino 		    && double_int_fits_in_shwi_p (bit_offset))
860*95d28233SJohn Marino 		  maxsize = TREE_INT_CST_LOW (asize)
861*95d28233SJohn Marino 			    - double_int_to_shwi (bit_offset);
862e4b17023SJohn Marino 		else
863e4b17023SJohn Marino 		  maxsize = -1;
864e4b17023SJohn Marino 
865e4b17023SJohn Marino 		/* Remember that we have seen an array ref with a variable
866e4b17023SJohn Marino 		   index.  */
867e4b17023SJohn Marino 		seen_variable_array_ref = true;
868e4b17023SJohn Marino 	      }
869e4b17023SJohn Marino 	  }
870e4b17023SJohn Marino 	  break;
871e4b17023SJohn Marino 
872e4b17023SJohn Marino 	case REALPART_EXPR:
873e4b17023SJohn Marino 	  break;
874e4b17023SJohn Marino 
875e4b17023SJohn Marino 	case IMAGPART_EXPR:
876*95d28233SJohn Marino 	  bit_offset
877*95d28233SJohn Marino 	    = double_int_add (bit_offset, uhwi_to_double_int (bitsize));
878e4b17023SJohn Marino 	  break;
879e4b17023SJohn Marino 
880e4b17023SJohn Marino 	case VIEW_CONVERT_EXPR:
881e4b17023SJohn Marino 	  break;
882e4b17023SJohn Marino 
883*95d28233SJohn Marino 	case TARGET_MEM_REF:
884*95d28233SJohn Marino 	  /* Via the variable index or index2 we can reach the
885*95d28233SJohn Marino 	     whole object.  Still hand back the decl here.  */
886*95d28233SJohn Marino 	  if (TREE_CODE (TMR_BASE (exp)) == ADDR_EXPR
887*95d28233SJohn Marino 	      && (TMR_INDEX (exp) || TMR_INDEX2 (exp)))
888*95d28233SJohn Marino 	    {
889*95d28233SJohn Marino 	      exp = TREE_OPERAND (TMR_BASE (exp), 0);
890*95d28233SJohn Marino 	      bit_offset = double_int_zero;
891*95d28233SJohn Marino 	      maxsize = -1;
892*95d28233SJohn Marino 	      goto done;
893*95d28233SJohn Marino 	    }
894*95d28233SJohn Marino 	  /* Fallthru.  */
895e4b17023SJohn Marino 	case MEM_REF:
896*95d28233SJohn Marino 	  /* We need to deal with variable arrays ending structures such as
897*95d28233SJohn Marino 	     struct { int length; int a[1]; } x;           x.a[d]
898*95d28233SJohn Marino 	     struct { struct { int a; int b; } a[1]; } x;  x.a[d].a
899*95d28233SJohn Marino 	     struct { struct { int a[1]; } a[1]; } x;      x.a[0][d], x.a[d][0]
900*95d28233SJohn Marino 	     struct { int len; union { int a[1]; struct X x; } u; } x; x.u.a[d]
901*95d28233SJohn Marino 	     where we do not know maxsize for variable index accesses to
902*95d28233SJohn Marino 	     the array.  The simplest way to conservatively deal with this
903*95d28233SJohn Marino 	     is to punt in the case that offset + maxsize reaches the
904*95d28233SJohn Marino 	     base type boundary.  This needs to include possible trailing
905*95d28233SJohn Marino 	     padding that is there for alignment purposes.  */
906*95d28233SJohn Marino 	  if (seen_variable_array_ref
907*95d28233SJohn Marino 	      && maxsize != -1
908*95d28233SJohn Marino 	      && (!double_int_fits_in_shwi_p (bit_offset)
909*95d28233SJohn Marino 		  || !host_integerp (TYPE_SIZE (TREE_TYPE (exp)), 1)
910*95d28233SJohn Marino 		  || (double_int_to_shwi (bit_offset) + maxsize
911*95d28233SJohn Marino 		      == (HOST_WIDE_INT) TREE_INT_CST_LOW
912*95d28233SJohn Marino 		            (TYPE_SIZE (TREE_TYPE (exp))))))
913*95d28233SJohn Marino 	    maxsize = -1;
914*95d28233SJohn Marino 
915e4b17023SJohn Marino 	  /* Hand back the decl for MEM[&decl, off].  */
916e4b17023SJohn Marino 	  if (TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR)
917e4b17023SJohn Marino 	    {
918e4b17023SJohn Marino 	      if (integer_zerop (TREE_OPERAND (exp, 1)))
919e4b17023SJohn Marino 		exp = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
920e4b17023SJohn Marino 	      else
921e4b17023SJohn Marino 		{
922e4b17023SJohn Marino 		  double_int off = mem_ref_offset (exp);
923e4b17023SJohn Marino 		  off = double_int_lshift (off,
924e4b17023SJohn Marino 					   BITS_PER_UNIT == 8
925e4b17023SJohn Marino 					   ? 3 : exact_log2 (BITS_PER_UNIT),
926e4b17023SJohn Marino 					   HOST_BITS_PER_DOUBLE_INT, true);
927*95d28233SJohn Marino 		  off = double_int_add (off, bit_offset);
928e4b17023SJohn Marino 		  if (double_int_fits_in_shwi_p (off))
929e4b17023SJohn Marino 		    {
930*95d28233SJohn Marino 		      bit_offset = off;
931e4b17023SJohn Marino 		      exp = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
932e4b17023SJohn Marino 		    }
933e4b17023SJohn Marino 		}
934e4b17023SJohn Marino 	    }
935e4b17023SJohn Marino 	  goto done;
936e4b17023SJohn Marino 
937e4b17023SJohn Marino 	default:
938e4b17023SJohn Marino 	  goto done;
939e4b17023SJohn Marino 	}
940e4b17023SJohn Marino 
941e4b17023SJohn Marino       exp = TREE_OPERAND (exp, 0);
942e4b17023SJohn Marino     }
943e4b17023SJohn Marino 
944*95d28233SJohn Marino   /* We need to deal with variable arrays ending structures.  */
945e4b17023SJohn Marino   if (seen_variable_array_ref
946e4b17023SJohn Marino       && maxsize != -1
947*95d28233SJohn Marino       && (!double_int_fits_in_shwi_p (bit_offset)
948*95d28233SJohn Marino 	  || !host_integerp (TYPE_SIZE (TREE_TYPE (exp)), 1)
949*95d28233SJohn Marino 	  || (double_int_to_shwi (bit_offset) + maxsize
950*95d28233SJohn Marino 	      == (HOST_WIDE_INT)
951*95d28233SJohn Marino 		   TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (exp))))))
952e4b17023SJohn Marino     maxsize = -1;
953e4b17023SJohn Marino 
954*95d28233SJohn Marino  done:
955*95d28233SJohn Marino   if (!double_int_fits_in_shwi_p (bit_offset))
956*95d28233SJohn Marino     {
957*95d28233SJohn Marino       *poffset = 0;
958*95d28233SJohn Marino       *psize = bitsize;
959*95d28233SJohn Marino       *pmax_size = -1;
960*95d28233SJohn Marino 
961*95d28233SJohn Marino       return exp;
962*95d28233SJohn Marino     }
963*95d28233SJohn Marino 
964*95d28233SJohn Marino   hbit_offset = double_int_to_shwi (bit_offset);
965*95d28233SJohn Marino 
966e4b17023SJohn Marino   /* In case of a decl or constant base object we can do better.  */
967e4b17023SJohn Marino 
968e4b17023SJohn Marino   if (DECL_P (exp))
969e4b17023SJohn Marino     {
970e4b17023SJohn Marino       /* If maxsize is unknown adjust it according to the size of the
971e4b17023SJohn Marino          base decl.  */
972e4b17023SJohn Marino       if (maxsize == -1
973e4b17023SJohn Marino 	  && host_integerp (DECL_SIZE (exp), 1))
974*95d28233SJohn Marino 	maxsize = TREE_INT_CST_LOW (DECL_SIZE (exp)) - hbit_offset;
975e4b17023SJohn Marino     }
976e4b17023SJohn Marino   else if (CONSTANT_CLASS_P (exp))
977e4b17023SJohn Marino     {
978e4b17023SJohn Marino       /* If maxsize is unknown adjust it according to the size of the
979e4b17023SJohn Marino          base type constant.  */
980e4b17023SJohn Marino       if (maxsize == -1
981e4b17023SJohn Marino 	  && host_integerp (TYPE_SIZE (TREE_TYPE (exp)), 1))
982*95d28233SJohn Marino 	maxsize = TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (exp))) - hbit_offset;
983e4b17023SJohn Marino     }
984e4b17023SJohn Marino 
985e4b17023SJohn Marino   /* ???  Due to negative offsets in ARRAY_REF we can end up with
986e4b17023SJohn Marino      negative bit_offset here.  We might want to store a zero offset
987e4b17023SJohn Marino      in this case.  */
988*95d28233SJohn Marino   *poffset = hbit_offset;
989e4b17023SJohn Marino   *psize = bitsize;
990e4b17023SJohn Marino   *pmax_size = maxsize;
991e4b17023SJohn Marino 
992e4b17023SJohn Marino   return exp;
993e4b17023SJohn Marino }
994e4b17023SJohn Marino 
995e4b17023SJohn Marino /* Returns the base object and a constant BITS_PER_UNIT offset in *POFFSET that
996e4b17023SJohn Marino    denotes the starting address of the memory access EXP.
997e4b17023SJohn Marino    Returns NULL_TREE if the offset is not constant or any component
998e4b17023SJohn Marino    is not BITS_PER_UNIT-aligned.  */
999e4b17023SJohn Marino 
1000e4b17023SJohn Marino tree
get_addr_base_and_unit_offset(tree exp,HOST_WIDE_INT * poffset)1001e4b17023SJohn Marino get_addr_base_and_unit_offset (tree exp, HOST_WIDE_INT *poffset)
1002e4b17023SJohn Marino {
1003e4b17023SJohn Marino   return get_addr_base_and_unit_offset_1 (exp, poffset, NULL);
1004e4b17023SJohn Marino }
1005e4b17023SJohn Marino 
1006e4b17023SJohn Marino /* Returns true if STMT references an SSA_NAME that has
1007e4b17023SJohn Marino    SSA_NAME_OCCURS_IN_ABNORMAL_PHI set, otherwise false.  */
1008e4b17023SJohn Marino 
1009e4b17023SJohn Marino bool
stmt_references_abnormal_ssa_name(gimple stmt)1010e4b17023SJohn Marino stmt_references_abnormal_ssa_name (gimple stmt)
1011e4b17023SJohn Marino {
1012e4b17023SJohn Marino   ssa_op_iter oi;
1013e4b17023SJohn Marino   use_operand_p use_p;
1014e4b17023SJohn Marino 
1015e4b17023SJohn Marino   FOR_EACH_SSA_USE_OPERAND (use_p, stmt, oi, SSA_OP_USE)
1016e4b17023SJohn Marino     {
1017e4b17023SJohn Marino       if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (USE_FROM_PTR (use_p)))
1018e4b17023SJohn Marino 	return true;
1019e4b17023SJohn Marino     }
1020e4b17023SJohn Marino 
1021e4b17023SJohn Marino   return false;
1022e4b17023SJohn Marino }
1023