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