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