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