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