]>
Commit | Line | Data |
---|---|---|
6de9cd9a | 1 | /* Inline functions for tree-flow.h |
f93089d2 | 2 | Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. |
6de9cd9a DN |
3 | Contributed by Diego Novillo <dnovillo@redhat.com> |
4 | ||
5 | This file is part of GCC. | |
6 | ||
7 | GCC is free software; you can redistribute it and/or modify | |
8 | it under the terms of the GNU General Public License as published by | |
9 | the Free Software Foundation; either version 2, or (at your option) | |
10 | any later version. | |
11 | ||
12 | GCC is distributed in the hope that it will be useful, | |
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | GNU General Public License for more details. | |
16 | ||
17 | You should have received a copy of the GNU General Public License | |
18 | along with GCC; see the file COPYING. If not, write to | |
366ccddb KC |
19 | the Free Software Foundation, 51 Franklin Street, Fifth Floor, |
20 | Boston, MA 02110-1301, USA. */ | |
6de9cd9a DN |
21 | |
22 | #ifndef _TREE_FLOW_INLINE_H | |
23 | #define _TREE_FLOW_INLINE_H 1 | |
24 | ||
25 | /* Inline functions for manipulating various data structures defined in | |
26 | tree-flow.h. See tree-flow.h for documentation. */ | |
27 | ||
a3648cfc DB |
28 | /* Initialize the hashtable iterator HTI to point to hashtable TABLE */ |
29 | ||
30 | static inline void * | |
31 | first_htab_element (htab_iterator *hti, htab_t table) | |
32 | { | |
33 | hti->htab = table; | |
34 | hti->slot = table->entries; | |
35 | hti->limit = hti->slot + htab_size (table); | |
36 | do | |
37 | { | |
38 | PTR x = *(hti->slot); | |
39 | if (x != HTAB_EMPTY_ENTRY && x != HTAB_DELETED_ENTRY) | |
40 | break; | |
41 | } while (++(hti->slot) < hti->limit); | |
42 | ||
43 | if (hti->slot < hti->limit) | |
44 | return *(hti->slot); | |
45 | return NULL; | |
46 | } | |
47 | ||
48 | /* Return current non-empty/deleted slot of the hashtable pointed to by HTI, | |
49 | or NULL if we have reached the end. */ | |
50 | ||
51 | static inline bool | |
52 | end_htab_p (htab_iterator *hti) | |
53 | { | |
54 | if (hti->slot >= hti->limit) | |
55 | return true; | |
56 | return false; | |
57 | } | |
58 | ||
206048bd | 59 | /* Advance the hashtable iterator pointed to by HTI to the next element of the |
a3648cfc DB |
60 | hashtable. */ |
61 | ||
62 | static inline void * | |
63 | next_htab_element (htab_iterator *hti) | |
64 | { | |
65 | while (++(hti->slot) < hti->limit) | |
66 | { | |
67 | PTR x = *(hti->slot); | |
68 | if (x != HTAB_EMPTY_ENTRY && x != HTAB_DELETED_ENTRY) | |
69 | return x; | |
70 | }; | |
71 | return NULL; | |
72 | } | |
73 | ||
74 | /* Initialize ITER to point to the first referenced variable in the | |
75 | referenced_vars hashtable, and return that variable. */ | |
76 | ||
77 | static inline tree | |
78 | first_referenced_var (referenced_var_iterator *iter) | |
79 | { | |
80 | struct int_tree_map *itm; | |
cceb1885 GDR |
81 | itm = (struct int_tree_map *) first_htab_element (&iter->hti, |
82 | referenced_vars); | |
a3648cfc DB |
83 | if (!itm) |
84 | return NULL; | |
85 | return itm->to; | |
86 | } | |
87 | ||
88 | /* Return true if we have hit the end of the referenced variables ITER is | |
89 | iterating through. */ | |
90 | ||
91 | static inline bool | |
92 | end_referenced_vars_p (referenced_var_iterator *iter) | |
93 | { | |
94 | return end_htab_p (&iter->hti); | |
95 | } | |
96 | ||
97 | /* Make ITER point to the next referenced_var in the referenced_var hashtable, | |
98 | and return that variable. */ | |
99 | ||
100 | static inline tree | |
101 | next_referenced_var (referenced_var_iterator *iter) | |
102 | { | |
103 | struct int_tree_map *itm; | |
cceb1885 | 104 | itm = (struct int_tree_map *) next_htab_element (&iter->hti); |
a3648cfc DB |
105 | if (!itm) |
106 | return NULL; | |
107 | return itm->to; | |
108 | } | |
b9d33488 DB |
109 | |
110 | /* Fill up VEC with the variables in the referenced vars hashtable. */ | |
111 | ||
112 | static inline void | |
113 | fill_referenced_var_vec (VEC (tree, heap) **vec) | |
114 | { | |
115 | referenced_var_iterator rvi; | |
116 | tree var; | |
117 | *vec = NULL; | |
118 | FOR_EACH_REFERENCED_VAR (var, rvi) | |
119 | VEC_safe_push (tree, heap, *vec, var); | |
120 | } | |
121 | ||
0566b51e DB |
122 | /* Return the variable annotation for T, which must be a _DECL node. |
123 | Return NULL if the variable annotation doesn't already exist. */ | |
6de9cd9a DN |
124 | static inline var_ann_t |
125 | var_ann (tree t) | |
126 | { | |
1e128c5f GB |
127 | gcc_assert (t); |
128 | gcc_assert (DECL_P (t)); | |
3bfdb124 | 129 | gcc_assert (TREE_CODE (t) != FUNCTION_DECL); |
1e128c5f | 130 | gcc_assert (!t->common.ann || t->common.ann->common.type == VAR_ANN); |
6de9cd9a DN |
131 | |
132 | return (var_ann_t) t->common.ann; | |
133 | } | |
134 | ||
0566b51e DB |
135 | /* Return the variable annotation for T, which must be a _DECL node. |
136 | Create the variable annotation if it doesn't exist. */ | |
6de9cd9a DN |
137 | static inline var_ann_t |
138 | get_var_ann (tree var) | |
139 | { | |
140 | var_ann_t ann = var_ann (var); | |
141 | return (ann) ? ann : create_var_ann (var); | |
142 | } | |
143 | ||
3bfdb124 DB |
144 | /* Return the function annotation for T, which must be a FUNCTION_DECL node. |
145 | Return NULL if the function annotation doesn't already exist. */ | |
146 | static inline function_ann_t | |
147 | function_ann (tree t) | |
148 | { | |
149 | gcc_assert (t); | |
150 | gcc_assert (TREE_CODE (t) == FUNCTION_DECL); | |
151 | gcc_assert (!t->common.ann || t->common.ann->common.type == FUNCTION_ANN); | |
152 | ||
153 | return (function_ann_t) t->common.ann; | |
154 | } | |
155 | ||
156 | /* Return the function annotation for T, which must be a FUNCTION_DECL node. | |
157 | Create the function annotation if it doesn't exist. */ | |
158 | static inline function_ann_t | |
159 | get_function_ann (tree var) | |
160 | { | |
161 | function_ann_t ann = function_ann (var); | |
162 | return (ann) ? ann : create_function_ann (var); | |
163 | } | |
164 | ||
0566b51e DB |
165 | /* Return the statement annotation for T, which must be a statement |
166 | node. Return NULL if the statement annotation doesn't exist. */ | |
6de9cd9a DN |
167 | static inline stmt_ann_t |
168 | stmt_ann (tree t) | |
169 | { | |
1e128c5f GB |
170 | #ifdef ENABLE_CHECKING |
171 | gcc_assert (is_gimple_stmt (t)); | |
6de9cd9a | 172 | #endif |
6de9cd9a DN |
173 | return (stmt_ann_t) t->common.ann; |
174 | } | |
175 | ||
0566b51e DB |
176 | /* Return the statement annotation for T, which must be a statement |
177 | node. Create the statement annotation if it doesn't exist. */ | |
6de9cd9a DN |
178 | static inline stmt_ann_t |
179 | get_stmt_ann (tree stmt) | |
180 | { | |
181 | stmt_ann_t ann = stmt_ann (stmt); | |
182 | return (ann) ? ann : create_stmt_ann (stmt); | |
183 | } | |
184 | ||
0566b51e | 185 | /* Return the annotation type for annotation ANN. */ |
6de9cd9a | 186 | static inline enum tree_ann_type |
06d72ee6 | 187 | ann_type (tree_ann_t ann) |
6de9cd9a DN |
188 | { |
189 | return ann->common.type; | |
190 | } | |
191 | ||
0566b51e | 192 | /* Return the basic block for statement T. */ |
6de9cd9a DN |
193 | static inline basic_block |
194 | bb_for_stmt (tree t) | |
195 | { | |
30d396e3 ZD |
196 | stmt_ann_t ann; |
197 | ||
198 | if (TREE_CODE (t) == PHI_NODE) | |
199 | return PHI_BB (t); | |
200 | ||
201 | ann = stmt_ann (t); | |
6de9cd9a DN |
202 | return ann ? ann->bb : NULL; |
203 | } | |
204 | ||
0566b51e DB |
205 | /* Return the may_aliases varray for variable VAR, or NULL if it has |
206 | no may aliases. */ | |
780e37d3 | 207 | static inline VEC(tree, gc) * |
6de9cd9a DN |
208 | may_aliases (tree var) |
209 | { | |
210 | var_ann_t ann = var_ann (var); | |
211 | return ann ? ann->may_aliases : NULL; | |
212 | } | |
213 | ||
0566b51e DB |
214 | /* Return the line number for EXPR, or return -1 if we have no line |
215 | number information for it. */ | |
6de9cd9a DN |
216 | static inline int |
217 | get_lineno (tree expr) | |
218 | { | |
219 | if (expr == NULL_TREE) | |
220 | return -1; | |
221 | ||
222 | if (TREE_CODE (expr) == COMPOUND_EXPR) | |
223 | expr = TREE_OPERAND (expr, 0); | |
224 | ||
9506ac2b | 225 | if (! EXPR_HAS_LOCATION (expr)) |
6de9cd9a DN |
226 | return -1; |
227 | ||
228 | return EXPR_LINENO (expr); | |
229 | } | |
230 | ||
0566b51e DB |
231 | /* Return the file name for EXPR, or return "???" if we have no |
232 | filename information. */ | |
6de9cd9a DN |
233 | static inline const char * |
234 | get_filename (tree expr) | |
235 | { | |
9506ac2b | 236 | const char *filename; |
6de9cd9a DN |
237 | if (expr == NULL_TREE) |
238 | return "???"; | |
239 | ||
240 | if (TREE_CODE (expr) == COMPOUND_EXPR) | |
241 | expr = TREE_OPERAND (expr, 0); | |
242 | ||
9506ac2b PB |
243 | if (EXPR_HAS_LOCATION (expr) && (filename = EXPR_FILENAME (expr))) |
244 | return filename; | |
6de9cd9a DN |
245 | else |
246 | return "???"; | |
247 | } | |
248 | ||
7ded35b4 RS |
249 | /* Return true if T is a noreturn call. */ |
250 | static inline bool | |
251 | noreturn_call_p (tree t) | |
252 | { | |
253 | tree call = get_call_expr_in (t); | |
254 | return call != 0 && (call_expr_flags (call) & ECF_NORETURN) != 0; | |
255 | } | |
256 | ||
0566b51e | 257 | /* Mark statement T as modified. */ |
6de9cd9a | 258 | static inline void |
f430bae8 | 259 | mark_stmt_modified (tree t) |
6de9cd9a | 260 | { |
f430bae8 AM |
261 | stmt_ann_t ann; |
262 | if (TREE_CODE (t) == PHI_NODE) | |
263 | return; | |
264 | ||
265 | ann = stmt_ann (t); | |
6de9cd9a DN |
266 | if (ann == NULL) |
267 | ann = create_stmt_ann (t); | |
7ded35b4 | 268 | else if (noreturn_call_p (t)) |
d4e6fecb | 269 | VEC_safe_push (tree, gc, modified_noreturn_calls, t); |
6de9cd9a DN |
270 | ann->modified = 1; |
271 | } | |
272 | ||
f430bae8 | 273 | /* Mark statement T as modified, and update it. */ |
6de9cd9a | 274 | static inline void |
f430bae8 | 275 | update_stmt (tree t) |
6de9cd9a | 276 | { |
f430bae8 AM |
277 | if (TREE_CODE (t) == PHI_NODE) |
278 | return; | |
279 | mark_stmt_modified (t); | |
280 | update_stmt_operands (t); | |
281 | } | |
282 | ||
283 | static inline void | |
284 | update_stmt_if_modified (tree t) | |
285 | { | |
286 | if (stmt_modified_p (t)) | |
287 | update_stmt_operands (t); | |
288 | } | |
289 | ||
0566b51e | 290 | /* Return true if T is marked as modified, false otherwise. */ |
6de9cd9a DN |
291 | static inline bool |
292 | stmt_modified_p (tree t) | |
293 | { | |
294 | stmt_ann_t ann = stmt_ann (t); | |
295 | ||
296 | /* Note that if the statement doesn't yet have an annotation, we consider it | |
f430bae8 AM |
297 | modified. This will force the next call to update_stmt_operands to scan |
298 | the statement. */ | |
6de9cd9a DN |
299 | return ann ? ann->modified : true; |
300 | } | |
301 | ||
f430bae8 AM |
302 | /* Delink an immediate_uses node from its chain. */ |
303 | static inline void | |
f47c96aa | 304 | delink_imm_use (ssa_use_operand_t *linknode) |
f430bae8 AM |
305 | { |
306 | /* Return if this node is not in a list. */ | |
307 | if (linknode->prev == NULL) | |
308 | return; | |
309 | ||
310 | linknode->prev->next = linknode->next; | |
311 | linknode->next->prev = linknode->prev; | |
312 | linknode->prev = NULL; | |
313 | linknode->next = NULL; | |
314 | } | |
315 | ||
316 | /* Link ssa_imm_use node LINKNODE into the chain for LIST. */ | |
317 | static inline void | |
f47c96aa | 318 | link_imm_use_to_list (ssa_use_operand_t *linknode, ssa_use_operand_t *list) |
f430bae8 AM |
319 | { |
320 | /* Link the new node at the head of the list. If we are in the process of | |
be12e697 | 321 | traversing the list, we won't visit any new nodes added to it. */ |
f430bae8 AM |
322 | linknode->prev = list; |
323 | linknode->next = list->next; | |
324 | list->next->prev = linknode; | |
325 | list->next = linknode; | |
326 | } | |
327 | ||
328 | /* Link ssa_imm_use node LINKNODE into the chain for DEF. */ | |
329 | static inline void | |
f47c96aa | 330 | link_imm_use (ssa_use_operand_t *linknode, tree def) |
f430bae8 | 331 | { |
f47c96aa | 332 | ssa_use_operand_t *root; |
f430bae8 AM |
333 | |
334 | if (!def || TREE_CODE (def) != SSA_NAME) | |
335 | linknode->prev = NULL; | |
336 | else | |
337 | { | |
338 | root = &(SSA_NAME_IMM_USE_NODE (def)); | |
339 | #ifdef ENABLE_CHECKING | |
340 | if (linknode->use) | |
341 | gcc_assert (*(linknode->use) == def); | |
342 | #endif | |
343 | link_imm_use_to_list (linknode, root); | |
344 | } | |
345 | } | |
346 | ||
206048bd | 347 | /* Set the value of a use pointed to by USE to VAL. */ |
f430bae8 AM |
348 | static inline void |
349 | set_ssa_use_from_ptr (use_operand_p use, tree val) | |
350 | { | |
351 | delink_imm_use (use); | |
352 | *(use->use) = val; | |
353 | link_imm_use (use, val); | |
354 | } | |
355 | ||
0fa2e4df | 356 | /* Link ssa_imm_use node LINKNODE into the chain for DEF, with use occurring |
f430bae8 AM |
357 | in STMT. */ |
358 | static inline void | |
f47c96aa | 359 | link_imm_use_stmt (ssa_use_operand_t *linknode, tree def, tree stmt) |
f430bae8 AM |
360 | { |
361 | if (stmt) | |
362 | link_imm_use (linknode, def); | |
363 | else | |
364 | link_imm_use (linknode, NULL); | |
365 | linknode->stmt = stmt; | |
366 | } | |
367 | ||
368 | /* Relink a new node in place of an old node in the list. */ | |
369 | static inline void | |
f47c96aa | 370 | relink_imm_use (ssa_use_operand_t *node, ssa_use_operand_t *old) |
f430bae8 | 371 | { |
f430bae8 | 372 | /* The node one had better be in the same list. */ |
0e61db61 | 373 | gcc_assert (*(old->use) == *(node->use)); |
f430bae8 AM |
374 | node->prev = old->prev; |
375 | node->next = old->next; | |
376 | if (old->prev) | |
377 | { | |
378 | old->prev->next = node; | |
379 | old->next->prev = node; | |
380 | /* Remove the old node from the list. */ | |
381 | old->prev = NULL; | |
382 | } | |
f430bae8 AM |
383 | } |
384 | ||
0fa2e4df | 385 | /* Relink ssa_imm_use node LINKNODE into the chain for OLD, with use occurring |
f430bae8 AM |
386 | in STMT. */ |
387 | static inline void | |
f47c96aa | 388 | relink_imm_use_stmt (ssa_use_operand_t *linknode, ssa_use_operand_t *old, tree stmt) |
f430bae8 AM |
389 | { |
390 | if (stmt) | |
391 | relink_imm_use (linknode, old); | |
392 | else | |
393 | link_imm_use (linknode, NULL); | |
394 | linknode->stmt = stmt; | |
395 | } | |
396 | ||
397 | /* Finished the traverse of an immediate use list IMM by removing it from | |
398 | the list. */ | |
399 | static inline void | |
400 | end_safe_imm_use_traverse (imm_use_iterator *imm) | |
401 | { | |
402 | delink_imm_use (&(imm->iter_node)); | |
403 | } | |
404 | ||
405 | /* Return true if IMM is at the end of the list. */ | |
406 | static inline bool | |
407 | end_safe_imm_use_p (imm_use_iterator *imm) | |
408 | { | |
409 | return (imm->imm_use == imm->end_p); | |
410 | } | |
411 | ||
412 | /* Initialize iterator IMM to process the list for VAR. */ | |
413 | static inline use_operand_p | |
414 | first_safe_imm_use (imm_use_iterator *imm, tree var) | |
415 | { | |
416 | /* Set up and link the iterator node into the linked list for VAR. */ | |
417 | imm->iter_node.use = NULL; | |
418 | imm->iter_node.stmt = NULL_TREE; | |
419 | imm->end_p = &(SSA_NAME_IMM_USE_NODE (var)); | |
420 | /* Check if there are 0 elements. */ | |
421 | if (imm->end_p->next == imm->end_p) | |
422 | { | |
423 | imm->imm_use = imm->end_p; | |
424 | return NULL_USE_OPERAND_P; | |
425 | } | |
426 | ||
427 | link_imm_use (&(imm->iter_node), var); | |
428 | imm->imm_use = imm->iter_node.next; | |
429 | return imm->imm_use; | |
430 | } | |
431 | ||
d566f6ef | 432 | /* Bump IMM to the next use in the list. */ |
f430bae8 AM |
433 | static inline use_operand_p |
434 | next_safe_imm_use (imm_use_iterator *imm) | |
435 | { | |
f47c96aa | 436 | ssa_use_operand_t *ptr; |
f430bae8 AM |
437 | use_operand_p old; |
438 | ||
439 | old = imm->imm_use; | |
f652d14b KH |
440 | /* If the next node following the iter_node is still the one referred to by |
441 | imm_use, then the list hasn't changed, go to the next node. */ | |
f430bae8 AM |
442 | if (imm->iter_node.next == imm->imm_use) |
443 | { | |
444 | ptr = &(imm->iter_node); | |
f652d14b | 445 | /* Remove iternode from the list. */ |
f430bae8 AM |
446 | delink_imm_use (ptr); |
447 | imm->imm_use = imm->imm_use->next; | |
448 | if (! end_safe_imm_use_p (imm)) | |
449 | { | |
d566f6ef | 450 | /* This isn't the end, link iternode before the next use. */ |
f430bae8 AM |
451 | ptr->prev = imm->imm_use->prev; |
452 | ptr->next = imm->imm_use; | |
453 | imm->imm_use->prev->next = ptr; | |
454 | imm->imm_use->prev = ptr; | |
455 | } | |
456 | else | |
457 | return old; | |
458 | } | |
459 | else | |
460 | { | |
461 | /* If the 'next' value after the iterator isn't the same as it was, then | |
f652d14b | 462 | a node has been deleted, so we simply proceed to the node following |
f430bae8 AM |
463 | where the iterator is in the list. */ |
464 | imm->imm_use = imm->iter_node.next; | |
465 | if (end_safe_imm_use_p (imm)) | |
466 | { | |
467 | end_safe_imm_use_traverse (imm); | |
468 | return old; | |
469 | } | |
470 | } | |
471 | ||
472 | return imm->imm_use; | |
473 | } | |
474 | ||
f652d14b | 475 | /* Return true is IMM has reached the end of the immediate use list. */ |
f430bae8 AM |
476 | static inline bool |
477 | end_readonly_imm_use_p (imm_use_iterator *imm) | |
478 | { | |
479 | return (imm->imm_use == imm->end_p); | |
480 | } | |
481 | ||
482 | /* Initialize iterator IMM to process the list for VAR. */ | |
483 | static inline use_operand_p | |
484 | first_readonly_imm_use (imm_use_iterator *imm, tree var) | |
485 | { | |
486 | gcc_assert (TREE_CODE (var) == SSA_NAME); | |
487 | ||
488 | imm->end_p = &(SSA_NAME_IMM_USE_NODE (var)); | |
489 | imm->imm_use = imm->end_p->next; | |
490 | #ifdef ENABLE_CHECKING | |
491 | imm->iter_node.next = imm->imm_use->next; | |
492 | #endif | |
493 | if (end_readonly_imm_use_p (imm)) | |
494 | return NULL_USE_OPERAND_P; | |
495 | return imm->imm_use; | |
496 | } | |
497 | ||
d566f6ef | 498 | /* Bump IMM to the next use in the list. */ |
f430bae8 AM |
499 | static inline use_operand_p |
500 | next_readonly_imm_use (imm_use_iterator *imm) | |
501 | { | |
502 | use_operand_p old = imm->imm_use; | |
503 | ||
504 | #ifdef ENABLE_CHECKING | |
505 | /* If this assertion fails, it indicates the 'next' pointer has changed | |
506 | since we the last bump. This indicates that the list is being modified | |
507 | via stmt changes, or SET_USE, or somesuch thing, and you need to be | |
508 | using the SAFE version of the iterator. */ | |
509 | gcc_assert (imm->iter_node.next == old->next); | |
510 | imm->iter_node.next = old->next->next; | |
511 | #endif | |
512 | ||
513 | imm->imm_use = old->next; | |
514 | if (end_readonly_imm_use_p (imm)) | |
515 | return old; | |
516 | return imm->imm_use; | |
517 | } | |
518 | ||
519 | /* Return true if VAR has no uses. */ | |
520 | static inline bool | |
521 | has_zero_uses (tree var) | |
522 | { | |
f47c96aa | 523 | ssa_use_operand_t *ptr; |
f430bae8 AM |
524 | ptr = &(SSA_NAME_IMM_USE_NODE (var)); |
525 | /* A single use means there is no items in the list. */ | |
526 | return (ptr == ptr->next); | |
527 | } | |
528 | ||
529 | /* Return true if VAR has a single use. */ | |
530 | static inline bool | |
531 | has_single_use (tree var) | |
532 | { | |
f47c96aa | 533 | ssa_use_operand_t *ptr; |
f430bae8 AM |
534 | ptr = &(SSA_NAME_IMM_USE_NODE (var)); |
535 | /* A single use means there is one item in the list. */ | |
536 | return (ptr != ptr->next && ptr == ptr->next->next); | |
537 | } | |
538 | ||
539 | /* If VAR has only a single immediate use, return true, and set USE_P and STMT | |
f652d14b | 540 | to the use pointer and stmt of occurrence. */ |
f430bae8 AM |
541 | static inline bool |
542 | single_imm_use (tree var, use_operand_p *use_p, tree *stmt) | |
543 | { | |
f47c96aa | 544 | ssa_use_operand_t *ptr; |
f430bae8 AM |
545 | |
546 | ptr = &(SSA_NAME_IMM_USE_NODE (var)); | |
547 | if (ptr != ptr->next && ptr == ptr->next->next) | |
548 | { | |
549 | *use_p = ptr->next; | |
550 | *stmt = ptr->next->stmt; | |
551 | return true; | |
552 | } | |
553 | *use_p = NULL_USE_OPERAND_P; | |
554 | *stmt = NULL_TREE; | |
555 | return false; | |
556 | } | |
557 | ||
558 | /* Return the number of immediate uses of VAR. */ | |
559 | static inline unsigned int | |
560 | num_imm_uses (tree var) | |
561 | { | |
f47c96aa | 562 | ssa_use_operand_t *ptr, *start; |
f430bae8 AM |
563 | unsigned int num; |
564 | ||
565 | start = &(SSA_NAME_IMM_USE_NODE (var)); | |
566 | num = 0; | |
567 | for (ptr = start->next; ptr != start; ptr = ptr->next) | |
568 | num++; | |
569 | ||
570 | return num; | |
571 | } | |
572 | ||
a32b97a2 | 573 | |
d00ad49b AM |
574 | /* Return the tree pointer to by USE. */ |
575 | static inline tree | |
576 | get_use_from_ptr (use_operand_p use) | |
577 | { | |
f430bae8 | 578 | return *(use->use); |
d00ad49b AM |
579 | } |
580 | ||
581 | /* Return the tree pointer to by DEF. */ | |
582 | static inline tree | |
583 | get_def_from_ptr (def_operand_p def) | |
584 | { | |
f47c96aa | 585 | return *def; |
d00ad49b AM |
586 | } |
587 | ||
588 | /* Return a def_operand_p pointer for the result of PHI. */ | |
589 | static inline def_operand_p | |
590 | get_phi_result_ptr (tree phi) | |
591 | { | |
f47c96aa | 592 | return &(PHI_RESULT_TREE (phi)); |
a32b97a2 BB |
593 | } |
594 | ||
d00ad49b AM |
595 | /* Return a use_operand_p pointer for argument I of phinode PHI. */ |
596 | static inline use_operand_p | |
597 | get_phi_arg_def_ptr (tree phi, int i) | |
598 | { | |
f430bae8 | 599 | return &(PHI_ARG_IMM_USE_NODE (phi,i)); |
6de9cd9a DN |
600 | } |
601 | ||
e54d0214 | 602 | |
f430bae8 AM |
603 | /* Return the bitmap of addresses taken by STMT, or NULL if it takes |
604 | no addresses. */ | |
605 | static inline bitmap | |
606 | addresses_taken (tree stmt) | |
607 | { | |
608 | stmt_ann_t ann = stmt_ann (stmt); | |
609 | return ann ? ann->addresses_taken : NULL; | |
6de9cd9a DN |
610 | } |
611 | ||
0566b51e DB |
612 | /* Return the PHI nodes for basic block BB, or NULL if there are no |
613 | PHI nodes. */ | |
6de9cd9a DN |
614 | static inline tree |
615 | phi_nodes (basic_block bb) | |
616 | { | |
4aab792d | 617 | return bb->phi_nodes; |
6de9cd9a DN |
618 | } |
619 | ||
620 | /* Set list of phi nodes of a basic block BB to L. */ | |
621 | ||
622 | static inline void | |
623 | set_phi_nodes (basic_block bb, tree l) | |
624 | { | |
625 | tree phi; | |
626 | ||
4aab792d | 627 | bb->phi_nodes = l; |
17192884 | 628 | for (phi = l; phi; phi = PHI_CHAIN (phi)) |
6de9cd9a DN |
629 | set_bb_for_stmt (phi, bb); |
630 | } | |
631 | ||
f430bae8 AM |
632 | /* Return the phi argument which contains the specified use. */ |
633 | ||
634 | static inline int | |
635 | phi_arg_index_from_use (use_operand_p use) | |
636 | { | |
637 | struct phi_arg_d *element, *root; | |
638 | int index; | |
639 | tree phi; | |
640 | ||
f652d14b | 641 | /* Since the use is the first thing in a PHI argument element, we can |
f430bae8 AM |
642 | calculate its index based on casting it to an argument, and performing |
643 | pointer arithmetic. */ | |
644 | ||
645 | phi = USE_STMT (use); | |
646 | gcc_assert (TREE_CODE (phi) == PHI_NODE); | |
647 | ||
648 | element = (struct phi_arg_d *)use; | |
649 | root = &(PHI_ARG_ELT (phi, 0)); | |
650 | index = element - root; | |
651 | ||
652 | #ifdef ENABLE_CHECKING | |
653 | /* Make sure the calculation doesn't have any leftover bytes. If it does, | |
f652d14b | 654 | then imm_use is likely not the first element in phi_arg_d. */ |
f430bae8 AM |
655 | gcc_assert ( |
656 | (((char *)element - (char *)root) % sizeof (struct phi_arg_d)) == 0); | |
657 | gcc_assert (index >= 0 && index < PHI_ARG_CAPACITY (phi)); | |
658 | #endif | |
659 | ||
660 | return index; | |
661 | } | |
662 | ||
727a31fa RH |
663 | /* Mark VAR as used, so that it'll be preserved during rtl expansion. */ |
664 | ||
665 | static inline void | |
666 | set_is_used (tree var) | |
667 | { | |
668 | var_ann_t ann = get_var_ann (var); | |
669 | ann->used = 1; | |
670 | } | |
671 | ||
672 | ||
6de9cd9a DN |
673 | /* ----------------------------------------------------------------------- */ |
674 | ||
0566b51e | 675 | /* Return true if T is an executable statement. */ |
6de9cd9a DN |
676 | static inline bool |
677 | is_exec_stmt (tree t) | |
678 | { | |
679 | return (t && !IS_EMPTY_STMT (t) && t != error_mark_node); | |
680 | } | |
681 | ||
682 | ||
683 | /* Return true if this stmt can be the target of a control transfer stmt such | |
684 | as a goto. */ | |
685 | static inline bool | |
686 | is_label_stmt (tree t) | |
687 | { | |
688 | if (t) | |
689 | switch (TREE_CODE (t)) | |
690 | { | |
691 | case LABEL_DECL: | |
692 | case LABEL_EXPR: | |
693 | case CASE_LABEL_EXPR: | |
694 | return true; | |
695 | default: | |
696 | return false; | |
697 | } | |
698 | return false; | |
699 | } | |
700 | ||
6de9cd9a DN |
701 | /* PHI nodes should contain only ssa_names and invariants. A test |
702 | for ssa_name is definitely simpler; don't let invalid contents | |
703 | slip in in the meantime. */ | |
704 | ||
705 | static inline bool | |
706 | phi_ssa_name_p (tree t) | |
707 | { | |
708 | if (TREE_CODE (t) == SSA_NAME) | |
709 | return true; | |
710 | #ifdef ENABLE_CHECKING | |
1e128c5f | 711 | gcc_assert (is_gimple_min_invariant (t)); |
6de9cd9a DN |
712 | #endif |
713 | return false; | |
714 | } | |
715 | ||
716 | /* ----------------------------------------------------------------------- */ | |
717 | ||
0566b51e DB |
718 | /* Return a block_stmt_iterator that points to beginning of basic |
719 | block BB. */ | |
6de9cd9a DN |
720 | static inline block_stmt_iterator |
721 | bsi_start (basic_block bb) | |
722 | { | |
723 | block_stmt_iterator bsi; | |
724 | if (bb->stmt_list) | |
725 | bsi.tsi = tsi_start (bb->stmt_list); | |
726 | else | |
727 | { | |
24bd1a0b | 728 | gcc_assert (bb->index < NUM_FIXED_BLOCKS); |
6de9cd9a DN |
729 | bsi.tsi.ptr = NULL; |
730 | bsi.tsi.container = NULL; | |
731 | } | |
732 | bsi.bb = bb; | |
733 | return bsi; | |
734 | } | |
735 | ||
93954fcc | 736 | /* Return a block statement iterator that points to the first non-label |
35771d34 | 737 | statement in block BB. */ |
d7621d3c ZD |
738 | |
739 | static inline block_stmt_iterator | |
740 | bsi_after_labels (basic_block bb) | |
741 | { | |
35771d34 | 742 | block_stmt_iterator bsi = bsi_start (bb); |
d7621d3c | 743 | |
35771d34 PB |
744 | while (!bsi_end_p (bsi) && TREE_CODE (bsi_stmt (bsi)) == LABEL_EXPR) |
745 | bsi_next (&bsi); | |
d7621d3c ZD |
746 | |
747 | return bsi; | |
748 | } | |
749 | ||
0566b51e DB |
750 | /* Return a block statement iterator that points to the end of basic |
751 | block BB. */ | |
6de9cd9a DN |
752 | static inline block_stmt_iterator |
753 | bsi_last (basic_block bb) | |
754 | { | |
755 | block_stmt_iterator bsi; | |
756 | if (bb->stmt_list) | |
757 | bsi.tsi = tsi_last (bb->stmt_list); | |
758 | else | |
759 | { | |
24bd1a0b | 760 | gcc_assert (bb->index < NUM_FIXED_BLOCKS); |
6de9cd9a DN |
761 | bsi.tsi.ptr = NULL; |
762 | bsi.tsi.container = NULL; | |
763 | } | |
764 | bsi.bb = bb; | |
765 | return bsi; | |
766 | } | |
767 | ||
0566b51e DB |
768 | /* Return true if block statement iterator I has reached the end of |
769 | the basic block. */ | |
6de9cd9a DN |
770 | static inline bool |
771 | bsi_end_p (block_stmt_iterator i) | |
772 | { | |
773 | return tsi_end_p (i.tsi); | |
774 | } | |
775 | ||
0566b51e DB |
776 | /* Modify block statement iterator I so that it is at the next |
777 | statement in the basic block. */ | |
6de9cd9a DN |
778 | static inline void |
779 | bsi_next (block_stmt_iterator *i) | |
780 | { | |
781 | tsi_next (&i->tsi); | |
782 | } | |
783 | ||
0566b51e DB |
784 | /* Modify block statement iterator I so that it is at the previous |
785 | statement in the basic block. */ | |
6de9cd9a DN |
786 | static inline void |
787 | bsi_prev (block_stmt_iterator *i) | |
788 | { | |
789 | tsi_prev (&i->tsi); | |
790 | } | |
791 | ||
0566b51e DB |
792 | /* Return the statement that block statement iterator I is currently |
793 | at. */ | |
6de9cd9a DN |
794 | static inline tree |
795 | bsi_stmt (block_stmt_iterator i) | |
796 | { | |
797 | return tsi_stmt (i.tsi); | |
798 | } | |
799 | ||
0566b51e DB |
800 | /* Return a pointer to the statement that block statement iterator I |
801 | is currently at. */ | |
6de9cd9a DN |
802 | static inline tree * |
803 | bsi_stmt_ptr (block_stmt_iterator i) | |
804 | { | |
805 | return tsi_stmt_ptr (i.tsi); | |
806 | } | |
807 | ||
9baba81b SP |
808 | /* Returns the loop of the statement STMT. */ |
809 | ||
810 | static inline struct loop * | |
811 | loop_containing_stmt (tree stmt) | |
812 | { | |
813 | basic_block bb = bb_for_stmt (stmt); | |
814 | if (!bb) | |
815 | return NULL; | |
816 | ||
817 | return bb->loop_father; | |
818 | } | |
819 | ||
0566b51e | 820 | /* Return true if VAR is a clobbered by function calls. */ |
6de9cd9a DN |
821 | static inline bool |
822 | is_call_clobbered (tree var) | |
823 | { | |
fe1f8f44 DB |
824 | if (!MTAG_P (var)) |
825 | return DECL_CALL_CLOBBERED (var); | |
826 | else | |
827 | return bitmap_bit_p (call_clobbered_vars, DECL_UID (var)); | |
6de9cd9a DN |
828 | } |
829 | ||
0566b51e | 830 | /* Mark variable VAR as being clobbered by function calls. */ |
6de9cd9a | 831 | static inline void |
d16a5e36 | 832 | mark_call_clobbered (tree var, unsigned int escape_type) |
6de9cd9a | 833 | { |
d16a5e36 | 834 | var_ann (var)->escape_mask |= escape_type; |
fe1f8f44 DB |
835 | if (!MTAG_P (var)) |
836 | DECL_CALL_CLOBBERED (var) = true; | |
a3648cfc | 837 | bitmap_set_bit (call_clobbered_vars, DECL_UID (var)); |
6de9cd9a DN |
838 | } |
839 | ||
90e34bd6 DN |
840 | /* Clear the call-clobbered attribute from variable VAR. */ |
841 | static inline void | |
842 | clear_call_clobbered (tree var) | |
843 | { | |
d16a5e36 DB |
844 | var_ann_t ann = var_ann (var); |
845 | ann->escape_mask = 0; | |
326eda4b DB |
846 | if (MTAG_P (var) && TREE_CODE (var) != STRUCT_FIELD_TAG) |
847 | MTAG_GLOBAL (var) = 0; | |
fe1f8f44 DB |
848 | if (!MTAG_P (var)) |
849 | DECL_CALL_CLOBBERED (var) = false; | |
a3648cfc | 850 | bitmap_clear_bit (call_clobbered_vars, DECL_UID (var)); |
90e34bd6 DN |
851 | } |
852 | ||
0566b51e | 853 | /* Mark variable VAR as being non-addressable. */ |
6de9cd9a DN |
854 | static inline void |
855 | mark_non_addressable (tree var) | |
856 | { | |
fe1f8f44 DB |
857 | if (!MTAG_P (var)) |
858 | DECL_CALL_CLOBBERED (var) = false; | |
a3648cfc | 859 | bitmap_clear_bit (call_clobbered_vars, DECL_UID (var)); |
6de9cd9a DN |
860 | TREE_ADDRESSABLE (var) = 0; |
861 | } | |
862 | ||
06d72ee6 DB |
863 | /* Return the common annotation for T. Return NULL if the annotation |
864 | doesn't already exist. */ | |
865 | static inline tree_ann_t | |
866 | tree_ann (tree t) | |
867 | { | |
868 | return t->common.ann; | |
869 | } | |
870 | ||
871 | /* Return a common annotation for T. Create the constant annotation if it | |
872 | doesn't exist. */ | |
873 | static inline tree_ann_t | |
874 | get_tree_ann (tree t) | |
875 | { | |
876 | tree_ann_t ann = tree_ann (t); | |
877 | return (ann) ? ann : create_tree_ann (t); | |
878 | } | |
879 | ||
4c124b4c AM |
880 | /* ----------------------------------------------------------------------- */ |
881 | ||
882 | /* The following set of routines are used to iterator over various type of | |
883 | SSA operands. */ | |
884 | ||
885 | /* Return true if PTR is finished iterating. */ | |
886 | static inline bool | |
887 | op_iter_done (ssa_op_iter *ptr) | |
888 | { | |
889 | return ptr->done; | |
890 | } | |
891 | ||
892 | /* Get the next iterator use value for PTR. */ | |
893 | static inline use_operand_p | |
894 | op_iter_next_use (ssa_op_iter *ptr) | |
895 | { | |
f47c96aa AM |
896 | use_operand_p use_p; |
897 | #ifdef ENABLE_CHECKING | |
898 | gcc_assert (ptr->iter_type == ssa_op_iter_use); | |
899 | #endif | |
900 | if (ptr->uses) | |
4c124b4c | 901 | { |
f47c96aa AM |
902 | use_p = USE_OP_PTR (ptr->uses); |
903 | ptr->uses = ptr->uses->next; | |
904 | return use_p; | |
4c124b4c | 905 | } |
f47c96aa | 906 | if (ptr->vuses) |
4c124b4c | 907 | { |
f47c96aa AM |
908 | use_p = VUSE_OP_PTR (ptr->vuses); |
909 | ptr->vuses = ptr->vuses->next; | |
910 | return use_p; | |
4c124b4c | 911 | } |
f47c96aa | 912 | if (ptr->mayuses) |
4c124b4c | 913 | { |
f47c96aa AM |
914 | use_p = MAYDEF_OP_PTR (ptr->mayuses); |
915 | ptr->mayuses = ptr->mayuses->next; | |
916 | return use_p; | |
52328bf6 | 917 | } |
f47c96aa | 918 | if (ptr->mustkills) |
52328bf6 | 919 | { |
f47c96aa AM |
920 | use_p = MUSTDEF_KILL_PTR (ptr->mustkills); |
921 | ptr->mustkills = ptr->mustkills->next; | |
922 | return use_p; | |
923 | } | |
924 | if (ptr->phi_i < ptr->num_phi) | |
925 | { | |
926 | return PHI_ARG_DEF_PTR (ptr->phi_stmt, (ptr->phi_i)++); | |
4c124b4c AM |
927 | } |
928 | ptr->done = true; | |
929 | return NULL_USE_OPERAND_P; | |
930 | } | |
931 | ||
932 | /* Get the next iterator def value for PTR. */ | |
933 | static inline def_operand_p | |
934 | op_iter_next_def (ssa_op_iter *ptr) | |
935 | { | |
f47c96aa AM |
936 | def_operand_p def_p; |
937 | #ifdef ENABLE_CHECKING | |
938 | gcc_assert (ptr->iter_type == ssa_op_iter_def); | |
939 | #endif | |
940 | if (ptr->defs) | |
4c124b4c | 941 | { |
f47c96aa AM |
942 | def_p = DEF_OP_PTR (ptr->defs); |
943 | ptr->defs = ptr->defs->next; | |
944 | return def_p; | |
4c124b4c | 945 | } |
f47c96aa | 946 | if (ptr->mustdefs) |
4c124b4c | 947 | { |
f47c96aa AM |
948 | def_p = MUSTDEF_RESULT_PTR (ptr->mustdefs); |
949 | ptr->mustdefs = ptr->mustdefs->next; | |
950 | return def_p; | |
4c124b4c | 951 | } |
f47c96aa | 952 | if (ptr->maydefs) |
4c124b4c | 953 | { |
f47c96aa AM |
954 | def_p = MAYDEF_RESULT_PTR (ptr->maydefs); |
955 | ptr->maydefs = ptr->maydefs->next; | |
956 | return def_p; | |
4c124b4c AM |
957 | } |
958 | ptr->done = true; | |
959 | return NULL_DEF_OPERAND_P; | |
960 | } | |
961 | ||
962 | /* Get the next iterator tree value for PTR. */ | |
963 | static inline tree | |
964 | op_iter_next_tree (ssa_op_iter *ptr) | |
965 | { | |
f47c96aa AM |
966 | tree val; |
967 | #ifdef ENABLE_CHECKING | |
968 | gcc_assert (ptr->iter_type == ssa_op_iter_tree); | |
969 | #endif | |
970 | if (ptr->uses) | |
4c124b4c | 971 | { |
f47c96aa AM |
972 | val = USE_OP (ptr->uses); |
973 | ptr->uses = ptr->uses->next; | |
974 | return val; | |
4c124b4c | 975 | } |
f47c96aa | 976 | if (ptr->vuses) |
4c124b4c | 977 | { |
f47c96aa AM |
978 | val = VUSE_OP (ptr->vuses); |
979 | ptr->vuses = ptr->vuses->next; | |
980 | return val; | |
4c124b4c | 981 | } |
f47c96aa | 982 | if (ptr->mayuses) |
4c124b4c | 983 | { |
f47c96aa AM |
984 | val = MAYDEF_OP (ptr->mayuses); |
985 | ptr->mayuses = ptr->mayuses->next; | |
986 | return val; | |
4c124b4c | 987 | } |
f47c96aa | 988 | if (ptr->mustkills) |
52328bf6 | 989 | { |
f47c96aa AM |
990 | val = MUSTDEF_KILL (ptr->mustkills); |
991 | ptr->mustkills = ptr->mustkills->next; | |
992 | return val; | |
52328bf6 | 993 | } |
f47c96aa | 994 | if (ptr->defs) |
4c124b4c | 995 | { |
f47c96aa AM |
996 | val = DEF_OP (ptr->defs); |
997 | ptr->defs = ptr->defs->next; | |
998 | return val; | |
4c124b4c | 999 | } |
f47c96aa | 1000 | if (ptr->mustdefs) |
4c124b4c | 1001 | { |
f47c96aa AM |
1002 | val = MUSTDEF_RESULT (ptr->mustdefs); |
1003 | ptr->mustdefs = ptr->mustdefs->next; | |
1004 | return val; | |
4c124b4c | 1005 | } |
f47c96aa | 1006 | if (ptr->maydefs) |
4c124b4c | 1007 | { |
f47c96aa AM |
1008 | val = MAYDEF_RESULT (ptr->maydefs); |
1009 | ptr->maydefs = ptr->maydefs->next; | |
1010 | return val; | |
4c124b4c | 1011 | } |
f47c96aa AM |
1012 | |
1013 | ptr->done = true; | |
1014 | return NULL_TREE; | |
1015 | ||
1016 | } | |
1017 | ||
1018 | ||
395bda42 | 1019 | /* This functions clears the iterator PTR, and marks it done. This is normally |
c83eecad | 1020 | used to prevent warnings in the compile about might be uninitialized |
f47c96aa AM |
1021 | components. */ |
1022 | ||
1023 | static inline void | |
1024 | clear_and_done_ssa_iter (ssa_op_iter *ptr) | |
1025 | { | |
1026 | ptr->defs = NULL; | |
1027 | ptr->uses = NULL; | |
1028 | ptr->vuses = NULL; | |
1029 | ptr->maydefs = NULL; | |
1030 | ptr->mayuses = NULL; | |
1031 | ptr->mustdefs = NULL; | |
1032 | ptr->mustkills = NULL; | |
1033 | ptr->iter_type = ssa_op_iter_none; | |
1034 | ptr->phi_i = 0; | |
1035 | ptr->num_phi = 0; | |
1036 | ptr->phi_stmt = NULL_TREE; | |
4c124b4c | 1037 | ptr->done = true; |
4c124b4c AM |
1038 | } |
1039 | ||
1040 | /* Initialize the iterator PTR to the virtual defs in STMT. */ | |
1041 | static inline void | |
1042 | op_iter_init (ssa_op_iter *ptr, tree stmt, int flags) | |
1043 | { | |
f47c96aa AM |
1044 | #ifdef ENABLE_CHECKING |
1045 | gcc_assert (stmt_ann (stmt)); | |
1046 | #endif | |
4c124b4c | 1047 | |
f47c96aa AM |
1048 | ptr->defs = (flags & SSA_OP_DEF) ? DEF_OPS (stmt) : NULL; |
1049 | ptr->uses = (flags & SSA_OP_USE) ? USE_OPS (stmt) : NULL; | |
1050 | ptr->vuses = (flags & SSA_OP_VUSE) ? VUSE_OPS (stmt) : NULL; | |
1051 | ptr->maydefs = (flags & SSA_OP_VMAYDEF) ? MAYDEF_OPS (stmt) : NULL; | |
1052 | ptr->mayuses = (flags & SSA_OP_VMAYUSE) ? MAYDEF_OPS (stmt) : NULL; | |
1053 | ptr->mustdefs = (flags & SSA_OP_VMUSTDEF) ? MUSTDEF_OPS (stmt) : NULL; | |
1054 | ptr->mustkills = (flags & SSA_OP_VMUSTKILL) ? MUSTDEF_OPS (stmt) : NULL; | |
4c124b4c | 1055 | ptr->done = false; |
f47c96aa AM |
1056 | |
1057 | ptr->phi_i = 0; | |
1058 | ptr->num_phi = 0; | |
1059 | ptr->phi_stmt = NULL_TREE; | |
4c124b4c AM |
1060 | } |
1061 | ||
1062 | /* Initialize iterator PTR to the use operands in STMT based on FLAGS. Return | |
1063 | the first use. */ | |
1064 | static inline use_operand_p | |
1065 | op_iter_init_use (ssa_op_iter *ptr, tree stmt, int flags) | |
1066 | { | |
66d3fe47 | 1067 | gcc_assert ((flags & SSA_OP_ALL_DEFS) == 0); |
4c124b4c | 1068 | op_iter_init (ptr, stmt, flags); |
f47c96aa | 1069 | ptr->iter_type = ssa_op_iter_use; |
4c124b4c AM |
1070 | return op_iter_next_use (ptr); |
1071 | } | |
1072 | ||
1073 | /* Initialize iterator PTR to the def operands in STMT based on FLAGS. Return | |
1074 | the first def. */ | |
1075 | static inline def_operand_p | |
1076 | op_iter_init_def (ssa_op_iter *ptr, tree stmt, int flags) | |
1077 | { | |
66d3fe47 | 1078 | gcc_assert ((flags & (SSA_OP_ALL_USES | SSA_OP_VIRTUAL_KILLS)) == 0); |
4c124b4c | 1079 | op_iter_init (ptr, stmt, flags); |
f47c96aa | 1080 | ptr->iter_type = ssa_op_iter_def; |
4c124b4c AM |
1081 | return op_iter_next_def (ptr); |
1082 | } | |
1083 | ||
1084 | /* Initialize iterator PTR to the operands in STMT based on FLAGS. Return | |
1085 | the first operand as a tree. */ | |
1086 | static inline tree | |
1087 | op_iter_init_tree (ssa_op_iter *ptr, tree stmt, int flags) | |
1088 | { | |
1089 | op_iter_init (ptr, stmt, flags); | |
f47c96aa | 1090 | ptr->iter_type = ssa_op_iter_tree; |
4c124b4c AM |
1091 | return op_iter_next_tree (ptr); |
1092 | } | |
1093 | ||
52328bf6 DB |
1094 | /* Get the next iterator mustdef value for PTR, returning the mustdef values in |
1095 | KILL and DEF. */ | |
1096 | static inline void | |
f47c96aa AM |
1097 | op_iter_next_maymustdef (use_operand_p *use, def_operand_p *def, |
1098 | ssa_op_iter *ptr) | |
52328bf6 | 1099 | { |
f47c96aa AM |
1100 | #ifdef ENABLE_CHECKING |
1101 | gcc_assert (ptr->iter_type == ssa_op_iter_maymustdef); | |
1102 | #endif | |
1103 | if (ptr->mayuses) | |
52328bf6 | 1104 | { |
f47c96aa AM |
1105 | *def = MAYDEF_RESULT_PTR (ptr->mayuses); |
1106 | *use = MAYDEF_OP_PTR (ptr->mayuses); | |
1107 | ptr->mayuses = ptr->mayuses->next; | |
52328bf6 DB |
1108 | return; |
1109 | } | |
db30731a | 1110 | |
f47c96aa | 1111 | if (ptr->mustkills) |
4c124b4c | 1112 | { |
f47c96aa AM |
1113 | *def = MUSTDEF_RESULT_PTR (ptr->mustkills); |
1114 | *use = MUSTDEF_KILL_PTR (ptr->mustkills); | |
1115 | ptr->mustkills = ptr->mustkills->next; | |
4c124b4c AM |
1116 | return; |
1117 | } | |
4c124b4c | 1118 | |
f47c96aa AM |
1119 | *def = NULL_DEF_OPERAND_P; |
1120 | *use = NULL_USE_OPERAND_P; | |
db30731a JL |
1121 | ptr->done = true; |
1122 | return; | |
1123 | } | |
1124 | ||
f47c96aa | 1125 | |
4c124b4c AM |
1126 | /* Initialize iterator PTR to the operands in STMT. Return the first operands |
1127 | in USE and DEF. */ | |
1128 | static inline void | |
1129 | op_iter_init_maydef (ssa_op_iter *ptr, tree stmt, use_operand_p *use, | |
1130 | def_operand_p *def) | |
1131 | { | |
f47c96aa AM |
1132 | gcc_assert (TREE_CODE (stmt) != PHI_NODE); |
1133 | ||
4c124b4c | 1134 | op_iter_init (ptr, stmt, SSA_OP_VMAYUSE); |
f47c96aa AM |
1135 | ptr->iter_type = ssa_op_iter_maymustdef; |
1136 | op_iter_next_maymustdef (use, def, ptr); | |
4c124b4c | 1137 | } |
52328bf6 | 1138 | |
0bca51f0 | 1139 | |
52328bf6 DB |
1140 | /* Initialize iterator PTR to the operands in STMT. Return the first operands |
1141 | in KILL and DEF. */ | |
1142 | static inline void | |
1143 | op_iter_init_mustdef (ssa_op_iter *ptr, tree stmt, use_operand_p *kill, | |
1144 | def_operand_p *def) | |
1145 | { | |
f47c96aa AM |
1146 | gcc_assert (TREE_CODE (stmt) != PHI_NODE); |
1147 | ||
1148 | op_iter_init (ptr, stmt, SSA_OP_VMUSTKILL); | |
1149 | ptr->iter_type = ssa_op_iter_maymustdef; | |
1150 | op_iter_next_maymustdef (kill, def, ptr); | |
52328bf6 | 1151 | } |
c75ab022 | 1152 | |
db30731a JL |
1153 | /* Initialize iterator PTR to the operands in STMT. Return the first operands |
1154 | in KILL and DEF. */ | |
1155 | static inline void | |
1156 | op_iter_init_must_and_may_def (ssa_op_iter *ptr, tree stmt, | |
1157 | use_operand_p *kill, def_operand_p *def) | |
1158 | { | |
f47c96aa AM |
1159 | gcc_assert (TREE_CODE (stmt) != PHI_NODE); |
1160 | ||
1161 | op_iter_init (ptr, stmt, SSA_OP_VMUSTKILL|SSA_OP_VMAYUSE); | |
1162 | ptr->iter_type = ssa_op_iter_maymustdef; | |
1163 | op_iter_next_maymustdef (kill, def, ptr); | |
1164 | } | |
1165 | ||
1166 | ||
395bda42 | 1167 | /* If there is a single operand in STMT matching FLAGS, return it. Otherwise |
d7770457 | 1168 | return NULL. */ |
f47c96aa AM |
1169 | static inline tree |
1170 | single_ssa_tree_operand (tree stmt, int flags) | |
1171 | { | |
1172 | tree var; | |
1173 | ssa_op_iter iter; | |
1174 | ||
1175 | var = op_iter_init_tree (&iter, stmt, flags); | |
1176 | if (op_iter_done (&iter)) | |
1177 | return NULL_TREE; | |
1178 | op_iter_next_tree (&iter); | |
1179 | if (op_iter_done (&iter)) | |
1180 | return var; | |
1181 | return NULL_TREE; | |
1182 | } | |
1183 | ||
1184 | ||
395bda42 | 1185 | /* If there is a single operand in STMT matching FLAGS, return it. Otherwise |
d7770457 | 1186 | return NULL. */ |
f47c96aa AM |
1187 | static inline use_operand_p |
1188 | single_ssa_use_operand (tree stmt, int flags) | |
1189 | { | |
1190 | use_operand_p var; | |
1191 | ssa_op_iter iter; | |
1192 | ||
1193 | var = op_iter_init_use (&iter, stmt, flags); | |
1194 | if (op_iter_done (&iter)) | |
1195 | return NULL_USE_OPERAND_P; | |
1196 | op_iter_next_use (&iter); | |
1197 | if (op_iter_done (&iter)) | |
1198 | return var; | |
1199 | return NULL_USE_OPERAND_P; | |
1200 | } | |
1201 | ||
1202 | ||
1203 | ||
395bda42 | 1204 | /* If there is a single operand in STMT matching FLAGS, return it. Otherwise |
d7770457 | 1205 | return NULL. */ |
f47c96aa AM |
1206 | static inline def_operand_p |
1207 | single_ssa_def_operand (tree stmt, int flags) | |
1208 | { | |
1209 | def_operand_p var; | |
1210 | ssa_op_iter iter; | |
1211 | ||
1212 | var = op_iter_init_def (&iter, stmt, flags); | |
1213 | if (op_iter_done (&iter)) | |
1214 | return NULL_DEF_OPERAND_P; | |
1215 | op_iter_next_def (&iter); | |
1216 | if (op_iter_done (&iter)) | |
1217 | return var; | |
1218 | return NULL_DEF_OPERAND_P; | |
1219 | } | |
1220 | ||
1221 | ||
395bda42 | 1222 | /* If there is a single operand in STMT matching FLAGS, return it. Otherwise |
d7770457 | 1223 | return NULL. */ |
f47c96aa AM |
1224 | static inline bool |
1225 | zero_ssa_operands (tree stmt, int flags) | |
1226 | { | |
1227 | ssa_op_iter iter; | |
1228 | ||
1229 | op_iter_init_tree (&iter, stmt, flags); | |
1230 | return op_iter_done (&iter); | |
db30731a JL |
1231 | } |
1232 | ||
f47c96aa | 1233 | |
395bda42 | 1234 | /* Return the number of operands matching FLAGS in STMT. */ |
f47c96aa AM |
1235 | static inline int |
1236 | num_ssa_operands (tree stmt, int flags) | |
1237 | { | |
1238 | ssa_op_iter iter; | |
66d3fe47 | 1239 | tree t; |
f47c96aa AM |
1240 | int num = 0; |
1241 | ||
66d3fe47 | 1242 | FOR_EACH_SSA_TREE_OPERAND (t, stmt, iter, flags) |
f47c96aa | 1243 | num++; |
f47c96aa AM |
1244 | return num; |
1245 | } | |
1246 | ||
1247 | ||
1248 | /* Delink all immediate_use information for STMT. */ | |
1249 | static inline void | |
1250 | delink_stmt_imm_use (tree stmt) | |
1251 | { | |
1252 | ssa_op_iter iter; | |
1253 | use_operand_p use_p; | |
1254 | ||
1255 | if (ssa_operands_active ()) | |
1256 | FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, | |
1257 | (SSA_OP_ALL_USES | SSA_OP_ALL_KILLS)) | |
1258 | delink_imm_use (use_p); | |
1259 | } | |
1260 | ||
1261 | ||
1262 | /* This routine will compare all the operands matching FLAGS in STMT1 to those | |
1263 | in STMT2. TRUE is returned if they are the same. STMTs can be NULL. */ | |
1264 | static inline bool | |
1265 | compare_ssa_operands_equal (tree stmt1, tree stmt2, int flags) | |
1266 | { | |
1267 | ssa_op_iter iter1, iter2; | |
1268 | tree op1 = NULL_TREE; | |
1269 | tree op2 = NULL_TREE; | |
1270 | bool look1, look2; | |
1271 | ||
1272 | if (stmt1 == stmt2) | |
1273 | return true; | |
1274 | ||
1275 | look1 = stmt1 && stmt_ann (stmt1); | |
1276 | look2 = stmt2 && stmt_ann (stmt2); | |
1277 | ||
1278 | if (look1) | |
1279 | { | |
1280 | op1 = op_iter_init_tree (&iter1, stmt1, flags); | |
1281 | if (!look2) | |
1282 | return op_iter_done (&iter1); | |
1283 | } | |
1284 | else | |
1285 | clear_and_done_ssa_iter (&iter1); | |
1286 | ||
1287 | if (look2) | |
1288 | { | |
1289 | op2 = op_iter_init_tree (&iter2, stmt2, flags); | |
1290 | if (!look1) | |
1291 | return op_iter_done (&iter2); | |
1292 | } | |
1293 | else | |
1294 | clear_and_done_ssa_iter (&iter2); | |
1295 | ||
1296 | while (!op_iter_done (&iter1) && !op_iter_done (&iter2)) | |
1297 | { | |
1298 | if (op1 != op2) | |
1299 | return false; | |
1300 | op1 = op_iter_next_tree (&iter1); | |
1301 | op2 = op_iter_next_tree (&iter2); | |
1302 | } | |
1303 | ||
1304 | return (op_iter_done (&iter1) && op_iter_done (&iter2)); | |
1305 | } | |
1306 | ||
1307 | ||
1308 | /* If there is a single DEF in the PHI node which matches FLAG, return it. | |
1309 | Otherwise return NULL_DEF_OPERAND_P. */ | |
1310 | static inline tree | |
1311 | single_phi_def (tree stmt, int flags) | |
1312 | { | |
1313 | tree def = PHI_RESULT (stmt); | |
1314 | if ((flags & SSA_OP_DEF) && is_gimple_reg (def)) | |
1315 | return def; | |
1316 | if ((flags & SSA_OP_VIRTUAL_DEFS) && !is_gimple_reg (def)) | |
1317 | return def; | |
1318 | return NULL_TREE; | |
1319 | } | |
1320 | ||
1321 | /* Initialize the iterator PTR for uses matching FLAGS in PHI. FLAGS should | |
1322 | be either SSA_OP_USES or SAS_OP_VIRTUAL_USES. */ | |
1323 | static inline use_operand_p | |
1324 | op_iter_init_phiuse (ssa_op_iter *ptr, tree phi, int flags) | |
1325 | { | |
1326 | tree phi_def = PHI_RESULT (phi); | |
1327 | int comp; | |
1328 | ||
1329 | clear_and_done_ssa_iter (ptr); | |
1330 | ptr->done = false; | |
1331 | ||
1332 | gcc_assert ((flags & (SSA_OP_USE | SSA_OP_VIRTUAL_USES)) != 0); | |
1333 | ||
1334 | comp = (is_gimple_reg (phi_def) ? SSA_OP_USE : SSA_OP_VIRTUAL_USES); | |
1335 | ||
395bda42 | 1336 | /* If the PHI node doesn't the operand type we care about, we're done. */ |
f47c96aa AM |
1337 | if ((flags & comp) == 0) |
1338 | { | |
1339 | ptr->done = true; | |
1340 | return NULL_USE_OPERAND_P; | |
1341 | } | |
1342 | ||
1343 | ptr->phi_stmt = phi; | |
1344 | ptr->num_phi = PHI_NUM_ARGS (phi); | |
1345 | ptr->iter_type = ssa_op_iter_use; | |
1346 | return op_iter_next_use (ptr); | |
1347 | } | |
1348 | ||
1349 | ||
395bda42 | 1350 | /* Start an iterator for a PHI definition. */ |
f47c96aa AM |
1351 | |
1352 | static inline def_operand_p | |
1353 | op_iter_init_phidef (ssa_op_iter *ptr, tree phi, int flags) | |
1354 | { | |
1355 | tree phi_def = PHI_RESULT (phi); | |
1356 | int comp; | |
1357 | ||
1358 | clear_and_done_ssa_iter (ptr); | |
1359 | ptr->done = false; | |
1360 | ||
1361 | gcc_assert ((flags & (SSA_OP_DEF | SSA_OP_VIRTUAL_DEFS)) != 0); | |
1362 | ||
1363 | comp = (is_gimple_reg (phi_def) ? SSA_OP_DEF : SSA_OP_VIRTUAL_DEFS); | |
1364 | ||
395bda42 | 1365 | /* If the PHI node doesn't the operand type we care about, we're done. */ |
f47c96aa AM |
1366 | if ((flags & comp) == 0) |
1367 | { | |
1368 | ptr->done = true; | |
1369 | return NULL_USE_OPERAND_P; | |
1370 | } | |
1371 | ||
1372 | ptr->iter_type = ssa_op_iter_def; | |
1373 | /* The first call to op_iter_next_def will terminate the iterator since | |
1374 | all the fields are NULL. Simply return the result here as the first and | |
1375 | therefore only result. */ | |
1376 | return PHI_RESULT_PTR (phi); | |
1377 | } | |
1378 | ||
1379 | ||
1380 | ||
db30731a JL |
1381 | /* Return true if VAR cannot be modified by the program. */ |
1382 | ||
1383 | static inline bool | |
1384 | unmodifiable_var_p (tree var) | |
1385 | { | |
1386 | if (TREE_CODE (var) == SSA_NAME) | |
1387 | var = SSA_NAME_VAR (var); | |
326eda4b DB |
1388 | |
1389 | if (MTAG_P (var)) | |
1390 | return TREE_READONLY (var) && (TREE_STATIC (var) || MTAG_GLOBAL (var)); | |
1391 | ||
db30731a JL |
1392 | return TREE_READONLY (var) && (TREE_STATIC (var) || DECL_EXTERNAL (var)); |
1393 | } | |
1394 | ||
8d66aeca | 1395 | /* Return true if REF, an ARRAY_REF, has an INDIRECT_REF somewhere in it. */ |
b1347638 DB |
1396 | |
1397 | static inline bool | |
8d66aeca | 1398 | array_ref_contains_indirect_ref (tree ref) |
b1347638 | 1399 | { |
8d66aeca RG |
1400 | gcc_assert (TREE_CODE (ref) == ARRAY_REF); |
1401 | ||
1402 | do { | |
1403 | ref = TREE_OPERAND (ref, 0); | |
1404 | } while (handled_component_p (ref)); | |
1405 | ||
1406 | return TREE_CODE (ref) == INDIRECT_REF; | |
b1347638 DB |
1407 | } |
1408 | ||
8d66aeca RG |
1409 | /* Return true if REF, a handled component reference, has an ARRAY_REF |
1410 | somewhere in it. */ | |
c75ab022 DB |
1411 | |
1412 | static inline bool | |
1413 | ref_contains_array_ref (tree ref) | |
1414 | { | |
8d66aeca RG |
1415 | gcc_assert (handled_component_p (ref)); |
1416 | ||
1417 | do { | |
1418 | if (TREE_CODE (ref) == ARRAY_REF) | |
1419 | return true; | |
1420 | ref = TREE_OPERAND (ref, 0); | |
1421 | } while (handled_component_p (ref)); | |
1422 | ||
c75ab022 DB |
1423 | return false; |
1424 | } | |
1425 | ||
1426 | /* Given a variable VAR, lookup and return a pointer to the list of | |
1427 | subvariables for it. */ | |
1428 | ||
1429 | static inline subvar_t * | |
1430 | lookup_subvars_for_var (tree var) | |
1431 | { | |
1432 | var_ann_t ann = var_ann (var); | |
1433 | gcc_assert (ann); | |
1434 | return &ann->subvars; | |
1435 | } | |
1436 | ||
1437 | /* Given a variable VAR, return a linked list of subvariables for VAR, or | |
1438 | NULL, if there are no subvariables. */ | |
1439 | ||
1440 | static inline subvar_t | |
1441 | get_subvars_for_var (tree var) | |
1442 | { | |
1443 | subvar_t subvars; | |
1444 | ||
1445 | gcc_assert (SSA_VAR_P (var)); | |
1446 | ||
1447 | if (TREE_CODE (var) == SSA_NAME) | |
1448 | subvars = *(lookup_subvars_for_var (SSA_NAME_VAR (var))); | |
1449 | else | |
1450 | subvars = *(lookup_subvars_for_var (var)); | |
1451 | return subvars; | |
1452 | } | |
1453 | ||
e8ca4159 DN |
1454 | /* Return the subvariable of VAR at offset OFFSET. */ |
1455 | ||
1456 | static inline tree | |
1457 | get_subvar_at (tree var, unsigned HOST_WIDE_INT offset) | |
1458 | { | |
1459 | subvar_t sv; | |
1460 | ||
1461 | for (sv = get_subvars_for_var (var); sv; sv = sv->next) | |
3c0b6c43 | 1462 | if (SFT_OFFSET (sv->var) == offset) |
e8ca4159 DN |
1463 | return sv->var; |
1464 | ||
1465 | return NULL_TREE; | |
1466 | } | |
1467 | ||
c75ab022 | 1468 | /* Return true if V is a tree that we can have subvars for. |
a916f21d | 1469 | Normally, this is any aggregate type. Also complex |
8ae5e6f2 | 1470 | types which are not gimple registers can have subvars. */ |
c75ab022 DB |
1471 | |
1472 | static inline bool | |
1473 | var_can_have_subvars (tree v) | |
1474 | { | |
1651647c AP |
1475 | /* Volatile variables should never have subvars. */ |
1476 | if (TREE_THIS_VOLATILE (v)) | |
1477 | return false; | |
1478 | ||
8ae5e6f2 AP |
1479 | /* Non decls or memory tags can never have subvars. */ |
1480 | if (!DECL_P (v) || MTAG_P (v)) | |
1481 | return false; | |
1482 | ||
a916f21d RG |
1483 | /* Aggregates can have subvars. */ |
1484 | if (AGGREGATE_TYPE_P (TREE_TYPE (v))) | |
8ae5e6f2 AP |
1485 | return true; |
1486 | ||
1487 | /* Complex types variables which are not also a gimple register can | |
1488 | have subvars. */ | |
1489 | if (TREE_CODE (TREE_TYPE (v)) == COMPLEX_TYPE | |
1490 | && !DECL_COMPLEX_GIMPLE_REG_P (v)) | |
1491 | return true; | |
1492 | ||
1493 | return false; | |
c75ab022 DB |
1494 | } |
1495 | ||
1496 | ||
013cc86f DB |
1497 | /* Return true if OFFSET and SIZE define a range that overlaps with some |
1498 | portion of the range of SV, a subvar. If there was an exact overlap, | |
1499 | *EXACT will be set to true upon return. */ | |
1500 | ||
1501 | static inline bool | |
e8ca4159 | 1502 | overlap_subvar (unsigned HOST_WIDE_INT offset, unsigned HOST_WIDE_INT size, |
3c0b6c43 | 1503 | tree sv, bool *exact) |
013cc86f DB |
1504 | { |
1505 | /* There are three possible cases of overlap. | |
1506 | 1. We can have an exact overlap, like so: | |
1507 | |offset, offset + size | | |
1508 | |sv->offset, sv->offset + sv->size | | |
1509 | ||
1510 | 2. We can have offset starting after sv->offset, like so: | |
1511 | ||
1512 | |offset, offset + size | | |
1513 | |sv->offset, sv->offset + sv->size | | |
1514 | ||
1515 | 3. We can have offset starting before sv->offset, like so: | |
1516 | ||
1517 | |offset, offset + size | | |
1518 | |sv->offset, sv->offset + sv->size| | |
1519 | */ | |
1520 | ||
1521 | if (exact) | |
1522 | *exact = false; | |
3c0b6c43 | 1523 | if (offset == SFT_OFFSET (sv) && size == SFT_SIZE (sv)) |
013cc86f DB |
1524 | { |
1525 | if (exact) | |
1526 | *exact = true; | |
1527 | return true; | |
1528 | } | |
3c0b6c43 DB |
1529 | else if (offset >= SFT_OFFSET (sv) |
1530 | && offset < (SFT_OFFSET (sv) + SFT_SIZE (sv))) | |
013cc86f DB |
1531 | { |
1532 | return true; | |
1533 | } | |
3c0b6c43 DB |
1534 | else if (offset < SFT_OFFSET (sv) |
1535 | && (size > SFT_OFFSET (sv) - offset)) | |
013cc86f DB |
1536 | { |
1537 | return true; | |
1538 | } | |
1539 | return false; | |
1540 | ||
1541 | } | |
c75ab022 | 1542 | |
6de9cd9a | 1543 | #endif /* _TREE_FLOW_INLINE_H */ |