]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/tree-flow-inline.h
tree-ssa.h: New.
[thirdparty/gcc.git] / gcc / tree-flow-inline.h
CommitLineData
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
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9dcd6f09 9the Free Software Foundation; either version 3, or (at your option)
6de9cd9a
DN
10any later version.
11
12GCC is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
9dcd6f09
NC
18along 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. */
31static inline bool
9566a759 32gimple_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 38static inline tree
5006671f 39gimple_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
47static inline void *
48first_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
68static inline bool
9566a759 69end_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
79static inline void *
80next_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. */
92static inline unsigned int
93gimple_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. */
99static inline void
100set_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. */
106static inline unsigned int
107inc_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 114static inline int
726a989a 115get_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. */
130static inline void
f47c96aa 131delink_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. */
144static inline void
f47c96aa 145link_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. */
156static inline void
f47c96aa 157link_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
173static inline void
174set_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. */
183static inline void
726a989a 184link_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. */
194static inline void
f47c96aa 195relink_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. */
212static inline void
726a989a
RB
213relink_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 225static inline bool
9566a759 226end_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. */
232static inline use_operand_p
233first_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
246static inline use_operand_p
247next_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 */
267extern bool has_zero_uses_1 (const ssa_use_operand_t *head);
268extern 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 272static inline bool
9566a759 273has_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 290static inline bool
9566a759 291has_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 313static inline bool
726a989a 314single_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 348static inline unsigned int
9566a759 349num_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
367static inline tree
368get_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
374static inline tree
375get_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
382static inline use_operand_p
383gimple_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
390static inline tree
391gimple_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
399static inline tree *
400gimple_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
407static inline edge
408gimple_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
415static inline source_location
416gimple_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
423static inline source_location
424gimple_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
431static inline void
432gimple_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
439static inline bool
440gimple_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 448static inline gimple_seq
9678086d 449phi_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 455static inline gimple_seq *
3e8b732e 456phi_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
464static inline void
726a989a 465set_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
478static inline int
479phi_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
507static inline bool
9566a759 508is_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
518static inline bool
519may_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
535static inline bool
9566a759 536phi_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
547static inline struct loop *
726a989a 548loop_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. */
564static inline bool
9566a759 565op_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. */
571static inline use_operand_p
572op_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. */
591static inline def_operand_p
592op_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. */
626static inline tree
627op_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
670static inline void
671clear_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. */
683static inline void
726a989a 684op_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. */
724static inline use_operand_p
726a989a 725op_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. */
736static inline def_operand_p
726a989a 737op_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. */
748static inline tree
726a989a 749op_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 759static inline tree
726a989a 760single_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 777static inline use_operand_p
726a989a 778single_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 796static inline def_operand_p
726a989a 797single_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 814static inline bool
726a989a 815zero_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 825static inline int
726a989a 826num_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
838static inline use_operand_p
839op_iter_init_phiuse (ssa_op_iter *ptr, gimple phi, int flags);
f47c96aa
AM
840
841/* Delink all immediate_use information for STMT. */
842static inline void
726a989a 843delink_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. */
856static inline tree
726a989a 857single_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 869static inline use_operand_p
726a989a 870op_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
899static inline def_operand_p
726a989a 900op_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
929static inline bool
9566a759 930end_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
938static inline void
939end_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
950static inline use_operand_p
b8698a0f 951move_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
976static inline void
977link_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 1016static inline gimple
6c00f606
AM
1017first_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 1041static inline gimple
6c00f606
AM
1042next_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
1059static inline use_operand_p
1060first_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
1068static inline bool
9566a759 1069end_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
1076static inline use_operand_p
1077next_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
1091static inline bool
9566a759 1092unmodifiable_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
1103static inline bool
9566a759 1104ref_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
1119static inline bool
1120contains_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
1136static inline bool
1137ranges_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. */
1155static inline struct ssa_operands *
9566a759 1156gimple_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
1165static inline tree
726a989a 1166make_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
1174static inline tree
1175copy_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
1183static inline tree
1184duplicate_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
1192static inline tree
1193make_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
1212static inline tree
1213get_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 }
1340done:
1341
1342 *poffset = byte_offset;
1343 return exp;
1344}
1345
6de9cd9a 1346#endif /* _TREE_FLOW_INLINE_H */