xref: /dflybsd-src/contrib/gcc-4.7/gcc/tree-ssa.c (revision 04febcfb30580676d3e95f58a16c5137ee478b32)
1*e4b17023SJohn Marino /* Miscellaneous SSA utility functions.
2*e4b17023SJohn Marino    Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011
3*e4b17023SJohn Marino    Free Software Foundation, Inc.
4*e4b17023SJohn Marino 
5*e4b17023SJohn Marino This file is part of GCC.
6*e4b17023SJohn Marino 
7*e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify
8*e4b17023SJohn Marino it under the terms of the GNU General Public License as published by
9*e4b17023SJohn Marino the Free Software Foundation; either version 3, or (at your option)
10*e4b17023SJohn Marino any later version.
11*e4b17023SJohn Marino 
12*e4b17023SJohn Marino GCC is distributed in the hope that it will be useful,
13*e4b17023SJohn Marino but WITHOUT ANY WARRANTY; without even the implied warranty of
14*e4b17023SJohn Marino MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15*e4b17023SJohn Marino GNU General Public License for more details.
16*e4b17023SJohn Marino 
17*e4b17023SJohn Marino You should have received a copy of the GNU General Public License
18*e4b17023SJohn Marino along with GCC; see the file COPYING3.  If not see
19*e4b17023SJohn Marino <http://www.gnu.org/licenses/>.  */
20*e4b17023SJohn Marino 
21*e4b17023SJohn Marino #include "config.h"
22*e4b17023SJohn Marino #include "system.h"
23*e4b17023SJohn Marino #include "coretypes.h"
24*e4b17023SJohn Marino #include "tm.h"
25*e4b17023SJohn Marino #include "tree.h"
26*e4b17023SJohn Marino #include "flags.h"
27*e4b17023SJohn Marino #include "tm_p.h"
28*e4b17023SJohn Marino #include "target.h"
29*e4b17023SJohn Marino #include "ggc.h"
30*e4b17023SJohn Marino #include "langhooks.h"
31*e4b17023SJohn Marino #include "basic-block.h"
32*e4b17023SJohn Marino #include "output.h"
33*e4b17023SJohn Marino #include "function.h"
34*e4b17023SJohn Marino #include "tree-pretty-print.h"
35*e4b17023SJohn Marino #include "gimple-pretty-print.h"
36*e4b17023SJohn Marino #include "bitmap.h"
37*e4b17023SJohn Marino #include "pointer-set.h"
38*e4b17023SJohn Marino #include "tree-flow.h"
39*e4b17023SJohn Marino #include "gimple.h"
40*e4b17023SJohn Marino #include "tree-inline.h"
41*e4b17023SJohn Marino #include "timevar.h"
42*e4b17023SJohn Marino #include "hashtab.h"
43*e4b17023SJohn Marino #include "tree-dump.h"
44*e4b17023SJohn Marino #include "tree-pass.h"
45*e4b17023SJohn Marino #include "diagnostic-core.h"
46*e4b17023SJohn Marino #include "cfgloop.h"
47*e4b17023SJohn Marino 
48*e4b17023SJohn Marino /* Pointer map of variable mappings, keyed by edge.  */
49*e4b17023SJohn Marino static struct pointer_map_t *edge_var_maps;
50*e4b17023SJohn Marino 
51*e4b17023SJohn Marino 
52*e4b17023SJohn Marino /* Add a mapping with PHI RESULT and PHI DEF associated with edge E.  */
53*e4b17023SJohn Marino 
54*e4b17023SJohn Marino void
redirect_edge_var_map_add(edge e,tree result,tree def,source_location locus)55*e4b17023SJohn Marino redirect_edge_var_map_add (edge e, tree result, tree def, source_location locus)
56*e4b17023SJohn Marino {
57*e4b17023SJohn Marino   void **slot;
58*e4b17023SJohn Marino   edge_var_map_vector old_head, head;
59*e4b17023SJohn Marino   edge_var_map new_node;
60*e4b17023SJohn Marino 
61*e4b17023SJohn Marino   if (edge_var_maps == NULL)
62*e4b17023SJohn Marino     edge_var_maps = pointer_map_create ();
63*e4b17023SJohn Marino 
64*e4b17023SJohn Marino   slot = pointer_map_insert (edge_var_maps, e);
65*e4b17023SJohn Marino   old_head = head = (edge_var_map_vector) *slot;
66*e4b17023SJohn Marino   if (!head)
67*e4b17023SJohn Marino     {
68*e4b17023SJohn Marino       head = VEC_alloc (edge_var_map, heap, 5);
69*e4b17023SJohn Marino       *slot = head;
70*e4b17023SJohn Marino     }
71*e4b17023SJohn Marino   new_node.def = def;
72*e4b17023SJohn Marino   new_node.result = result;
73*e4b17023SJohn Marino   new_node.locus = locus;
74*e4b17023SJohn Marino 
75*e4b17023SJohn Marino   VEC_safe_push (edge_var_map, heap, head, &new_node);
76*e4b17023SJohn Marino   if (old_head != head)
77*e4b17023SJohn Marino     {
78*e4b17023SJohn Marino       /* The push did some reallocation.  Update the pointer map.  */
79*e4b17023SJohn Marino       *slot = head;
80*e4b17023SJohn Marino     }
81*e4b17023SJohn Marino }
82*e4b17023SJohn Marino 
83*e4b17023SJohn Marino 
84*e4b17023SJohn Marino /* Clear the var mappings in edge E.  */
85*e4b17023SJohn Marino 
86*e4b17023SJohn Marino void
redirect_edge_var_map_clear(edge e)87*e4b17023SJohn Marino redirect_edge_var_map_clear (edge e)
88*e4b17023SJohn Marino {
89*e4b17023SJohn Marino   void **slot;
90*e4b17023SJohn Marino   edge_var_map_vector head;
91*e4b17023SJohn Marino 
92*e4b17023SJohn Marino   if (!edge_var_maps)
93*e4b17023SJohn Marino     return;
94*e4b17023SJohn Marino 
95*e4b17023SJohn Marino   slot = pointer_map_contains (edge_var_maps, e);
96*e4b17023SJohn Marino 
97*e4b17023SJohn Marino   if (slot)
98*e4b17023SJohn Marino     {
99*e4b17023SJohn Marino       head = (edge_var_map_vector) *slot;
100*e4b17023SJohn Marino       VEC_free (edge_var_map, heap, head);
101*e4b17023SJohn Marino       *slot = NULL;
102*e4b17023SJohn Marino     }
103*e4b17023SJohn Marino }
104*e4b17023SJohn Marino 
105*e4b17023SJohn Marino 
106*e4b17023SJohn Marino /* Duplicate the redirected var mappings in OLDE in NEWE.
107*e4b17023SJohn Marino 
108*e4b17023SJohn Marino    Since we can't remove a mapping, let's just duplicate it.  This assumes a
109*e4b17023SJohn Marino    pointer_map can have multiple edges mapping to the same var_map (many to
110*e4b17023SJohn Marino    one mapping), since we don't remove the previous mappings.  */
111*e4b17023SJohn Marino 
112*e4b17023SJohn Marino void
redirect_edge_var_map_dup(edge newe,edge olde)113*e4b17023SJohn Marino redirect_edge_var_map_dup (edge newe, edge olde)
114*e4b17023SJohn Marino {
115*e4b17023SJohn Marino   void **new_slot, **old_slot;
116*e4b17023SJohn Marino   edge_var_map_vector head;
117*e4b17023SJohn Marino 
118*e4b17023SJohn Marino   if (!edge_var_maps)
119*e4b17023SJohn Marino     return;
120*e4b17023SJohn Marino 
121*e4b17023SJohn Marino   new_slot = pointer_map_insert (edge_var_maps, newe);
122*e4b17023SJohn Marino   old_slot = pointer_map_contains (edge_var_maps, olde);
123*e4b17023SJohn Marino   if (!old_slot)
124*e4b17023SJohn Marino     return;
125*e4b17023SJohn Marino   head = (edge_var_map_vector) *old_slot;
126*e4b17023SJohn Marino 
127*e4b17023SJohn Marino   if (head)
128*e4b17023SJohn Marino     *new_slot = VEC_copy (edge_var_map, heap, head);
129*e4b17023SJohn Marino   else
130*e4b17023SJohn Marino     *new_slot = VEC_alloc (edge_var_map, heap, 5);
131*e4b17023SJohn Marino }
132*e4b17023SJohn Marino 
133*e4b17023SJohn Marino 
134*e4b17023SJohn Marino /* Return the variable mappings for a given edge.  If there is none, return
135*e4b17023SJohn Marino    NULL.  */
136*e4b17023SJohn Marino 
137*e4b17023SJohn Marino edge_var_map_vector
redirect_edge_var_map_vector(edge e)138*e4b17023SJohn Marino redirect_edge_var_map_vector (edge e)
139*e4b17023SJohn Marino {
140*e4b17023SJohn Marino   void **slot;
141*e4b17023SJohn Marino 
142*e4b17023SJohn Marino   /* Hey, what kind of idiot would... you'd be surprised.  */
143*e4b17023SJohn Marino   if (!edge_var_maps)
144*e4b17023SJohn Marino     return NULL;
145*e4b17023SJohn Marino 
146*e4b17023SJohn Marino   slot = pointer_map_contains (edge_var_maps, e);
147*e4b17023SJohn Marino   if (!slot)
148*e4b17023SJohn Marino     return NULL;
149*e4b17023SJohn Marino 
150*e4b17023SJohn Marino   return (edge_var_map_vector) *slot;
151*e4b17023SJohn Marino }
152*e4b17023SJohn Marino 
153*e4b17023SJohn Marino /* Used by redirect_edge_var_map_destroy to free all memory.  */
154*e4b17023SJohn Marino 
155*e4b17023SJohn Marino static bool
free_var_map_entry(const void * key ATTRIBUTE_UNUSED,void ** value,void * data ATTRIBUTE_UNUSED)156*e4b17023SJohn Marino free_var_map_entry (const void *key ATTRIBUTE_UNUSED,
157*e4b17023SJohn Marino 		    void **value,
158*e4b17023SJohn Marino 		    void *data ATTRIBUTE_UNUSED)
159*e4b17023SJohn Marino {
160*e4b17023SJohn Marino   edge_var_map_vector head = (edge_var_map_vector) *value;
161*e4b17023SJohn Marino   VEC_free (edge_var_map, heap, head);
162*e4b17023SJohn Marino   return true;
163*e4b17023SJohn Marino }
164*e4b17023SJohn Marino 
165*e4b17023SJohn Marino /* Clear the edge variable mappings.  */
166*e4b17023SJohn Marino 
167*e4b17023SJohn Marino void
redirect_edge_var_map_destroy(void)168*e4b17023SJohn Marino redirect_edge_var_map_destroy (void)
169*e4b17023SJohn Marino {
170*e4b17023SJohn Marino   if (edge_var_maps)
171*e4b17023SJohn Marino     {
172*e4b17023SJohn Marino       pointer_map_traverse (edge_var_maps, free_var_map_entry, NULL);
173*e4b17023SJohn Marino       pointer_map_destroy (edge_var_maps);
174*e4b17023SJohn Marino       edge_var_maps = NULL;
175*e4b17023SJohn Marino     }
176*e4b17023SJohn Marino }
177*e4b17023SJohn Marino 
178*e4b17023SJohn Marino 
179*e4b17023SJohn Marino /* Remove the corresponding arguments from the PHI nodes in E's
180*e4b17023SJohn Marino    destination block and redirect it to DEST.  Return redirected edge.
181*e4b17023SJohn Marino    The list of removed arguments is stored in a vector accessed
182*e4b17023SJohn Marino    through edge_var_maps.  */
183*e4b17023SJohn Marino 
184*e4b17023SJohn Marino edge
ssa_redirect_edge(edge e,basic_block dest)185*e4b17023SJohn Marino ssa_redirect_edge (edge e, basic_block dest)
186*e4b17023SJohn Marino {
187*e4b17023SJohn Marino   gimple_stmt_iterator gsi;
188*e4b17023SJohn Marino   gimple phi;
189*e4b17023SJohn Marino 
190*e4b17023SJohn Marino   redirect_edge_var_map_clear (e);
191*e4b17023SJohn Marino 
192*e4b17023SJohn Marino   /* Remove the appropriate PHI arguments in E's destination block.  */
193*e4b17023SJohn Marino   for (gsi = gsi_start_phis (e->dest); !gsi_end_p (gsi); gsi_next (&gsi))
194*e4b17023SJohn Marino     {
195*e4b17023SJohn Marino       tree def;
196*e4b17023SJohn Marino       source_location locus ;
197*e4b17023SJohn Marino 
198*e4b17023SJohn Marino       phi = gsi_stmt (gsi);
199*e4b17023SJohn Marino       def = gimple_phi_arg_def (phi, e->dest_idx);
200*e4b17023SJohn Marino       locus = gimple_phi_arg_location (phi, e->dest_idx);
201*e4b17023SJohn Marino 
202*e4b17023SJohn Marino       if (def == NULL_TREE)
203*e4b17023SJohn Marino 	continue;
204*e4b17023SJohn Marino 
205*e4b17023SJohn Marino       redirect_edge_var_map_add (e, gimple_phi_result (phi), def, locus);
206*e4b17023SJohn Marino     }
207*e4b17023SJohn Marino 
208*e4b17023SJohn Marino   e = redirect_edge_succ_nodup (e, dest);
209*e4b17023SJohn Marino 
210*e4b17023SJohn Marino   return e;
211*e4b17023SJohn Marino }
212*e4b17023SJohn Marino 
213*e4b17023SJohn Marino 
214*e4b17023SJohn Marino /* Add PHI arguments queued in PENDING_STMT list on edge E to edge
215*e4b17023SJohn Marino    E->dest.  */
216*e4b17023SJohn Marino 
217*e4b17023SJohn Marino void
flush_pending_stmts(edge e)218*e4b17023SJohn Marino flush_pending_stmts (edge e)
219*e4b17023SJohn Marino {
220*e4b17023SJohn Marino   gimple phi;
221*e4b17023SJohn Marino   edge_var_map_vector v;
222*e4b17023SJohn Marino   edge_var_map *vm;
223*e4b17023SJohn Marino   int i;
224*e4b17023SJohn Marino   gimple_stmt_iterator gsi;
225*e4b17023SJohn Marino 
226*e4b17023SJohn Marino   v = redirect_edge_var_map_vector (e);
227*e4b17023SJohn Marino   if (!v)
228*e4b17023SJohn Marino     return;
229*e4b17023SJohn Marino 
230*e4b17023SJohn Marino   for (gsi = gsi_start_phis (e->dest), i = 0;
231*e4b17023SJohn Marino        !gsi_end_p (gsi) && VEC_iterate (edge_var_map, v, i, vm);
232*e4b17023SJohn Marino        gsi_next (&gsi), i++)
233*e4b17023SJohn Marino     {
234*e4b17023SJohn Marino       tree def;
235*e4b17023SJohn Marino 
236*e4b17023SJohn Marino       phi = gsi_stmt (gsi);
237*e4b17023SJohn Marino       def = redirect_edge_var_map_def (vm);
238*e4b17023SJohn Marino       add_phi_arg (phi, def, e, redirect_edge_var_map_location (vm));
239*e4b17023SJohn Marino     }
240*e4b17023SJohn Marino 
241*e4b17023SJohn Marino   redirect_edge_var_map_clear (e);
242*e4b17023SJohn Marino }
243*e4b17023SJohn Marino 
244*e4b17023SJohn Marino /* Given a tree for an expression for which we might want to emit
245*e4b17023SJohn Marino    locations or values in debug information (generally a variable, but
246*e4b17023SJohn Marino    we might deal with other kinds of trees in the future), return the
247*e4b17023SJohn Marino    tree that should be used as the variable of a DEBUG_BIND STMT or
248*e4b17023SJohn Marino    VAR_LOCATION INSN or NOTE.  Return NULL if VAR is not to be tracked.  */
249*e4b17023SJohn Marino 
250*e4b17023SJohn Marino tree
target_for_debug_bind(tree var)251*e4b17023SJohn Marino target_for_debug_bind (tree var)
252*e4b17023SJohn Marino {
253*e4b17023SJohn Marino   if (!MAY_HAVE_DEBUG_STMTS)
254*e4b17023SJohn Marino     return NULL_TREE;
255*e4b17023SJohn Marino 
256*e4b17023SJohn Marino   if (TREE_CODE (var) != VAR_DECL
257*e4b17023SJohn Marino       && TREE_CODE (var) != PARM_DECL)
258*e4b17023SJohn Marino     return NULL_TREE;
259*e4b17023SJohn Marino 
260*e4b17023SJohn Marino   if (DECL_HAS_VALUE_EXPR_P (var))
261*e4b17023SJohn Marino     return target_for_debug_bind (DECL_VALUE_EXPR (var));
262*e4b17023SJohn Marino 
263*e4b17023SJohn Marino   if (DECL_IGNORED_P (var))
264*e4b17023SJohn Marino     return NULL_TREE;
265*e4b17023SJohn Marino 
266*e4b17023SJohn Marino   if (!is_gimple_reg (var))
267*e4b17023SJohn Marino     {
268*e4b17023SJohn Marino       if (is_gimple_reg_type (TREE_TYPE (var))
269*e4b17023SJohn Marino 	  && referenced_var_lookup (cfun, DECL_UID (var)) == NULL_TREE)
270*e4b17023SJohn Marino 	return var;
271*e4b17023SJohn Marino       return NULL_TREE;
272*e4b17023SJohn Marino     }
273*e4b17023SJohn Marino 
274*e4b17023SJohn Marino   return var;
275*e4b17023SJohn Marino }
276*e4b17023SJohn Marino 
277*e4b17023SJohn Marino /* Called via walk_tree, look for SSA_NAMEs that have already been
278*e4b17023SJohn Marino    released.  */
279*e4b17023SJohn Marino 
280*e4b17023SJohn Marino static tree
find_released_ssa_name(tree * tp,int * walk_subtrees,void * data_)281*e4b17023SJohn Marino find_released_ssa_name (tree *tp, int *walk_subtrees, void *data_)
282*e4b17023SJohn Marino {
283*e4b17023SJohn Marino   struct walk_stmt_info *wi = (struct walk_stmt_info *) data_;
284*e4b17023SJohn Marino 
285*e4b17023SJohn Marino   if (wi && wi->is_lhs)
286*e4b17023SJohn Marino     return NULL_TREE;
287*e4b17023SJohn Marino 
288*e4b17023SJohn Marino   if (TREE_CODE (*tp) == SSA_NAME)
289*e4b17023SJohn Marino     {
290*e4b17023SJohn Marino       if (SSA_NAME_IN_FREE_LIST (*tp))
291*e4b17023SJohn Marino 	return *tp;
292*e4b17023SJohn Marino 
293*e4b17023SJohn Marino       *walk_subtrees = 0;
294*e4b17023SJohn Marino     }
295*e4b17023SJohn Marino   else if (IS_TYPE_OR_DECL_P (*tp))
296*e4b17023SJohn Marino     *walk_subtrees = 0;
297*e4b17023SJohn Marino 
298*e4b17023SJohn Marino   return NULL_TREE;
299*e4b17023SJohn Marino }
300*e4b17023SJohn Marino 
301*e4b17023SJohn Marino /* Insert a DEBUG BIND stmt before the DEF of VAR if VAR is referenced
302*e4b17023SJohn Marino    by other DEBUG stmts, and replace uses of the DEF with the
303*e4b17023SJohn Marino    newly-created debug temp.  */
304*e4b17023SJohn Marino 
305*e4b17023SJohn Marino void
insert_debug_temp_for_var_def(gimple_stmt_iterator * gsi,tree var)306*e4b17023SJohn Marino insert_debug_temp_for_var_def (gimple_stmt_iterator *gsi, tree var)
307*e4b17023SJohn Marino {
308*e4b17023SJohn Marino   imm_use_iterator imm_iter;
309*e4b17023SJohn Marino   use_operand_p use_p;
310*e4b17023SJohn Marino   gimple stmt;
311*e4b17023SJohn Marino   gimple def_stmt = NULL;
312*e4b17023SJohn Marino   int usecount = 0;
313*e4b17023SJohn Marino   tree value = NULL;
314*e4b17023SJohn Marino 
315*e4b17023SJohn Marino   if (!MAY_HAVE_DEBUG_STMTS)
316*e4b17023SJohn Marino     return;
317*e4b17023SJohn Marino 
318*e4b17023SJohn Marino   /* If this name has already been registered for replacement, do nothing
319*e4b17023SJohn Marino      as anything that uses this name isn't in SSA form.  */
320*e4b17023SJohn Marino   if (name_registered_for_update_p (var))
321*e4b17023SJohn Marino     return;
322*e4b17023SJohn Marino 
323*e4b17023SJohn Marino   /* Check whether there are debug stmts that reference this variable and,
324*e4b17023SJohn Marino      if there are, decide whether we should use a debug temp.  */
325*e4b17023SJohn Marino   FOR_EACH_IMM_USE_FAST (use_p, imm_iter, var)
326*e4b17023SJohn Marino     {
327*e4b17023SJohn Marino       stmt = USE_STMT (use_p);
328*e4b17023SJohn Marino 
329*e4b17023SJohn Marino       if (!gimple_debug_bind_p (stmt))
330*e4b17023SJohn Marino 	continue;
331*e4b17023SJohn Marino 
332*e4b17023SJohn Marino       if (usecount++)
333*e4b17023SJohn Marino 	break;
334*e4b17023SJohn Marino 
335*e4b17023SJohn Marino       if (gimple_debug_bind_get_value (stmt) != var)
336*e4b17023SJohn Marino 	{
337*e4b17023SJohn Marino 	  /* Count this as an additional use, so as to make sure we
338*e4b17023SJohn Marino 	     use a temp unless VAR's definition has a SINGLE_RHS that
339*e4b17023SJohn Marino 	     can be shared.  */
340*e4b17023SJohn Marino 	  usecount++;
341*e4b17023SJohn Marino 	  break;
342*e4b17023SJohn Marino 	}
343*e4b17023SJohn Marino     }
344*e4b17023SJohn Marino 
345*e4b17023SJohn Marino   if (!usecount)
346*e4b17023SJohn Marino     return;
347*e4b17023SJohn Marino 
348*e4b17023SJohn Marino   if (gsi)
349*e4b17023SJohn Marino     def_stmt = gsi_stmt (*gsi);
350*e4b17023SJohn Marino   else
351*e4b17023SJohn Marino     def_stmt = SSA_NAME_DEF_STMT (var);
352*e4b17023SJohn Marino 
353*e4b17023SJohn Marino   /* If we didn't get an insertion point, and the stmt has already
354*e4b17023SJohn Marino      been removed, we won't be able to insert the debug bind stmt, so
355*e4b17023SJohn Marino      we'll have to drop debug information.  */
356*e4b17023SJohn Marino   if (gimple_code (def_stmt) == GIMPLE_PHI)
357*e4b17023SJohn Marino     {
358*e4b17023SJohn Marino       value = degenerate_phi_result (def_stmt);
359*e4b17023SJohn Marino       if (value && walk_tree (&value, find_released_ssa_name, NULL, NULL))
360*e4b17023SJohn Marino 	value = NULL;
361*e4b17023SJohn Marino       /* error_mark_node is what fixup_noreturn_call changes PHI arguments
362*e4b17023SJohn Marino 	 to.  */
363*e4b17023SJohn Marino       else if (value == error_mark_node)
364*e4b17023SJohn Marino 	value = NULL;
365*e4b17023SJohn Marino     }
366*e4b17023SJohn Marino   else if (is_gimple_assign (def_stmt))
367*e4b17023SJohn Marino     {
368*e4b17023SJohn Marino       bool no_value = false;
369*e4b17023SJohn Marino 
370*e4b17023SJohn Marino       if (!dom_info_available_p (CDI_DOMINATORS))
371*e4b17023SJohn Marino 	{
372*e4b17023SJohn Marino 	  struct walk_stmt_info wi;
373*e4b17023SJohn Marino 
374*e4b17023SJohn Marino 	  memset (&wi, 0, sizeof (wi));
375*e4b17023SJohn Marino 
376*e4b17023SJohn Marino 	  /* When removing blocks without following reverse dominance
377*e4b17023SJohn Marino 	     order, we may sometimes encounter SSA_NAMEs that have
378*e4b17023SJohn Marino 	     already been released, referenced in other SSA_DEFs that
379*e4b17023SJohn Marino 	     we're about to release.  Consider:
380*e4b17023SJohn Marino 
381*e4b17023SJohn Marino 	     <bb X>:
382*e4b17023SJohn Marino 	     v_1 = foo;
383*e4b17023SJohn Marino 
384*e4b17023SJohn Marino 	     <bb Y>:
385*e4b17023SJohn Marino 	     w_2 = v_1 + bar;
386*e4b17023SJohn Marino 	     # DEBUG w => w_2
387*e4b17023SJohn Marino 
388*e4b17023SJohn Marino 	     If we deleted BB X first, propagating the value of w_2
389*e4b17023SJohn Marino 	     won't do us any good.  It's too late to recover their
390*e4b17023SJohn Marino 	     original definition of v_1: when it was deleted, it was
391*e4b17023SJohn Marino 	     only referenced in other DEFs, it couldn't possibly know
392*e4b17023SJohn Marino 	     it should have been retained, and propagating every
393*e4b17023SJohn Marino 	     single DEF just in case it might have to be propagated
394*e4b17023SJohn Marino 	     into a DEBUG STMT would probably be too wasteful.
395*e4b17023SJohn Marino 
396*e4b17023SJohn Marino 	     When dominator information is not readily available, we
397*e4b17023SJohn Marino 	     check for and accept some loss of debug information.  But
398*e4b17023SJohn Marino 	     if it is available, there's no excuse for us to remove
399*e4b17023SJohn Marino 	     blocks in the wrong order, so we don't even check for
400*e4b17023SJohn Marino 	     dead SSA NAMEs.  SSA verification shall catch any
401*e4b17023SJohn Marino 	     errors.  */
402*e4b17023SJohn Marino 	  if ((!gsi && !gimple_bb (def_stmt))
403*e4b17023SJohn Marino 	      || walk_gimple_op (def_stmt, find_released_ssa_name, &wi))
404*e4b17023SJohn Marino 	    no_value = true;
405*e4b17023SJohn Marino 	}
406*e4b17023SJohn Marino 
407*e4b17023SJohn Marino       if (!no_value)
408*e4b17023SJohn Marino 	value = gimple_assign_rhs_to_tree (def_stmt);
409*e4b17023SJohn Marino     }
410*e4b17023SJohn Marino 
411*e4b17023SJohn Marino   if (value)
412*e4b17023SJohn Marino     {
413*e4b17023SJohn Marino       /* If there's a single use of VAR, and VAR is the entire debug
414*e4b17023SJohn Marino 	 expression (usecount would have been incremented again
415*e4b17023SJohn Marino 	 otherwise), and the definition involves only constants and
416*e4b17023SJohn Marino 	 SSA names, then we can propagate VALUE into this single use,
417*e4b17023SJohn Marino 	 avoiding the temp.
418*e4b17023SJohn Marino 
419*e4b17023SJohn Marino 	 We can also avoid using a temp if VALUE can be shared and
420*e4b17023SJohn Marino 	 propagated into all uses, without generating expressions that
421*e4b17023SJohn Marino 	 wouldn't be valid gimple RHSs.
422*e4b17023SJohn Marino 
423*e4b17023SJohn Marino 	 Other cases that would require unsharing or non-gimple RHSs
424*e4b17023SJohn Marino 	 are deferred to a debug temp, although we could avoid temps
425*e4b17023SJohn Marino 	 at the expense of duplication of expressions.  */
426*e4b17023SJohn Marino 
427*e4b17023SJohn Marino       if (CONSTANT_CLASS_P (value)
428*e4b17023SJohn Marino 	  || gimple_code (def_stmt) == GIMPLE_PHI
429*e4b17023SJohn Marino 	  || (usecount == 1
430*e4b17023SJohn Marino 	      && (!gimple_assign_single_p (def_stmt)
431*e4b17023SJohn Marino 		  || is_gimple_min_invariant (value)))
432*e4b17023SJohn Marino 	  || is_gimple_reg (value))
433*e4b17023SJohn Marino 	value = unshare_expr (value);
434*e4b17023SJohn Marino       else
435*e4b17023SJohn Marino 	{
436*e4b17023SJohn Marino 	  gimple def_temp;
437*e4b17023SJohn Marino 	  tree vexpr = make_node (DEBUG_EXPR_DECL);
438*e4b17023SJohn Marino 
439*e4b17023SJohn Marino 	  def_temp = gimple_build_debug_bind (vexpr,
440*e4b17023SJohn Marino 					      unshare_expr (value),
441*e4b17023SJohn Marino 					      def_stmt);
442*e4b17023SJohn Marino 
443*e4b17023SJohn Marino 	  DECL_ARTIFICIAL (vexpr) = 1;
444*e4b17023SJohn Marino 	  TREE_TYPE (vexpr) = TREE_TYPE (value);
445*e4b17023SJohn Marino 	  if (DECL_P (value))
446*e4b17023SJohn Marino 	    DECL_MODE (vexpr) = DECL_MODE (value);
447*e4b17023SJohn Marino 	  else
448*e4b17023SJohn Marino 	    DECL_MODE (vexpr) = TYPE_MODE (TREE_TYPE (value));
449*e4b17023SJohn Marino 
450*e4b17023SJohn Marino 	  if (gsi)
451*e4b17023SJohn Marino 	    gsi_insert_before (gsi, def_temp, GSI_SAME_STMT);
452*e4b17023SJohn Marino 	  else
453*e4b17023SJohn Marino 	    {
454*e4b17023SJohn Marino 	      gimple_stmt_iterator ngsi = gsi_for_stmt (def_stmt);
455*e4b17023SJohn Marino 	      gsi_insert_before (&ngsi, def_temp, GSI_SAME_STMT);
456*e4b17023SJohn Marino 	    }
457*e4b17023SJohn Marino 
458*e4b17023SJohn Marino 	  value = vexpr;
459*e4b17023SJohn Marino 	}
460*e4b17023SJohn Marino     }
461*e4b17023SJohn Marino 
462*e4b17023SJohn Marino   FOR_EACH_IMM_USE_STMT (stmt, imm_iter, var)
463*e4b17023SJohn Marino     {
464*e4b17023SJohn Marino       if (!gimple_debug_bind_p (stmt))
465*e4b17023SJohn Marino 	continue;
466*e4b17023SJohn Marino 
467*e4b17023SJohn Marino       if (value)
468*e4b17023SJohn Marino 	{
469*e4b17023SJohn Marino 	  FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
470*e4b17023SJohn Marino 	    /* unshare_expr is not needed here.  vexpr is either a
471*e4b17023SJohn Marino 	       SINGLE_RHS, that can be safely shared, some other RHS
472*e4b17023SJohn Marino 	       that was unshared when we found it had a single debug
473*e4b17023SJohn Marino 	       use, or a DEBUG_EXPR_DECL, that can be safely
474*e4b17023SJohn Marino 	       shared.  */
475*e4b17023SJohn Marino 	    SET_USE (use_p, value);
476*e4b17023SJohn Marino 	  /* If we didn't replace uses with a debug decl fold the
477*e4b17023SJohn Marino 	     resulting expression.  Otherwise we end up with invalid IL.  */
478*e4b17023SJohn Marino 	  if (TREE_CODE (value) != DEBUG_EXPR_DECL)
479*e4b17023SJohn Marino 	    {
480*e4b17023SJohn Marino 	      gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
481*e4b17023SJohn Marino 	      fold_stmt_inplace (&gsi);
482*e4b17023SJohn Marino 	    }
483*e4b17023SJohn Marino 	}
484*e4b17023SJohn Marino       else
485*e4b17023SJohn Marino 	gimple_debug_bind_reset_value (stmt);
486*e4b17023SJohn Marino 
487*e4b17023SJohn Marino       update_stmt (stmt);
488*e4b17023SJohn Marino     }
489*e4b17023SJohn Marino }
490*e4b17023SJohn Marino 
491*e4b17023SJohn Marino 
492*e4b17023SJohn Marino /* Insert a DEBUG BIND stmt before STMT for each DEF referenced by
493*e4b17023SJohn Marino    other DEBUG stmts, and replace uses of the DEF with the
494*e4b17023SJohn Marino    newly-created debug temp.  */
495*e4b17023SJohn Marino 
496*e4b17023SJohn Marino void
insert_debug_temps_for_defs(gimple_stmt_iterator * gsi)497*e4b17023SJohn Marino insert_debug_temps_for_defs (gimple_stmt_iterator *gsi)
498*e4b17023SJohn Marino {
499*e4b17023SJohn Marino   gimple stmt;
500*e4b17023SJohn Marino   ssa_op_iter op_iter;
501*e4b17023SJohn Marino   def_operand_p def_p;
502*e4b17023SJohn Marino 
503*e4b17023SJohn Marino   if (!MAY_HAVE_DEBUG_STMTS)
504*e4b17023SJohn Marino     return;
505*e4b17023SJohn Marino 
506*e4b17023SJohn Marino   stmt = gsi_stmt (*gsi);
507*e4b17023SJohn Marino 
508*e4b17023SJohn Marino   FOR_EACH_PHI_OR_STMT_DEF (def_p, stmt, op_iter, SSA_OP_DEF)
509*e4b17023SJohn Marino     {
510*e4b17023SJohn Marino       tree var = DEF_FROM_PTR (def_p);
511*e4b17023SJohn Marino 
512*e4b17023SJohn Marino       if (TREE_CODE (var) != SSA_NAME)
513*e4b17023SJohn Marino 	continue;
514*e4b17023SJohn Marino 
515*e4b17023SJohn Marino       insert_debug_temp_for_var_def (gsi, var);
516*e4b17023SJohn Marino     }
517*e4b17023SJohn Marino }
518*e4b17023SJohn Marino 
519*e4b17023SJohn Marino /* Reset all debug stmts that use SSA_NAME(s) defined in STMT.  */
520*e4b17023SJohn Marino 
521*e4b17023SJohn Marino void
reset_debug_uses(gimple stmt)522*e4b17023SJohn Marino reset_debug_uses (gimple stmt)
523*e4b17023SJohn Marino {
524*e4b17023SJohn Marino   ssa_op_iter op_iter;
525*e4b17023SJohn Marino   def_operand_p def_p;
526*e4b17023SJohn Marino   imm_use_iterator imm_iter;
527*e4b17023SJohn Marino   gimple use_stmt;
528*e4b17023SJohn Marino 
529*e4b17023SJohn Marino   if (!MAY_HAVE_DEBUG_STMTS)
530*e4b17023SJohn Marino     return;
531*e4b17023SJohn Marino 
532*e4b17023SJohn Marino   FOR_EACH_PHI_OR_STMT_DEF (def_p, stmt, op_iter, SSA_OP_DEF)
533*e4b17023SJohn Marino     {
534*e4b17023SJohn Marino       tree var = DEF_FROM_PTR (def_p);
535*e4b17023SJohn Marino 
536*e4b17023SJohn Marino       if (TREE_CODE (var) != SSA_NAME)
537*e4b17023SJohn Marino 	continue;
538*e4b17023SJohn Marino 
539*e4b17023SJohn Marino       FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, var)
540*e4b17023SJohn Marino 	{
541*e4b17023SJohn Marino 	  if (!gimple_debug_bind_p (use_stmt))
542*e4b17023SJohn Marino 	    continue;
543*e4b17023SJohn Marino 
544*e4b17023SJohn Marino 	  gimple_debug_bind_reset_value (use_stmt);
545*e4b17023SJohn Marino 	  update_stmt (use_stmt);
546*e4b17023SJohn Marino 	}
547*e4b17023SJohn Marino     }
548*e4b17023SJohn Marino }
549*e4b17023SJohn Marino 
550*e4b17023SJohn Marino /* Delete SSA DEFs for SSA versions in the TOREMOVE bitmap, removing
551*e4b17023SJohn Marino    dominated stmts before their dominators, so that release_ssa_defs
552*e4b17023SJohn Marino    stands a chance of propagating DEFs into debug bind stmts.  */
553*e4b17023SJohn Marino 
554*e4b17023SJohn Marino void
release_defs_bitset(bitmap toremove)555*e4b17023SJohn Marino release_defs_bitset (bitmap toremove)
556*e4b17023SJohn Marino {
557*e4b17023SJohn Marino   unsigned j;
558*e4b17023SJohn Marino   bitmap_iterator bi;
559*e4b17023SJohn Marino 
560*e4b17023SJohn Marino   /* Performing a topological sort is probably overkill, this will
561*e4b17023SJohn Marino      most likely run in slightly superlinear time, rather than the
562*e4b17023SJohn Marino      pathological quadratic worst case.  */
563*e4b17023SJohn Marino   while (!bitmap_empty_p (toremove))
564*e4b17023SJohn Marino     EXECUTE_IF_SET_IN_BITMAP (toremove, 0, j, bi)
565*e4b17023SJohn Marino       {
566*e4b17023SJohn Marino 	bool remove_now = true;
567*e4b17023SJohn Marino 	tree var = ssa_name (j);
568*e4b17023SJohn Marino 	gimple stmt;
569*e4b17023SJohn Marino 	imm_use_iterator uit;
570*e4b17023SJohn Marino 
571*e4b17023SJohn Marino 	FOR_EACH_IMM_USE_STMT (stmt, uit, var)
572*e4b17023SJohn Marino 	  {
573*e4b17023SJohn Marino 	    ssa_op_iter dit;
574*e4b17023SJohn Marino 	    def_operand_p def_p;
575*e4b17023SJohn Marino 
576*e4b17023SJohn Marino 	    /* We can't propagate PHI nodes into debug stmts.  */
577*e4b17023SJohn Marino 	    if (gimple_code (stmt) == GIMPLE_PHI
578*e4b17023SJohn Marino 		|| is_gimple_debug (stmt))
579*e4b17023SJohn Marino 	      continue;
580*e4b17023SJohn Marino 
581*e4b17023SJohn Marino 	    /* If we find another definition to remove that uses
582*e4b17023SJohn Marino 	       the one we're looking at, defer the removal of this
583*e4b17023SJohn Marino 	       one, so that it can be propagated into debug stmts
584*e4b17023SJohn Marino 	       after the other is.  */
585*e4b17023SJohn Marino 	    FOR_EACH_SSA_DEF_OPERAND (def_p, stmt, dit, SSA_OP_DEF)
586*e4b17023SJohn Marino 	      {
587*e4b17023SJohn Marino 		tree odef = DEF_FROM_PTR (def_p);
588*e4b17023SJohn Marino 
589*e4b17023SJohn Marino 		if (bitmap_bit_p (toremove, SSA_NAME_VERSION (odef)))
590*e4b17023SJohn Marino 		  {
591*e4b17023SJohn Marino 		    remove_now = false;
592*e4b17023SJohn Marino 		    break;
593*e4b17023SJohn Marino 		  }
594*e4b17023SJohn Marino 	      }
595*e4b17023SJohn Marino 
596*e4b17023SJohn Marino 	    if (!remove_now)
597*e4b17023SJohn Marino 	      BREAK_FROM_IMM_USE_STMT (uit);
598*e4b17023SJohn Marino 	  }
599*e4b17023SJohn Marino 
600*e4b17023SJohn Marino 	if (remove_now)
601*e4b17023SJohn Marino 	  {
602*e4b17023SJohn Marino 	    gimple def = SSA_NAME_DEF_STMT (var);
603*e4b17023SJohn Marino 	    gimple_stmt_iterator gsi = gsi_for_stmt (def);
604*e4b17023SJohn Marino 
605*e4b17023SJohn Marino 	    if (gimple_code (def) == GIMPLE_PHI)
606*e4b17023SJohn Marino 	      remove_phi_node (&gsi, true);
607*e4b17023SJohn Marino 	    else
608*e4b17023SJohn Marino 	      {
609*e4b17023SJohn Marino 		gsi_remove (&gsi, true);
610*e4b17023SJohn Marino 		release_defs (def);
611*e4b17023SJohn Marino 	      }
612*e4b17023SJohn Marino 
613*e4b17023SJohn Marino 	    bitmap_clear_bit (toremove, j);
614*e4b17023SJohn Marino 	  }
615*e4b17023SJohn Marino       }
616*e4b17023SJohn Marino }
617*e4b17023SJohn Marino 
618*e4b17023SJohn Marino /* Return true if SSA_NAME is malformed and mark it visited.
619*e4b17023SJohn Marino 
620*e4b17023SJohn Marino    IS_VIRTUAL is true if this SSA_NAME was found inside a virtual
621*e4b17023SJohn Marino       operand.  */
622*e4b17023SJohn Marino 
623*e4b17023SJohn Marino static bool
verify_ssa_name(tree ssa_name,bool is_virtual)624*e4b17023SJohn Marino verify_ssa_name (tree ssa_name, bool is_virtual)
625*e4b17023SJohn Marino {
626*e4b17023SJohn Marino   if (TREE_CODE (ssa_name) != SSA_NAME)
627*e4b17023SJohn Marino     {
628*e4b17023SJohn Marino       error ("expected an SSA_NAME object");
629*e4b17023SJohn Marino       return true;
630*e4b17023SJohn Marino     }
631*e4b17023SJohn Marino 
632*e4b17023SJohn Marino   if (TREE_TYPE (ssa_name) != TREE_TYPE (SSA_NAME_VAR (ssa_name)))
633*e4b17023SJohn Marino     {
634*e4b17023SJohn Marino       error ("type mismatch between an SSA_NAME and its symbol");
635*e4b17023SJohn Marino       return true;
636*e4b17023SJohn Marino     }
637*e4b17023SJohn Marino 
638*e4b17023SJohn Marino   if (SSA_NAME_IN_FREE_LIST (ssa_name))
639*e4b17023SJohn Marino     {
640*e4b17023SJohn Marino       error ("found an SSA_NAME that had been released into the free pool");
641*e4b17023SJohn Marino       return true;
642*e4b17023SJohn Marino     }
643*e4b17023SJohn Marino 
644*e4b17023SJohn Marino   if (is_virtual && is_gimple_reg (ssa_name))
645*e4b17023SJohn Marino     {
646*e4b17023SJohn Marino       error ("found a virtual definition for a GIMPLE register");
647*e4b17023SJohn Marino       return true;
648*e4b17023SJohn Marino     }
649*e4b17023SJohn Marino 
650*e4b17023SJohn Marino   if (is_virtual && SSA_NAME_VAR (ssa_name) != gimple_vop (cfun))
651*e4b17023SJohn Marino     {
652*e4b17023SJohn Marino       error ("virtual SSA name for non-VOP decl");
653*e4b17023SJohn Marino       return true;
654*e4b17023SJohn Marino     }
655*e4b17023SJohn Marino 
656*e4b17023SJohn Marino   if (!is_virtual && !is_gimple_reg (ssa_name))
657*e4b17023SJohn Marino     {
658*e4b17023SJohn Marino       error ("found a real definition for a non-register");
659*e4b17023SJohn Marino       return true;
660*e4b17023SJohn Marino     }
661*e4b17023SJohn Marino 
662*e4b17023SJohn Marino   if (SSA_NAME_IS_DEFAULT_DEF (ssa_name)
663*e4b17023SJohn Marino       && !gimple_nop_p (SSA_NAME_DEF_STMT (ssa_name)))
664*e4b17023SJohn Marino     {
665*e4b17023SJohn Marino       error ("found a default name with a non-empty defining statement");
666*e4b17023SJohn Marino       return true;
667*e4b17023SJohn Marino     }
668*e4b17023SJohn Marino 
669*e4b17023SJohn Marino   return false;
670*e4b17023SJohn Marino }
671*e4b17023SJohn Marino 
672*e4b17023SJohn Marino 
673*e4b17023SJohn Marino /* Return true if the definition of SSA_NAME at block BB is malformed.
674*e4b17023SJohn Marino 
675*e4b17023SJohn Marino    STMT is the statement where SSA_NAME is created.
676*e4b17023SJohn Marino 
677*e4b17023SJohn Marino    DEFINITION_BLOCK is an array of basic blocks indexed by SSA_NAME
678*e4b17023SJohn Marino       version numbers.  If DEFINITION_BLOCK[SSA_NAME_VERSION] is set,
679*e4b17023SJohn Marino       it means that the block in that array slot contains the
680*e4b17023SJohn Marino       definition of SSA_NAME.
681*e4b17023SJohn Marino 
682*e4b17023SJohn Marino    IS_VIRTUAL is true if SSA_NAME is created by a VDEF.  */
683*e4b17023SJohn Marino 
684*e4b17023SJohn Marino static bool
verify_def(basic_block bb,basic_block * definition_block,tree ssa_name,gimple stmt,bool is_virtual)685*e4b17023SJohn Marino verify_def (basic_block bb, basic_block *definition_block, tree ssa_name,
686*e4b17023SJohn Marino 	    gimple stmt, bool is_virtual)
687*e4b17023SJohn Marino {
688*e4b17023SJohn Marino   if (verify_ssa_name (ssa_name, is_virtual))
689*e4b17023SJohn Marino     goto err;
690*e4b17023SJohn Marino 
691*e4b17023SJohn Marino   if (TREE_CODE (SSA_NAME_VAR (ssa_name)) == RESULT_DECL
692*e4b17023SJohn Marino       && DECL_BY_REFERENCE (SSA_NAME_VAR (ssa_name)))
693*e4b17023SJohn Marino     {
694*e4b17023SJohn Marino       error ("RESULT_DECL should be read only when DECL_BY_REFERENCE is set");
695*e4b17023SJohn Marino       goto err;
696*e4b17023SJohn Marino     }
697*e4b17023SJohn Marino 
698*e4b17023SJohn Marino   if (definition_block[SSA_NAME_VERSION (ssa_name)])
699*e4b17023SJohn Marino     {
700*e4b17023SJohn Marino       error ("SSA_NAME created in two different blocks %i and %i",
701*e4b17023SJohn Marino 	     definition_block[SSA_NAME_VERSION (ssa_name)]->index, bb->index);
702*e4b17023SJohn Marino       goto err;
703*e4b17023SJohn Marino     }
704*e4b17023SJohn Marino 
705*e4b17023SJohn Marino   definition_block[SSA_NAME_VERSION (ssa_name)] = bb;
706*e4b17023SJohn Marino 
707*e4b17023SJohn Marino   if (SSA_NAME_DEF_STMT (ssa_name) != stmt)
708*e4b17023SJohn Marino     {
709*e4b17023SJohn Marino       error ("SSA_NAME_DEF_STMT is wrong");
710*e4b17023SJohn Marino       fprintf (stderr, "Expected definition statement:\n");
711*e4b17023SJohn Marino       print_gimple_stmt (stderr, SSA_NAME_DEF_STMT (ssa_name), 4, TDF_VOPS);
712*e4b17023SJohn Marino       fprintf (stderr, "\nActual definition statement:\n");
713*e4b17023SJohn Marino       print_gimple_stmt (stderr, stmt, 4, TDF_VOPS);
714*e4b17023SJohn Marino       goto err;
715*e4b17023SJohn Marino     }
716*e4b17023SJohn Marino 
717*e4b17023SJohn Marino   return false;
718*e4b17023SJohn Marino 
719*e4b17023SJohn Marino err:
720*e4b17023SJohn Marino   fprintf (stderr, "while verifying SSA_NAME ");
721*e4b17023SJohn Marino   print_generic_expr (stderr, ssa_name, 0);
722*e4b17023SJohn Marino   fprintf (stderr, " in statement\n");
723*e4b17023SJohn Marino   print_gimple_stmt (stderr, stmt, 4, TDF_VOPS);
724*e4b17023SJohn Marino 
725*e4b17023SJohn Marino   return true;
726*e4b17023SJohn Marino }
727*e4b17023SJohn Marino 
728*e4b17023SJohn Marino 
729*e4b17023SJohn Marino /* Return true if the use of SSA_NAME at statement STMT in block BB is
730*e4b17023SJohn Marino    malformed.
731*e4b17023SJohn Marino 
732*e4b17023SJohn Marino    DEF_BB is the block where SSA_NAME was found to be created.
733*e4b17023SJohn Marino 
734*e4b17023SJohn Marino    IDOM contains immediate dominator information for the flowgraph.
735*e4b17023SJohn Marino 
736*e4b17023SJohn Marino    CHECK_ABNORMAL is true if the caller wants to check whether this use
737*e4b17023SJohn Marino       is flowing through an abnormal edge (only used when checking PHI
738*e4b17023SJohn Marino       arguments).
739*e4b17023SJohn Marino 
740*e4b17023SJohn Marino    If NAMES_DEFINED_IN_BB is not NULL, it contains a bitmap of ssa names
741*e4b17023SJohn Marino      that are defined before STMT in basic block BB.  */
742*e4b17023SJohn Marino 
743*e4b17023SJohn Marino static bool
verify_use(basic_block bb,basic_block def_bb,use_operand_p use_p,gimple stmt,bool check_abnormal,bitmap names_defined_in_bb)744*e4b17023SJohn Marino verify_use (basic_block bb, basic_block def_bb, use_operand_p use_p,
745*e4b17023SJohn Marino 	    gimple stmt, bool check_abnormal, bitmap names_defined_in_bb)
746*e4b17023SJohn Marino {
747*e4b17023SJohn Marino   bool err = false;
748*e4b17023SJohn Marino   tree ssa_name = USE_FROM_PTR (use_p);
749*e4b17023SJohn Marino 
750*e4b17023SJohn Marino   if (!TREE_VISITED (ssa_name))
751*e4b17023SJohn Marino     if (verify_imm_links (stderr, ssa_name))
752*e4b17023SJohn Marino       err = true;
753*e4b17023SJohn Marino 
754*e4b17023SJohn Marino   TREE_VISITED (ssa_name) = 1;
755*e4b17023SJohn Marino 
756*e4b17023SJohn Marino   if (gimple_nop_p (SSA_NAME_DEF_STMT (ssa_name))
757*e4b17023SJohn Marino       && SSA_NAME_IS_DEFAULT_DEF (ssa_name))
758*e4b17023SJohn Marino     ; /* Default definitions have empty statements.  Nothing to do.  */
759*e4b17023SJohn Marino   else if (!def_bb)
760*e4b17023SJohn Marino     {
761*e4b17023SJohn Marino       error ("missing definition");
762*e4b17023SJohn Marino       err = true;
763*e4b17023SJohn Marino     }
764*e4b17023SJohn Marino   else if (bb != def_bb
765*e4b17023SJohn Marino 	   && !dominated_by_p (CDI_DOMINATORS, bb, def_bb))
766*e4b17023SJohn Marino     {
767*e4b17023SJohn Marino       error ("definition in block %i does not dominate use in block %i",
768*e4b17023SJohn Marino 	     def_bb->index, bb->index);
769*e4b17023SJohn Marino       err = true;
770*e4b17023SJohn Marino     }
771*e4b17023SJohn Marino   else if (bb == def_bb
772*e4b17023SJohn Marino 	   && names_defined_in_bb != NULL
773*e4b17023SJohn Marino 	   && !bitmap_bit_p (names_defined_in_bb, SSA_NAME_VERSION (ssa_name)))
774*e4b17023SJohn Marino     {
775*e4b17023SJohn Marino       error ("definition in block %i follows the use", def_bb->index);
776*e4b17023SJohn Marino       err = true;
777*e4b17023SJohn Marino     }
778*e4b17023SJohn Marino 
779*e4b17023SJohn Marino   if (check_abnormal
780*e4b17023SJohn Marino       && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ssa_name))
781*e4b17023SJohn Marino     {
782*e4b17023SJohn Marino       error ("SSA_NAME_OCCURS_IN_ABNORMAL_PHI should be set");
783*e4b17023SJohn Marino       err = true;
784*e4b17023SJohn Marino     }
785*e4b17023SJohn Marino 
786*e4b17023SJohn Marino   /* Make sure the use is in an appropriate list by checking the previous
787*e4b17023SJohn Marino      element to make sure it's the same.  */
788*e4b17023SJohn Marino   if (use_p->prev == NULL)
789*e4b17023SJohn Marino     {
790*e4b17023SJohn Marino       error ("no immediate_use list");
791*e4b17023SJohn Marino       err = true;
792*e4b17023SJohn Marino     }
793*e4b17023SJohn Marino   else
794*e4b17023SJohn Marino     {
795*e4b17023SJohn Marino       tree listvar;
796*e4b17023SJohn Marino       if (use_p->prev->use == NULL)
797*e4b17023SJohn Marino 	listvar = use_p->prev->loc.ssa_name;
798*e4b17023SJohn Marino       else
799*e4b17023SJohn Marino 	listvar = USE_FROM_PTR (use_p->prev);
800*e4b17023SJohn Marino       if (listvar != ssa_name)
801*e4b17023SJohn Marino         {
802*e4b17023SJohn Marino 	  error ("wrong immediate use list");
803*e4b17023SJohn Marino 	  err = true;
804*e4b17023SJohn Marino 	}
805*e4b17023SJohn Marino     }
806*e4b17023SJohn Marino 
807*e4b17023SJohn Marino   if (err)
808*e4b17023SJohn Marino     {
809*e4b17023SJohn Marino       fprintf (stderr, "for SSA_NAME: ");
810*e4b17023SJohn Marino       print_generic_expr (stderr, ssa_name, TDF_VOPS);
811*e4b17023SJohn Marino       fprintf (stderr, " in statement:\n");
812*e4b17023SJohn Marino       print_gimple_stmt (stderr, stmt, 0, TDF_VOPS);
813*e4b17023SJohn Marino     }
814*e4b17023SJohn Marino 
815*e4b17023SJohn Marino   return err;
816*e4b17023SJohn Marino }
817*e4b17023SJohn Marino 
818*e4b17023SJohn Marino 
819*e4b17023SJohn Marino /* Return true if any of the arguments for PHI node PHI at block BB is
820*e4b17023SJohn Marino    malformed.
821*e4b17023SJohn Marino 
822*e4b17023SJohn Marino    DEFINITION_BLOCK is an array of basic blocks indexed by SSA_NAME
823*e4b17023SJohn Marino       version numbers.  If DEFINITION_BLOCK[SSA_NAME_VERSION] is set,
824*e4b17023SJohn Marino       it means that the block in that array slot contains the
825*e4b17023SJohn Marino       definition of SSA_NAME.  */
826*e4b17023SJohn Marino 
827*e4b17023SJohn Marino static bool
verify_phi_args(gimple phi,basic_block bb,basic_block * definition_block)828*e4b17023SJohn Marino verify_phi_args (gimple phi, basic_block bb, basic_block *definition_block)
829*e4b17023SJohn Marino {
830*e4b17023SJohn Marino   edge e;
831*e4b17023SJohn Marino   bool err = false;
832*e4b17023SJohn Marino   size_t i, phi_num_args = gimple_phi_num_args (phi);
833*e4b17023SJohn Marino 
834*e4b17023SJohn Marino   if (EDGE_COUNT (bb->preds) != phi_num_args)
835*e4b17023SJohn Marino     {
836*e4b17023SJohn Marino       error ("incoming edge count does not match number of PHI arguments");
837*e4b17023SJohn Marino       err = true;
838*e4b17023SJohn Marino       goto error;
839*e4b17023SJohn Marino     }
840*e4b17023SJohn Marino 
841*e4b17023SJohn Marino   for (i = 0; i < phi_num_args; i++)
842*e4b17023SJohn Marino     {
843*e4b17023SJohn Marino       use_operand_p op_p = gimple_phi_arg_imm_use_ptr (phi, i);
844*e4b17023SJohn Marino       tree op = USE_FROM_PTR (op_p);
845*e4b17023SJohn Marino 
846*e4b17023SJohn Marino       e = EDGE_PRED (bb, i);
847*e4b17023SJohn Marino 
848*e4b17023SJohn Marino       if (op == NULL_TREE)
849*e4b17023SJohn Marino 	{
850*e4b17023SJohn Marino 	  error ("PHI argument is missing for edge %d->%d",
851*e4b17023SJohn Marino 	         e->src->index,
852*e4b17023SJohn Marino 		 e->dest->index);
853*e4b17023SJohn Marino 	  err = true;
854*e4b17023SJohn Marino 	  goto error;
855*e4b17023SJohn Marino 	}
856*e4b17023SJohn Marino 
857*e4b17023SJohn Marino       if (TREE_CODE (op) != SSA_NAME && !is_gimple_min_invariant (op))
858*e4b17023SJohn Marino 	{
859*e4b17023SJohn Marino 	  error ("PHI argument is not SSA_NAME, or invariant");
860*e4b17023SJohn Marino 	  err = true;
861*e4b17023SJohn Marino 	}
862*e4b17023SJohn Marino 
863*e4b17023SJohn Marino       if (TREE_CODE (op) == SSA_NAME)
864*e4b17023SJohn Marino 	{
865*e4b17023SJohn Marino 	  err = verify_ssa_name (op, !is_gimple_reg (gimple_phi_result (phi)));
866*e4b17023SJohn Marino 	  err |= verify_use (e->src, definition_block[SSA_NAME_VERSION (op)],
867*e4b17023SJohn Marino 			     op_p, phi, e->flags & EDGE_ABNORMAL, NULL);
868*e4b17023SJohn Marino 	}
869*e4b17023SJohn Marino 
870*e4b17023SJohn Marino       if (TREE_CODE (op) == ADDR_EXPR)
871*e4b17023SJohn Marino 	{
872*e4b17023SJohn Marino 	  tree base = TREE_OPERAND (op, 0);
873*e4b17023SJohn Marino 	  while (handled_component_p (base))
874*e4b17023SJohn Marino 	    base = TREE_OPERAND (base, 0);
875*e4b17023SJohn Marino 	  if ((TREE_CODE (base) == VAR_DECL
876*e4b17023SJohn Marino 	       || TREE_CODE (base) == PARM_DECL
877*e4b17023SJohn Marino 	       || TREE_CODE (base) == RESULT_DECL)
878*e4b17023SJohn Marino 	      && !TREE_ADDRESSABLE (base))
879*e4b17023SJohn Marino 	    {
880*e4b17023SJohn Marino 	      error ("address taken, but ADDRESSABLE bit not set");
881*e4b17023SJohn Marino 	      err = true;
882*e4b17023SJohn Marino 	    }
883*e4b17023SJohn Marino 	}
884*e4b17023SJohn Marino 
885*e4b17023SJohn Marino       if (e->dest != bb)
886*e4b17023SJohn Marino 	{
887*e4b17023SJohn Marino 	  error ("wrong edge %d->%d for PHI argument",
888*e4b17023SJohn Marino 	         e->src->index, e->dest->index);
889*e4b17023SJohn Marino 	  err = true;
890*e4b17023SJohn Marino 	}
891*e4b17023SJohn Marino 
892*e4b17023SJohn Marino       if (err)
893*e4b17023SJohn Marino 	{
894*e4b17023SJohn Marino 	  fprintf (stderr, "PHI argument\n");
895*e4b17023SJohn Marino 	  print_generic_stmt (stderr, op, TDF_VOPS);
896*e4b17023SJohn Marino 	  goto error;
897*e4b17023SJohn Marino 	}
898*e4b17023SJohn Marino     }
899*e4b17023SJohn Marino 
900*e4b17023SJohn Marino error:
901*e4b17023SJohn Marino   if (err)
902*e4b17023SJohn Marino     {
903*e4b17023SJohn Marino       fprintf (stderr, "for PHI node\n");
904*e4b17023SJohn Marino       print_gimple_stmt (stderr, phi, 0, TDF_VOPS|TDF_MEMSYMS);
905*e4b17023SJohn Marino     }
906*e4b17023SJohn Marino 
907*e4b17023SJohn Marino 
908*e4b17023SJohn Marino   return err;
909*e4b17023SJohn Marino }
910*e4b17023SJohn Marino 
911*e4b17023SJohn Marino 
912*e4b17023SJohn Marino /* Verify common invariants in the SSA web.
913*e4b17023SJohn Marino    TODO: verify the variable annotations.  */
914*e4b17023SJohn Marino 
915*e4b17023SJohn Marino DEBUG_FUNCTION void
verify_ssa(bool check_modified_stmt)916*e4b17023SJohn Marino verify_ssa (bool check_modified_stmt)
917*e4b17023SJohn Marino {
918*e4b17023SJohn Marino   size_t i;
919*e4b17023SJohn Marino   basic_block bb;
920*e4b17023SJohn Marino   basic_block *definition_block = XCNEWVEC (basic_block, num_ssa_names);
921*e4b17023SJohn Marino   ssa_op_iter iter;
922*e4b17023SJohn Marino   tree op;
923*e4b17023SJohn Marino   enum dom_state orig_dom_state = dom_info_state (CDI_DOMINATORS);
924*e4b17023SJohn Marino   bitmap names_defined_in_bb = BITMAP_ALLOC (NULL);
925*e4b17023SJohn Marino 
926*e4b17023SJohn Marino   gcc_assert (!need_ssa_update_p (cfun));
927*e4b17023SJohn Marino 
928*e4b17023SJohn Marino   timevar_push (TV_TREE_SSA_VERIFY);
929*e4b17023SJohn Marino 
930*e4b17023SJohn Marino   /* Keep track of SSA names present in the IL.  */
931*e4b17023SJohn Marino   for (i = 1; i < num_ssa_names; i++)
932*e4b17023SJohn Marino     {
933*e4b17023SJohn Marino       tree name = ssa_name (i);
934*e4b17023SJohn Marino       if (name)
935*e4b17023SJohn Marino 	{
936*e4b17023SJohn Marino 	  gimple stmt;
937*e4b17023SJohn Marino 	  TREE_VISITED (name) = 0;
938*e4b17023SJohn Marino 
939*e4b17023SJohn Marino 	  verify_ssa_name (name, !is_gimple_reg (name));
940*e4b17023SJohn Marino 
941*e4b17023SJohn Marino 	  stmt = SSA_NAME_DEF_STMT (name);
942*e4b17023SJohn Marino 	  if (!gimple_nop_p (stmt))
943*e4b17023SJohn Marino 	    {
944*e4b17023SJohn Marino 	      basic_block bb = gimple_bb (stmt);
945*e4b17023SJohn Marino 	      verify_def (bb, definition_block,
946*e4b17023SJohn Marino 			  name, stmt, !is_gimple_reg (name));
947*e4b17023SJohn Marino 
948*e4b17023SJohn Marino 	    }
949*e4b17023SJohn Marino 	}
950*e4b17023SJohn Marino     }
951*e4b17023SJohn Marino 
952*e4b17023SJohn Marino   calculate_dominance_info (CDI_DOMINATORS);
953*e4b17023SJohn Marino 
954*e4b17023SJohn Marino   /* Now verify all the uses and make sure they agree with the definitions
955*e4b17023SJohn Marino      found in the previous pass.  */
956*e4b17023SJohn Marino   FOR_EACH_BB (bb)
957*e4b17023SJohn Marino     {
958*e4b17023SJohn Marino       edge e;
959*e4b17023SJohn Marino       gimple phi;
960*e4b17023SJohn Marino       edge_iterator ei;
961*e4b17023SJohn Marino       gimple_stmt_iterator gsi;
962*e4b17023SJohn Marino 
963*e4b17023SJohn Marino       /* Make sure that all edges have a clear 'aux' field.  */
964*e4b17023SJohn Marino       FOR_EACH_EDGE (e, ei, bb->preds)
965*e4b17023SJohn Marino 	{
966*e4b17023SJohn Marino 	  if (e->aux)
967*e4b17023SJohn Marino 	    {
968*e4b17023SJohn Marino 	      error ("AUX pointer initialized for edge %d->%d", e->src->index,
969*e4b17023SJohn Marino 		      e->dest->index);
970*e4b17023SJohn Marino 	      goto err;
971*e4b17023SJohn Marino 	    }
972*e4b17023SJohn Marino 	}
973*e4b17023SJohn Marino 
974*e4b17023SJohn Marino       /* Verify the arguments for every PHI node in the block.  */
975*e4b17023SJohn Marino       for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
976*e4b17023SJohn Marino 	{
977*e4b17023SJohn Marino 	  phi = gsi_stmt (gsi);
978*e4b17023SJohn Marino 	  if (verify_phi_args (phi, bb, definition_block))
979*e4b17023SJohn Marino 	    goto err;
980*e4b17023SJohn Marino 
981*e4b17023SJohn Marino 	  bitmap_set_bit (names_defined_in_bb,
982*e4b17023SJohn Marino 			  SSA_NAME_VERSION (gimple_phi_result (phi)));
983*e4b17023SJohn Marino 	}
984*e4b17023SJohn Marino 
985*e4b17023SJohn Marino       /* Now verify all the uses and vuses in every statement of the block.  */
986*e4b17023SJohn Marino       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
987*e4b17023SJohn Marino 	{
988*e4b17023SJohn Marino 	  gimple stmt = gsi_stmt (gsi);
989*e4b17023SJohn Marino 	  use_operand_p use_p;
990*e4b17023SJohn Marino 
991*e4b17023SJohn Marino 	  if (check_modified_stmt && gimple_modified_p (stmt))
992*e4b17023SJohn Marino 	    {
993*e4b17023SJohn Marino 	      error ("stmt (%p) marked modified after optimization pass: ",
994*e4b17023SJohn Marino 		     (void *)stmt);
995*e4b17023SJohn Marino 	      print_gimple_stmt (stderr, stmt, 0, TDF_VOPS);
996*e4b17023SJohn Marino 	      goto err;
997*e4b17023SJohn Marino 	    }
998*e4b17023SJohn Marino 
999*e4b17023SJohn Marino 	  if (verify_ssa_operands (stmt))
1000*e4b17023SJohn Marino 	    {
1001*e4b17023SJohn Marino 	      print_gimple_stmt (stderr, stmt, 0, TDF_VOPS);
1002*e4b17023SJohn Marino 	      goto err;
1003*e4b17023SJohn Marino 	    }
1004*e4b17023SJohn Marino 
1005*e4b17023SJohn Marino 	  if (gimple_debug_bind_p (stmt)
1006*e4b17023SJohn Marino 	      && !gimple_debug_bind_has_value_p (stmt))
1007*e4b17023SJohn Marino 	    continue;
1008*e4b17023SJohn Marino 
1009*e4b17023SJohn Marino 	  FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE|SSA_OP_VUSE)
1010*e4b17023SJohn Marino 	    {
1011*e4b17023SJohn Marino 	      op = USE_FROM_PTR (use_p);
1012*e4b17023SJohn Marino 	      if (verify_use (bb, definition_block[SSA_NAME_VERSION (op)],
1013*e4b17023SJohn Marino 			      use_p, stmt, false, names_defined_in_bb))
1014*e4b17023SJohn Marino 		goto err;
1015*e4b17023SJohn Marino 	    }
1016*e4b17023SJohn Marino 
1017*e4b17023SJohn Marino 	  FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_ALL_DEFS)
1018*e4b17023SJohn Marino 	    {
1019*e4b17023SJohn Marino 	      if (SSA_NAME_DEF_STMT (op) != stmt)
1020*e4b17023SJohn Marino 		{
1021*e4b17023SJohn Marino 		  error ("SSA_NAME_DEF_STMT is wrong");
1022*e4b17023SJohn Marino 		  fprintf (stderr, "Expected definition statement:\n");
1023*e4b17023SJohn Marino 		  print_gimple_stmt (stderr, stmt, 4, TDF_VOPS);
1024*e4b17023SJohn Marino 		  fprintf (stderr, "\nActual definition statement:\n");
1025*e4b17023SJohn Marino 		  print_gimple_stmt (stderr, SSA_NAME_DEF_STMT (op),
1026*e4b17023SJohn Marino 				     4, TDF_VOPS);
1027*e4b17023SJohn Marino 		  goto err;
1028*e4b17023SJohn Marino 		}
1029*e4b17023SJohn Marino 	      bitmap_set_bit (names_defined_in_bb, SSA_NAME_VERSION (op));
1030*e4b17023SJohn Marino 	    }
1031*e4b17023SJohn Marino 	}
1032*e4b17023SJohn Marino 
1033*e4b17023SJohn Marino       bitmap_clear (names_defined_in_bb);
1034*e4b17023SJohn Marino     }
1035*e4b17023SJohn Marino 
1036*e4b17023SJohn Marino   free (definition_block);
1037*e4b17023SJohn Marino 
1038*e4b17023SJohn Marino   /* Restore the dominance information to its prior known state, so
1039*e4b17023SJohn Marino      that we do not perturb the compiler's subsequent behavior.  */
1040*e4b17023SJohn Marino   if (orig_dom_state == DOM_NONE)
1041*e4b17023SJohn Marino     free_dominance_info (CDI_DOMINATORS);
1042*e4b17023SJohn Marino   else
1043*e4b17023SJohn Marino     set_dom_info_availability (CDI_DOMINATORS, orig_dom_state);
1044*e4b17023SJohn Marino 
1045*e4b17023SJohn Marino   BITMAP_FREE (names_defined_in_bb);
1046*e4b17023SJohn Marino   timevar_pop (TV_TREE_SSA_VERIFY);
1047*e4b17023SJohn Marino   return;
1048*e4b17023SJohn Marino 
1049*e4b17023SJohn Marino err:
1050*e4b17023SJohn Marino   internal_error ("verify_ssa failed");
1051*e4b17023SJohn Marino }
1052*e4b17023SJohn Marino 
1053*e4b17023SJohn Marino /* Return true if the uid in both int tree maps are equal.  */
1054*e4b17023SJohn Marino 
1055*e4b17023SJohn Marino int
int_tree_map_eq(const void * va,const void * vb)1056*e4b17023SJohn Marino int_tree_map_eq (const void *va, const void *vb)
1057*e4b17023SJohn Marino {
1058*e4b17023SJohn Marino   const struct int_tree_map *a = (const struct int_tree_map *) va;
1059*e4b17023SJohn Marino   const struct int_tree_map *b = (const struct int_tree_map *) vb;
1060*e4b17023SJohn Marino   return (a->uid == b->uid);
1061*e4b17023SJohn Marino }
1062*e4b17023SJohn Marino 
1063*e4b17023SJohn Marino /* Hash a UID in a int_tree_map.  */
1064*e4b17023SJohn Marino 
1065*e4b17023SJohn Marino unsigned int
int_tree_map_hash(const void * item)1066*e4b17023SJohn Marino int_tree_map_hash (const void *item)
1067*e4b17023SJohn Marino {
1068*e4b17023SJohn Marino   return ((const struct int_tree_map *)item)->uid;
1069*e4b17023SJohn Marino }
1070*e4b17023SJohn Marino 
1071*e4b17023SJohn Marino /* Return true if the DECL_UID in both trees are equal.  */
1072*e4b17023SJohn Marino 
1073*e4b17023SJohn Marino int
uid_decl_map_eq(const void * va,const void * vb)1074*e4b17023SJohn Marino uid_decl_map_eq (const void *va, const void *vb)
1075*e4b17023SJohn Marino {
1076*e4b17023SJohn Marino   const_tree a = (const_tree) va;
1077*e4b17023SJohn Marino   const_tree b = (const_tree) vb;
1078*e4b17023SJohn Marino   return (a->decl_minimal.uid == b->decl_minimal.uid);
1079*e4b17023SJohn Marino }
1080*e4b17023SJohn Marino 
1081*e4b17023SJohn Marino /* Hash a tree in a uid_decl_map.  */
1082*e4b17023SJohn Marino 
1083*e4b17023SJohn Marino unsigned int
uid_decl_map_hash(const void * item)1084*e4b17023SJohn Marino uid_decl_map_hash (const void *item)
1085*e4b17023SJohn Marino {
1086*e4b17023SJohn Marino   return ((const_tree)item)->decl_minimal.uid;
1087*e4b17023SJohn Marino }
1088*e4b17023SJohn Marino 
1089*e4b17023SJohn Marino /* Return true if the DECL_UID in both trees are equal.  */
1090*e4b17023SJohn Marino 
1091*e4b17023SJohn Marino static int
uid_ssaname_map_eq(const void * va,const void * vb)1092*e4b17023SJohn Marino uid_ssaname_map_eq (const void *va, const void *vb)
1093*e4b17023SJohn Marino {
1094*e4b17023SJohn Marino   const_tree a = (const_tree) va;
1095*e4b17023SJohn Marino   const_tree b = (const_tree) vb;
1096*e4b17023SJohn Marino   return (a->ssa_name.var->decl_minimal.uid == b->ssa_name.var->decl_minimal.uid);
1097*e4b17023SJohn Marino }
1098*e4b17023SJohn Marino 
1099*e4b17023SJohn Marino /* Hash a tree in a uid_decl_map.  */
1100*e4b17023SJohn Marino 
1101*e4b17023SJohn Marino static unsigned int
uid_ssaname_map_hash(const void * item)1102*e4b17023SJohn Marino uid_ssaname_map_hash (const void *item)
1103*e4b17023SJohn Marino {
1104*e4b17023SJohn Marino   return ((const_tree)item)->ssa_name.var->decl_minimal.uid;
1105*e4b17023SJohn Marino }
1106*e4b17023SJohn Marino 
1107*e4b17023SJohn Marino 
1108*e4b17023SJohn Marino /* Initialize global DFA and SSA structures.  */
1109*e4b17023SJohn Marino 
1110*e4b17023SJohn Marino void
init_tree_ssa(struct function * fn)1111*e4b17023SJohn Marino init_tree_ssa (struct function *fn)
1112*e4b17023SJohn Marino {
1113*e4b17023SJohn Marino   fn->gimple_df = ggc_alloc_cleared_gimple_df ();
1114*e4b17023SJohn Marino   fn->gimple_df->referenced_vars = htab_create_ggc (20, uid_decl_map_hash,
1115*e4b17023SJohn Marino 				     		    uid_decl_map_eq, NULL);
1116*e4b17023SJohn Marino   fn->gimple_df->default_defs = htab_create_ggc (20, uid_ssaname_map_hash,
1117*e4b17023SJohn Marino 				                 uid_ssaname_map_eq, NULL);
1118*e4b17023SJohn Marino   pt_solution_reset (&fn->gimple_df->escaped);
1119*e4b17023SJohn Marino   init_ssanames (fn, 0);
1120*e4b17023SJohn Marino   init_phinodes ();
1121*e4b17023SJohn Marino }
1122*e4b17023SJohn Marino 
1123*e4b17023SJohn Marino 
1124*e4b17023SJohn Marino /* Deallocate memory associated with SSA data structures for FNDECL.  */
1125*e4b17023SJohn Marino 
1126*e4b17023SJohn Marino void
delete_tree_ssa(void)1127*e4b17023SJohn Marino delete_tree_ssa (void)
1128*e4b17023SJohn Marino {
1129*e4b17023SJohn Marino   referenced_var_iterator rvi;
1130*e4b17023SJohn Marino   tree var;
1131*e4b17023SJohn Marino 
1132*e4b17023SJohn Marino   /* Remove annotations from every referenced local variable.  */
1133*e4b17023SJohn Marino   FOR_EACH_REFERENCED_VAR (cfun, var, rvi)
1134*e4b17023SJohn Marino     {
1135*e4b17023SJohn Marino       if (is_global_var (var))
1136*e4b17023SJohn Marino 	continue;
1137*e4b17023SJohn Marino       if (var_ann (var))
1138*e4b17023SJohn Marino 	{
1139*e4b17023SJohn Marino 	  ggc_free (var_ann (var));
1140*e4b17023SJohn Marino 	  *DECL_VAR_ANN_PTR (var) = NULL;
1141*e4b17023SJohn Marino 	}
1142*e4b17023SJohn Marino     }
1143*e4b17023SJohn Marino   htab_delete (gimple_referenced_vars (cfun));
1144*e4b17023SJohn Marino   cfun->gimple_df->referenced_vars = NULL;
1145*e4b17023SJohn Marino 
1146*e4b17023SJohn Marino   fini_ssanames ();
1147*e4b17023SJohn Marino   fini_phinodes ();
1148*e4b17023SJohn Marino 
1149*e4b17023SJohn Marino   /* We no longer maintain the SSA operand cache at this point.  */
1150*e4b17023SJohn Marino   if (ssa_operands_active ())
1151*e4b17023SJohn Marino     fini_ssa_operands ();
1152*e4b17023SJohn Marino 
1153*e4b17023SJohn Marino   htab_delete (cfun->gimple_df->default_defs);
1154*e4b17023SJohn Marino   cfun->gimple_df->default_defs = NULL;
1155*e4b17023SJohn Marino   pt_solution_reset (&cfun->gimple_df->escaped);
1156*e4b17023SJohn Marino   if (cfun->gimple_df->decls_to_pointers != NULL)
1157*e4b17023SJohn Marino     pointer_map_destroy (cfun->gimple_df->decls_to_pointers);
1158*e4b17023SJohn Marino   cfun->gimple_df->decls_to_pointers = NULL;
1159*e4b17023SJohn Marino   cfun->gimple_df->modified_noreturn_calls = NULL;
1160*e4b17023SJohn Marino   cfun->gimple_df = NULL;
1161*e4b17023SJohn Marino 
1162*e4b17023SJohn Marino   /* We no longer need the edge variable maps.  */
1163*e4b17023SJohn Marino   redirect_edge_var_map_destroy ();
1164*e4b17023SJohn Marino }
1165*e4b17023SJohn Marino 
1166*e4b17023SJohn Marino /* Return true if the conversion from INNER_TYPE to OUTER_TYPE is a
1167*e4b17023SJohn Marino    useless type conversion, otherwise return false.
1168*e4b17023SJohn Marino 
1169*e4b17023SJohn Marino    This function implicitly defines the middle-end type system.  With
1170*e4b17023SJohn Marino    the notion of 'a < b' meaning that useless_type_conversion_p (a, b)
1171*e4b17023SJohn Marino    holds and 'a > b' meaning that useless_type_conversion_p (b, a) holds,
1172*e4b17023SJohn Marino    the following invariants shall be fulfilled:
1173*e4b17023SJohn Marino 
1174*e4b17023SJohn Marino      1) useless_type_conversion_p is transitive.
1175*e4b17023SJohn Marino 	If a < b and b < c then a < c.
1176*e4b17023SJohn Marino 
1177*e4b17023SJohn Marino      2) useless_type_conversion_p is not symmetric.
1178*e4b17023SJohn Marino 	From a < b does not follow a > b.
1179*e4b17023SJohn Marino 
1180*e4b17023SJohn Marino      3) Types define the available set of operations applicable to values.
1181*e4b17023SJohn Marino 	A type conversion is useless if the operations for the target type
1182*e4b17023SJohn Marino 	is a subset of the operations for the source type.  For example
1183*e4b17023SJohn Marino 	casts to void* are useless, casts from void* are not (void* can't
1184*e4b17023SJohn Marino 	be dereferenced or offsetted, but copied, hence its set of operations
1185*e4b17023SJohn Marino 	is a strict subset of that of all other data pointer types).  Casts
1186*e4b17023SJohn Marino 	to const T* are useless (can't be written to), casts from const T*
1187*e4b17023SJohn Marino 	to T* are not.  */
1188*e4b17023SJohn Marino 
1189*e4b17023SJohn Marino bool
useless_type_conversion_p(tree outer_type,tree inner_type)1190*e4b17023SJohn Marino useless_type_conversion_p (tree outer_type, tree inner_type)
1191*e4b17023SJohn Marino {
1192*e4b17023SJohn Marino   /* Do the following before stripping toplevel qualifiers.  */
1193*e4b17023SJohn Marino   if (POINTER_TYPE_P (inner_type)
1194*e4b17023SJohn Marino       && POINTER_TYPE_P (outer_type))
1195*e4b17023SJohn Marino     {
1196*e4b17023SJohn Marino       /* Do not lose casts between pointers to different address spaces.  */
1197*e4b17023SJohn Marino       if (TYPE_ADDR_SPACE (TREE_TYPE (outer_type))
1198*e4b17023SJohn Marino 	  != TYPE_ADDR_SPACE (TREE_TYPE (inner_type)))
1199*e4b17023SJohn Marino 	return false;
1200*e4b17023SJohn Marino     }
1201*e4b17023SJohn Marino 
1202*e4b17023SJohn Marino   /* From now on qualifiers on value types do not matter.  */
1203*e4b17023SJohn Marino   inner_type = TYPE_MAIN_VARIANT (inner_type);
1204*e4b17023SJohn Marino   outer_type = TYPE_MAIN_VARIANT (outer_type);
1205*e4b17023SJohn Marino 
1206*e4b17023SJohn Marino   if (inner_type == outer_type)
1207*e4b17023SJohn Marino     return true;
1208*e4b17023SJohn Marino 
1209*e4b17023SJohn Marino   /* If we know the canonical types, compare them.  */
1210*e4b17023SJohn Marino   if (TYPE_CANONICAL (inner_type)
1211*e4b17023SJohn Marino       && TYPE_CANONICAL (inner_type) == TYPE_CANONICAL (outer_type))
1212*e4b17023SJohn Marino     return true;
1213*e4b17023SJohn Marino 
1214*e4b17023SJohn Marino   /* Changes in machine mode are never useless conversions unless we
1215*e4b17023SJohn Marino      deal with aggregate types in which case we defer to later checks.  */
1216*e4b17023SJohn Marino   if (TYPE_MODE (inner_type) != TYPE_MODE (outer_type)
1217*e4b17023SJohn Marino       && !AGGREGATE_TYPE_P (inner_type))
1218*e4b17023SJohn Marino     return false;
1219*e4b17023SJohn Marino 
1220*e4b17023SJohn Marino   /* If both the inner and outer types are integral types, then the
1221*e4b17023SJohn Marino      conversion is not necessary if they have the same mode and
1222*e4b17023SJohn Marino      signedness and precision, and both or neither are boolean.  */
1223*e4b17023SJohn Marino   if (INTEGRAL_TYPE_P (inner_type)
1224*e4b17023SJohn Marino       && INTEGRAL_TYPE_P (outer_type))
1225*e4b17023SJohn Marino     {
1226*e4b17023SJohn Marino       /* Preserve changes in signedness or precision.  */
1227*e4b17023SJohn Marino       if (TYPE_UNSIGNED (inner_type) != TYPE_UNSIGNED (outer_type)
1228*e4b17023SJohn Marino 	  || TYPE_PRECISION (inner_type) != TYPE_PRECISION (outer_type))
1229*e4b17023SJohn Marino 	return false;
1230*e4b17023SJohn Marino 
1231*e4b17023SJohn Marino       /* Preserve conversions to/from BOOLEAN_TYPE if types are not
1232*e4b17023SJohn Marino 	 of precision one.  */
1233*e4b17023SJohn Marino       if (((TREE_CODE (inner_type) == BOOLEAN_TYPE)
1234*e4b17023SJohn Marino 	   != (TREE_CODE (outer_type) == BOOLEAN_TYPE))
1235*e4b17023SJohn Marino 	  && TYPE_PRECISION (outer_type) != 1)
1236*e4b17023SJohn Marino 	return false;
1237*e4b17023SJohn Marino 
1238*e4b17023SJohn Marino       /* We don't need to preserve changes in the types minimum or
1239*e4b17023SJohn Marino 	 maximum value in general as these do not generate code
1240*e4b17023SJohn Marino 	 unless the types precisions are different.  */
1241*e4b17023SJohn Marino       return true;
1242*e4b17023SJohn Marino     }
1243*e4b17023SJohn Marino 
1244*e4b17023SJohn Marino   /* Scalar floating point types with the same mode are compatible.  */
1245*e4b17023SJohn Marino   else if (SCALAR_FLOAT_TYPE_P (inner_type)
1246*e4b17023SJohn Marino 	   && SCALAR_FLOAT_TYPE_P (outer_type))
1247*e4b17023SJohn Marino     return true;
1248*e4b17023SJohn Marino 
1249*e4b17023SJohn Marino   /* Fixed point types with the same mode are compatible.  */
1250*e4b17023SJohn Marino   else if (FIXED_POINT_TYPE_P (inner_type)
1251*e4b17023SJohn Marino 	   && FIXED_POINT_TYPE_P (outer_type))
1252*e4b17023SJohn Marino     return true;
1253*e4b17023SJohn Marino 
1254*e4b17023SJohn Marino   /* We need to take special care recursing to pointed-to types.  */
1255*e4b17023SJohn Marino   else if (POINTER_TYPE_P (inner_type)
1256*e4b17023SJohn Marino 	   && POINTER_TYPE_P (outer_type))
1257*e4b17023SJohn Marino     {
1258*e4b17023SJohn Marino       /* Do not lose casts to function pointer types.  */
1259*e4b17023SJohn Marino       if ((TREE_CODE (TREE_TYPE (outer_type)) == FUNCTION_TYPE
1260*e4b17023SJohn Marino 	   || TREE_CODE (TREE_TYPE (outer_type)) == METHOD_TYPE)
1261*e4b17023SJohn Marino 	  && !(TREE_CODE (TREE_TYPE (inner_type)) == FUNCTION_TYPE
1262*e4b17023SJohn Marino 	       || TREE_CODE (TREE_TYPE (inner_type)) == METHOD_TYPE))
1263*e4b17023SJohn Marino 	return false;
1264*e4b17023SJohn Marino 
1265*e4b17023SJohn Marino       /* We do not care for const qualification of the pointed-to types
1266*e4b17023SJohn Marino 	 as const qualification has no semantic value to the middle-end.  */
1267*e4b17023SJohn Marino 
1268*e4b17023SJohn Marino       /* Otherwise pointers/references are equivalent.  */
1269*e4b17023SJohn Marino       return true;
1270*e4b17023SJohn Marino     }
1271*e4b17023SJohn Marino 
1272*e4b17023SJohn Marino   /* Recurse for complex types.  */
1273*e4b17023SJohn Marino   else if (TREE_CODE (inner_type) == COMPLEX_TYPE
1274*e4b17023SJohn Marino 	   && TREE_CODE (outer_type) == COMPLEX_TYPE)
1275*e4b17023SJohn Marino     return useless_type_conversion_p (TREE_TYPE (outer_type),
1276*e4b17023SJohn Marino 				      TREE_TYPE (inner_type));
1277*e4b17023SJohn Marino 
1278*e4b17023SJohn Marino   /* Recurse for vector types with the same number of subparts.  */
1279*e4b17023SJohn Marino   else if (TREE_CODE (inner_type) == VECTOR_TYPE
1280*e4b17023SJohn Marino 	   && TREE_CODE (outer_type) == VECTOR_TYPE
1281*e4b17023SJohn Marino 	   && TYPE_PRECISION (inner_type) == TYPE_PRECISION (outer_type))
1282*e4b17023SJohn Marino     return useless_type_conversion_p (TREE_TYPE (outer_type),
1283*e4b17023SJohn Marino 				      TREE_TYPE (inner_type));
1284*e4b17023SJohn Marino 
1285*e4b17023SJohn Marino   else if (TREE_CODE (inner_type) == ARRAY_TYPE
1286*e4b17023SJohn Marino 	   && TREE_CODE (outer_type) == ARRAY_TYPE)
1287*e4b17023SJohn Marino     {
1288*e4b17023SJohn Marino       /* Preserve string attributes.  */
1289*e4b17023SJohn Marino       if (TYPE_STRING_FLAG (inner_type) != TYPE_STRING_FLAG (outer_type))
1290*e4b17023SJohn Marino 	return false;
1291*e4b17023SJohn Marino 
1292*e4b17023SJohn Marino       /* Conversions from array types with unknown extent to
1293*e4b17023SJohn Marino 	 array types with known extent are not useless.  */
1294*e4b17023SJohn Marino       if (!TYPE_DOMAIN (inner_type)
1295*e4b17023SJohn Marino 	  && TYPE_DOMAIN (outer_type))
1296*e4b17023SJohn Marino 	return false;
1297*e4b17023SJohn Marino 
1298*e4b17023SJohn Marino       /* Nor are conversions from array types with non-constant size to
1299*e4b17023SJohn Marino          array types with constant size or to different size.  */
1300*e4b17023SJohn Marino       if (TYPE_SIZE (outer_type)
1301*e4b17023SJohn Marino 	  && TREE_CODE (TYPE_SIZE (outer_type)) == INTEGER_CST
1302*e4b17023SJohn Marino 	  && (!TYPE_SIZE (inner_type)
1303*e4b17023SJohn Marino 	      || TREE_CODE (TYPE_SIZE (inner_type)) != INTEGER_CST
1304*e4b17023SJohn Marino 	      || !tree_int_cst_equal (TYPE_SIZE (outer_type),
1305*e4b17023SJohn Marino 				      TYPE_SIZE (inner_type))))
1306*e4b17023SJohn Marino 	return false;
1307*e4b17023SJohn Marino 
1308*e4b17023SJohn Marino       /* Check conversions between arrays with partially known extents.
1309*e4b17023SJohn Marino 	 If the array min/max values are constant they have to match.
1310*e4b17023SJohn Marino 	 Otherwise allow conversions to unknown and variable extents.
1311*e4b17023SJohn Marino 	 In particular this declares conversions that may change the
1312*e4b17023SJohn Marino 	 mode to BLKmode as useless.  */
1313*e4b17023SJohn Marino       if (TYPE_DOMAIN (inner_type)
1314*e4b17023SJohn Marino 	  && TYPE_DOMAIN (outer_type)
1315*e4b17023SJohn Marino 	  && TYPE_DOMAIN (inner_type) != TYPE_DOMAIN (outer_type))
1316*e4b17023SJohn Marino 	{
1317*e4b17023SJohn Marino 	  tree inner_min = TYPE_MIN_VALUE (TYPE_DOMAIN (inner_type));
1318*e4b17023SJohn Marino 	  tree outer_min = TYPE_MIN_VALUE (TYPE_DOMAIN (outer_type));
1319*e4b17023SJohn Marino 	  tree inner_max = TYPE_MAX_VALUE (TYPE_DOMAIN (inner_type));
1320*e4b17023SJohn Marino 	  tree outer_max = TYPE_MAX_VALUE (TYPE_DOMAIN (outer_type));
1321*e4b17023SJohn Marino 
1322*e4b17023SJohn Marino 	  /* After gimplification a variable min/max value carries no
1323*e4b17023SJohn Marino 	     additional information compared to a NULL value.  All that
1324*e4b17023SJohn Marino 	     matters has been lowered to be part of the IL.  */
1325*e4b17023SJohn Marino 	  if (inner_min && TREE_CODE (inner_min) != INTEGER_CST)
1326*e4b17023SJohn Marino 	    inner_min = NULL_TREE;
1327*e4b17023SJohn Marino 	  if (outer_min && TREE_CODE (outer_min) != INTEGER_CST)
1328*e4b17023SJohn Marino 	    outer_min = NULL_TREE;
1329*e4b17023SJohn Marino 	  if (inner_max && TREE_CODE (inner_max) != INTEGER_CST)
1330*e4b17023SJohn Marino 	    inner_max = NULL_TREE;
1331*e4b17023SJohn Marino 	  if (outer_max && TREE_CODE (outer_max) != INTEGER_CST)
1332*e4b17023SJohn Marino 	    outer_max = NULL_TREE;
1333*e4b17023SJohn Marino 
1334*e4b17023SJohn Marino 	  /* Conversions NULL / variable <- cst are useless, but not
1335*e4b17023SJohn Marino 	     the other way around.  */
1336*e4b17023SJohn Marino 	  if (outer_min
1337*e4b17023SJohn Marino 	      && (!inner_min
1338*e4b17023SJohn Marino 		  || !tree_int_cst_equal (inner_min, outer_min)))
1339*e4b17023SJohn Marino 	    return false;
1340*e4b17023SJohn Marino 	  if (outer_max
1341*e4b17023SJohn Marino 	      && (!inner_max
1342*e4b17023SJohn Marino 		  || !tree_int_cst_equal (inner_max, outer_max)))
1343*e4b17023SJohn Marino 	    return false;
1344*e4b17023SJohn Marino 	}
1345*e4b17023SJohn Marino 
1346*e4b17023SJohn Marino       /* Recurse on the element check.  */
1347*e4b17023SJohn Marino       return useless_type_conversion_p (TREE_TYPE (outer_type),
1348*e4b17023SJohn Marino 					TREE_TYPE (inner_type));
1349*e4b17023SJohn Marino     }
1350*e4b17023SJohn Marino 
1351*e4b17023SJohn Marino   else if ((TREE_CODE (inner_type) == FUNCTION_TYPE
1352*e4b17023SJohn Marino 	    || TREE_CODE (inner_type) == METHOD_TYPE)
1353*e4b17023SJohn Marino 	   && TREE_CODE (inner_type) == TREE_CODE (outer_type))
1354*e4b17023SJohn Marino     {
1355*e4b17023SJohn Marino       tree outer_parm, inner_parm;
1356*e4b17023SJohn Marino 
1357*e4b17023SJohn Marino       /* If the return types are not compatible bail out.  */
1358*e4b17023SJohn Marino       if (!useless_type_conversion_p (TREE_TYPE (outer_type),
1359*e4b17023SJohn Marino 				      TREE_TYPE (inner_type)))
1360*e4b17023SJohn Marino 	return false;
1361*e4b17023SJohn Marino 
1362*e4b17023SJohn Marino       /* Method types should belong to a compatible base class.  */
1363*e4b17023SJohn Marino       if (TREE_CODE (inner_type) == METHOD_TYPE
1364*e4b17023SJohn Marino 	  && !useless_type_conversion_p (TYPE_METHOD_BASETYPE (outer_type),
1365*e4b17023SJohn Marino 					 TYPE_METHOD_BASETYPE (inner_type)))
1366*e4b17023SJohn Marino 	return false;
1367*e4b17023SJohn Marino 
1368*e4b17023SJohn Marino       /* A conversion to an unprototyped argument list is ok.  */
1369*e4b17023SJohn Marino       if (!prototype_p (outer_type))
1370*e4b17023SJohn Marino 	return true;
1371*e4b17023SJohn Marino 
1372*e4b17023SJohn Marino       /* If the unqualified argument types are compatible the conversion
1373*e4b17023SJohn Marino 	 is useless.  */
1374*e4b17023SJohn Marino       if (TYPE_ARG_TYPES (outer_type) == TYPE_ARG_TYPES (inner_type))
1375*e4b17023SJohn Marino 	return true;
1376*e4b17023SJohn Marino 
1377*e4b17023SJohn Marino       for (outer_parm = TYPE_ARG_TYPES (outer_type),
1378*e4b17023SJohn Marino 	   inner_parm = TYPE_ARG_TYPES (inner_type);
1379*e4b17023SJohn Marino 	   outer_parm && inner_parm;
1380*e4b17023SJohn Marino 	   outer_parm = TREE_CHAIN (outer_parm),
1381*e4b17023SJohn Marino 	   inner_parm = TREE_CHAIN (inner_parm))
1382*e4b17023SJohn Marino 	if (!useless_type_conversion_p
1383*e4b17023SJohn Marino 	       (TYPE_MAIN_VARIANT (TREE_VALUE (outer_parm)),
1384*e4b17023SJohn Marino 		TYPE_MAIN_VARIANT (TREE_VALUE (inner_parm))))
1385*e4b17023SJohn Marino 	  return false;
1386*e4b17023SJohn Marino 
1387*e4b17023SJohn Marino       /* If there is a mismatch in the number of arguments the functions
1388*e4b17023SJohn Marino 	 are not compatible.  */
1389*e4b17023SJohn Marino       if (outer_parm || inner_parm)
1390*e4b17023SJohn Marino 	return false;
1391*e4b17023SJohn Marino 
1392*e4b17023SJohn Marino       /* Defer to the target if necessary.  */
1393*e4b17023SJohn Marino       if (TYPE_ATTRIBUTES (inner_type) || TYPE_ATTRIBUTES (outer_type))
1394*e4b17023SJohn Marino 	return comp_type_attributes (outer_type, inner_type) != 0;
1395*e4b17023SJohn Marino 
1396*e4b17023SJohn Marino       return true;
1397*e4b17023SJohn Marino     }
1398*e4b17023SJohn Marino 
1399*e4b17023SJohn Marino   /* For aggregates we rely on TYPE_CANONICAL exclusively and require
1400*e4b17023SJohn Marino      explicit conversions for types involving to be structurally
1401*e4b17023SJohn Marino      compared types.  */
1402*e4b17023SJohn Marino   else if (AGGREGATE_TYPE_P (inner_type)
1403*e4b17023SJohn Marino 	   && TREE_CODE (inner_type) == TREE_CODE (outer_type))
1404*e4b17023SJohn Marino     return false;
1405*e4b17023SJohn Marino 
1406*e4b17023SJohn Marino   return false;
1407*e4b17023SJohn Marino }
1408*e4b17023SJohn Marino 
1409*e4b17023SJohn Marino /* Return true if a conversion from either type of TYPE1 and TYPE2
1410*e4b17023SJohn Marino    to the other is not required.  Otherwise return false.  */
1411*e4b17023SJohn Marino 
1412*e4b17023SJohn Marino bool
types_compatible_p(tree type1,tree type2)1413*e4b17023SJohn Marino types_compatible_p (tree type1, tree type2)
1414*e4b17023SJohn Marino {
1415*e4b17023SJohn Marino   return (type1 == type2
1416*e4b17023SJohn Marino 	  || (useless_type_conversion_p (type1, type2)
1417*e4b17023SJohn Marino 	      && useless_type_conversion_p (type2, type1)));
1418*e4b17023SJohn Marino }
1419*e4b17023SJohn Marino 
1420*e4b17023SJohn Marino /* Return true if EXPR is a useless type conversion, otherwise return
1421*e4b17023SJohn Marino    false.  */
1422*e4b17023SJohn Marino 
1423*e4b17023SJohn Marino bool
tree_ssa_useless_type_conversion(tree expr)1424*e4b17023SJohn Marino tree_ssa_useless_type_conversion (tree expr)
1425*e4b17023SJohn Marino {
1426*e4b17023SJohn Marino   /* If we have an assignment that merely uses a NOP_EXPR to change
1427*e4b17023SJohn Marino      the top of the RHS to the type of the LHS and the type conversion
1428*e4b17023SJohn Marino      is "safe", then strip away the type conversion so that we can
1429*e4b17023SJohn Marino      enter LHS = RHS into the const_and_copies table.  */
1430*e4b17023SJohn Marino   if (CONVERT_EXPR_P (expr)
1431*e4b17023SJohn Marino       || TREE_CODE (expr) == VIEW_CONVERT_EXPR
1432*e4b17023SJohn Marino       || TREE_CODE (expr) == NON_LVALUE_EXPR)
1433*e4b17023SJohn Marino     return useless_type_conversion_p
1434*e4b17023SJohn Marino       (TREE_TYPE (expr),
1435*e4b17023SJohn Marino        TREE_TYPE (TREE_OPERAND (expr, 0)));
1436*e4b17023SJohn Marino 
1437*e4b17023SJohn Marino   return false;
1438*e4b17023SJohn Marino }
1439*e4b17023SJohn Marino 
1440*e4b17023SJohn Marino /* Strip conversions from EXP according to
1441*e4b17023SJohn Marino    tree_ssa_useless_type_conversion and return the resulting
1442*e4b17023SJohn Marino    expression.  */
1443*e4b17023SJohn Marino 
1444*e4b17023SJohn Marino tree
tree_ssa_strip_useless_type_conversions(tree exp)1445*e4b17023SJohn Marino tree_ssa_strip_useless_type_conversions (tree exp)
1446*e4b17023SJohn Marino {
1447*e4b17023SJohn Marino   while (tree_ssa_useless_type_conversion (exp))
1448*e4b17023SJohn Marino     exp = TREE_OPERAND (exp, 0);
1449*e4b17023SJohn Marino   return exp;
1450*e4b17023SJohn Marino }
1451*e4b17023SJohn Marino 
1452*e4b17023SJohn Marino 
1453*e4b17023SJohn Marino /* Internal helper for walk_use_def_chains.  VAR, FN and DATA are as
1454*e4b17023SJohn Marino    described in walk_use_def_chains.
1455*e4b17023SJohn Marino 
1456*e4b17023SJohn Marino    VISITED is a pointer set used to mark visited SSA_NAMEs to avoid
1457*e4b17023SJohn Marino       infinite loops.  We used to have a bitmap for this to just mark
1458*e4b17023SJohn Marino       SSA versions we had visited.  But non-sparse bitmaps are way too
1459*e4b17023SJohn Marino       expensive, while sparse bitmaps may cause quadratic behavior.
1460*e4b17023SJohn Marino 
1461*e4b17023SJohn Marino    IS_DFS is true if the caller wants to perform a depth-first search
1462*e4b17023SJohn Marino       when visiting PHI nodes.  A DFS will visit each PHI argument and
1463*e4b17023SJohn Marino       call FN after each one.  Otherwise, all the arguments are
1464*e4b17023SJohn Marino       visited first and then FN is called with each of the visited
1465*e4b17023SJohn Marino       arguments in a separate pass.  */
1466*e4b17023SJohn Marino 
1467*e4b17023SJohn Marino static bool
walk_use_def_chains_1(tree var,walk_use_def_chains_fn fn,void * data,struct pointer_set_t * visited,bool is_dfs)1468*e4b17023SJohn Marino walk_use_def_chains_1 (tree var, walk_use_def_chains_fn fn, void *data,
1469*e4b17023SJohn Marino 		       struct pointer_set_t *visited, bool is_dfs)
1470*e4b17023SJohn Marino {
1471*e4b17023SJohn Marino   gimple def_stmt;
1472*e4b17023SJohn Marino 
1473*e4b17023SJohn Marino   if (pointer_set_insert (visited, var))
1474*e4b17023SJohn Marino     return false;
1475*e4b17023SJohn Marino 
1476*e4b17023SJohn Marino   def_stmt = SSA_NAME_DEF_STMT (var);
1477*e4b17023SJohn Marino 
1478*e4b17023SJohn Marino   if (gimple_code (def_stmt) != GIMPLE_PHI)
1479*e4b17023SJohn Marino     {
1480*e4b17023SJohn Marino       /* If we reached the end of the use-def chain, call FN.  */
1481*e4b17023SJohn Marino       return fn (var, def_stmt, data);
1482*e4b17023SJohn Marino     }
1483*e4b17023SJohn Marino   else
1484*e4b17023SJohn Marino     {
1485*e4b17023SJohn Marino       size_t i;
1486*e4b17023SJohn Marino 
1487*e4b17023SJohn Marino       /* When doing a breadth-first search, call FN before following the
1488*e4b17023SJohn Marino 	 use-def links for each argument.  */
1489*e4b17023SJohn Marino       if (!is_dfs)
1490*e4b17023SJohn Marino 	for (i = 0; i < gimple_phi_num_args (def_stmt); i++)
1491*e4b17023SJohn Marino 	  if (fn (gimple_phi_arg_def (def_stmt, i), def_stmt, data))
1492*e4b17023SJohn Marino 	    return true;
1493*e4b17023SJohn Marino 
1494*e4b17023SJohn Marino       /* Follow use-def links out of each PHI argument.  */
1495*e4b17023SJohn Marino       for (i = 0; i < gimple_phi_num_args (def_stmt); i++)
1496*e4b17023SJohn Marino 	{
1497*e4b17023SJohn Marino 	  tree arg = gimple_phi_arg_def (def_stmt, i);
1498*e4b17023SJohn Marino 
1499*e4b17023SJohn Marino 	  /* ARG may be NULL for newly introduced PHI nodes.  */
1500*e4b17023SJohn Marino 	  if (arg
1501*e4b17023SJohn Marino 	      && TREE_CODE (arg) == SSA_NAME
1502*e4b17023SJohn Marino 	      && walk_use_def_chains_1 (arg, fn, data, visited, is_dfs))
1503*e4b17023SJohn Marino 	    return true;
1504*e4b17023SJohn Marino 	}
1505*e4b17023SJohn Marino 
1506*e4b17023SJohn Marino       /* When doing a depth-first search, call FN after following the
1507*e4b17023SJohn Marino 	 use-def links for each argument.  */
1508*e4b17023SJohn Marino       if (is_dfs)
1509*e4b17023SJohn Marino 	for (i = 0; i < gimple_phi_num_args (def_stmt); i++)
1510*e4b17023SJohn Marino 	  if (fn (gimple_phi_arg_def (def_stmt, i), def_stmt, data))
1511*e4b17023SJohn Marino 	    return true;
1512*e4b17023SJohn Marino     }
1513*e4b17023SJohn Marino 
1514*e4b17023SJohn Marino   return false;
1515*e4b17023SJohn Marino }
1516*e4b17023SJohn Marino 
1517*e4b17023SJohn Marino 
1518*e4b17023SJohn Marino 
1519*e4b17023SJohn Marino /* Walk use-def chains starting at the SSA variable VAR.  Call
1520*e4b17023SJohn Marino    function FN at each reaching definition found.  FN takes three
1521*e4b17023SJohn Marino    arguments: VAR, its defining statement (DEF_STMT) and a generic
1522*e4b17023SJohn Marino    pointer to whatever state information that FN may want to maintain
1523*e4b17023SJohn Marino    (DATA).  FN is able to stop the walk by returning true, otherwise
1524*e4b17023SJohn Marino    in order to continue the walk, FN should return false.
1525*e4b17023SJohn Marino 
1526*e4b17023SJohn Marino    Note, that if DEF_STMT is a PHI node, the semantics are slightly
1527*e4b17023SJohn Marino    different.  The first argument to FN is no longer the original
1528*e4b17023SJohn Marino    variable VAR, but the PHI argument currently being examined.  If FN
1529*e4b17023SJohn Marino    wants to get at VAR, it should call PHI_RESULT (PHI).
1530*e4b17023SJohn Marino 
1531*e4b17023SJohn Marino    If IS_DFS is true, this function will:
1532*e4b17023SJohn Marino 
1533*e4b17023SJohn Marino 	1- walk the use-def chains for all the PHI arguments, and,
1534*e4b17023SJohn Marino 	2- call (*FN) (ARG, PHI, DATA) on all the PHI arguments.
1535*e4b17023SJohn Marino 
1536*e4b17023SJohn Marino    If IS_DFS is false, the two steps above are done in reverse order
1537*e4b17023SJohn Marino    (i.e., a breadth-first search).  */
1538*e4b17023SJohn Marino 
1539*e4b17023SJohn Marino void
walk_use_def_chains(tree var,walk_use_def_chains_fn fn,void * data,bool is_dfs)1540*e4b17023SJohn Marino walk_use_def_chains (tree var, walk_use_def_chains_fn fn, void *data,
1541*e4b17023SJohn Marino                      bool is_dfs)
1542*e4b17023SJohn Marino {
1543*e4b17023SJohn Marino   gimple def_stmt;
1544*e4b17023SJohn Marino 
1545*e4b17023SJohn Marino   gcc_assert (TREE_CODE (var) == SSA_NAME);
1546*e4b17023SJohn Marino 
1547*e4b17023SJohn Marino   def_stmt = SSA_NAME_DEF_STMT (var);
1548*e4b17023SJohn Marino 
1549*e4b17023SJohn Marino   /* We only need to recurse if the reaching definition comes from a PHI
1550*e4b17023SJohn Marino      node.  */
1551*e4b17023SJohn Marino   if (gimple_code (def_stmt) != GIMPLE_PHI)
1552*e4b17023SJohn Marino     (*fn) (var, def_stmt, data);
1553*e4b17023SJohn Marino   else
1554*e4b17023SJohn Marino     {
1555*e4b17023SJohn Marino       struct pointer_set_t *visited = pointer_set_create ();
1556*e4b17023SJohn Marino       walk_use_def_chains_1 (var, fn, data, visited, is_dfs);
1557*e4b17023SJohn Marino       pointer_set_destroy (visited);
1558*e4b17023SJohn Marino     }
1559*e4b17023SJohn Marino }
1560*e4b17023SJohn Marino 
1561*e4b17023SJohn Marino 
1562*e4b17023SJohn Marino /* Emit warnings for uninitialized variables.  This is done in two passes.
1563*e4b17023SJohn Marino 
1564*e4b17023SJohn Marino    The first pass notices real uses of SSA names with undefined values.
1565*e4b17023SJohn Marino    Such uses are unconditionally uninitialized, and we can be certain that
1566*e4b17023SJohn Marino    such a use is a mistake.  This pass is run before most optimizations,
1567*e4b17023SJohn Marino    so that we catch as many as we can.
1568*e4b17023SJohn Marino 
1569*e4b17023SJohn Marino    The second pass follows PHI nodes to find uses that are potentially
1570*e4b17023SJohn Marino    uninitialized.  In this case we can't necessarily prove that the use
1571*e4b17023SJohn Marino    is really uninitialized.  This pass is run after most optimizations,
1572*e4b17023SJohn Marino    so that we thread as many jumps and possible, and delete as much dead
1573*e4b17023SJohn Marino    code as possible, in order to reduce false positives.  We also look
1574*e4b17023SJohn Marino    again for plain uninitialized variables, since optimization may have
1575*e4b17023SJohn Marino    changed conditionally uninitialized to unconditionally uninitialized.  */
1576*e4b17023SJohn Marino 
1577*e4b17023SJohn Marino /* Emit a warning for EXPR based on variable VAR at the point in the
1578*e4b17023SJohn Marino    program T, an SSA_NAME, is used being uninitialized.  The exact
1579*e4b17023SJohn Marino    warning text is in MSGID and LOCUS may contain a location or be null.
1580*e4b17023SJohn Marino    WC is the warning code.  */
1581*e4b17023SJohn Marino 
1582*e4b17023SJohn Marino void
warn_uninit(enum opt_code wc,tree t,tree expr,tree var,const char * gmsgid,void * data)1583*e4b17023SJohn Marino warn_uninit (enum opt_code wc, tree t,
1584*e4b17023SJohn Marino 	     tree expr, tree var, const char *gmsgid, void *data)
1585*e4b17023SJohn Marino {
1586*e4b17023SJohn Marino   gimple context = (gimple) data;
1587*e4b17023SJohn Marino   location_t location;
1588*e4b17023SJohn Marino   expanded_location xloc, floc;
1589*e4b17023SJohn Marino 
1590*e4b17023SJohn Marino   if (!ssa_undefined_value_p (t))
1591*e4b17023SJohn Marino     return;
1592*e4b17023SJohn Marino 
1593*e4b17023SJohn Marino   /* TREE_NO_WARNING either means we already warned, or the front end
1594*e4b17023SJohn Marino      wishes to suppress the warning.  */
1595*e4b17023SJohn Marino   if ((context
1596*e4b17023SJohn Marino        && (gimple_no_warning_p (context)
1597*e4b17023SJohn Marino 	   || (gimple_assign_single_p (context)
1598*e4b17023SJohn Marino 	       && TREE_NO_WARNING (gimple_assign_rhs1 (context)))))
1599*e4b17023SJohn Marino       || TREE_NO_WARNING (expr))
1600*e4b17023SJohn Marino     return;
1601*e4b17023SJohn Marino 
1602*e4b17023SJohn Marino   location = (context != NULL && gimple_has_location (context))
1603*e4b17023SJohn Marino 	     ? gimple_location (context)
1604*e4b17023SJohn Marino 	     : DECL_SOURCE_LOCATION (var);
1605*e4b17023SJohn Marino   xloc = expand_location (location);
1606*e4b17023SJohn Marino   floc = expand_location (DECL_SOURCE_LOCATION (cfun->decl));
1607*e4b17023SJohn Marino   if (warning_at (location, wc, gmsgid, expr))
1608*e4b17023SJohn Marino     {
1609*e4b17023SJohn Marino       TREE_NO_WARNING (expr) = 1;
1610*e4b17023SJohn Marino 
1611*e4b17023SJohn Marino       if (location == DECL_SOURCE_LOCATION (var))
1612*e4b17023SJohn Marino 	return;
1613*e4b17023SJohn Marino       if (xloc.file != floc.file
1614*e4b17023SJohn Marino 	  || xloc.line < floc.line
1615*e4b17023SJohn Marino 	  || xloc.line > LOCATION_LINE (cfun->function_end_locus))
1616*e4b17023SJohn Marino 	inform (DECL_SOURCE_LOCATION (var), "%qD was declared here", var);
1617*e4b17023SJohn Marino     }
1618*e4b17023SJohn Marino }
1619*e4b17023SJohn Marino 
1620*e4b17023SJohn Marino unsigned int
warn_uninitialized_vars(bool warn_possibly_uninitialized)1621*e4b17023SJohn Marino warn_uninitialized_vars (bool warn_possibly_uninitialized)
1622*e4b17023SJohn Marino {
1623*e4b17023SJohn Marino   gimple_stmt_iterator gsi;
1624*e4b17023SJohn Marino   basic_block bb;
1625*e4b17023SJohn Marino 
1626*e4b17023SJohn Marino   FOR_EACH_BB (bb)
1627*e4b17023SJohn Marino     {
1628*e4b17023SJohn Marino       bool always_executed = dominated_by_p (CDI_POST_DOMINATORS,
1629*e4b17023SJohn Marino 					     single_succ (ENTRY_BLOCK_PTR), bb);
1630*e4b17023SJohn Marino       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1631*e4b17023SJohn Marino 	{
1632*e4b17023SJohn Marino 	  gimple stmt = gsi_stmt (gsi);
1633*e4b17023SJohn Marino 	  use_operand_p use_p;
1634*e4b17023SJohn Marino 	  ssa_op_iter op_iter;
1635*e4b17023SJohn Marino 	  tree use;
1636*e4b17023SJohn Marino 
1637*e4b17023SJohn Marino 	  if (is_gimple_debug (stmt))
1638*e4b17023SJohn Marino 	    continue;
1639*e4b17023SJohn Marino 
1640*e4b17023SJohn Marino 	  /* We only do data flow with SSA_NAMEs, so that's all we
1641*e4b17023SJohn Marino 	     can warn about.  */
1642*e4b17023SJohn Marino 	  FOR_EACH_SSA_USE_OPERAND (use_p, stmt, op_iter, SSA_OP_USE)
1643*e4b17023SJohn Marino 	    {
1644*e4b17023SJohn Marino 	      use = USE_FROM_PTR (use_p);
1645*e4b17023SJohn Marino 	      if (always_executed)
1646*e4b17023SJohn Marino 		warn_uninit (OPT_Wuninitialized, use,
1647*e4b17023SJohn Marino 			     SSA_NAME_VAR (use), SSA_NAME_VAR (use),
1648*e4b17023SJohn Marino 			     "%qD is used uninitialized in this function",
1649*e4b17023SJohn Marino 			     stmt);
1650*e4b17023SJohn Marino 	      else if (warn_possibly_uninitialized)
1651*e4b17023SJohn Marino 		warn_uninit (OPT_Wuninitialized, use,
1652*e4b17023SJohn Marino 			     SSA_NAME_VAR (use), SSA_NAME_VAR (use),
1653*e4b17023SJohn Marino 			     "%qD may be used uninitialized in this function",
1654*e4b17023SJohn Marino 			     stmt);
1655*e4b17023SJohn Marino 	    }
1656*e4b17023SJohn Marino 
1657*e4b17023SJohn Marino 	  /* For memory the only cheap thing we can do is see if we
1658*e4b17023SJohn Marino 	     have a use of the default def of the virtual operand.
1659*e4b17023SJohn Marino 	     ???  Note that at -O0 we do not have virtual operands.
1660*e4b17023SJohn Marino 	     ???  Not so cheap would be to use the alias oracle via
1661*e4b17023SJohn Marino 	     walk_aliased_vdefs, if we don't find any aliasing vdef
1662*e4b17023SJohn Marino 	     warn as is-used-uninitialized, if we don't find an aliasing
1663*e4b17023SJohn Marino 	     vdef that kills our use (stmt_kills_ref_p), warn as
1664*e4b17023SJohn Marino 	     may-be-used-uninitialized.  But this walk is quadratic and
1665*e4b17023SJohn Marino 	     so must be limited which means we would miss warning
1666*e4b17023SJohn Marino 	     opportunities.  */
1667*e4b17023SJohn Marino 	  use = gimple_vuse (stmt);
1668*e4b17023SJohn Marino 	  if (use
1669*e4b17023SJohn Marino 	      && gimple_assign_single_p (stmt)
1670*e4b17023SJohn Marino 	      && !gimple_vdef (stmt)
1671*e4b17023SJohn Marino 	      && SSA_NAME_IS_DEFAULT_DEF (use))
1672*e4b17023SJohn Marino 	    {
1673*e4b17023SJohn Marino 	      tree rhs = gimple_assign_rhs1 (stmt);
1674*e4b17023SJohn Marino 	      tree base = get_base_address (rhs);
1675*e4b17023SJohn Marino 
1676*e4b17023SJohn Marino 	      /* Do not warn if it can be initialized outside this function.  */
1677*e4b17023SJohn Marino 	      if (TREE_CODE (base) != VAR_DECL
1678*e4b17023SJohn Marino 		  || DECL_HARD_REGISTER (base)
1679*e4b17023SJohn Marino 		  || is_global_var (base))
1680*e4b17023SJohn Marino 		continue;
1681*e4b17023SJohn Marino 
1682*e4b17023SJohn Marino 	      if (always_executed)
1683*e4b17023SJohn Marino 		warn_uninit (OPT_Wuninitialized, use, gimple_assign_rhs1 (stmt),
1684*e4b17023SJohn Marino 			     base,
1685*e4b17023SJohn Marino 			     "%qE is used uninitialized in this function",
1686*e4b17023SJohn Marino 			     stmt);
1687*e4b17023SJohn Marino 	      else if (warn_possibly_uninitialized)
1688*e4b17023SJohn Marino 		warn_uninit (OPT_Wuninitialized, use, gimple_assign_rhs1 (stmt),
1689*e4b17023SJohn Marino 			     base,
1690*e4b17023SJohn Marino 			     "%qE may be used uninitialized in this function",
1691*e4b17023SJohn Marino 			     stmt);
1692*e4b17023SJohn Marino 	    }
1693*e4b17023SJohn Marino 	}
1694*e4b17023SJohn Marino     }
1695*e4b17023SJohn Marino 
1696*e4b17023SJohn Marino   return 0;
1697*e4b17023SJohn Marino }
1698*e4b17023SJohn Marino 
1699*e4b17023SJohn Marino static unsigned int
execute_early_warn_uninitialized(void)1700*e4b17023SJohn Marino execute_early_warn_uninitialized (void)
1701*e4b17023SJohn Marino {
1702*e4b17023SJohn Marino   /* Currently, this pass runs always but
1703*e4b17023SJohn Marino      execute_late_warn_uninitialized only runs with optimization. With
1704*e4b17023SJohn Marino      optimization we want to warn about possible uninitialized as late
1705*e4b17023SJohn Marino      as possible, thus don't do it here.  However, without
1706*e4b17023SJohn Marino      optimization we need to warn here about "may be uninitialized".
1707*e4b17023SJohn Marino   */
1708*e4b17023SJohn Marino   calculate_dominance_info (CDI_POST_DOMINATORS);
1709*e4b17023SJohn Marino 
1710*e4b17023SJohn Marino   warn_uninitialized_vars (/*warn_possibly_uninitialized=*/!optimize);
1711*e4b17023SJohn Marino 
1712*e4b17023SJohn Marino   /* Post-dominator information can not be reliably updated. Free it
1713*e4b17023SJohn Marino      after the use.  */
1714*e4b17023SJohn Marino 
1715*e4b17023SJohn Marino   free_dominance_info (CDI_POST_DOMINATORS);
1716*e4b17023SJohn Marino   return 0;
1717*e4b17023SJohn Marino }
1718*e4b17023SJohn Marino 
1719*e4b17023SJohn Marino static bool
gate_warn_uninitialized(void)1720*e4b17023SJohn Marino gate_warn_uninitialized (void)
1721*e4b17023SJohn Marino {
1722*e4b17023SJohn Marino   return warn_uninitialized != 0;
1723*e4b17023SJohn Marino }
1724*e4b17023SJohn Marino 
1725*e4b17023SJohn Marino struct gimple_opt_pass pass_early_warn_uninitialized =
1726*e4b17023SJohn Marino {
1727*e4b17023SJohn Marino  {
1728*e4b17023SJohn Marino   GIMPLE_PASS,
1729*e4b17023SJohn Marino   "*early_warn_uninitialized",		/* name */
1730*e4b17023SJohn Marino   gate_warn_uninitialized,		/* gate */
1731*e4b17023SJohn Marino   execute_early_warn_uninitialized,	/* execute */
1732*e4b17023SJohn Marino   NULL,					/* sub */
1733*e4b17023SJohn Marino   NULL,					/* next */
1734*e4b17023SJohn Marino   0,					/* static_pass_number */
1735*e4b17023SJohn Marino   TV_TREE_UNINIT,			/* tv_id */
1736*e4b17023SJohn Marino   PROP_ssa,				/* properties_required */
1737*e4b17023SJohn Marino   0,					/* properties_provided */
1738*e4b17023SJohn Marino   0,					/* properties_destroyed */
1739*e4b17023SJohn Marino   0,					/* todo_flags_start */
1740*e4b17023SJohn Marino   0                                     /* todo_flags_finish */
1741*e4b17023SJohn Marino  }
1742*e4b17023SJohn Marino };
1743*e4b17023SJohn Marino 
1744*e4b17023SJohn Marino 
1745*e4b17023SJohn Marino /* If necessary, rewrite the base of the reference tree *TP from
1746*e4b17023SJohn Marino    a MEM_REF to a plain or converted symbol.  */
1747*e4b17023SJohn Marino 
1748*e4b17023SJohn Marino static void
maybe_rewrite_mem_ref_base(tree * tp)1749*e4b17023SJohn Marino maybe_rewrite_mem_ref_base (tree *tp)
1750*e4b17023SJohn Marino {
1751*e4b17023SJohn Marino   tree sym;
1752*e4b17023SJohn Marino 
1753*e4b17023SJohn Marino   while (handled_component_p (*tp))
1754*e4b17023SJohn Marino     tp = &TREE_OPERAND (*tp, 0);
1755*e4b17023SJohn Marino   if (TREE_CODE (*tp) == MEM_REF
1756*e4b17023SJohn Marino       && TREE_CODE (TREE_OPERAND (*tp, 0)) == ADDR_EXPR
1757*e4b17023SJohn Marino       && (sym = TREE_OPERAND (TREE_OPERAND (*tp, 0), 0))
1758*e4b17023SJohn Marino       && DECL_P (sym)
1759*e4b17023SJohn Marino       && !TREE_ADDRESSABLE (sym)
1760*e4b17023SJohn Marino       && symbol_marked_for_renaming (sym))
1761*e4b17023SJohn Marino     {
1762*e4b17023SJohn Marino       if (TREE_CODE (TREE_TYPE (sym)) == VECTOR_TYPE
1763*e4b17023SJohn Marino 	  && useless_type_conversion_p (TREE_TYPE (*tp),
1764*e4b17023SJohn Marino 					TREE_TYPE (TREE_TYPE (sym)))
1765*e4b17023SJohn Marino 	  && multiple_of_p (sizetype, TREE_OPERAND (*tp, 1),
1766*e4b17023SJohn Marino 			    TYPE_SIZE_UNIT (TREE_TYPE (*tp))))
1767*e4b17023SJohn Marino 	{
1768*e4b17023SJohn Marino 	  *tp = build3 (BIT_FIELD_REF, TREE_TYPE (*tp), sym,
1769*e4b17023SJohn Marino 			TYPE_SIZE (TREE_TYPE (*tp)),
1770*e4b17023SJohn Marino 			int_const_binop (MULT_EXPR,
1771*e4b17023SJohn Marino 					 bitsize_int (BITS_PER_UNIT),
1772*e4b17023SJohn Marino 					 TREE_OPERAND (*tp, 1)));
1773*e4b17023SJohn Marino 	}
1774*e4b17023SJohn Marino       else if (TREE_CODE (TREE_TYPE (sym)) == COMPLEX_TYPE
1775*e4b17023SJohn Marino 	       && useless_type_conversion_p (TREE_TYPE (*tp),
1776*e4b17023SJohn Marino 					     TREE_TYPE (TREE_TYPE (sym))))
1777*e4b17023SJohn Marino 	{
1778*e4b17023SJohn Marino 	  *tp = build1 (integer_zerop (TREE_OPERAND (*tp, 1))
1779*e4b17023SJohn Marino 			? REALPART_EXPR : IMAGPART_EXPR,
1780*e4b17023SJohn Marino 			TREE_TYPE (*tp), sym);
1781*e4b17023SJohn Marino 	}
1782*e4b17023SJohn Marino       else if (integer_zerop (TREE_OPERAND (*tp, 1)))
1783*e4b17023SJohn Marino 	{
1784*e4b17023SJohn Marino 	  if (!useless_type_conversion_p (TREE_TYPE (*tp),
1785*e4b17023SJohn Marino 					  TREE_TYPE (sym)))
1786*e4b17023SJohn Marino 	    *tp = build1 (VIEW_CONVERT_EXPR,
1787*e4b17023SJohn Marino 			  TREE_TYPE (*tp), sym);
1788*e4b17023SJohn Marino 	  else
1789*e4b17023SJohn Marino 	    *tp = sym;
1790*e4b17023SJohn Marino 	}
1791*e4b17023SJohn Marino     }
1792*e4b17023SJohn Marino }
1793*e4b17023SJohn Marino 
1794*e4b17023SJohn Marino /* For a tree REF return its base if it is the base of a MEM_REF
1795*e4b17023SJohn Marino    that cannot be rewritten into SSA form.  Otherwise return NULL_TREE.  */
1796*e4b17023SJohn Marino 
1797*e4b17023SJohn Marino static tree
non_rewritable_mem_ref_base(tree ref)1798*e4b17023SJohn Marino non_rewritable_mem_ref_base (tree ref)
1799*e4b17023SJohn Marino {
1800*e4b17023SJohn Marino   tree base = ref;
1801*e4b17023SJohn Marino 
1802*e4b17023SJohn Marino   /* A plain decl does not need it set.  */
1803*e4b17023SJohn Marino   if (DECL_P (ref))
1804*e4b17023SJohn Marino     return NULL_TREE;
1805*e4b17023SJohn Marino 
1806*e4b17023SJohn Marino   while (handled_component_p (base))
1807*e4b17023SJohn Marino     base = TREE_OPERAND (base, 0);
1808*e4b17023SJohn Marino 
1809*e4b17023SJohn Marino   /* But watch out for MEM_REFs we cannot lower to a
1810*e4b17023SJohn Marino      VIEW_CONVERT_EXPR or a BIT_FIELD_REF.  */
1811*e4b17023SJohn Marino   if (TREE_CODE (base) == MEM_REF
1812*e4b17023SJohn Marino       && TREE_CODE (TREE_OPERAND (base, 0)) == ADDR_EXPR)
1813*e4b17023SJohn Marino     {
1814*e4b17023SJohn Marino       tree decl = TREE_OPERAND (TREE_OPERAND (base, 0), 0);
1815*e4b17023SJohn Marino       if ((TREE_CODE (TREE_TYPE (decl)) == VECTOR_TYPE
1816*e4b17023SJohn Marino 	   || TREE_CODE (TREE_TYPE (decl)) == COMPLEX_TYPE)
1817*e4b17023SJohn Marino 	  && useless_type_conversion_p (TREE_TYPE (base),
1818*e4b17023SJohn Marino 					TREE_TYPE (TREE_TYPE (decl)))
1819*e4b17023SJohn Marino 	  && double_int_fits_in_uhwi_p (mem_ref_offset (base))
1820*e4b17023SJohn Marino 	  && double_int_ucmp
1821*e4b17023SJohn Marino 	       (tree_to_double_int (TYPE_SIZE_UNIT (TREE_TYPE (decl))),
1822*e4b17023SJohn Marino 		mem_ref_offset (base)) == 1
1823*e4b17023SJohn Marino 	  && multiple_of_p (sizetype, TREE_OPERAND (base, 1),
1824*e4b17023SJohn Marino 			    TYPE_SIZE_UNIT (TREE_TYPE (base))))
1825*e4b17023SJohn Marino 	return NULL_TREE;
1826*e4b17023SJohn Marino       if (DECL_P (decl)
1827*e4b17023SJohn Marino 	  && (!integer_zerop (TREE_OPERAND (base, 1))
1828*e4b17023SJohn Marino 	      || (DECL_SIZE (decl)
1829*e4b17023SJohn Marino 		  != TYPE_SIZE (TREE_TYPE (base)))
1830*e4b17023SJohn Marino 	      || TREE_THIS_VOLATILE (decl) != TREE_THIS_VOLATILE (base)))
1831*e4b17023SJohn Marino 	return decl;
1832*e4b17023SJohn Marino     }
1833*e4b17023SJohn Marino 
1834*e4b17023SJohn Marino   return NULL_TREE;
1835*e4b17023SJohn Marino }
1836*e4b17023SJohn Marino 
1837*e4b17023SJohn Marino /* For an lvalue tree LHS return true if it cannot be rewritten into SSA form.
1838*e4b17023SJohn Marino    Otherwise return true.  */
1839*e4b17023SJohn Marino 
1840*e4b17023SJohn Marino static bool
non_rewritable_lvalue_p(tree lhs)1841*e4b17023SJohn Marino non_rewritable_lvalue_p (tree lhs)
1842*e4b17023SJohn Marino {
1843*e4b17023SJohn Marino   /* A plain decl is always rewritable.  */
1844*e4b17023SJohn Marino   if (DECL_P (lhs))
1845*e4b17023SJohn Marino     return false;
1846*e4b17023SJohn Marino 
1847*e4b17023SJohn Marino   /* A decl that is wrapped inside a MEM-REF that covers
1848*e4b17023SJohn Marino      it full is also rewritable.
1849*e4b17023SJohn Marino      ???  The following could be relaxed allowing component
1850*e4b17023SJohn Marino      references that do not change the access size.  */
1851*e4b17023SJohn Marino   if (TREE_CODE (lhs) == MEM_REF
1852*e4b17023SJohn Marino       && TREE_CODE (TREE_OPERAND (lhs, 0)) == ADDR_EXPR
1853*e4b17023SJohn Marino       && integer_zerop (TREE_OPERAND (lhs, 1)))
1854*e4b17023SJohn Marino     {
1855*e4b17023SJohn Marino       tree decl = TREE_OPERAND (TREE_OPERAND (lhs, 0), 0);
1856*e4b17023SJohn Marino       if (DECL_P (decl)
1857*e4b17023SJohn Marino 	  && DECL_SIZE (decl) == TYPE_SIZE (TREE_TYPE (lhs))
1858*e4b17023SJohn Marino 	  && (TREE_THIS_VOLATILE (decl) == TREE_THIS_VOLATILE (lhs)))
1859*e4b17023SJohn Marino 	return false;
1860*e4b17023SJohn Marino     }
1861*e4b17023SJohn Marino 
1862*e4b17023SJohn Marino   return true;
1863*e4b17023SJohn Marino }
1864*e4b17023SJohn Marino 
1865*e4b17023SJohn Marino /* When possible, clear TREE_ADDRESSABLE bit or set DECL_GIMPLE_REG_P bit and
1866*e4b17023SJohn Marino    mark the variable VAR for conversion into SSA.  Return true when updating
1867*e4b17023SJohn Marino    stmts is required.  */
1868*e4b17023SJohn Marino 
1869*e4b17023SJohn Marino static bool
maybe_optimize_var(tree var,bitmap addresses_taken,bitmap not_reg_needs)1870*e4b17023SJohn Marino maybe_optimize_var (tree var, bitmap addresses_taken, bitmap not_reg_needs)
1871*e4b17023SJohn Marino {
1872*e4b17023SJohn Marino   bool update_vops = false;
1873*e4b17023SJohn Marino 
1874*e4b17023SJohn Marino   /* Global Variables, result decls cannot be changed.  */
1875*e4b17023SJohn Marino   if (is_global_var (var)
1876*e4b17023SJohn Marino       || TREE_CODE (var) == RESULT_DECL
1877*e4b17023SJohn Marino       || bitmap_bit_p (addresses_taken, DECL_UID (var)))
1878*e4b17023SJohn Marino     return false;
1879*e4b17023SJohn Marino 
1880*e4b17023SJohn Marino   /* If the variable is not in the list of referenced vars then we
1881*e4b17023SJohn Marino      do not need to touch it nor can we rename it.  */
1882*e4b17023SJohn Marino   if (!referenced_var_lookup (cfun, DECL_UID (var)))
1883*e4b17023SJohn Marino     return false;
1884*e4b17023SJohn Marino 
1885*e4b17023SJohn Marino   if (TREE_ADDRESSABLE (var)
1886*e4b17023SJohn Marino       /* Do not change TREE_ADDRESSABLE if we need to preserve var as
1887*e4b17023SJohn Marino 	 a non-register.  Otherwise we are confused and forget to
1888*e4b17023SJohn Marino 	 add virtual operands for it.  */
1889*e4b17023SJohn Marino       && (!is_gimple_reg_type (TREE_TYPE (var))
1890*e4b17023SJohn Marino 	  || TREE_CODE (TREE_TYPE (var)) == VECTOR_TYPE
1891*e4b17023SJohn Marino 	  || TREE_CODE (TREE_TYPE (var)) == COMPLEX_TYPE
1892*e4b17023SJohn Marino 	  || !bitmap_bit_p (not_reg_needs, DECL_UID (var))))
1893*e4b17023SJohn Marino     {
1894*e4b17023SJohn Marino       TREE_ADDRESSABLE (var) = 0;
1895*e4b17023SJohn Marino       if (is_gimple_reg (var))
1896*e4b17023SJohn Marino 	mark_sym_for_renaming (var);
1897*e4b17023SJohn Marino       update_vops = true;
1898*e4b17023SJohn Marino       if (dump_file)
1899*e4b17023SJohn Marino 	{
1900*e4b17023SJohn Marino 	  fprintf (dump_file, "No longer having address taken: ");
1901*e4b17023SJohn Marino 	  print_generic_expr (dump_file, var, 0);
1902*e4b17023SJohn Marino 	  fprintf (dump_file, "\n");
1903*e4b17023SJohn Marino 	}
1904*e4b17023SJohn Marino     }
1905*e4b17023SJohn Marino 
1906*e4b17023SJohn Marino   if (!DECL_GIMPLE_REG_P (var)
1907*e4b17023SJohn Marino       && !bitmap_bit_p (not_reg_needs, DECL_UID (var))
1908*e4b17023SJohn Marino       && (TREE_CODE (TREE_TYPE (var)) == COMPLEX_TYPE
1909*e4b17023SJohn Marino 	  || TREE_CODE (TREE_TYPE (var)) == VECTOR_TYPE)
1910*e4b17023SJohn Marino       && !TREE_THIS_VOLATILE (var)
1911*e4b17023SJohn Marino       && (TREE_CODE (var) != VAR_DECL || !DECL_HARD_REGISTER (var)))
1912*e4b17023SJohn Marino     {
1913*e4b17023SJohn Marino       DECL_GIMPLE_REG_P (var) = 1;
1914*e4b17023SJohn Marino       mark_sym_for_renaming (var);
1915*e4b17023SJohn Marino       update_vops = true;
1916*e4b17023SJohn Marino       if (dump_file)
1917*e4b17023SJohn Marino 	{
1918*e4b17023SJohn Marino 	  fprintf (dump_file, "Now a gimple register: ");
1919*e4b17023SJohn Marino 	  print_generic_expr (dump_file, var, 0);
1920*e4b17023SJohn Marino 	  fprintf (dump_file, "\n");
1921*e4b17023SJohn Marino 	}
1922*e4b17023SJohn Marino     }
1923*e4b17023SJohn Marino 
1924*e4b17023SJohn Marino   return update_vops;
1925*e4b17023SJohn Marino }
1926*e4b17023SJohn Marino 
1927*e4b17023SJohn Marino /* Compute TREE_ADDRESSABLE and DECL_GIMPLE_REG_P for local variables.  */
1928*e4b17023SJohn Marino 
1929*e4b17023SJohn Marino void
execute_update_addresses_taken(void)1930*e4b17023SJohn Marino execute_update_addresses_taken (void)
1931*e4b17023SJohn Marino {
1932*e4b17023SJohn Marino   gimple_stmt_iterator gsi;
1933*e4b17023SJohn Marino   basic_block bb;
1934*e4b17023SJohn Marino   bitmap addresses_taken = BITMAP_ALLOC (NULL);
1935*e4b17023SJohn Marino   bitmap not_reg_needs = BITMAP_ALLOC (NULL);
1936*e4b17023SJohn Marino   bool update_vops = false;
1937*e4b17023SJohn Marino   tree var;
1938*e4b17023SJohn Marino   unsigned i;
1939*e4b17023SJohn Marino 
1940*e4b17023SJohn Marino   timevar_push (TV_ADDRESS_TAKEN);
1941*e4b17023SJohn Marino 
1942*e4b17023SJohn Marino   /* Collect into ADDRESSES_TAKEN all variables whose address is taken within
1943*e4b17023SJohn Marino      the function body.  */
1944*e4b17023SJohn Marino   FOR_EACH_BB (bb)
1945*e4b17023SJohn Marino     {
1946*e4b17023SJohn Marino       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1947*e4b17023SJohn Marino 	{
1948*e4b17023SJohn Marino 	  gimple stmt = gsi_stmt (gsi);
1949*e4b17023SJohn Marino 	  enum gimple_code code = gimple_code (stmt);
1950*e4b17023SJohn Marino 	  tree decl;
1951*e4b17023SJohn Marino 
1952*e4b17023SJohn Marino 	  /* Note all addresses taken by the stmt.  */
1953*e4b17023SJohn Marino 	  gimple_ior_addresses_taken (addresses_taken, stmt);
1954*e4b17023SJohn Marino 
1955*e4b17023SJohn Marino 	  /* If we have a call or an assignment, see if the lhs contains
1956*e4b17023SJohn Marino 	     a local decl that requires not to be a gimple register.  */
1957*e4b17023SJohn Marino 	  if (code == GIMPLE_ASSIGN || code == GIMPLE_CALL)
1958*e4b17023SJohn Marino 	    {
1959*e4b17023SJohn Marino               tree lhs = gimple_get_lhs (stmt);
1960*e4b17023SJohn Marino               if (lhs
1961*e4b17023SJohn Marino 		  && TREE_CODE (lhs) != SSA_NAME
1962*e4b17023SJohn Marino 		  && non_rewritable_lvalue_p (lhs))
1963*e4b17023SJohn Marino 		{
1964*e4b17023SJohn Marino 		  decl = get_base_address (lhs);
1965*e4b17023SJohn Marino 		  if (DECL_P (decl))
1966*e4b17023SJohn Marino 		    bitmap_set_bit (not_reg_needs, DECL_UID (decl));
1967*e4b17023SJohn Marino                 }
1968*e4b17023SJohn Marino 	    }
1969*e4b17023SJohn Marino 
1970*e4b17023SJohn Marino 	  if (gimple_assign_single_p (stmt))
1971*e4b17023SJohn Marino 	    {
1972*e4b17023SJohn Marino 	      tree rhs = gimple_assign_rhs1 (stmt);
1973*e4b17023SJohn Marino 	      if ((decl = non_rewritable_mem_ref_base (rhs)))
1974*e4b17023SJohn Marino 		bitmap_set_bit (not_reg_needs, DECL_UID (decl));
1975*e4b17023SJohn Marino 	    }
1976*e4b17023SJohn Marino 
1977*e4b17023SJohn Marino 	  else if (code == GIMPLE_CALL)
1978*e4b17023SJohn Marino 	    {
1979*e4b17023SJohn Marino 	      for (i = 0; i < gimple_call_num_args (stmt); ++i)
1980*e4b17023SJohn Marino 		{
1981*e4b17023SJohn Marino 		  tree arg = gimple_call_arg (stmt, i);
1982*e4b17023SJohn Marino 		  if ((decl = non_rewritable_mem_ref_base (arg)))
1983*e4b17023SJohn Marino 		    bitmap_set_bit (not_reg_needs, DECL_UID (decl));
1984*e4b17023SJohn Marino 		}
1985*e4b17023SJohn Marino 	    }
1986*e4b17023SJohn Marino 
1987*e4b17023SJohn Marino 	  else if (code == GIMPLE_ASM)
1988*e4b17023SJohn Marino 	    {
1989*e4b17023SJohn Marino 	      for (i = 0; i < gimple_asm_noutputs (stmt); ++i)
1990*e4b17023SJohn Marino 		{
1991*e4b17023SJohn Marino 		  tree link = gimple_asm_output_op (stmt, i);
1992*e4b17023SJohn Marino 		  tree lhs = TREE_VALUE (link);
1993*e4b17023SJohn Marino 		  if (TREE_CODE (lhs) != SSA_NAME)
1994*e4b17023SJohn Marino 		    {
1995*e4b17023SJohn Marino 		      decl = get_base_address (lhs);
1996*e4b17023SJohn Marino 		      if (DECL_P (decl)
1997*e4b17023SJohn Marino 			  && (non_rewritable_lvalue_p (lhs)
1998*e4b17023SJohn Marino 			      /* We cannot move required conversions from
1999*e4b17023SJohn Marino 				 the lhs to the rhs in asm statements, so
2000*e4b17023SJohn Marino 				 require we do not need any.  */
2001*e4b17023SJohn Marino 			      || !useless_type_conversion_p
2002*e4b17023SJohn Marino 			            (TREE_TYPE (lhs), TREE_TYPE (decl))))
2003*e4b17023SJohn Marino 			bitmap_set_bit (not_reg_needs, DECL_UID (decl));
2004*e4b17023SJohn Marino 		    }
2005*e4b17023SJohn Marino 		}
2006*e4b17023SJohn Marino 	      for (i = 0; i < gimple_asm_ninputs (stmt); ++i)
2007*e4b17023SJohn Marino 		{
2008*e4b17023SJohn Marino 		  tree link = gimple_asm_input_op (stmt, i);
2009*e4b17023SJohn Marino 		  if ((decl = non_rewritable_mem_ref_base (TREE_VALUE (link))))
2010*e4b17023SJohn Marino 		    bitmap_set_bit (not_reg_needs, DECL_UID (decl));
2011*e4b17023SJohn Marino 		}
2012*e4b17023SJohn Marino 	    }
2013*e4b17023SJohn Marino 	}
2014*e4b17023SJohn Marino 
2015*e4b17023SJohn Marino       for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2016*e4b17023SJohn Marino 	{
2017*e4b17023SJohn Marino 	  size_t i;
2018*e4b17023SJohn Marino 	  gimple phi = gsi_stmt (gsi);
2019*e4b17023SJohn Marino 
2020*e4b17023SJohn Marino 	  for (i = 0; i < gimple_phi_num_args (phi); i++)
2021*e4b17023SJohn Marino 	    {
2022*e4b17023SJohn Marino 	      tree op = PHI_ARG_DEF (phi, i), var;
2023*e4b17023SJohn Marino 	      if (TREE_CODE (op) == ADDR_EXPR
2024*e4b17023SJohn Marino 		  && (var = get_base_address (TREE_OPERAND (op, 0))) != NULL
2025*e4b17023SJohn Marino 		  && DECL_P (var))
2026*e4b17023SJohn Marino 		bitmap_set_bit (addresses_taken, DECL_UID (var));
2027*e4b17023SJohn Marino 	    }
2028*e4b17023SJohn Marino 	}
2029*e4b17023SJohn Marino     }
2030*e4b17023SJohn Marino 
2031*e4b17023SJohn Marino   /* We cannot iterate over all referenced vars because that can contain
2032*e4b17023SJohn Marino      unused vars from BLOCK trees, which causes code generation differences
2033*e4b17023SJohn Marino      for -g vs. -g0.  */
2034*e4b17023SJohn Marino   for (var = DECL_ARGUMENTS (cfun->decl); var; var = DECL_CHAIN (var))
2035*e4b17023SJohn Marino     update_vops |= maybe_optimize_var (var, addresses_taken, not_reg_needs);
2036*e4b17023SJohn Marino 
2037*e4b17023SJohn Marino   FOR_EACH_VEC_ELT (tree, cfun->local_decls, i, var)
2038*e4b17023SJohn Marino     update_vops |= maybe_optimize_var (var, addresses_taken, not_reg_needs);
2039*e4b17023SJohn Marino 
2040*e4b17023SJohn Marino   /* Operand caches need to be recomputed for operands referencing the updated
2041*e4b17023SJohn Marino      variables.  */
2042*e4b17023SJohn Marino   if (update_vops)
2043*e4b17023SJohn Marino     {
2044*e4b17023SJohn Marino       FOR_EACH_BB (bb)
2045*e4b17023SJohn Marino 	for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
2046*e4b17023SJohn Marino 	  {
2047*e4b17023SJohn Marino 	    gimple stmt = gsi_stmt (gsi);
2048*e4b17023SJohn Marino 
2049*e4b17023SJohn Marino 	    /* Re-write TARGET_MEM_REFs of symbols we want to
2050*e4b17023SJohn Marino 	       rewrite into SSA form.  */
2051*e4b17023SJohn Marino 	    if (gimple_assign_single_p (stmt))
2052*e4b17023SJohn Marino 	      {
2053*e4b17023SJohn Marino 		tree lhs = gimple_assign_lhs (stmt);
2054*e4b17023SJohn Marino 		tree rhs, *rhsp = gimple_assign_rhs1_ptr (stmt);
2055*e4b17023SJohn Marino 		tree sym;
2056*e4b17023SJohn Marino 
2057*e4b17023SJohn Marino 		/* We shouldn't have any fancy wrapping of
2058*e4b17023SJohn Marino 		   component-refs on the LHS, but look through
2059*e4b17023SJohn Marino 		   VIEW_CONVERT_EXPRs as that is easy.  */
2060*e4b17023SJohn Marino 		while (TREE_CODE (lhs) == VIEW_CONVERT_EXPR)
2061*e4b17023SJohn Marino 		  lhs = TREE_OPERAND (lhs, 0);
2062*e4b17023SJohn Marino 		if (TREE_CODE (lhs) == MEM_REF
2063*e4b17023SJohn Marino 		    && TREE_CODE (TREE_OPERAND (lhs, 0)) == ADDR_EXPR
2064*e4b17023SJohn Marino 		    && integer_zerop (TREE_OPERAND (lhs, 1))
2065*e4b17023SJohn Marino 		    && (sym = TREE_OPERAND (TREE_OPERAND (lhs, 0), 0))
2066*e4b17023SJohn Marino 		    && DECL_P (sym)
2067*e4b17023SJohn Marino 		    && !TREE_ADDRESSABLE (sym)
2068*e4b17023SJohn Marino 		    && symbol_marked_for_renaming (sym))
2069*e4b17023SJohn Marino 		  lhs = sym;
2070*e4b17023SJohn Marino 		else
2071*e4b17023SJohn Marino 		  lhs = gimple_assign_lhs (stmt);
2072*e4b17023SJohn Marino 
2073*e4b17023SJohn Marino 		/* Rewrite the RHS and make sure the resulting assignment
2074*e4b17023SJohn Marino 		   is validly typed.  */
2075*e4b17023SJohn Marino 		maybe_rewrite_mem_ref_base (rhsp);
2076*e4b17023SJohn Marino 		rhs = gimple_assign_rhs1 (stmt);
2077*e4b17023SJohn Marino 		if (gimple_assign_lhs (stmt) != lhs
2078*e4b17023SJohn Marino 		    && !useless_type_conversion_p (TREE_TYPE (lhs),
2079*e4b17023SJohn Marino 						   TREE_TYPE (rhs)))
2080*e4b17023SJohn Marino 		  rhs = fold_build1 (VIEW_CONVERT_EXPR,
2081*e4b17023SJohn Marino 				     TREE_TYPE (lhs), rhs);
2082*e4b17023SJohn Marino 
2083*e4b17023SJohn Marino 		if (gimple_assign_lhs (stmt) != lhs)
2084*e4b17023SJohn Marino 		  gimple_assign_set_lhs (stmt, lhs);
2085*e4b17023SJohn Marino 
2086*e4b17023SJohn Marino 		/* For var ={v} {CLOBBER}; where var lost
2087*e4b17023SJohn Marino 		   TREE_ADDRESSABLE just remove the stmt.  */
2088*e4b17023SJohn Marino 		if (DECL_P (lhs)
2089*e4b17023SJohn Marino 		    && TREE_CLOBBER_P (rhs)
2090*e4b17023SJohn Marino 		    && symbol_marked_for_renaming (lhs))
2091*e4b17023SJohn Marino 		  {
2092*e4b17023SJohn Marino 		    unlink_stmt_vdef (stmt);
2093*e4b17023SJohn Marino       		    gsi_remove (&gsi, true);
2094*e4b17023SJohn Marino 		    release_defs (stmt);
2095*e4b17023SJohn Marino 		    continue;
2096*e4b17023SJohn Marino 		  }
2097*e4b17023SJohn Marino 
2098*e4b17023SJohn Marino 		if (gimple_assign_rhs1 (stmt) != rhs)
2099*e4b17023SJohn Marino 		  {
2100*e4b17023SJohn Marino 		    gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
2101*e4b17023SJohn Marino 		    gimple_assign_set_rhs_from_tree (&gsi, rhs);
2102*e4b17023SJohn Marino 		  }
2103*e4b17023SJohn Marino 	      }
2104*e4b17023SJohn Marino 
2105*e4b17023SJohn Marino 	    else if (gimple_code (stmt) == GIMPLE_CALL)
2106*e4b17023SJohn Marino 	      {
2107*e4b17023SJohn Marino 		unsigned i;
2108*e4b17023SJohn Marino 		for (i = 0; i < gimple_call_num_args (stmt); ++i)
2109*e4b17023SJohn Marino 		  {
2110*e4b17023SJohn Marino 		    tree *argp = gimple_call_arg_ptr (stmt, i);
2111*e4b17023SJohn Marino 		    maybe_rewrite_mem_ref_base (argp);
2112*e4b17023SJohn Marino 		  }
2113*e4b17023SJohn Marino 	      }
2114*e4b17023SJohn Marino 
2115*e4b17023SJohn Marino 	    else if (gimple_code (stmt) == GIMPLE_ASM)
2116*e4b17023SJohn Marino 	      {
2117*e4b17023SJohn Marino 		unsigned i;
2118*e4b17023SJohn Marino 		for (i = 0; i < gimple_asm_noutputs (stmt); ++i)
2119*e4b17023SJohn Marino 		  {
2120*e4b17023SJohn Marino 		    tree link = gimple_asm_output_op (stmt, i);
2121*e4b17023SJohn Marino 		    maybe_rewrite_mem_ref_base (&TREE_VALUE (link));
2122*e4b17023SJohn Marino 		  }
2123*e4b17023SJohn Marino 		for (i = 0; i < gimple_asm_ninputs (stmt); ++i)
2124*e4b17023SJohn Marino 		  {
2125*e4b17023SJohn Marino 		    tree link = gimple_asm_input_op (stmt, i);
2126*e4b17023SJohn Marino 		    maybe_rewrite_mem_ref_base (&TREE_VALUE (link));
2127*e4b17023SJohn Marino 		  }
2128*e4b17023SJohn Marino 	      }
2129*e4b17023SJohn Marino 
2130*e4b17023SJohn Marino 	    else if (gimple_debug_bind_p (stmt)
2131*e4b17023SJohn Marino 		     && gimple_debug_bind_has_value_p (stmt))
2132*e4b17023SJohn Marino 	      {
2133*e4b17023SJohn Marino 		tree *valuep = gimple_debug_bind_get_value_ptr (stmt);
2134*e4b17023SJohn Marino 		tree decl;
2135*e4b17023SJohn Marino 		maybe_rewrite_mem_ref_base (valuep);
2136*e4b17023SJohn Marino 		decl = non_rewritable_mem_ref_base (*valuep);
2137*e4b17023SJohn Marino 		if (decl && symbol_marked_for_renaming (decl))
2138*e4b17023SJohn Marino 		  gimple_debug_bind_reset_value (stmt);
2139*e4b17023SJohn Marino 	      }
2140*e4b17023SJohn Marino 
2141*e4b17023SJohn Marino 	    if (gimple_references_memory_p (stmt)
2142*e4b17023SJohn Marino 		|| is_gimple_debug (stmt))
2143*e4b17023SJohn Marino 	      update_stmt (stmt);
2144*e4b17023SJohn Marino 
2145*e4b17023SJohn Marino 	    gsi_next (&gsi);
2146*e4b17023SJohn Marino 	  }
2147*e4b17023SJohn Marino 
2148*e4b17023SJohn Marino       /* Update SSA form here, we are called as non-pass as well.  */
2149*e4b17023SJohn Marino       if (number_of_loops () > 1 && loops_state_satisfies_p (LOOP_CLOSED_SSA))
2150*e4b17023SJohn Marino 	rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa);
2151*e4b17023SJohn Marino       else
2152*e4b17023SJohn Marino 	update_ssa (TODO_update_ssa);
2153*e4b17023SJohn Marino     }
2154*e4b17023SJohn Marino 
2155*e4b17023SJohn Marino   BITMAP_FREE (not_reg_needs);
2156*e4b17023SJohn Marino   BITMAP_FREE (addresses_taken);
2157*e4b17023SJohn Marino   timevar_pop (TV_ADDRESS_TAKEN);
2158*e4b17023SJohn Marino }
2159*e4b17023SJohn Marino 
2160*e4b17023SJohn Marino struct gimple_opt_pass pass_update_address_taken =
2161*e4b17023SJohn Marino {
2162*e4b17023SJohn Marino  {
2163*e4b17023SJohn Marino   GIMPLE_PASS,
2164*e4b17023SJohn Marino   "addressables",			/* name */
2165*e4b17023SJohn Marino   NULL,					/* gate */
2166*e4b17023SJohn Marino   NULL,					/* execute */
2167*e4b17023SJohn Marino   NULL,					/* sub */
2168*e4b17023SJohn Marino   NULL,					/* next */
2169*e4b17023SJohn Marino   0,					/* static_pass_number */
2170*e4b17023SJohn Marino   TV_ADDRESS_TAKEN,			/* tv_id */
2171*e4b17023SJohn Marino   PROP_ssa,				/* properties_required */
2172*e4b17023SJohn Marino   0,					/* properties_provided */
2173*e4b17023SJohn Marino   0,					/* properties_destroyed */
2174*e4b17023SJohn Marino   0,					/* todo_flags_start */
2175*e4b17023SJohn Marino   TODO_update_address_taken             /* todo_flags_finish */
2176*e4b17023SJohn Marino  }
2177*e4b17023SJohn Marino };
2178