OSDN Git Service

2004-08-22 Andrew Pinski <apinski@apple.com>
[pf3gnuchains/gcc-fork.git] / gcc / tree-flow-inline.h
1 /* Inline functions for tree-flow.h
2    Copyright (C) 2001, 2003 Free Software Foundation, Inc.
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
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.  */
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
28 /* Return the variable annotation for T, which must be a _DECL node.
29    Return NULL if the variable annotation doesn't already exist.  */
30 static inline var_ann_t
31 var_ann (tree t)
32 {
33 #if defined ENABLE_CHECKING
34   if (t == NULL_TREE
35       || !DECL_P (t)
36       || (t->common.ann
37           && t->common.ann->common.type != VAR_ANN))
38     abort ();
39 #endif
40
41   return (var_ann_t) t->common.ann;
42 }
43
44 /* Return the variable annotation for T, which must be a _DECL node.
45    Create the variable annotation if it doesn't exist.  */
46 static inline var_ann_t
47 get_var_ann (tree var)
48 {
49   var_ann_t ann = var_ann (var);
50   return (ann) ? ann : create_var_ann (var);
51 }
52
53 /* Return the statement annotation for T, which must be a statement
54    node.  Return NULL if the statement annotation doesn't exist.  */
55 static inline stmt_ann_t
56 stmt_ann (tree t)
57 {
58 #if defined ENABLE_CHECKING
59   if (!is_gimple_stmt (t))
60     abort ();
61 #endif
62
63   return (stmt_ann_t) t->common.ann;
64 }
65
66 /* Return the statement annotation for T, which must be a statement
67    node.  Create the statement annotation if it doesn't exist.  */
68 static inline stmt_ann_t
69 get_stmt_ann (tree stmt)
70 {
71   stmt_ann_t ann = stmt_ann (stmt);
72   return (ann) ? ann : create_stmt_ann (stmt);
73 }
74
75
76 /* Return the annotation type for annotation ANN.  */
77 static inline enum tree_ann_type
78 ann_type (tree_ann_t ann)
79 {
80   return ann->common.type;
81 }
82
83 /* Return the basic block for statement T.  */
84 static inline basic_block
85 bb_for_stmt (tree t)
86 {
87   stmt_ann_t ann = stmt_ann (t);
88   return ann ? ann->bb : NULL;
89 }
90
91 /* Return the may_aliases varray for variable VAR, or NULL if it has
92    no may aliases.  */
93 static inline varray_type
94 may_aliases (tree var)
95 {
96   var_ann_t ann = var_ann (var);
97   return ann ? ann->may_aliases : NULL;
98 }
99
100 /* Return the line number for EXPR, or return -1 if we have no line
101    number information for it.  */
102 static inline int
103 get_lineno (tree expr)
104 {
105   if (expr == NULL_TREE)
106     return -1;
107
108   if (TREE_CODE (expr) == COMPOUND_EXPR)
109     expr = TREE_OPERAND (expr, 0);
110
111   if (! EXPR_HAS_LOCATION (expr))
112     return -1;
113
114   return EXPR_LINENO (expr);
115 }
116
117 /* Return the file name for EXPR, or return "???" if we have no
118    filename information.  */
119 static inline const char *
120 get_filename (tree expr)
121 {
122   const char *filename;
123   if (expr == NULL_TREE)
124     return "???";
125
126   if (TREE_CODE (expr) == COMPOUND_EXPR)
127     expr = TREE_OPERAND (expr, 0);
128
129   if (EXPR_HAS_LOCATION (expr) && (filename = EXPR_FILENAME (expr)))
130     return filename;
131   else
132     return "???";
133 }
134
135 /* Mark statement T as modified.  */
136 static inline void
137 modify_stmt (tree t)
138 {
139   stmt_ann_t ann = stmt_ann (t);
140   if (ann == NULL)
141     ann = create_stmt_ann (t);
142   ann->modified = 1;
143 }
144
145 /* Mark statement T as unmodified.  */
146 static inline void
147 unmodify_stmt (tree t)
148 {
149   stmt_ann_t ann = stmt_ann (t);
150   if (ann == NULL)
151     ann = create_stmt_ann (t);
152   ann->modified = 0;
153 }
154
155 /* Return true if T is marked as modified, false otherwise.  */
156 static inline bool
157 stmt_modified_p (tree t)
158 {
159   stmt_ann_t ann = stmt_ann (t);
160
161   /* Note that if the statement doesn't yet have an annotation, we consider it
162      modified.  This will force the next call to get_stmt_operands to scan the
163      statement.  */
164   return ann ? ann->modified : true;
165 }
166
167 /* Return the definitions present in ANN, a statement annotation.
168    Return NULL if this annotation contains no definitions.  */
169 static inline def_optype
170 get_def_ops (stmt_ann_t ann)
171 {
172   return ann ? ann->operands.def_ops : NULL;
173 }
174
175 /* Return the uses present in ANN, a statement annotation.
176    Return NULL if this annotation contains no uses.  */
177 static inline use_optype
178 get_use_ops (stmt_ann_t ann)
179 {
180   return ann ? ann->operands.use_ops : NULL;
181 }
182
183 /* Return the virtual may-defs present in ANN, a statement
184    annotation.
185    Return NULL if this annotation contains no virtual may-defs.  */
186 static inline v_may_def_optype
187 get_v_may_def_ops (stmt_ann_t ann)
188 {
189   return ann ? ann->operands.v_may_def_ops : NULL;
190 }
191
192 /* Return the virtual uses present in ANN, a statement annotation.
193    Return NULL if this annotation contains no virtual uses.  */
194 static inline vuse_optype
195 get_vuse_ops (stmt_ann_t ann)
196 {
197   return ann ? ann->operands.vuse_ops : NULL;
198 }
199
200 /* Return the virtual must-defs present in ANN, a statement
201    annotation.  Return NULL if this annotation contains no must-defs.*/
202 static inline v_must_def_optype
203 get_v_must_def_ops (stmt_ann_t ann)
204 {
205   return ann ? ann->operands.v_must_def_ops : NULL;
206 }
207
208 /* Return the tree pointer to by USE.  */ 
209 static inline tree
210 get_use_from_ptr (use_operand_p use)
211
212   return *(use.use);
213
214
215 /* Return the tree pointer to by DEF.  */
216 static inline tree
217 get_def_from_ptr (def_operand_p def)
218 {
219   return *(def.def);
220 }
221
222 /* Return a pointer to the tree that is at INDEX in the USES array.  */
223 static inline use_operand_p
224 get_use_op_ptr (use_optype uses, unsigned int index)
225 {
226 #ifdef ENABLE_CHECKING
227   if (index >= uses->num_uses)
228     abort();
229 #endif
230   return uses->uses[index];
231 }
232
233 /* Return a def_operand_p pointer for element INDEX of DEFS.  */
234 static inline def_operand_p
235 get_def_op_ptr (def_optype defs, unsigned int index)
236 {
237 #ifdef ENABLE_CHECKING
238   if (index >= defs->num_defs)
239     abort();
240 #endif
241   return defs->defs[index];
242 }
243
244
245 /* Return the def_operand_p that is the V_MAY_DEF_RESULT for the V_MAY_DEF
246    at INDEX in the V_MAY_DEFS array.  */
247 static inline def_operand_p
248 get_v_may_def_result_ptr(v_may_def_optype v_may_defs, unsigned int index)
249 {
250   def_operand_p op;
251 #ifdef ENABLE_CHECKING
252   if (index >= v_may_defs->num_v_may_defs)
253     abort();
254 #endif
255   op.def = &(v_may_defs->v_may_defs[index].def);
256   return op;
257 }
258
259 /* Return a use_operand_p that is the V_MAY_DEF_OP for the V_MAY_DEF at
260    INDEX in the V_MAY_DEFS array.  */
261 static inline use_operand_p
262 get_v_may_def_op_ptr(v_may_def_optype v_may_defs, unsigned int index)
263 {
264   use_operand_p op;
265 #ifdef ENABLE_CHECKING
266   if (index >= v_may_defs->num_v_may_defs)
267     abort();
268 #endif
269   op.use = &(v_may_defs->v_may_defs[index].use);
270   return op;
271 }
272
273 /* Return a use_operand_p that is at INDEX in the VUSES array.  */
274 static inline use_operand_p
275 get_vuse_op_ptr(vuse_optype vuses, unsigned int index)
276 {
277   use_operand_p op;
278 #ifdef ENABLE_CHECKING
279   if (index >= vuses->num_vuses)
280     abort();
281 #endif
282   op.use = &(vuses->vuses[index]);
283   return op;
284 }
285
286 /* Return a def_operand_p that is the V_MUST_DEF_OP for the
287    V_MUST_DEF at INDEX in the V_MUST_DEFS array.  */
288 static inline def_operand_p
289 get_v_must_def_op_ptr (v_must_def_optype v_must_defs, unsigned int index)
290 {
291   def_operand_p op;
292 #ifdef ENABLE_CHECKING
293   if (index >= v_must_defs->num_v_must_defs)
294     abort();
295 #endif
296   op.def = &(v_must_defs->v_must_defs[index]);
297   return op;
298 }
299
300 /* Return a def_operand_p pointer for the result of PHI.  */
301 static inline def_operand_p
302 get_phi_result_ptr (tree phi)
303 {
304   def_operand_p op;
305   op.def = &(PHI_RESULT_TREE (phi));
306   return op;
307 }
308
309 /* Return a use_operand_p pointer for argument I of phinode PHI.  */
310 static inline use_operand_p
311 get_phi_arg_def_ptr (tree phi, int i)
312 {
313   use_operand_p op;
314   op.use = &(PHI_ARG_DEF_TREE (phi, i));
315   return op;
316 }
317  
318 /* Return the bitmap of addresses taken by STMT, or NULL if it takes
319    no addresses.  */
320 static inline bitmap
321 addresses_taken (tree stmt)
322 {
323   stmt_ann_t ann = stmt_ann (stmt);
324   return ann ? ann->addresses_taken : NULL;
325 }
326
327 /* Return the immediate uses of STMT, or NULL if this information is
328    not computed.  */
329 static dataflow_t
330 get_immediate_uses (tree stmt)
331 {
332   stmt_ann_t ann = stmt_ann (stmt);
333   return ann ? ann->df : NULL;
334 }
335
336 /* Return the number of immediate uses present in the dataflow
337    information at DF.  */
338 static inline int
339 num_immediate_uses (dataflow_t df)
340 {
341   varray_type imm;
342
343   if (!df)
344     return 0;
345
346   imm = df->immediate_uses;
347   if (!imm)
348     return df->uses[1] ? 2 : 1;
349
350   return VARRAY_ACTIVE_SIZE (imm) + 2;
351 }
352
353 /* Return the tree that is at NUM in the immediate use DF array.  */
354 static inline tree
355 immediate_use (dataflow_t df, int num)
356 {
357   if (!df)
358     return NULL_TREE;
359
360 #ifdef ENABLE_CHECKING
361   if (num >= num_immediate_uses (df))
362     abort ();
363 #endif
364   if (num < 2)
365     return df->uses[num];
366   return VARRAY_TREE (df->immediate_uses, num - 2);
367 }
368
369 /* Return the basic_block annotation for BB.  */
370 static inline bb_ann_t
371 bb_ann (basic_block bb)
372 {
373   return (bb_ann_t)bb->tree_annotations;
374 }
375
376 /* Return the PHI nodes for basic block BB, or NULL if there are no
377    PHI nodes.  */
378 static inline tree
379 phi_nodes (basic_block bb)
380 {
381   if (bb->index < 0)
382     return NULL;
383   return bb_ann (bb)->phi_nodes;
384 }
385
386 /* Set list of phi nodes of a basic block BB to L.  */
387
388 static inline void
389 set_phi_nodes (basic_block bb, tree l)
390 {
391   tree phi;
392
393   bb_ann (bb)->phi_nodes = l;
394   for (phi = l; phi; phi = PHI_CHAIN (phi))
395     set_bb_for_stmt (phi, bb);
396 }
397
398 /* Return the phi index number for an edge.  */
399 static inline int
400 phi_arg_from_edge (tree phi, edge e)
401 {
402   int i;
403 #if defined ENABLE_CHECKING
404   if (!phi || TREE_CODE (phi) != PHI_NODE)
405     abort();
406 #endif
407
408   for (i = 0; i < PHI_NUM_ARGS (phi); i++)
409     if (PHI_ARG_EDGE (phi, i) == e)
410       return i;
411
412   return -1;
413 }
414
415 /* Mark VAR as used, so that it'll be preserved during rtl expansion.  */
416
417 static inline void
418 set_is_used (tree var)
419 {
420   var_ann_t ann = get_var_ann (var);
421   ann->used = 1;
422 }
423
424
425 /*  -----------------------------------------------------------------------  */
426
427 /* Return true if T is an executable statement.  */
428 static inline bool
429 is_exec_stmt (tree t)
430 {
431   return (t && !IS_EMPTY_STMT (t) && t != error_mark_node);
432 }
433
434
435 /* Return true if this stmt can be the target of a control transfer stmt such
436    as a goto.  */
437 static inline bool
438 is_label_stmt (tree t)
439 {
440   if (t)
441     switch (TREE_CODE (t))
442       {
443         case LABEL_DECL:
444         case LABEL_EXPR:
445         case CASE_LABEL_EXPR:
446           return true;
447         default:
448           return false;
449       }
450   return false;
451 }
452
453 /* Set the default definition for VAR to DEF.  */
454 static inline void
455 set_default_def (tree var, tree def)
456 {
457   var_ann_t ann = get_var_ann (var);
458   ann->default_def = def;
459 }
460
461 /* Return the default definition for variable VAR, or NULL if none
462    exists.  */
463 static inline tree
464 default_def (tree var)
465 {
466   var_ann_t ann = var_ann (var);
467   return ann ? ann->default_def : NULL_TREE;
468 }
469
470 /* PHI nodes should contain only ssa_names and invariants.  A test
471    for ssa_name is definitely simpler; don't let invalid contents
472    slip in in the meantime.  */
473
474 static inline bool
475 phi_ssa_name_p (tree t)
476 {
477   if (TREE_CODE (t) == SSA_NAME)
478     return true;
479 #ifdef ENABLE_CHECKING
480   if (!is_gimple_min_invariant (t))
481     abort ();
482 #endif
483   return false;
484 }
485
486 /*  -----------------------------------------------------------------------  */
487
488 /* Return a block_stmt_iterator that points to beginning of basic
489    block BB.  */
490 static inline block_stmt_iterator
491 bsi_start (basic_block bb)
492 {
493   block_stmt_iterator bsi;
494   if (bb->stmt_list)
495     bsi.tsi = tsi_start (bb->stmt_list);
496   else
497     {
498 #ifdef ENABLE_CHECKING
499       if (bb->index >= 0)
500         abort ();
501 #endif
502       bsi.tsi.ptr = NULL;
503       bsi.tsi.container = NULL;
504     }
505   bsi.bb = bb;
506   return bsi;
507 }
508
509 /* Return a block statement iterator that points to the last label in
510    block BB.  */
511
512 static inline block_stmt_iterator
513 bsi_after_labels (basic_block bb)
514 {
515   block_stmt_iterator bsi;
516   tree_stmt_iterator next;
517
518   bsi.bb = bb;
519
520   if (!bb->stmt_list)
521     {
522 #ifdef ENABLE_CHECKING
523       if (bb->index >= 0)
524         abort ();
525 #endif
526       bsi.tsi.ptr = NULL;
527       bsi.tsi.container = NULL;
528       return bsi;
529     }
530
531   bsi.tsi = tsi_start (bb->stmt_list);
532   if (tsi_end_p (bsi.tsi))
533     return bsi;
534
535   /* Ensure that there are some labels.  The rationale is that we want
536      to insert after the bsi that is returned, and these insertions should
537      be placed at the start of the basic block.  This would not work if the
538      first statement was not label; rather fail here than enable the user
539      proceed in wrong way.  */
540   if (TREE_CODE (tsi_stmt (bsi.tsi)) != LABEL_EXPR)
541     abort ();
542
543   next = bsi.tsi;
544   tsi_next (&next);
545
546   while (!tsi_end_p (next)
547          && TREE_CODE (tsi_stmt (next)) == LABEL_EXPR)
548     {
549       bsi.tsi = next;
550       tsi_next (&next);
551     }
552
553   return bsi;
554 }
555
556 /* Return a block statement iterator that points to the end of basic
557    block BB.  */
558 static inline block_stmt_iterator
559 bsi_last (basic_block bb)
560 {
561   block_stmt_iterator bsi;
562   if (bb->stmt_list)
563     bsi.tsi = tsi_last (bb->stmt_list);
564   else
565     {
566 #ifdef ENABLE_CHECKING
567       if (bb->index >= 0)
568         abort ();
569 #endif
570       bsi.tsi.ptr = NULL;
571       bsi.tsi.container = NULL;
572     }
573   bsi.bb = bb;
574   return bsi;
575 }
576
577 /* Return true if block statement iterator I has reached the end of
578    the basic block.  */
579 static inline bool
580 bsi_end_p (block_stmt_iterator i)
581 {
582   return tsi_end_p (i.tsi);
583 }
584
585 /* Modify block statement iterator I so that it is at the next
586    statement in the basic block.  */
587 static inline void
588 bsi_next (block_stmt_iterator *i)
589 {
590   tsi_next (&i->tsi);
591 }
592
593 /* Modify block statement iterator I so that it is at the previous
594    statement in the basic block.  */
595 static inline void
596 bsi_prev (block_stmt_iterator *i)
597 {
598   tsi_prev (&i->tsi);
599 }
600
601 /* Return the statement that block statement iterator I is currently
602    at.  */
603 static inline tree
604 bsi_stmt (block_stmt_iterator i)
605 {
606   return tsi_stmt (i.tsi);
607 }
608
609 /* Return a pointer to the statement that block statement iterator I
610    is currently at.  */
611 static inline tree *
612 bsi_stmt_ptr (block_stmt_iterator i)
613 {
614   return tsi_stmt_ptr (i.tsi);
615 }
616
617 /* Returns the loop of the statement STMT.  */
618
619 static inline struct loop *
620 loop_containing_stmt (tree stmt)
621 {
622   basic_block bb = bb_for_stmt (stmt);
623   if (!bb)
624     return NULL;
625
626   return bb->loop_father;
627 }
628
629 /* Return true if VAR is a clobbered by function calls.  */
630 static inline bool
631 is_call_clobbered (tree var)
632 {
633   return is_global_var (var)
634          || bitmap_bit_p (call_clobbered_vars, var_ann (var)->uid);
635 }
636
637 /* Mark variable VAR as being clobbered by function calls.  */
638 static inline void
639 mark_call_clobbered (tree var)
640 {
641   var_ann_t ann = var_ann (var);
642   /* If VAR is a memory tag, then we need to consider it a global
643      variable.  This is because the pointer that VAR represents has
644      been found to point to either an arbitrary location or to a known
645      location in global memory.  */
646   if (ann->mem_tag_kind != NOT_A_TAG)
647     DECL_EXTERNAL (var) = 1;
648   bitmap_set_bit (call_clobbered_vars, ann->uid);
649 }
650
651 /* Mark variable VAR as being non-addressable.  */
652 static inline void
653 mark_non_addressable (tree var)
654 {
655   bitmap_clear_bit (call_clobbered_vars, var_ann (var)->uid);
656   TREE_ADDRESSABLE (var) = 0;
657 }
658
659 /* Return the common annotation for T.  Return NULL if the annotation
660    doesn't already exist.  */
661 static inline tree_ann_t
662 tree_ann (tree t)
663 {
664   return t->common.ann;
665 }
666
667 /* Return a common annotation for T.  Create the constant annotation if it
668    doesn't exist.  */
669 static inline tree_ann_t
670 get_tree_ann (tree t)
671 {
672   tree_ann_t ann = tree_ann (t);
673   return (ann) ? ann : create_tree_ann (t);
674 }
675
676 #endif /* _TREE_FLOW_INLINE_H  */