xref: /dflybsd-src/contrib/gcc-4.7/gcc/tree-flow-inline.h (revision 04febcfb30580676d3e95f58a16c5137ee478b32)
1*e4b17023SJohn Marino /* Inline functions for tree-flow.h
2*e4b17023SJohn Marino    Copyright (C) 2001, 2003, 2005, 2006, 2007, 2008, 2010
3*e4b17023SJohn Marino    Free Software Foundation, Inc.
4*e4b17023SJohn Marino    Contributed by Diego Novillo <dnovillo@redhat.com>
5*e4b17023SJohn Marino 
6*e4b17023SJohn Marino This file is part of GCC.
7*e4b17023SJohn Marino 
8*e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify
9*e4b17023SJohn Marino it under the terms of the GNU General Public License as published by
10*e4b17023SJohn Marino the Free Software Foundation; either version 3, or (at your option)
11*e4b17023SJohn Marino any later version.
12*e4b17023SJohn Marino 
13*e4b17023SJohn Marino GCC is distributed in the hope that it will be useful,
14*e4b17023SJohn Marino but WITHOUT ANY WARRANTY; without even the implied warranty of
15*e4b17023SJohn Marino MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16*e4b17023SJohn Marino GNU General Public License for more details.
17*e4b17023SJohn Marino 
18*e4b17023SJohn Marino You should have received a copy of the GNU General Public License
19*e4b17023SJohn Marino along with GCC; see the file COPYING3.  If not see
20*e4b17023SJohn Marino <http://www.gnu.org/licenses/>.  */
21*e4b17023SJohn Marino 
22*e4b17023SJohn Marino #ifndef _TREE_FLOW_INLINE_H
23*e4b17023SJohn Marino #define _TREE_FLOW_INLINE_H 1
24*e4b17023SJohn Marino 
25*e4b17023SJohn Marino /* Inline functions for manipulating various data structures defined in
26*e4b17023SJohn Marino    tree-flow.h.  See tree-flow.h for documentation.  */
27*e4b17023SJohn Marino 
28*e4b17023SJohn Marino /* Return true when gimple SSA form was built.
29*e4b17023SJohn Marino    gimple_in_ssa_p is queried by gimplifier in various early stages before SSA
30*e4b17023SJohn Marino    infrastructure is initialized.  Check for presence of the datastructures
31*e4b17023SJohn Marino    at first place.  */
32*e4b17023SJohn Marino static inline bool
gimple_in_ssa_p(const struct function * fun)33*e4b17023SJohn Marino gimple_in_ssa_p (const struct function *fun)
34*e4b17023SJohn Marino {
35*e4b17023SJohn Marino   return fun && fun->gimple_df && fun->gimple_df->in_ssa_p;
36*e4b17023SJohn Marino }
37*e4b17023SJohn Marino 
38*e4b17023SJohn Marino /* Array of all variables referenced in the function.  */
39*e4b17023SJohn Marino static inline htab_t
gimple_referenced_vars(const struct function * fun)40*e4b17023SJohn Marino gimple_referenced_vars (const struct function *fun)
41*e4b17023SJohn Marino {
42*e4b17023SJohn Marino   if (!fun->gimple_df)
43*e4b17023SJohn Marino     return NULL;
44*e4b17023SJohn Marino   return fun->gimple_df->referenced_vars;
45*e4b17023SJohn Marino }
46*e4b17023SJohn Marino 
47*e4b17023SJohn Marino /* Artificial variable used for the virtual operand FUD chain.  */
48*e4b17023SJohn Marino static inline tree
gimple_vop(const struct function * fun)49*e4b17023SJohn Marino gimple_vop (const struct function *fun)
50*e4b17023SJohn Marino {
51*e4b17023SJohn Marino   gcc_checking_assert (fun && fun->gimple_df);
52*e4b17023SJohn Marino   return fun->gimple_df->vop;
53*e4b17023SJohn Marino }
54*e4b17023SJohn Marino 
55*e4b17023SJohn Marino /* Initialize the hashtable iterator HTI to point to hashtable TABLE */
56*e4b17023SJohn Marino 
57*e4b17023SJohn Marino static inline void *
first_htab_element(htab_iterator * hti,htab_t table)58*e4b17023SJohn Marino first_htab_element (htab_iterator *hti, htab_t table)
59*e4b17023SJohn Marino {
60*e4b17023SJohn Marino   hti->htab = table;
61*e4b17023SJohn Marino   hti->slot = table->entries;
62*e4b17023SJohn Marino   hti->limit = hti->slot + htab_size (table);
63*e4b17023SJohn Marino   do
64*e4b17023SJohn Marino     {
65*e4b17023SJohn Marino       PTR x = *(hti->slot);
66*e4b17023SJohn Marino       if (x != HTAB_EMPTY_ENTRY && x != HTAB_DELETED_ENTRY)
67*e4b17023SJohn Marino 	break;
68*e4b17023SJohn Marino     } while (++(hti->slot) < hti->limit);
69*e4b17023SJohn Marino 
70*e4b17023SJohn Marino   if (hti->slot < hti->limit)
71*e4b17023SJohn Marino     return *(hti->slot);
72*e4b17023SJohn Marino   return NULL;
73*e4b17023SJohn Marino }
74*e4b17023SJohn Marino 
75*e4b17023SJohn Marino /* Return current non-empty/deleted slot of the hashtable pointed to by HTI,
76*e4b17023SJohn Marino    or NULL if we have  reached the end.  */
77*e4b17023SJohn Marino 
78*e4b17023SJohn Marino static inline bool
end_htab_p(const htab_iterator * hti)79*e4b17023SJohn Marino end_htab_p (const htab_iterator *hti)
80*e4b17023SJohn Marino {
81*e4b17023SJohn Marino   if (hti->slot >= hti->limit)
82*e4b17023SJohn Marino     return true;
83*e4b17023SJohn Marino   return false;
84*e4b17023SJohn Marino }
85*e4b17023SJohn Marino 
86*e4b17023SJohn Marino /* Advance the hashtable iterator pointed to by HTI to the next element of the
87*e4b17023SJohn Marino    hashtable.  */
88*e4b17023SJohn Marino 
89*e4b17023SJohn Marino static inline void *
next_htab_element(htab_iterator * hti)90*e4b17023SJohn Marino next_htab_element (htab_iterator *hti)
91*e4b17023SJohn Marino {
92*e4b17023SJohn Marino   while (++(hti->slot) < hti->limit)
93*e4b17023SJohn Marino     {
94*e4b17023SJohn Marino       PTR x = *(hti->slot);
95*e4b17023SJohn Marino       if (x != HTAB_EMPTY_ENTRY && x != HTAB_DELETED_ENTRY)
96*e4b17023SJohn Marino 	return x;
97*e4b17023SJohn Marino     };
98*e4b17023SJohn Marino   return NULL;
99*e4b17023SJohn Marino }
100*e4b17023SJohn Marino 
101*e4b17023SJohn Marino /* Get the variable with uid UID from the list of referenced vars.  */
102*e4b17023SJohn Marino 
103*e4b17023SJohn Marino static inline tree
referenced_var(unsigned int uid)104*e4b17023SJohn Marino referenced_var (unsigned int uid)
105*e4b17023SJohn Marino {
106*e4b17023SJohn Marino   tree var = referenced_var_lookup (cfun, uid);
107*e4b17023SJohn Marino   gcc_assert (var || uid == 0);
108*e4b17023SJohn Marino   return var;
109*e4b17023SJohn Marino }
110*e4b17023SJohn Marino 
111*e4b17023SJohn Marino /* Initialize ITER to point to the first referenced variable in the
112*e4b17023SJohn Marino    referenced_vars hashtable, and return that variable.  */
113*e4b17023SJohn Marino 
114*e4b17023SJohn Marino static inline tree
first_referenced_var(struct function * fn,referenced_var_iterator * iter)115*e4b17023SJohn Marino first_referenced_var (struct function *fn, referenced_var_iterator *iter)
116*e4b17023SJohn Marino {
117*e4b17023SJohn Marino   return (tree) first_htab_element (&iter->hti,
118*e4b17023SJohn Marino 				    gimple_referenced_vars (fn));
119*e4b17023SJohn Marino }
120*e4b17023SJohn Marino 
121*e4b17023SJohn Marino /* Return true if we have hit the end of the referenced variables ITER is
122*e4b17023SJohn Marino    iterating through.  */
123*e4b17023SJohn Marino 
124*e4b17023SJohn Marino static inline bool
end_referenced_vars_p(const referenced_var_iterator * iter)125*e4b17023SJohn Marino end_referenced_vars_p (const referenced_var_iterator *iter)
126*e4b17023SJohn Marino {
127*e4b17023SJohn Marino   return end_htab_p (&iter->hti);
128*e4b17023SJohn Marino }
129*e4b17023SJohn Marino 
130*e4b17023SJohn Marino /* Make ITER point to the next referenced_var in the referenced_var hashtable,
131*e4b17023SJohn Marino    and return that variable.  */
132*e4b17023SJohn Marino 
133*e4b17023SJohn Marino static inline tree
next_referenced_var(referenced_var_iterator * iter)134*e4b17023SJohn Marino next_referenced_var (referenced_var_iterator *iter)
135*e4b17023SJohn Marino {
136*e4b17023SJohn Marino   return (tree) next_htab_element (&iter->hti);
137*e4b17023SJohn Marino }
138*e4b17023SJohn Marino 
139*e4b17023SJohn Marino /* Return the variable annotation for T, which must be a _DECL node.
140*e4b17023SJohn Marino    Return NULL if the variable annotation doesn't already exist.  */
141*e4b17023SJohn Marino static inline var_ann_t
var_ann(const_tree t)142*e4b17023SJohn Marino var_ann (const_tree t)
143*e4b17023SJohn Marino {
144*e4b17023SJohn Marino   const var_ann_t *p = DECL_VAR_ANN_PTR (t);
145*e4b17023SJohn Marino   return p ? *p : NULL;
146*e4b17023SJohn Marino }
147*e4b17023SJohn Marino 
148*e4b17023SJohn Marino /* Get the number of the next statement uid to be allocated.  */
149*e4b17023SJohn Marino static inline unsigned int
gimple_stmt_max_uid(struct function * fn)150*e4b17023SJohn Marino gimple_stmt_max_uid (struct function *fn)
151*e4b17023SJohn Marino {
152*e4b17023SJohn Marino   return fn->last_stmt_uid;
153*e4b17023SJohn Marino }
154*e4b17023SJohn Marino 
155*e4b17023SJohn Marino /* Set the number of the next statement uid to be allocated.  */
156*e4b17023SJohn Marino static inline void
set_gimple_stmt_max_uid(struct function * fn,unsigned int maxid)157*e4b17023SJohn Marino set_gimple_stmt_max_uid (struct function *fn, unsigned int maxid)
158*e4b17023SJohn Marino {
159*e4b17023SJohn Marino   fn->last_stmt_uid = maxid;
160*e4b17023SJohn Marino }
161*e4b17023SJohn Marino 
162*e4b17023SJohn Marino /* Set the number of the next statement uid to be allocated.  */
163*e4b17023SJohn Marino static inline unsigned int
inc_gimple_stmt_max_uid(struct function * fn)164*e4b17023SJohn Marino inc_gimple_stmt_max_uid (struct function *fn)
165*e4b17023SJohn Marino {
166*e4b17023SJohn Marino   return fn->last_stmt_uid++;
167*e4b17023SJohn Marino }
168*e4b17023SJohn Marino 
169*e4b17023SJohn Marino /* Return the line number for EXPR, or return -1 if we have no line
170*e4b17023SJohn Marino    number information for it.  */
171*e4b17023SJohn Marino static inline int
get_lineno(const_gimple stmt)172*e4b17023SJohn Marino get_lineno (const_gimple stmt)
173*e4b17023SJohn Marino {
174*e4b17023SJohn Marino   location_t loc;
175*e4b17023SJohn Marino 
176*e4b17023SJohn Marino   if (!stmt)
177*e4b17023SJohn Marino     return -1;
178*e4b17023SJohn Marino 
179*e4b17023SJohn Marino   loc = gimple_location (stmt);
180*e4b17023SJohn Marino   if (loc == UNKNOWN_LOCATION)
181*e4b17023SJohn Marino     return -1;
182*e4b17023SJohn Marino 
183*e4b17023SJohn Marino   return LOCATION_LINE (loc);
184*e4b17023SJohn Marino }
185*e4b17023SJohn Marino 
186*e4b17023SJohn Marino /* Delink an immediate_uses node from its chain.  */
187*e4b17023SJohn Marino static inline void
delink_imm_use(ssa_use_operand_t * linknode)188*e4b17023SJohn Marino delink_imm_use (ssa_use_operand_t *linknode)
189*e4b17023SJohn Marino {
190*e4b17023SJohn Marino   /* Return if this node is not in a list.  */
191*e4b17023SJohn Marino   if (linknode->prev == NULL)
192*e4b17023SJohn Marino     return;
193*e4b17023SJohn Marino 
194*e4b17023SJohn Marino   linknode->prev->next = linknode->next;
195*e4b17023SJohn Marino   linknode->next->prev = linknode->prev;
196*e4b17023SJohn Marino   linknode->prev = NULL;
197*e4b17023SJohn Marino   linknode->next = NULL;
198*e4b17023SJohn Marino }
199*e4b17023SJohn Marino 
200*e4b17023SJohn Marino /* Link ssa_imm_use node LINKNODE into the chain for LIST.  */
201*e4b17023SJohn Marino static inline void
link_imm_use_to_list(ssa_use_operand_t * linknode,ssa_use_operand_t * list)202*e4b17023SJohn Marino link_imm_use_to_list (ssa_use_operand_t *linknode, ssa_use_operand_t *list)
203*e4b17023SJohn Marino {
204*e4b17023SJohn Marino   /* Link the new node at the head of the list.  If we are in the process of
205*e4b17023SJohn Marino      traversing the list, we won't visit any new nodes added to it.  */
206*e4b17023SJohn Marino   linknode->prev = list;
207*e4b17023SJohn Marino   linknode->next = list->next;
208*e4b17023SJohn Marino   list->next->prev = linknode;
209*e4b17023SJohn Marino   list->next = linknode;
210*e4b17023SJohn Marino }
211*e4b17023SJohn Marino 
212*e4b17023SJohn Marino /* Link ssa_imm_use node LINKNODE into the chain for DEF.  */
213*e4b17023SJohn Marino static inline void
link_imm_use(ssa_use_operand_t * linknode,tree def)214*e4b17023SJohn Marino link_imm_use (ssa_use_operand_t *linknode, tree def)
215*e4b17023SJohn Marino {
216*e4b17023SJohn Marino   ssa_use_operand_t *root;
217*e4b17023SJohn Marino 
218*e4b17023SJohn Marino   if (!def || TREE_CODE (def) != SSA_NAME)
219*e4b17023SJohn Marino     linknode->prev = NULL;
220*e4b17023SJohn Marino   else
221*e4b17023SJohn Marino     {
222*e4b17023SJohn Marino       root = &(SSA_NAME_IMM_USE_NODE (def));
223*e4b17023SJohn Marino       if (linknode->use)
224*e4b17023SJohn Marino         gcc_checking_assert (*(linknode->use) == def);
225*e4b17023SJohn Marino       link_imm_use_to_list (linknode, root);
226*e4b17023SJohn Marino     }
227*e4b17023SJohn Marino }
228*e4b17023SJohn Marino 
229*e4b17023SJohn Marino /* Set the value of a use pointed to by USE to VAL.  */
230*e4b17023SJohn Marino static inline void
set_ssa_use_from_ptr(use_operand_p use,tree val)231*e4b17023SJohn Marino set_ssa_use_from_ptr (use_operand_p use, tree val)
232*e4b17023SJohn Marino {
233*e4b17023SJohn Marino   delink_imm_use (use);
234*e4b17023SJohn Marino   *(use->use) = val;
235*e4b17023SJohn Marino   link_imm_use (use, val);
236*e4b17023SJohn Marino }
237*e4b17023SJohn Marino 
238*e4b17023SJohn Marino /* Link ssa_imm_use node LINKNODE into the chain for DEF, with use occurring
239*e4b17023SJohn Marino    in STMT.  */
240*e4b17023SJohn Marino static inline void
link_imm_use_stmt(ssa_use_operand_t * linknode,tree def,gimple stmt)241*e4b17023SJohn Marino link_imm_use_stmt (ssa_use_operand_t *linknode, tree def, gimple stmt)
242*e4b17023SJohn Marino {
243*e4b17023SJohn Marino   if (stmt)
244*e4b17023SJohn Marino     link_imm_use (linknode, def);
245*e4b17023SJohn Marino   else
246*e4b17023SJohn Marino     link_imm_use (linknode, NULL);
247*e4b17023SJohn Marino   linknode->loc.stmt = stmt;
248*e4b17023SJohn Marino }
249*e4b17023SJohn Marino 
250*e4b17023SJohn Marino /* Relink a new node in place of an old node in the list.  */
251*e4b17023SJohn Marino static inline void
relink_imm_use(ssa_use_operand_t * node,ssa_use_operand_t * old)252*e4b17023SJohn Marino relink_imm_use (ssa_use_operand_t *node, ssa_use_operand_t *old)
253*e4b17023SJohn Marino {
254*e4b17023SJohn Marino   /* The node one had better be in the same list.  */
255*e4b17023SJohn Marino   gcc_checking_assert (*(old->use) == *(node->use));
256*e4b17023SJohn Marino   node->prev = old->prev;
257*e4b17023SJohn Marino   node->next = old->next;
258*e4b17023SJohn Marino   if (old->prev)
259*e4b17023SJohn Marino     {
260*e4b17023SJohn Marino       old->prev->next = node;
261*e4b17023SJohn Marino       old->next->prev = node;
262*e4b17023SJohn Marino       /* Remove the old node from the list.  */
263*e4b17023SJohn Marino       old->prev = NULL;
264*e4b17023SJohn Marino     }
265*e4b17023SJohn Marino }
266*e4b17023SJohn Marino 
267*e4b17023SJohn Marino /* Relink ssa_imm_use node LINKNODE into the chain for OLD, with use occurring
268*e4b17023SJohn Marino    in STMT.  */
269*e4b17023SJohn Marino static inline void
relink_imm_use_stmt(ssa_use_operand_t * linknode,ssa_use_operand_t * old,gimple stmt)270*e4b17023SJohn Marino relink_imm_use_stmt (ssa_use_operand_t *linknode, ssa_use_operand_t *old,
271*e4b17023SJohn Marino 		     gimple stmt)
272*e4b17023SJohn Marino {
273*e4b17023SJohn Marino   if (stmt)
274*e4b17023SJohn Marino     relink_imm_use (linknode, old);
275*e4b17023SJohn Marino   else
276*e4b17023SJohn Marino     link_imm_use (linknode, NULL);
277*e4b17023SJohn Marino   linknode->loc.stmt = stmt;
278*e4b17023SJohn Marino }
279*e4b17023SJohn Marino 
280*e4b17023SJohn Marino 
281*e4b17023SJohn Marino /* Return true is IMM has reached the end of the immediate use list.  */
282*e4b17023SJohn Marino static inline bool
end_readonly_imm_use_p(const imm_use_iterator * imm)283*e4b17023SJohn Marino end_readonly_imm_use_p (const imm_use_iterator *imm)
284*e4b17023SJohn Marino {
285*e4b17023SJohn Marino   return (imm->imm_use == imm->end_p);
286*e4b17023SJohn Marino }
287*e4b17023SJohn Marino 
288*e4b17023SJohn Marino /* Initialize iterator IMM to process the list for VAR.  */
289*e4b17023SJohn Marino static inline use_operand_p
first_readonly_imm_use(imm_use_iterator * imm,tree var)290*e4b17023SJohn Marino first_readonly_imm_use (imm_use_iterator *imm, tree var)
291*e4b17023SJohn Marino {
292*e4b17023SJohn Marino   imm->end_p = &(SSA_NAME_IMM_USE_NODE (var));
293*e4b17023SJohn Marino   imm->imm_use = imm->end_p->next;
294*e4b17023SJohn Marino #ifdef ENABLE_CHECKING
295*e4b17023SJohn Marino   imm->iter_node.next = imm->imm_use->next;
296*e4b17023SJohn Marino #endif
297*e4b17023SJohn Marino   if (end_readonly_imm_use_p (imm))
298*e4b17023SJohn Marino     return NULL_USE_OPERAND_P;
299*e4b17023SJohn Marino   return imm->imm_use;
300*e4b17023SJohn Marino }
301*e4b17023SJohn Marino 
302*e4b17023SJohn Marino /* Bump IMM to the next use in the list.  */
303*e4b17023SJohn Marino static inline use_operand_p
next_readonly_imm_use(imm_use_iterator * imm)304*e4b17023SJohn Marino next_readonly_imm_use (imm_use_iterator *imm)
305*e4b17023SJohn Marino {
306*e4b17023SJohn Marino   use_operand_p old = imm->imm_use;
307*e4b17023SJohn Marino 
308*e4b17023SJohn Marino #ifdef ENABLE_CHECKING
309*e4b17023SJohn Marino   /* If this assertion fails, it indicates the 'next' pointer has changed
310*e4b17023SJohn Marino      since the last bump.  This indicates that the list is being modified
311*e4b17023SJohn Marino      via stmt changes, or SET_USE, or somesuch thing, and you need to be
312*e4b17023SJohn Marino      using the SAFE version of the iterator.  */
313*e4b17023SJohn Marino   gcc_assert (imm->iter_node.next == old->next);
314*e4b17023SJohn Marino   imm->iter_node.next = old->next->next;
315*e4b17023SJohn Marino #endif
316*e4b17023SJohn Marino 
317*e4b17023SJohn Marino   imm->imm_use = old->next;
318*e4b17023SJohn Marino   if (end_readonly_imm_use_p (imm))
319*e4b17023SJohn Marino     return NULL_USE_OPERAND_P;
320*e4b17023SJohn Marino   return imm->imm_use;
321*e4b17023SJohn Marino }
322*e4b17023SJohn Marino 
323*e4b17023SJohn Marino /* tree-cfg.c */
324*e4b17023SJohn Marino extern bool has_zero_uses_1 (const ssa_use_operand_t *head);
325*e4b17023SJohn Marino extern bool single_imm_use_1 (const ssa_use_operand_t *head,
326*e4b17023SJohn Marino 			      use_operand_p *use_p, gimple *stmt);
327*e4b17023SJohn Marino 
328*e4b17023SJohn Marino /* Return true if VAR has no nondebug uses.  */
329*e4b17023SJohn Marino static inline bool
has_zero_uses(const_tree var)330*e4b17023SJohn Marino has_zero_uses (const_tree var)
331*e4b17023SJohn Marino {
332*e4b17023SJohn Marino   const ssa_use_operand_t *const ptr = &(SSA_NAME_IMM_USE_NODE (var));
333*e4b17023SJohn Marino 
334*e4b17023SJohn Marino   /* A single use_operand means there is no items in the list.  */
335*e4b17023SJohn Marino   if (ptr == ptr->next)
336*e4b17023SJohn Marino     return true;
337*e4b17023SJohn Marino 
338*e4b17023SJohn Marino   /* If there are debug stmts, we have to look at each use and see
339*e4b17023SJohn Marino      whether there are any nondebug uses.  */
340*e4b17023SJohn Marino   if (!MAY_HAVE_DEBUG_STMTS)
341*e4b17023SJohn Marino     return false;
342*e4b17023SJohn Marino 
343*e4b17023SJohn Marino   return has_zero_uses_1 (ptr);
344*e4b17023SJohn Marino }
345*e4b17023SJohn Marino 
346*e4b17023SJohn Marino /* Return true if VAR has a single nondebug use.  */
347*e4b17023SJohn Marino static inline bool
has_single_use(const_tree var)348*e4b17023SJohn Marino has_single_use (const_tree var)
349*e4b17023SJohn Marino {
350*e4b17023SJohn Marino   const ssa_use_operand_t *const ptr = &(SSA_NAME_IMM_USE_NODE (var));
351*e4b17023SJohn Marino 
352*e4b17023SJohn Marino   /* If there aren't any uses whatsoever, we're done.  */
353*e4b17023SJohn Marino   if (ptr == ptr->next)
354*e4b17023SJohn Marino     return false;
355*e4b17023SJohn Marino 
356*e4b17023SJohn Marino   /* If there's a single use, check that it's not a debug stmt.  */
357*e4b17023SJohn Marino   if (ptr == ptr->next->next)
358*e4b17023SJohn Marino     return !is_gimple_debug (USE_STMT (ptr->next));
359*e4b17023SJohn Marino 
360*e4b17023SJohn Marino   /* If there are debug stmts, we have to look at each of them.  */
361*e4b17023SJohn Marino   if (!MAY_HAVE_DEBUG_STMTS)
362*e4b17023SJohn Marino     return false;
363*e4b17023SJohn Marino 
364*e4b17023SJohn Marino   return single_imm_use_1 (ptr, NULL, NULL);
365*e4b17023SJohn Marino }
366*e4b17023SJohn Marino 
367*e4b17023SJohn Marino 
368*e4b17023SJohn Marino /* If VAR has only a single immediate nondebug use, return true, and
369*e4b17023SJohn Marino    set USE_P and STMT to the use pointer and stmt of occurrence.  */
370*e4b17023SJohn Marino static inline bool
single_imm_use(const_tree var,use_operand_p * use_p,gimple * stmt)371*e4b17023SJohn Marino single_imm_use (const_tree var, use_operand_p *use_p, gimple *stmt)
372*e4b17023SJohn Marino {
373*e4b17023SJohn Marino   const ssa_use_operand_t *const ptr = &(SSA_NAME_IMM_USE_NODE (var));
374*e4b17023SJohn Marino 
375*e4b17023SJohn Marino   /* If there aren't any uses whatsoever, we're done.  */
376*e4b17023SJohn Marino   if (ptr == ptr->next)
377*e4b17023SJohn Marino     {
378*e4b17023SJohn Marino     return_false:
379*e4b17023SJohn Marino       *use_p = NULL_USE_OPERAND_P;
380*e4b17023SJohn Marino       *stmt = NULL;
381*e4b17023SJohn Marino       return false;
382*e4b17023SJohn Marino     }
383*e4b17023SJohn Marino 
384*e4b17023SJohn Marino   /* If there's a single use, check that it's not a debug stmt.  */
385*e4b17023SJohn Marino   if (ptr == ptr->next->next)
386*e4b17023SJohn Marino     {
387*e4b17023SJohn Marino       if (!is_gimple_debug (USE_STMT (ptr->next)))
388*e4b17023SJohn Marino 	{
389*e4b17023SJohn Marino 	  *use_p = ptr->next;
390*e4b17023SJohn Marino 	  *stmt = ptr->next->loc.stmt;
391*e4b17023SJohn Marino 	  return true;
392*e4b17023SJohn Marino 	}
393*e4b17023SJohn Marino       else
394*e4b17023SJohn Marino 	goto return_false;
395*e4b17023SJohn Marino     }
396*e4b17023SJohn Marino 
397*e4b17023SJohn Marino   /* If there are debug stmts, we have to look at each of them.  */
398*e4b17023SJohn Marino   if (!MAY_HAVE_DEBUG_STMTS)
399*e4b17023SJohn Marino     goto return_false;
400*e4b17023SJohn Marino 
401*e4b17023SJohn Marino   return single_imm_use_1 (ptr, use_p, stmt);
402*e4b17023SJohn Marino }
403*e4b17023SJohn Marino 
404*e4b17023SJohn Marino /* Return the number of nondebug immediate uses of VAR.  */
405*e4b17023SJohn Marino static inline unsigned int
num_imm_uses(const_tree var)406*e4b17023SJohn Marino num_imm_uses (const_tree var)
407*e4b17023SJohn Marino {
408*e4b17023SJohn Marino   const ssa_use_operand_t *const start = &(SSA_NAME_IMM_USE_NODE (var));
409*e4b17023SJohn Marino   const ssa_use_operand_t *ptr;
410*e4b17023SJohn Marino   unsigned int num = 0;
411*e4b17023SJohn Marino 
412*e4b17023SJohn Marino   if (!MAY_HAVE_DEBUG_STMTS)
413*e4b17023SJohn Marino     for (ptr = start->next; ptr != start; ptr = ptr->next)
414*e4b17023SJohn Marino       num++;
415*e4b17023SJohn Marino   else
416*e4b17023SJohn Marino     for (ptr = start->next; ptr != start; ptr = ptr->next)
417*e4b17023SJohn Marino       if (!is_gimple_debug (USE_STMT (ptr)))
418*e4b17023SJohn Marino 	num++;
419*e4b17023SJohn Marino 
420*e4b17023SJohn Marino   return num;
421*e4b17023SJohn Marino }
422*e4b17023SJohn Marino 
423*e4b17023SJohn Marino /* Return the tree pointed-to by USE.  */
424*e4b17023SJohn Marino static inline tree
get_use_from_ptr(use_operand_p use)425*e4b17023SJohn Marino get_use_from_ptr (use_operand_p use)
426*e4b17023SJohn Marino {
427*e4b17023SJohn Marino   return *(use->use);
428*e4b17023SJohn Marino }
429*e4b17023SJohn Marino 
430*e4b17023SJohn Marino /* Return the tree pointed-to by DEF.  */
431*e4b17023SJohn Marino static inline tree
get_def_from_ptr(def_operand_p def)432*e4b17023SJohn Marino get_def_from_ptr (def_operand_p def)
433*e4b17023SJohn Marino {
434*e4b17023SJohn Marino   return *def;
435*e4b17023SJohn Marino }
436*e4b17023SJohn Marino 
437*e4b17023SJohn Marino /* Return a use_operand_p pointer for argument I of PHI node GS.  */
438*e4b17023SJohn Marino 
439*e4b17023SJohn Marino static inline use_operand_p
gimple_phi_arg_imm_use_ptr(gimple gs,int i)440*e4b17023SJohn Marino gimple_phi_arg_imm_use_ptr (gimple gs, int i)
441*e4b17023SJohn Marino {
442*e4b17023SJohn Marino   return &gimple_phi_arg (gs, i)->imm_use;
443*e4b17023SJohn Marino }
444*e4b17023SJohn Marino 
445*e4b17023SJohn Marino /* Return the tree operand for argument I of PHI node GS.  */
446*e4b17023SJohn Marino 
447*e4b17023SJohn Marino static inline tree
gimple_phi_arg_def(gimple gs,size_t index)448*e4b17023SJohn Marino gimple_phi_arg_def (gimple gs, size_t index)
449*e4b17023SJohn Marino {
450*e4b17023SJohn Marino   struct phi_arg_d *pd = gimple_phi_arg (gs, index);
451*e4b17023SJohn Marino   return get_use_from_ptr (&pd->imm_use);
452*e4b17023SJohn Marino }
453*e4b17023SJohn Marino 
454*e4b17023SJohn Marino /* Return a pointer to the tree operand for argument I of PHI node GS.  */
455*e4b17023SJohn Marino 
456*e4b17023SJohn Marino static inline tree *
gimple_phi_arg_def_ptr(gimple gs,size_t index)457*e4b17023SJohn Marino gimple_phi_arg_def_ptr (gimple gs, size_t index)
458*e4b17023SJohn Marino {
459*e4b17023SJohn Marino   return &gimple_phi_arg (gs, index)->def;
460*e4b17023SJohn Marino }
461*e4b17023SJohn Marino 
462*e4b17023SJohn Marino /* Return the edge associated with argument I of phi node GS.  */
463*e4b17023SJohn Marino 
464*e4b17023SJohn Marino static inline edge
gimple_phi_arg_edge(gimple gs,size_t i)465*e4b17023SJohn Marino gimple_phi_arg_edge (gimple gs, size_t i)
466*e4b17023SJohn Marino {
467*e4b17023SJohn Marino   return EDGE_PRED (gimple_bb (gs), i);
468*e4b17023SJohn Marino }
469*e4b17023SJohn Marino 
470*e4b17023SJohn Marino /* Return the source location of gimple argument I of phi node GS.  */
471*e4b17023SJohn Marino 
472*e4b17023SJohn Marino static inline source_location
gimple_phi_arg_location(gimple gs,size_t i)473*e4b17023SJohn Marino gimple_phi_arg_location (gimple gs, size_t i)
474*e4b17023SJohn Marino {
475*e4b17023SJohn Marino   return gimple_phi_arg (gs, i)->locus;
476*e4b17023SJohn Marino }
477*e4b17023SJohn Marino 
478*e4b17023SJohn Marino /* Return the source location of the argument on edge E of phi node GS.  */
479*e4b17023SJohn Marino 
480*e4b17023SJohn Marino static inline source_location
gimple_phi_arg_location_from_edge(gimple gs,edge e)481*e4b17023SJohn Marino gimple_phi_arg_location_from_edge (gimple gs, edge e)
482*e4b17023SJohn Marino {
483*e4b17023SJohn Marino   return gimple_phi_arg (gs, e->dest_idx)->locus;
484*e4b17023SJohn Marino }
485*e4b17023SJohn Marino 
486*e4b17023SJohn Marino /* Set the source location of gimple argument I of phi node GS to LOC.  */
487*e4b17023SJohn Marino 
488*e4b17023SJohn Marino static inline void
gimple_phi_arg_set_location(gimple gs,size_t i,source_location loc)489*e4b17023SJohn Marino gimple_phi_arg_set_location (gimple gs, size_t i, source_location loc)
490*e4b17023SJohn Marino {
491*e4b17023SJohn Marino   gimple_phi_arg (gs, i)->locus = loc;
492*e4b17023SJohn Marino }
493*e4b17023SJohn Marino 
494*e4b17023SJohn Marino /* Return TRUE if argument I of phi node GS has a location record.  */
495*e4b17023SJohn Marino 
496*e4b17023SJohn Marino static inline bool
gimple_phi_arg_has_location(gimple gs,size_t i)497*e4b17023SJohn Marino gimple_phi_arg_has_location (gimple gs, size_t i)
498*e4b17023SJohn Marino {
499*e4b17023SJohn Marino   return gimple_phi_arg_location (gs, i) != UNKNOWN_LOCATION;
500*e4b17023SJohn Marino }
501*e4b17023SJohn Marino 
502*e4b17023SJohn Marino 
503*e4b17023SJohn Marino /* Return the PHI nodes for basic block BB, or NULL if there are no
504*e4b17023SJohn Marino    PHI nodes.  */
505*e4b17023SJohn Marino static inline gimple_seq
phi_nodes(const_basic_block bb)506*e4b17023SJohn Marino phi_nodes (const_basic_block bb)
507*e4b17023SJohn Marino {
508*e4b17023SJohn Marino   gcc_checking_assert (!(bb->flags & BB_RTL));
509*e4b17023SJohn Marino   if (!bb->il.gimple)
510*e4b17023SJohn Marino     return NULL;
511*e4b17023SJohn Marino   return bb->il.gimple->phi_nodes;
512*e4b17023SJohn Marino }
513*e4b17023SJohn Marino 
514*e4b17023SJohn Marino /* Set PHI nodes of a basic block BB to SEQ.  */
515*e4b17023SJohn Marino 
516*e4b17023SJohn Marino static inline void
set_phi_nodes(basic_block bb,gimple_seq seq)517*e4b17023SJohn Marino set_phi_nodes (basic_block bb, gimple_seq seq)
518*e4b17023SJohn Marino {
519*e4b17023SJohn Marino   gimple_stmt_iterator i;
520*e4b17023SJohn Marino 
521*e4b17023SJohn Marino   gcc_checking_assert (!(bb->flags & BB_RTL));
522*e4b17023SJohn Marino   bb->il.gimple->phi_nodes = seq;
523*e4b17023SJohn Marino   if (seq)
524*e4b17023SJohn Marino     for (i = gsi_start (seq); !gsi_end_p (i); gsi_next (&i))
525*e4b17023SJohn Marino       gimple_set_bb (gsi_stmt (i), bb);
526*e4b17023SJohn Marino }
527*e4b17023SJohn Marino 
528*e4b17023SJohn Marino /* Return the phi argument which contains the specified use.  */
529*e4b17023SJohn Marino 
530*e4b17023SJohn Marino static inline int
phi_arg_index_from_use(use_operand_p use)531*e4b17023SJohn Marino phi_arg_index_from_use (use_operand_p use)
532*e4b17023SJohn Marino {
533*e4b17023SJohn Marino   struct phi_arg_d *element, *root;
534*e4b17023SJohn Marino   size_t index;
535*e4b17023SJohn Marino   gimple phi;
536*e4b17023SJohn Marino 
537*e4b17023SJohn Marino   /* Since the use is the first thing in a PHI argument element, we can
538*e4b17023SJohn Marino      calculate its index based on casting it to an argument, and performing
539*e4b17023SJohn Marino      pointer arithmetic.  */
540*e4b17023SJohn Marino 
541*e4b17023SJohn Marino   phi = USE_STMT (use);
542*e4b17023SJohn Marino 
543*e4b17023SJohn Marino   element = (struct phi_arg_d *)use;
544*e4b17023SJohn Marino   root = gimple_phi_arg (phi, 0);
545*e4b17023SJohn Marino   index = element - root;
546*e4b17023SJohn Marino 
547*e4b17023SJohn Marino   /* Make sure the calculation doesn't have any leftover bytes.  If it does,
548*e4b17023SJohn Marino      then imm_use is likely not the first element in phi_arg_d.  */
549*e4b17023SJohn Marino   gcc_checking_assert ((((char *)element - (char *)root)
550*e4b17023SJohn Marino 			% sizeof (struct phi_arg_d)) == 0
551*e4b17023SJohn Marino 		       && index < gimple_phi_capacity (phi));
552*e4b17023SJohn Marino 
553*e4b17023SJohn Marino  return index;
554*e4b17023SJohn Marino }
555*e4b17023SJohn Marino 
556*e4b17023SJohn Marino /* Mark VAR as used, so that it'll be preserved during rtl expansion.  */
557*e4b17023SJohn Marino 
558*e4b17023SJohn Marino static inline void
set_is_used(tree var)559*e4b17023SJohn Marino set_is_used (tree var)
560*e4b17023SJohn Marino {
561*e4b17023SJohn Marino   var_ann_t ann = var_ann (var);
562*e4b17023SJohn Marino   ann->used = true;
563*e4b17023SJohn Marino }
564*e4b17023SJohn Marino 
565*e4b17023SJohn Marino /* Clear VAR's used flag.  */
566*e4b17023SJohn Marino 
567*e4b17023SJohn Marino static inline void
clear_is_used(tree var)568*e4b17023SJohn Marino clear_is_used (tree var)
569*e4b17023SJohn Marino {
570*e4b17023SJohn Marino   var_ann_t ann = var_ann (var);
571*e4b17023SJohn Marino   ann->used = false;
572*e4b17023SJohn Marino }
573*e4b17023SJohn Marino 
574*e4b17023SJohn Marino /* Return true if VAR is marked as used.  */
575*e4b17023SJohn Marino 
576*e4b17023SJohn Marino static inline bool
is_used_p(tree var)577*e4b17023SJohn Marino is_used_p (tree var)
578*e4b17023SJohn Marino {
579*e4b17023SJohn Marino   var_ann_t ann = var_ann (var);
580*e4b17023SJohn Marino   return ann->used;
581*e4b17023SJohn Marino }
582*e4b17023SJohn Marino 
583*e4b17023SJohn Marino /* Return true if T (assumed to be a DECL) is a global variable.
584*e4b17023SJohn Marino    A variable is considered global if its storage is not automatic.  */
585*e4b17023SJohn Marino 
586*e4b17023SJohn Marino static inline bool
is_global_var(const_tree t)587*e4b17023SJohn Marino is_global_var (const_tree t)
588*e4b17023SJohn Marino {
589*e4b17023SJohn Marino   return (TREE_STATIC (t) || DECL_EXTERNAL (t));
590*e4b17023SJohn Marino }
591*e4b17023SJohn Marino 
592*e4b17023SJohn Marino 
593*e4b17023SJohn Marino /* Return true if VAR may be aliased.  A variable is considered as
594*e4b17023SJohn Marino    maybe aliased if it has its address taken by the local TU
595*e4b17023SJohn Marino    or possibly by another TU and might be modified through a pointer.  */
596*e4b17023SJohn Marino 
597*e4b17023SJohn Marino static inline bool
may_be_aliased(const_tree var)598*e4b17023SJohn Marino may_be_aliased (const_tree var)
599*e4b17023SJohn Marino {
600*e4b17023SJohn Marino   return (TREE_CODE (var) != CONST_DECL
601*e4b17023SJohn Marino 	  && !((TREE_STATIC (var) || TREE_PUBLIC (var) || DECL_EXTERNAL (var))
602*e4b17023SJohn Marino 	       && TREE_READONLY (var)
603*e4b17023SJohn Marino 	       && !TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (var)))
604*e4b17023SJohn Marino 	  && (TREE_PUBLIC (var)
605*e4b17023SJohn Marino 	      || DECL_EXTERNAL (var)
606*e4b17023SJohn Marino 	      || TREE_ADDRESSABLE (var)));
607*e4b17023SJohn Marino }
608*e4b17023SJohn Marino 
609*e4b17023SJohn Marino 
610*e4b17023SJohn Marino /* PHI nodes should contain only ssa_names and invariants.  A test
611*e4b17023SJohn Marino    for ssa_name is definitely simpler; don't let invalid contents
612*e4b17023SJohn Marino    slip in in the meantime.  */
613*e4b17023SJohn Marino 
614*e4b17023SJohn Marino static inline bool
phi_ssa_name_p(const_tree t)615*e4b17023SJohn Marino phi_ssa_name_p (const_tree t)
616*e4b17023SJohn Marino {
617*e4b17023SJohn Marino   if (TREE_CODE (t) == SSA_NAME)
618*e4b17023SJohn Marino     return true;
619*e4b17023SJohn Marino   gcc_checking_assert (is_gimple_min_invariant (t));
620*e4b17023SJohn Marino   return false;
621*e4b17023SJohn Marino }
622*e4b17023SJohn Marino 
623*e4b17023SJohn Marino 
624*e4b17023SJohn Marino /* Returns the loop of the statement STMT.  */
625*e4b17023SJohn Marino 
626*e4b17023SJohn Marino static inline struct loop *
loop_containing_stmt(gimple stmt)627*e4b17023SJohn Marino loop_containing_stmt (gimple stmt)
628*e4b17023SJohn Marino {
629*e4b17023SJohn Marino   basic_block bb = gimple_bb (stmt);
630*e4b17023SJohn Marino   if (!bb)
631*e4b17023SJohn Marino     return NULL;
632*e4b17023SJohn Marino 
633*e4b17023SJohn Marino   return bb->loop_father;
634*e4b17023SJohn Marino }
635*e4b17023SJohn Marino 
636*e4b17023SJohn Marino 
637*e4b17023SJohn Marino /*  -----------------------------------------------------------------------  */
638*e4b17023SJohn Marino 
639*e4b17023SJohn Marino /* The following set of routines are used to iterator over various type of
640*e4b17023SJohn Marino    SSA operands.  */
641*e4b17023SJohn Marino 
642*e4b17023SJohn Marino /* Return true if PTR is finished iterating.  */
643*e4b17023SJohn Marino static inline bool
op_iter_done(const ssa_op_iter * ptr)644*e4b17023SJohn Marino op_iter_done (const ssa_op_iter *ptr)
645*e4b17023SJohn Marino {
646*e4b17023SJohn Marino   return ptr->done;
647*e4b17023SJohn Marino }
648*e4b17023SJohn Marino 
649*e4b17023SJohn Marino /* Get the next iterator use value for PTR.  */
650*e4b17023SJohn Marino static inline use_operand_p
op_iter_next_use(ssa_op_iter * ptr)651*e4b17023SJohn Marino op_iter_next_use (ssa_op_iter *ptr)
652*e4b17023SJohn Marino {
653*e4b17023SJohn Marino   use_operand_p use_p;
654*e4b17023SJohn Marino   gcc_checking_assert (ptr->iter_type == ssa_op_iter_use);
655*e4b17023SJohn Marino   if (ptr->uses)
656*e4b17023SJohn Marino     {
657*e4b17023SJohn Marino       use_p = USE_OP_PTR (ptr->uses);
658*e4b17023SJohn Marino       ptr->uses = ptr->uses->next;
659*e4b17023SJohn Marino       return use_p;
660*e4b17023SJohn Marino     }
661*e4b17023SJohn Marino   if (ptr->phi_i < ptr->num_phi)
662*e4b17023SJohn Marino     {
663*e4b17023SJohn Marino       return PHI_ARG_DEF_PTR (ptr->phi_stmt, (ptr->phi_i)++);
664*e4b17023SJohn Marino     }
665*e4b17023SJohn Marino   ptr->done = true;
666*e4b17023SJohn Marino   return NULL_USE_OPERAND_P;
667*e4b17023SJohn Marino }
668*e4b17023SJohn Marino 
669*e4b17023SJohn Marino /* Get the next iterator def value for PTR.  */
670*e4b17023SJohn Marino static inline def_operand_p
op_iter_next_def(ssa_op_iter * ptr)671*e4b17023SJohn Marino op_iter_next_def (ssa_op_iter *ptr)
672*e4b17023SJohn Marino {
673*e4b17023SJohn Marino   def_operand_p def_p;
674*e4b17023SJohn Marino   gcc_checking_assert (ptr->iter_type == ssa_op_iter_def);
675*e4b17023SJohn Marino   if (ptr->defs)
676*e4b17023SJohn Marino     {
677*e4b17023SJohn Marino       def_p = DEF_OP_PTR (ptr->defs);
678*e4b17023SJohn Marino       ptr->defs = ptr->defs->next;
679*e4b17023SJohn Marino       return def_p;
680*e4b17023SJohn Marino     }
681*e4b17023SJohn Marino   ptr->done = true;
682*e4b17023SJohn Marino   return NULL_DEF_OPERAND_P;
683*e4b17023SJohn Marino }
684*e4b17023SJohn Marino 
685*e4b17023SJohn Marino /* Get the next iterator tree value for PTR.  */
686*e4b17023SJohn Marino static inline tree
op_iter_next_tree(ssa_op_iter * ptr)687*e4b17023SJohn Marino op_iter_next_tree (ssa_op_iter *ptr)
688*e4b17023SJohn Marino {
689*e4b17023SJohn Marino   tree val;
690*e4b17023SJohn Marino   gcc_checking_assert (ptr->iter_type == ssa_op_iter_tree);
691*e4b17023SJohn Marino   if (ptr->uses)
692*e4b17023SJohn Marino     {
693*e4b17023SJohn Marino       val = USE_OP (ptr->uses);
694*e4b17023SJohn Marino       ptr->uses = ptr->uses->next;
695*e4b17023SJohn Marino       return val;
696*e4b17023SJohn Marino     }
697*e4b17023SJohn Marino   if (ptr->defs)
698*e4b17023SJohn Marino     {
699*e4b17023SJohn Marino       val = DEF_OP (ptr->defs);
700*e4b17023SJohn Marino       ptr->defs = ptr->defs->next;
701*e4b17023SJohn Marino       return val;
702*e4b17023SJohn Marino     }
703*e4b17023SJohn Marino 
704*e4b17023SJohn Marino   ptr->done = true;
705*e4b17023SJohn Marino   return NULL_TREE;
706*e4b17023SJohn Marino 
707*e4b17023SJohn Marino }
708*e4b17023SJohn Marino 
709*e4b17023SJohn Marino 
710*e4b17023SJohn Marino /* This functions clears the iterator PTR, and marks it done.  This is normally
711*e4b17023SJohn Marino    used to prevent warnings in the compile about might be uninitialized
712*e4b17023SJohn Marino    components.  */
713*e4b17023SJohn Marino 
714*e4b17023SJohn Marino static inline void
clear_and_done_ssa_iter(ssa_op_iter * ptr)715*e4b17023SJohn Marino clear_and_done_ssa_iter (ssa_op_iter *ptr)
716*e4b17023SJohn Marino {
717*e4b17023SJohn Marino   ptr->defs = NULL;
718*e4b17023SJohn Marino   ptr->uses = NULL;
719*e4b17023SJohn Marino   ptr->iter_type = ssa_op_iter_none;
720*e4b17023SJohn Marino   ptr->phi_i = 0;
721*e4b17023SJohn Marino   ptr->num_phi = 0;
722*e4b17023SJohn Marino   ptr->phi_stmt = NULL;
723*e4b17023SJohn Marino   ptr->done = true;
724*e4b17023SJohn Marino }
725*e4b17023SJohn Marino 
726*e4b17023SJohn Marino /* Initialize the iterator PTR to the virtual defs in STMT.  */
727*e4b17023SJohn Marino static inline void
op_iter_init(ssa_op_iter * ptr,gimple stmt,int flags)728*e4b17023SJohn Marino op_iter_init (ssa_op_iter *ptr, gimple stmt, int flags)
729*e4b17023SJohn Marino {
730*e4b17023SJohn Marino   /* PHI nodes require a different iterator initialization path.  We
731*e4b17023SJohn Marino      do not support iterating over virtual defs or uses without
732*e4b17023SJohn Marino      iterating over defs or uses at the same time.  */
733*e4b17023SJohn Marino   gcc_checking_assert (gimple_code (stmt) != GIMPLE_PHI
734*e4b17023SJohn Marino 		       && (!(flags & SSA_OP_VDEF) || (flags & SSA_OP_DEF))
735*e4b17023SJohn Marino 		       && (!(flags & SSA_OP_VUSE) || (flags & SSA_OP_USE)));
736*e4b17023SJohn Marino   ptr->defs = (flags & (SSA_OP_DEF|SSA_OP_VDEF)) ? gimple_def_ops (stmt) : NULL;
737*e4b17023SJohn Marino   if (!(flags & SSA_OP_VDEF)
738*e4b17023SJohn Marino       && ptr->defs
739*e4b17023SJohn Marino       && gimple_vdef (stmt) != NULL_TREE)
740*e4b17023SJohn Marino     ptr->defs = ptr->defs->next;
741*e4b17023SJohn Marino   ptr->uses = (flags & (SSA_OP_USE|SSA_OP_VUSE)) ? gimple_use_ops (stmt) : NULL;
742*e4b17023SJohn Marino   if (!(flags & SSA_OP_VUSE)
743*e4b17023SJohn Marino       && ptr->uses
744*e4b17023SJohn Marino       && gimple_vuse (stmt) != NULL_TREE)
745*e4b17023SJohn Marino     ptr->uses = ptr->uses->next;
746*e4b17023SJohn Marino   ptr->done = false;
747*e4b17023SJohn Marino 
748*e4b17023SJohn Marino   ptr->phi_i = 0;
749*e4b17023SJohn Marino   ptr->num_phi = 0;
750*e4b17023SJohn Marino   ptr->phi_stmt = NULL;
751*e4b17023SJohn Marino }
752*e4b17023SJohn Marino 
753*e4b17023SJohn Marino /* Initialize iterator PTR to the use operands in STMT based on FLAGS. Return
754*e4b17023SJohn Marino    the first use.  */
755*e4b17023SJohn Marino static inline use_operand_p
op_iter_init_use(ssa_op_iter * ptr,gimple stmt,int flags)756*e4b17023SJohn Marino op_iter_init_use (ssa_op_iter *ptr, gimple stmt, int flags)
757*e4b17023SJohn Marino {
758*e4b17023SJohn Marino   gcc_checking_assert ((flags & SSA_OP_ALL_DEFS) == 0
759*e4b17023SJohn Marino 		       && (flags & SSA_OP_USE));
760*e4b17023SJohn Marino   op_iter_init (ptr, stmt, flags);
761*e4b17023SJohn Marino   ptr->iter_type = ssa_op_iter_use;
762*e4b17023SJohn Marino   return op_iter_next_use (ptr);
763*e4b17023SJohn Marino }
764*e4b17023SJohn Marino 
765*e4b17023SJohn Marino /* Initialize iterator PTR to the def operands in STMT based on FLAGS. Return
766*e4b17023SJohn Marino    the first def.  */
767*e4b17023SJohn Marino static inline def_operand_p
op_iter_init_def(ssa_op_iter * ptr,gimple stmt,int flags)768*e4b17023SJohn Marino op_iter_init_def (ssa_op_iter *ptr, gimple stmt, int flags)
769*e4b17023SJohn Marino {
770*e4b17023SJohn Marino   gcc_checking_assert ((flags & SSA_OP_ALL_USES) == 0
771*e4b17023SJohn Marino 		       && (flags & SSA_OP_DEF));
772*e4b17023SJohn Marino   op_iter_init (ptr, stmt, flags);
773*e4b17023SJohn Marino   ptr->iter_type = ssa_op_iter_def;
774*e4b17023SJohn Marino   return op_iter_next_def (ptr);
775*e4b17023SJohn Marino }
776*e4b17023SJohn Marino 
777*e4b17023SJohn Marino /* Initialize iterator PTR to the operands in STMT based on FLAGS. Return
778*e4b17023SJohn Marino    the first operand as a tree.  */
779*e4b17023SJohn Marino static inline tree
op_iter_init_tree(ssa_op_iter * ptr,gimple stmt,int flags)780*e4b17023SJohn Marino op_iter_init_tree (ssa_op_iter *ptr, gimple stmt, int flags)
781*e4b17023SJohn Marino {
782*e4b17023SJohn Marino   op_iter_init (ptr, stmt, flags);
783*e4b17023SJohn Marino   ptr->iter_type = ssa_op_iter_tree;
784*e4b17023SJohn Marino   return op_iter_next_tree (ptr);
785*e4b17023SJohn Marino }
786*e4b17023SJohn Marino 
787*e4b17023SJohn Marino 
788*e4b17023SJohn Marino /* If there is a single operand in STMT matching FLAGS, return it.  Otherwise
789*e4b17023SJohn Marino    return NULL.  */
790*e4b17023SJohn Marino static inline tree
single_ssa_tree_operand(gimple stmt,int flags)791*e4b17023SJohn Marino single_ssa_tree_operand (gimple stmt, int flags)
792*e4b17023SJohn Marino {
793*e4b17023SJohn Marino   tree var;
794*e4b17023SJohn Marino   ssa_op_iter iter;
795*e4b17023SJohn Marino 
796*e4b17023SJohn Marino   var = op_iter_init_tree (&iter, stmt, flags);
797*e4b17023SJohn Marino   if (op_iter_done (&iter))
798*e4b17023SJohn Marino     return NULL_TREE;
799*e4b17023SJohn Marino   op_iter_next_tree (&iter);
800*e4b17023SJohn Marino   if (op_iter_done (&iter))
801*e4b17023SJohn Marino     return var;
802*e4b17023SJohn Marino   return NULL_TREE;
803*e4b17023SJohn Marino }
804*e4b17023SJohn Marino 
805*e4b17023SJohn Marino 
806*e4b17023SJohn Marino /* If there is a single operand in STMT matching FLAGS, return it.  Otherwise
807*e4b17023SJohn Marino    return NULL.  */
808*e4b17023SJohn Marino static inline use_operand_p
single_ssa_use_operand(gimple stmt,int flags)809*e4b17023SJohn Marino single_ssa_use_operand (gimple stmt, int flags)
810*e4b17023SJohn Marino {
811*e4b17023SJohn Marino   use_operand_p var;
812*e4b17023SJohn Marino   ssa_op_iter iter;
813*e4b17023SJohn Marino 
814*e4b17023SJohn Marino   var = op_iter_init_use (&iter, stmt, flags);
815*e4b17023SJohn Marino   if (op_iter_done (&iter))
816*e4b17023SJohn Marino     return NULL_USE_OPERAND_P;
817*e4b17023SJohn Marino   op_iter_next_use (&iter);
818*e4b17023SJohn Marino   if (op_iter_done (&iter))
819*e4b17023SJohn Marino     return var;
820*e4b17023SJohn Marino   return NULL_USE_OPERAND_P;
821*e4b17023SJohn Marino }
822*e4b17023SJohn Marino 
823*e4b17023SJohn Marino 
824*e4b17023SJohn Marino 
825*e4b17023SJohn Marino /* If there is a single operand in STMT matching FLAGS, return it.  Otherwise
826*e4b17023SJohn Marino    return NULL.  */
827*e4b17023SJohn Marino static inline def_operand_p
single_ssa_def_operand(gimple stmt,int flags)828*e4b17023SJohn Marino single_ssa_def_operand (gimple stmt, int flags)
829*e4b17023SJohn Marino {
830*e4b17023SJohn Marino   def_operand_p var;
831*e4b17023SJohn Marino   ssa_op_iter iter;
832*e4b17023SJohn Marino 
833*e4b17023SJohn Marino   var = op_iter_init_def (&iter, stmt, flags);
834*e4b17023SJohn Marino   if (op_iter_done (&iter))
835*e4b17023SJohn Marino     return NULL_DEF_OPERAND_P;
836*e4b17023SJohn Marino   op_iter_next_def (&iter);
837*e4b17023SJohn Marino   if (op_iter_done (&iter))
838*e4b17023SJohn Marino     return var;
839*e4b17023SJohn Marino   return NULL_DEF_OPERAND_P;
840*e4b17023SJohn Marino }
841*e4b17023SJohn Marino 
842*e4b17023SJohn Marino 
843*e4b17023SJohn Marino /* Return true if there are zero operands in STMT matching the type
844*e4b17023SJohn Marino    given in FLAGS.  */
845*e4b17023SJohn Marino static inline bool
zero_ssa_operands(gimple stmt,int flags)846*e4b17023SJohn Marino zero_ssa_operands (gimple stmt, int flags)
847*e4b17023SJohn Marino {
848*e4b17023SJohn Marino   ssa_op_iter iter;
849*e4b17023SJohn Marino 
850*e4b17023SJohn Marino   op_iter_init_tree (&iter, stmt, flags);
851*e4b17023SJohn Marino   return op_iter_done (&iter);
852*e4b17023SJohn Marino }
853*e4b17023SJohn Marino 
854*e4b17023SJohn Marino 
855*e4b17023SJohn Marino /* Return the number of operands matching FLAGS in STMT.  */
856*e4b17023SJohn Marino static inline int
num_ssa_operands(gimple stmt,int flags)857*e4b17023SJohn Marino num_ssa_operands (gimple stmt, int flags)
858*e4b17023SJohn Marino {
859*e4b17023SJohn Marino   ssa_op_iter iter;
860*e4b17023SJohn Marino   tree t;
861*e4b17023SJohn Marino   int num = 0;
862*e4b17023SJohn Marino 
863*e4b17023SJohn Marino   gcc_checking_assert (gimple_code (stmt) != GIMPLE_PHI);
864*e4b17023SJohn Marino   FOR_EACH_SSA_TREE_OPERAND (t, stmt, iter, flags)
865*e4b17023SJohn Marino     num++;
866*e4b17023SJohn Marino   return num;
867*e4b17023SJohn Marino }
868*e4b17023SJohn Marino 
869*e4b17023SJohn Marino static inline use_operand_p
870*e4b17023SJohn Marino op_iter_init_phiuse (ssa_op_iter *ptr, gimple phi, int flags);
871*e4b17023SJohn Marino 
872*e4b17023SJohn Marino /* Delink all immediate_use information for STMT.  */
873*e4b17023SJohn Marino static inline void
delink_stmt_imm_use(gimple stmt)874*e4b17023SJohn Marino delink_stmt_imm_use (gimple stmt)
875*e4b17023SJohn Marino {
876*e4b17023SJohn Marino    ssa_op_iter iter;
877*e4b17023SJohn Marino    use_operand_p use_p;
878*e4b17023SJohn Marino 
879*e4b17023SJohn Marino    if (ssa_operands_active ())
880*e4b17023SJohn Marino      FOR_EACH_PHI_OR_STMT_USE (use_p, stmt, iter, SSA_OP_ALL_USES)
881*e4b17023SJohn Marino        delink_imm_use (use_p);
882*e4b17023SJohn Marino }
883*e4b17023SJohn Marino 
884*e4b17023SJohn Marino 
885*e4b17023SJohn Marino /* If there is a single DEF in the PHI node which matches FLAG, return it.
886*e4b17023SJohn Marino    Otherwise return NULL_DEF_OPERAND_P.  */
887*e4b17023SJohn Marino static inline tree
single_phi_def(gimple stmt,int flags)888*e4b17023SJohn Marino single_phi_def (gimple stmt, int flags)
889*e4b17023SJohn Marino {
890*e4b17023SJohn Marino   tree def = PHI_RESULT (stmt);
891*e4b17023SJohn Marino   if ((flags & SSA_OP_DEF) && is_gimple_reg (def))
892*e4b17023SJohn Marino     return def;
893*e4b17023SJohn Marino   if ((flags & SSA_OP_VIRTUAL_DEFS) && !is_gimple_reg (def))
894*e4b17023SJohn Marino     return def;
895*e4b17023SJohn Marino   return NULL_TREE;
896*e4b17023SJohn Marino }
897*e4b17023SJohn Marino 
898*e4b17023SJohn Marino /* Initialize the iterator PTR for uses matching FLAGS in PHI.  FLAGS should
899*e4b17023SJohn Marino    be either SSA_OP_USES or SSA_OP_VIRTUAL_USES.  */
900*e4b17023SJohn Marino static inline use_operand_p
op_iter_init_phiuse(ssa_op_iter * ptr,gimple phi,int flags)901*e4b17023SJohn Marino op_iter_init_phiuse (ssa_op_iter *ptr, gimple phi, int flags)
902*e4b17023SJohn Marino {
903*e4b17023SJohn Marino   tree phi_def = gimple_phi_result (phi);
904*e4b17023SJohn Marino   int comp;
905*e4b17023SJohn Marino 
906*e4b17023SJohn Marino   clear_and_done_ssa_iter (ptr);
907*e4b17023SJohn Marino   ptr->done = false;
908*e4b17023SJohn Marino 
909*e4b17023SJohn Marino   gcc_checking_assert ((flags & (SSA_OP_USE | SSA_OP_VIRTUAL_USES)) != 0);
910*e4b17023SJohn Marino 
911*e4b17023SJohn Marino   comp = (is_gimple_reg (phi_def) ? SSA_OP_USE : SSA_OP_VIRTUAL_USES);
912*e4b17023SJohn Marino 
913*e4b17023SJohn Marino   /* If the PHI node doesn't the operand type we care about, we're done.  */
914*e4b17023SJohn Marino   if ((flags & comp) == 0)
915*e4b17023SJohn Marino     {
916*e4b17023SJohn Marino       ptr->done = true;
917*e4b17023SJohn Marino       return NULL_USE_OPERAND_P;
918*e4b17023SJohn Marino     }
919*e4b17023SJohn Marino 
920*e4b17023SJohn Marino   ptr->phi_stmt = phi;
921*e4b17023SJohn Marino   ptr->num_phi = gimple_phi_num_args (phi);
922*e4b17023SJohn Marino   ptr->iter_type = ssa_op_iter_use;
923*e4b17023SJohn Marino   return op_iter_next_use (ptr);
924*e4b17023SJohn Marino }
925*e4b17023SJohn Marino 
926*e4b17023SJohn Marino 
927*e4b17023SJohn Marino /* Start an iterator for a PHI definition.  */
928*e4b17023SJohn Marino 
929*e4b17023SJohn Marino static inline def_operand_p
op_iter_init_phidef(ssa_op_iter * ptr,gimple phi,int flags)930*e4b17023SJohn Marino op_iter_init_phidef (ssa_op_iter *ptr, gimple phi, int flags)
931*e4b17023SJohn Marino {
932*e4b17023SJohn Marino   tree phi_def = PHI_RESULT (phi);
933*e4b17023SJohn Marino   int comp;
934*e4b17023SJohn Marino 
935*e4b17023SJohn Marino   clear_and_done_ssa_iter (ptr);
936*e4b17023SJohn Marino   ptr->done = false;
937*e4b17023SJohn Marino 
938*e4b17023SJohn Marino   gcc_checking_assert ((flags & (SSA_OP_DEF | SSA_OP_VIRTUAL_DEFS)) != 0);
939*e4b17023SJohn Marino 
940*e4b17023SJohn Marino   comp = (is_gimple_reg (phi_def) ? SSA_OP_DEF : SSA_OP_VIRTUAL_DEFS);
941*e4b17023SJohn Marino 
942*e4b17023SJohn Marino   /* If the PHI node doesn't have the operand type we care about,
943*e4b17023SJohn Marino      we're done.  */
944*e4b17023SJohn Marino   if ((flags & comp) == 0)
945*e4b17023SJohn Marino     {
946*e4b17023SJohn Marino       ptr->done = true;
947*e4b17023SJohn Marino       return NULL_DEF_OPERAND_P;
948*e4b17023SJohn Marino     }
949*e4b17023SJohn Marino 
950*e4b17023SJohn Marino   ptr->iter_type = ssa_op_iter_def;
951*e4b17023SJohn Marino   /* The first call to op_iter_next_def will terminate the iterator since
952*e4b17023SJohn Marino      all the fields are NULL.  Simply return the result here as the first and
953*e4b17023SJohn Marino      therefore only result.  */
954*e4b17023SJohn Marino   return PHI_RESULT_PTR (phi);
955*e4b17023SJohn Marino }
956*e4b17023SJohn Marino 
957*e4b17023SJohn Marino /* Return true is IMM has reached the end of the immediate use stmt list.  */
958*e4b17023SJohn Marino 
959*e4b17023SJohn Marino static inline bool
end_imm_use_stmt_p(const imm_use_iterator * imm)960*e4b17023SJohn Marino end_imm_use_stmt_p (const imm_use_iterator *imm)
961*e4b17023SJohn Marino {
962*e4b17023SJohn Marino   return (imm->imm_use == imm->end_p);
963*e4b17023SJohn Marino }
964*e4b17023SJohn Marino 
965*e4b17023SJohn Marino /* Finished the traverse of an immediate use stmt list IMM by removing the
966*e4b17023SJohn Marino    placeholder node from the list.  */
967*e4b17023SJohn Marino 
968*e4b17023SJohn Marino static inline void
end_imm_use_stmt_traverse(imm_use_iterator * imm)969*e4b17023SJohn Marino end_imm_use_stmt_traverse (imm_use_iterator *imm)
970*e4b17023SJohn Marino {
971*e4b17023SJohn Marino   delink_imm_use (&(imm->iter_node));
972*e4b17023SJohn Marino }
973*e4b17023SJohn Marino 
974*e4b17023SJohn Marino /* Immediate use traversal of uses within a stmt require that all the
975*e4b17023SJohn Marino    uses on a stmt be sequentially listed.  This routine is used to build up
976*e4b17023SJohn Marino    this sequential list by adding USE_P to the end of the current list
977*e4b17023SJohn Marino    currently delimited by HEAD and LAST_P.  The new LAST_P value is
978*e4b17023SJohn Marino    returned.  */
979*e4b17023SJohn Marino 
980*e4b17023SJohn Marino static inline use_operand_p
move_use_after_head(use_operand_p use_p,use_operand_p head,use_operand_p last_p)981*e4b17023SJohn Marino move_use_after_head (use_operand_p use_p, use_operand_p head,
982*e4b17023SJohn Marino 		      use_operand_p last_p)
983*e4b17023SJohn Marino {
984*e4b17023SJohn Marino   gcc_checking_assert (USE_FROM_PTR (use_p) == USE_FROM_PTR (head));
985*e4b17023SJohn Marino   /* Skip head when we find it.  */
986*e4b17023SJohn Marino   if (use_p != head)
987*e4b17023SJohn Marino     {
988*e4b17023SJohn Marino       /* If use_p is already linked in after last_p, continue.  */
989*e4b17023SJohn Marino       if (last_p->next == use_p)
990*e4b17023SJohn Marino 	last_p = use_p;
991*e4b17023SJohn Marino       else
992*e4b17023SJohn Marino 	{
993*e4b17023SJohn Marino 	  /* Delink from current location, and link in at last_p.  */
994*e4b17023SJohn Marino 	  delink_imm_use (use_p);
995*e4b17023SJohn Marino 	  link_imm_use_to_list (use_p, last_p);
996*e4b17023SJohn Marino 	  last_p = use_p;
997*e4b17023SJohn Marino 	}
998*e4b17023SJohn Marino     }
999*e4b17023SJohn Marino   return last_p;
1000*e4b17023SJohn Marino }
1001*e4b17023SJohn Marino 
1002*e4b17023SJohn Marino 
1003*e4b17023SJohn Marino /* This routine will relink all uses with the same stmt as HEAD into the list
1004*e4b17023SJohn Marino    immediately following HEAD for iterator IMM.  */
1005*e4b17023SJohn Marino 
1006*e4b17023SJohn Marino static inline void
link_use_stmts_after(use_operand_p head,imm_use_iterator * imm)1007*e4b17023SJohn Marino link_use_stmts_after (use_operand_p head, imm_use_iterator *imm)
1008*e4b17023SJohn Marino {
1009*e4b17023SJohn Marino   use_operand_p use_p;
1010*e4b17023SJohn Marino   use_operand_p last_p = head;
1011*e4b17023SJohn Marino   gimple head_stmt = USE_STMT (head);
1012*e4b17023SJohn Marino   tree use = USE_FROM_PTR (head);
1013*e4b17023SJohn Marino   ssa_op_iter op_iter;
1014*e4b17023SJohn Marino   int flag;
1015*e4b17023SJohn Marino 
1016*e4b17023SJohn Marino   /* Only look at virtual or real uses, depending on the type of HEAD.  */
1017*e4b17023SJohn Marino   flag = (is_gimple_reg (use) ? SSA_OP_USE : SSA_OP_VIRTUAL_USES);
1018*e4b17023SJohn Marino 
1019*e4b17023SJohn Marino   if (gimple_code (head_stmt) == GIMPLE_PHI)
1020*e4b17023SJohn Marino     {
1021*e4b17023SJohn Marino       FOR_EACH_PHI_ARG (use_p, head_stmt, op_iter, flag)
1022*e4b17023SJohn Marino 	if (USE_FROM_PTR (use_p) == use)
1023*e4b17023SJohn Marino 	  last_p = move_use_after_head (use_p, head, last_p);
1024*e4b17023SJohn Marino     }
1025*e4b17023SJohn Marino   else
1026*e4b17023SJohn Marino     {
1027*e4b17023SJohn Marino       if (flag == SSA_OP_USE)
1028*e4b17023SJohn Marino 	{
1029*e4b17023SJohn Marino 	  FOR_EACH_SSA_USE_OPERAND (use_p, head_stmt, op_iter, flag)
1030*e4b17023SJohn Marino 	    if (USE_FROM_PTR (use_p) == use)
1031*e4b17023SJohn Marino 	      last_p = move_use_after_head (use_p, head, last_p);
1032*e4b17023SJohn Marino 	}
1033*e4b17023SJohn Marino       else if ((use_p = gimple_vuse_op (head_stmt)) != NULL_USE_OPERAND_P)
1034*e4b17023SJohn Marino 	{
1035*e4b17023SJohn Marino 	  if (USE_FROM_PTR (use_p) == use)
1036*e4b17023SJohn Marino 	    last_p = move_use_after_head (use_p, head, last_p);
1037*e4b17023SJohn Marino 	}
1038*e4b17023SJohn Marino     }
1039*e4b17023SJohn Marino   /* Link iter node in after last_p.  */
1040*e4b17023SJohn Marino   if (imm->iter_node.prev != NULL)
1041*e4b17023SJohn Marino     delink_imm_use (&imm->iter_node);
1042*e4b17023SJohn Marino   link_imm_use_to_list (&(imm->iter_node), last_p);
1043*e4b17023SJohn Marino }
1044*e4b17023SJohn Marino 
1045*e4b17023SJohn Marino /* Initialize IMM to traverse over uses of VAR.  Return the first statement.  */
1046*e4b17023SJohn Marino static inline gimple
first_imm_use_stmt(imm_use_iterator * imm,tree var)1047*e4b17023SJohn Marino first_imm_use_stmt (imm_use_iterator *imm, tree var)
1048*e4b17023SJohn Marino {
1049*e4b17023SJohn Marino   imm->end_p = &(SSA_NAME_IMM_USE_NODE (var));
1050*e4b17023SJohn Marino   imm->imm_use = imm->end_p->next;
1051*e4b17023SJohn Marino   imm->next_imm_name = NULL_USE_OPERAND_P;
1052*e4b17023SJohn Marino 
1053*e4b17023SJohn Marino   /* iter_node is used as a marker within the immediate use list to indicate
1054*e4b17023SJohn Marino      where the end of the current stmt's uses are.  Initialize it to NULL
1055*e4b17023SJohn Marino      stmt and use, which indicates a marker node.  */
1056*e4b17023SJohn Marino   imm->iter_node.prev = NULL_USE_OPERAND_P;
1057*e4b17023SJohn Marino   imm->iter_node.next = NULL_USE_OPERAND_P;
1058*e4b17023SJohn Marino   imm->iter_node.loc.stmt = NULL;
1059*e4b17023SJohn Marino   imm->iter_node.use = NULL;
1060*e4b17023SJohn Marino 
1061*e4b17023SJohn Marino   if (end_imm_use_stmt_p (imm))
1062*e4b17023SJohn Marino     return NULL;
1063*e4b17023SJohn Marino 
1064*e4b17023SJohn Marino   link_use_stmts_after (imm->imm_use, imm);
1065*e4b17023SJohn Marino 
1066*e4b17023SJohn Marino   return USE_STMT (imm->imm_use);
1067*e4b17023SJohn Marino }
1068*e4b17023SJohn Marino 
1069*e4b17023SJohn Marino /* Bump IMM to the next stmt which has a use of var.  */
1070*e4b17023SJohn Marino 
1071*e4b17023SJohn Marino static inline gimple
next_imm_use_stmt(imm_use_iterator * imm)1072*e4b17023SJohn Marino next_imm_use_stmt (imm_use_iterator *imm)
1073*e4b17023SJohn Marino {
1074*e4b17023SJohn Marino   imm->imm_use = imm->iter_node.next;
1075*e4b17023SJohn Marino   if (end_imm_use_stmt_p (imm))
1076*e4b17023SJohn Marino     {
1077*e4b17023SJohn Marino       if (imm->iter_node.prev != NULL)
1078*e4b17023SJohn Marino 	delink_imm_use (&imm->iter_node);
1079*e4b17023SJohn Marino       return NULL;
1080*e4b17023SJohn Marino     }
1081*e4b17023SJohn Marino 
1082*e4b17023SJohn Marino   link_use_stmts_after (imm->imm_use, imm);
1083*e4b17023SJohn Marino   return USE_STMT (imm->imm_use);
1084*e4b17023SJohn Marino }
1085*e4b17023SJohn Marino 
1086*e4b17023SJohn Marino /* This routine will return the first use on the stmt IMM currently refers
1087*e4b17023SJohn Marino    to.  */
1088*e4b17023SJohn Marino 
1089*e4b17023SJohn Marino static inline use_operand_p
first_imm_use_on_stmt(imm_use_iterator * imm)1090*e4b17023SJohn Marino first_imm_use_on_stmt (imm_use_iterator *imm)
1091*e4b17023SJohn Marino {
1092*e4b17023SJohn Marino   imm->next_imm_name = imm->imm_use->next;
1093*e4b17023SJohn Marino   return imm->imm_use;
1094*e4b17023SJohn Marino }
1095*e4b17023SJohn Marino 
1096*e4b17023SJohn Marino /*  Return TRUE if the last use on the stmt IMM refers to has been visited.  */
1097*e4b17023SJohn Marino 
1098*e4b17023SJohn Marino static inline bool
end_imm_use_on_stmt_p(const imm_use_iterator * imm)1099*e4b17023SJohn Marino end_imm_use_on_stmt_p (const imm_use_iterator *imm)
1100*e4b17023SJohn Marino {
1101*e4b17023SJohn Marino   return (imm->imm_use == &(imm->iter_node));
1102*e4b17023SJohn Marino }
1103*e4b17023SJohn Marino 
1104*e4b17023SJohn Marino /* Bump to the next use on the stmt IMM refers to, return NULL if done.  */
1105*e4b17023SJohn Marino 
1106*e4b17023SJohn Marino static inline use_operand_p
next_imm_use_on_stmt(imm_use_iterator * imm)1107*e4b17023SJohn Marino next_imm_use_on_stmt (imm_use_iterator *imm)
1108*e4b17023SJohn Marino {
1109*e4b17023SJohn Marino   imm->imm_use = imm->next_imm_name;
1110*e4b17023SJohn Marino   if (end_imm_use_on_stmt_p (imm))
1111*e4b17023SJohn Marino     return NULL_USE_OPERAND_P;
1112*e4b17023SJohn Marino   else
1113*e4b17023SJohn Marino     {
1114*e4b17023SJohn Marino       imm->next_imm_name = imm->imm_use->next;
1115*e4b17023SJohn Marino       return imm->imm_use;
1116*e4b17023SJohn Marino     }
1117*e4b17023SJohn Marino }
1118*e4b17023SJohn Marino 
1119*e4b17023SJohn Marino /* Return true if VAR cannot be modified by the program.  */
1120*e4b17023SJohn Marino 
1121*e4b17023SJohn Marino static inline bool
unmodifiable_var_p(const_tree var)1122*e4b17023SJohn Marino unmodifiable_var_p (const_tree var)
1123*e4b17023SJohn Marino {
1124*e4b17023SJohn Marino   if (TREE_CODE (var) == SSA_NAME)
1125*e4b17023SJohn Marino     var = SSA_NAME_VAR (var);
1126*e4b17023SJohn Marino 
1127*e4b17023SJohn Marino   return TREE_READONLY (var) && (TREE_STATIC (var) || DECL_EXTERNAL (var));
1128*e4b17023SJohn Marino }
1129*e4b17023SJohn Marino 
1130*e4b17023SJohn Marino /* Return true if REF, a handled component reference, has an ARRAY_REF
1131*e4b17023SJohn Marino    somewhere in it.  */
1132*e4b17023SJohn Marino 
1133*e4b17023SJohn Marino static inline bool
ref_contains_array_ref(const_tree ref)1134*e4b17023SJohn Marino ref_contains_array_ref (const_tree ref)
1135*e4b17023SJohn Marino {
1136*e4b17023SJohn Marino   gcc_checking_assert (handled_component_p (ref));
1137*e4b17023SJohn Marino 
1138*e4b17023SJohn Marino   do {
1139*e4b17023SJohn Marino     if (TREE_CODE (ref) == ARRAY_REF)
1140*e4b17023SJohn Marino       return true;
1141*e4b17023SJohn Marino     ref = TREE_OPERAND (ref, 0);
1142*e4b17023SJohn Marino   } while (handled_component_p (ref));
1143*e4b17023SJohn Marino 
1144*e4b17023SJohn Marino   return false;
1145*e4b17023SJohn Marino }
1146*e4b17023SJohn Marino 
1147*e4b17023SJohn Marino /* Return true if REF has an VIEW_CONVERT_EXPR somewhere in it.  */
1148*e4b17023SJohn Marino 
1149*e4b17023SJohn Marino static inline bool
contains_view_convert_expr_p(const_tree ref)1150*e4b17023SJohn Marino contains_view_convert_expr_p (const_tree ref)
1151*e4b17023SJohn Marino {
1152*e4b17023SJohn Marino   while (handled_component_p (ref))
1153*e4b17023SJohn Marino     {
1154*e4b17023SJohn Marino       if (TREE_CODE (ref) == VIEW_CONVERT_EXPR)
1155*e4b17023SJohn Marino 	return true;
1156*e4b17023SJohn Marino       ref = TREE_OPERAND (ref, 0);
1157*e4b17023SJohn Marino     }
1158*e4b17023SJohn Marino 
1159*e4b17023SJohn Marino   return false;
1160*e4b17023SJohn Marino }
1161*e4b17023SJohn Marino 
1162*e4b17023SJohn Marino /* Return true, if the two ranges [POS1, SIZE1] and [POS2, SIZE2]
1163*e4b17023SJohn Marino    overlap.  SIZE1 and/or SIZE2 can be (unsigned)-1 in which case the
1164*e4b17023SJohn Marino    range is open-ended.  Otherwise return false.  */
1165*e4b17023SJohn Marino 
1166*e4b17023SJohn Marino static inline bool
ranges_overlap_p(unsigned HOST_WIDE_INT pos1,unsigned HOST_WIDE_INT size1,unsigned HOST_WIDE_INT pos2,unsigned HOST_WIDE_INT size2)1167*e4b17023SJohn Marino ranges_overlap_p (unsigned HOST_WIDE_INT pos1,
1168*e4b17023SJohn Marino 		  unsigned HOST_WIDE_INT size1,
1169*e4b17023SJohn Marino 		  unsigned HOST_WIDE_INT pos2,
1170*e4b17023SJohn Marino 		  unsigned HOST_WIDE_INT size2)
1171*e4b17023SJohn Marino {
1172*e4b17023SJohn Marino   if (pos1 >= pos2
1173*e4b17023SJohn Marino       && (size2 == (unsigned HOST_WIDE_INT)-1
1174*e4b17023SJohn Marino 	  || pos1 < (pos2 + size2)))
1175*e4b17023SJohn Marino     return true;
1176*e4b17023SJohn Marino   if (pos2 >= pos1
1177*e4b17023SJohn Marino       && (size1 == (unsigned HOST_WIDE_INT)-1
1178*e4b17023SJohn Marino 	  || pos2 < (pos1 + size1)))
1179*e4b17023SJohn Marino     return true;
1180*e4b17023SJohn Marino 
1181*e4b17023SJohn Marino   return false;
1182*e4b17023SJohn Marino }
1183*e4b17023SJohn Marino 
1184*e4b17023SJohn Marino /* Accessor to tree-ssa-operands.c caches.  */
1185*e4b17023SJohn Marino static inline struct ssa_operands *
gimple_ssa_operands(const struct function * fun)1186*e4b17023SJohn Marino gimple_ssa_operands (const struct function *fun)
1187*e4b17023SJohn Marino {
1188*e4b17023SJohn Marino   return &fun->gimple_df->ssa_operands;
1189*e4b17023SJohn Marino }
1190*e4b17023SJohn Marino 
1191*e4b17023SJohn Marino /* Given an edge_var_map V, return the PHI arg definition.  */
1192*e4b17023SJohn Marino 
1193*e4b17023SJohn Marino static inline tree
redirect_edge_var_map_def(edge_var_map * v)1194*e4b17023SJohn Marino redirect_edge_var_map_def (edge_var_map *v)
1195*e4b17023SJohn Marino {
1196*e4b17023SJohn Marino   return v->def;
1197*e4b17023SJohn Marino }
1198*e4b17023SJohn Marino 
1199*e4b17023SJohn Marino /* Given an edge_var_map V, return the PHI result.  */
1200*e4b17023SJohn Marino 
1201*e4b17023SJohn Marino static inline tree
redirect_edge_var_map_result(edge_var_map * v)1202*e4b17023SJohn Marino redirect_edge_var_map_result (edge_var_map *v)
1203*e4b17023SJohn Marino {
1204*e4b17023SJohn Marino   return v->result;
1205*e4b17023SJohn Marino }
1206*e4b17023SJohn Marino 
1207*e4b17023SJohn Marino /* Given an edge_var_map V, return the PHI arg location.  */
1208*e4b17023SJohn Marino 
1209*e4b17023SJohn Marino static inline source_location
redirect_edge_var_map_location(edge_var_map * v)1210*e4b17023SJohn Marino redirect_edge_var_map_location (edge_var_map *v)
1211*e4b17023SJohn Marino {
1212*e4b17023SJohn Marino   return v->locus;
1213*e4b17023SJohn Marino }
1214*e4b17023SJohn Marino 
1215*e4b17023SJohn Marino 
1216*e4b17023SJohn Marino /* Return an SSA_NAME node for variable VAR defined in statement STMT
1217*e4b17023SJohn Marino    in function cfun.  */
1218*e4b17023SJohn Marino 
1219*e4b17023SJohn Marino static inline tree
make_ssa_name(tree var,gimple stmt)1220*e4b17023SJohn Marino make_ssa_name (tree var, gimple stmt)
1221*e4b17023SJohn Marino {
1222*e4b17023SJohn Marino   return make_ssa_name_fn (cfun, var, stmt);
1223*e4b17023SJohn Marino }
1224*e4b17023SJohn Marino 
1225*e4b17023SJohn Marino /* Returns the base object and a constant BITS_PER_UNIT offset in *POFFSET that
1226*e4b17023SJohn Marino    denotes the starting address of the memory access EXP.
1227*e4b17023SJohn Marino    Returns NULL_TREE if the offset is not constant or any component
1228*e4b17023SJohn Marino    is not BITS_PER_UNIT-aligned.
1229*e4b17023SJohn Marino    VALUEIZE if non-NULL is used to valueize SSA names.  It should return
1230*e4b17023SJohn Marino    its argument or a constant if the argument is known to be constant.  */
1231*e4b17023SJohn Marino 
1232*e4b17023SJohn Marino static inline tree
get_addr_base_and_unit_offset_1(tree exp,HOST_WIDE_INT * poffset,tree (* valueize)(tree))1233*e4b17023SJohn Marino get_addr_base_and_unit_offset_1 (tree exp, HOST_WIDE_INT *poffset,
1234*e4b17023SJohn Marino 				 tree (*valueize) (tree))
1235*e4b17023SJohn Marino {
1236*e4b17023SJohn Marino   HOST_WIDE_INT byte_offset = 0;
1237*e4b17023SJohn Marino 
1238*e4b17023SJohn Marino   /* Compute cumulative byte-offset for nested component-refs and array-refs,
1239*e4b17023SJohn Marino      and find the ultimate containing object.  */
1240*e4b17023SJohn Marino   while (1)
1241*e4b17023SJohn Marino     {
1242*e4b17023SJohn Marino       switch (TREE_CODE (exp))
1243*e4b17023SJohn Marino 	{
1244*e4b17023SJohn Marino 	case BIT_FIELD_REF:
1245*e4b17023SJohn Marino 	  return NULL_TREE;
1246*e4b17023SJohn Marino 
1247*e4b17023SJohn Marino 	case COMPONENT_REF:
1248*e4b17023SJohn Marino 	  {
1249*e4b17023SJohn Marino 	    tree field = TREE_OPERAND (exp, 1);
1250*e4b17023SJohn Marino 	    tree this_offset = component_ref_field_offset (exp);
1251*e4b17023SJohn Marino 	    HOST_WIDE_INT hthis_offset;
1252*e4b17023SJohn Marino 
1253*e4b17023SJohn Marino 	    if (!this_offset
1254*e4b17023SJohn Marino 		|| TREE_CODE (this_offset) != INTEGER_CST
1255*e4b17023SJohn Marino 		|| (TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (field))
1256*e4b17023SJohn Marino 		    % BITS_PER_UNIT))
1257*e4b17023SJohn Marino 	      return NULL_TREE;
1258*e4b17023SJohn Marino 
1259*e4b17023SJohn Marino 	    hthis_offset = TREE_INT_CST_LOW (this_offset);
1260*e4b17023SJohn Marino 	    hthis_offset += (TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (field))
1261*e4b17023SJohn Marino 			     / BITS_PER_UNIT);
1262*e4b17023SJohn Marino 	    byte_offset += hthis_offset;
1263*e4b17023SJohn Marino 	  }
1264*e4b17023SJohn Marino 	  break;
1265*e4b17023SJohn Marino 
1266*e4b17023SJohn Marino 	case ARRAY_REF:
1267*e4b17023SJohn Marino 	case ARRAY_RANGE_REF:
1268*e4b17023SJohn Marino 	  {
1269*e4b17023SJohn Marino 	    tree index = TREE_OPERAND (exp, 1);
1270*e4b17023SJohn Marino 	    tree low_bound, unit_size;
1271*e4b17023SJohn Marino 
1272*e4b17023SJohn Marino 	    if (valueize
1273*e4b17023SJohn Marino 		&& TREE_CODE (index) == SSA_NAME)
1274*e4b17023SJohn Marino 	      index = (*valueize) (index);
1275*e4b17023SJohn Marino 
1276*e4b17023SJohn Marino 	    /* If the resulting bit-offset is constant, track it.  */
1277*e4b17023SJohn Marino 	    if (TREE_CODE (index) == INTEGER_CST
1278*e4b17023SJohn Marino 		&& (low_bound = array_ref_low_bound (exp),
1279*e4b17023SJohn Marino 		    TREE_CODE (low_bound) == INTEGER_CST)
1280*e4b17023SJohn Marino 		&& (unit_size = array_ref_element_size (exp),
1281*e4b17023SJohn Marino 		    TREE_CODE (unit_size) == INTEGER_CST))
1282*e4b17023SJohn Marino 	      {
1283*e4b17023SJohn Marino 		HOST_WIDE_INT hindex = TREE_INT_CST_LOW (index);
1284*e4b17023SJohn Marino 
1285*e4b17023SJohn Marino 		hindex -= TREE_INT_CST_LOW (low_bound);
1286*e4b17023SJohn Marino 		hindex *= TREE_INT_CST_LOW (unit_size);
1287*e4b17023SJohn Marino 		byte_offset += hindex;
1288*e4b17023SJohn Marino 	      }
1289*e4b17023SJohn Marino 	    else
1290*e4b17023SJohn Marino 	      return NULL_TREE;
1291*e4b17023SJohn Marino 	  }
1292*e4b17023SJohn Marino 	  break;
1293*e4b17023SJohn Marino 
1294*e4b17023SJohn Marino 	case REALPART_EXPR:
1295*e4b17023SJohn Marino 	  break;
1296*e4b17023SJohn Marino 
1297*e4b17023SJohn Marino 	case IMAGPART_EXPR:
1298*e4b17023SJohn Marino 	  byte_offset += TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (exp)));
1299*e4b17023SJohn Marino 	  break;
1300*e4b17023SJohn Marino 
1301*e4b17023SJohn Marino 	case VIEW_CONVERT_EXPR:
1302*e4b17023SJohn Marino 	  break;
1303*e4b17023SJohn Marino 
1304*e4b17023SJohn Marino 	case MEM_REF:
1305*e4b17023SJohn Marino 	  {
1306*e4b17023SJohn Marino 	    tree base = TREE_OPERAND (exp, 0);
1307*e4b17023SJohn Marino 	    if (valueize
1308*e4b17023SJohn Marino 		&& TREE_CODE (base) == SSA_NAME)
1309*e4b17023SJohn Marino 	      base = (*valueize) (base);
1310*e4b17023SJohn Marino 
1311*e4b17023SJohn Marino 	    /* Hand back the decl for MEM[&decl, off].  */
1312*e4b17023SJohn Marino 	    if (TREE_CODE (base) == ADDR_EXPR)
1313*e4b17023SJohn Marino 	      {
1314*e4b17023SJohn Marino 		if (!integer_zerop (TREE_OPERAND (exp, 1)))
1315*e4b17023SJohn Marino 		  {
1316*e4b17023SJohn Marino 		    double_int off = mem_ref_offset (exp);
1317*e4b17023SJohn Marino 		    gcc_assert (off.high == -1 || off.high == 0);
1318*e4b17023SJohn Marino 		    byte_offset += double_int_to_shwi (off);
1319*e4b17023SJohn Marino 		  }
1320*e4b17023SJohn Marino 		exp = TREE_OPERAND (base, 0);
1321*e4b17023SJohn Marino 	      }
1322*e4b17023SJohn Marino 	    goto done;
1323*e4b17023SJohn Marino 	  }
1324*e4b17023SJohn Marino 
1325*e4b17023SJohn Marino 	case TARGET_MEM_REF:
1326*e4b17023SJohn Marino 	  {
1327*e4b17023SJohn Marino 	    tree base = TREE_OPERAND (exp, 0);
1328*e4b17023SJohn Marino 	    if (valueize
1329*e4b17023SJohn Marino 		&& TREE_CODE (base) == SSA_NAME)
1330*e4b17023SJohn Marino 	      base = (*valueize) (base);
1331*e4b17023SJohn Marino 
1332*e4b17023SJohn Marino 	    /* Hand back the decl for MEM[&decl, off].  */
1333*e4b17023SJohn Marino 	    if (TREE_CODE (base) == ADDR_EXPR)
1334*e4b17023SJohn Marino 	      {
1335*e4b17023SJohn Marino 		if (TMR_INDEX (exp) || TMR_INDEX2 (exp))
1336*e4b17023SJohn Marino 		  return NULL_TREE;
1337*e4b17023SJohn Marino 		if (!integer_zerop (TMR_OFFSET (exp)))
1338*e4b17023SJohn Marino 		  {
1339*e4b17023SJohn Marino 		    double_int off = mem_ref_offset (exp);
1340*e4b17023SJohn Marino 		    gcc_assert (off.high == -1 || off.high == 0);
1341*e4b17023SJohn Marino 		    byte_offset += double_int_to_shwi (off);
1342*e4b17023SJohn Marino 		  }
1343*e4b17023SJohn Marino 		exp = TREE_OPERAND (base, 0);
1344*e4b17023SJohn Marino 	      }
1345*e4b17023SJohn Marino 	    goto done;
1346*e4b17023SJohn Marino 	  }
1347*e4b17023SJohn Marino 
1348*e4b17023SJohn Marino 	default:
1349*e4b17023SJohn Marino 	  goto done;
1350*e4b17023SJohn Marino 	}
1351*e4b17023SJohn Marino 
1352*e4b17023SJohn Marino       exp = TREE_OPERAND (exp, 0);
1353*e4b17023SJohn Marino     }
1354*e4b17023SJohn Marino done:
1355*e4b17023SJohn Marino 
1356*e4b17023SJohn Marino   *poffset = byte_offset;
1357*e4b17023SJohn Marino   return exp;
1358*e4b17023SJohn Marino }
1359*e4b17023SJohn Marino 
1360*e4b17023SJohn Marino #endif /* _TREE_FLOW_INLINE_H  */
1361