OSDN Git Service

* config/m68k/m68k.h: Remove comments copied over from tm.texi.
[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 static inline var_ann_t
29 var_ann (tree t)
30 {
31 #if defined ENABLE_CHECKING
32   if (t == NULL_TREE
33       || !DECL_P (t)
34       || (t->common.ann
35           && t->common.ann->common.type != VAR_ANN))
36     abort ();
37 #endif
38
39   return (var_ann_t) t->common.ann;
40 }
41
42 static inline var_ann_t
43 get_var_ann (tree var)
44 {
45   var_ann_t ann = var_ann (var);
46   return (ann) ? ann : create_var_ann (var);
47 }
48
49 static inline stmt_ann_t
50 stmt_ann (tree t)
51 {
52 #if defined ENABLE_CHECKING
53   if (!is_gimple_stmt (t) && !is_essa_node (t))
54     abort ();
55 #endif
56
57   return (stmt_ann_t) t->common.ann;
58 }
59
60 static inline stmt_ann_t
61 get_stmt_ann (tree stmt)
62 {
63   stmt_ann_t ann = stmt_ann (stmt);
64   return (ann) ? ann : create_stmt_ann (stmt);
65 }
66
67 static inline ssa_name_ann_t
68 ssa_name_ann (tree t)
69 {
70 #if defined ENABLE_CHECKING
71   if (t == NULL_TREE
72       || TREE_CODE (t) != SSA_NAME
73       || (t->common.ann
74           && t->common.ann->common.type != SSA_NAME_ANN))
75     abort ();
76 #endif
77
78   return (ssa_name_ann_t) t->common.ann;
79 }
80
81 static inline ssa_name_ann_t
82 get_ssa_name_ann (tree var)
83 {
84   ssa_name_ann_t ann = ssa_name_ann (var);
85   return (ann) ? ann : create_ssa_name_ann (var);
86 }
87
88
89 static inline enum tree_ann_type
90 ann_type (tree_ann ann)
91 {
92   return ann->common.type;
93 }
94
95 static inline basic_block
96 bb_for_stmt (tree t)
97 {
98   stmt_ann_t ann = stmt_ann (t);
99   return ann ? ann->bb : NULL;
100 }
101
102 static inline varray_type
103 may_aliases (tree var)
104 {
105   var_ann_t ann = var_ann (var);
106   return ann ? ann->may_aliases : NULL;
107 }
108
109 static inline bool
110 has_hidden_use (tree var)
111 {
112   var_ann_t ann = var_ann (var);
113   return ann ? ann->has_hidden_use : false;
114 }
115
116 static inline void
117 set_has_hidden_use (tree var)
118 {
119   var_ann_t ann = var_ann (var);
120   if (ann == NULL)
121     ann = create_var_ann (var);
122   ann->has_hidden_use = 1;
123 }
124
125 static inline int
126 get_lineno (tree expr)
127 {
128   if (expr == NULL_TREE)
129     return -1;
130
131   if (TREE_CODE (expr) == COMPOUND_EXPR)
132     expr = TREE_OPERAND (expr, 0);
133
134   if (! EXPR_LOCUS (expr))
135     return -1;
136
137   return EXPR_LINENO (expr);
138 }
139
140 static inline const char *
141 get_filename (tree expr)
142 {
143   if (expr == NULL_TREE)
144     return "???";
145
146   if (TREE_CODE (expr) == COMPOUND_EXPR)
147     expr = TREE_OPERAND (expr, 0);
148
149   if (EXPR_LOCUS (expr) && EXPR_FILENAME (expr))
150     return EXPR_FILENAME (expr);
151   else
152     return "???";
153 }
154
155 static inline void
156 modify_stmt (tree t)
157 {
158   stmt_ann_t ann = stmt_ann (t);
159   if (ann == NULL)
160     ann = create_stmt_ann (t);
161   ann->modified = 1;
162 }
163
164 static inline void
165 unmodify_stmt (tree t)
166 {
167   stmt_ann_t ann = stmt_ann (t);
168   if (ann == NULL)
169     ann = create_stmt_ann (t);
170   ann->modified = 0;
171 }
172
173 static inline bool
174 stmt_modified_p (tree t)
175 {
176   stmt_ann_t ann = stmt_ann (t);
177
178   /* Note that if the statement doesn't yet have an annotation, we consider it
179      modified.  This will force the next call to get_stmt_operands to scan the
180      statement.  */
181   return ann ? ann->modified : true;
182 }
183
184 static inline def_optype
185 get_def_ops (stmt_ann_t ann)
186 {
187   return ann ? ann->def_ops : NULL;
188 }
189
190 static inline use_optype
191 get_use_ops (stmt_ann_t ann)
192 {
193   return ann ? ann->use_ops : NULL;
194 }
195
196 static inline vdef_optype
197 get_vdef_ops (stmt_ann_t ann)
198 {
199   return ann ? ann->vdef_ops : NULL;
200 }
201
202 static inline vuse_optype
203 get_vuse_ops (stmt_ann_t ann)
204 {
205   return ann ? ann->vuse_ops : NULL;
206 }
207
208 static inline tree *
209 get_use_op_ptr (use_optype uses, unsigned int index)
210 {
211 #ifdef ENABLE_CHECKING
212   if (index >= uses->num_uses)
213     abort();
214 #endif
215   return uses->uses[index];
216 }
217
218 static inline tree *
219 get_def_op_ptr (def_optype defs, unsigned int index)
220 {
221 #ifdef ENABLE_CHECKING
222   if (index >= defs->num_defs)
223     abort();
224 #endif
225   return defs->defs[index];
226 }
227
228 static inline tree *
229 get_vdef_result_ptr(vdef_optype vdefs, unsigned int index)
230 {
231 #ifdef ENABLE_CHECKING
232   if (index >= vdefs->num_vdefs)
233     abort();
234 #endif
235   return &(vdefs->vdefs[index * 2]);
236 }
237
238 static inline tree *
239 get_vdef_op_ptr(vdef_optype vdefs, unsigned int index)
240 {
241 #ifdef ENABLE_CHECKING
242   if (index >= vdefs->num_vdefs)
243     abort();
244 #endif
245   return &(vdefs->vdefs[index * 2 + 1]);
246 }
247
248 static inline tree *
249 get_vuse_op_ptr(vuse_optype vuses, unsigned int index)
250 {
251 #ifdef ENABLE_CHECKING
252   if (index >= vuses->num_vuses)
253     abort();
254 #endif
255   return &(vuses->vuses[index]);
256 }
257
258 static inline void
259 start_ssa_stmt_operands (tree stmt ATTRIBUTE_UNUSED)
260 {
261 #ifdef ENABLE_CHECKING
262   verify_start_operands (stmt);
263 #endif
264 }
265
266 static inline bitmap
267 addresses_taken (tree stmt)
268 {
269   stmt_ann_t ann = stmt_ann (stmt);
270   return ann ? ann->addresses_taken : NULL;
271 }
272
273 static dataflow_t
274 get_immediate_uses (tree stmt)
275 {
276   stmt_ann_t ann = stmt_ann (stmt);
277   return ann ? ann->df : NULL;
278 }
279
280 static inline int
281 num_immediate_uses (dataflow_t df)
282 {
283   varray_type imm;
284
285   if (!df)
286     return 0;
287
288   imm = df->immediate_uses;
289   if (!imm)
290     return df->uses[1] ? 2 : 1;
291
292   return VARRAY_ACTIVE_SIZE (imm) + 2;
293 }
294
295 static inline tree
296 immediate_use (dataflow_t df, int num)
297 {
298   if (!df)
299     return NULL_TREE;
300
301 #ifdef ENABLE_CHECKING
302   if (num >= num_immediate_uses (df))
303     abort ();
304 #endif
305   if (num < 2)
306     return df->uses[num];
307   return VARRAY_TREE (df->immediate_uses, num - 2);
308 }
309
310 static inline bb_ann_t
311 bb_ann (basic_block bb)
312 {
313   return (bb_ann_t)bb->tree_annotations;
314 }
315
316 static inline tree
317 phi_nodes (basic_block bb)
318 {
319   if (bb->index < 0)
320     return NULL;
321   return bb_ann (bb)->phi_nodes;
322 }
323
324 /* Set list of phi nodes of a basic block BB to L.  */
325
326 static inline void
327 set_phi_nodes (basic_block bb, tree l)
328 {
329   tree phi;
330
331   bb_ann (bb)->phi_nodes = l;
332   for (phi = l; phi; phi = TREE_CHAIN (phi))
333     set_bb_for_stmt (phi, bb);
334 }
335
336 /* Return the phi index number for an edge.  */
337 static inline int
338 phi_arg_from_edge (tree phi, edge e)
339 {
340   int i;
341 #if defined ENABLE_CHECKING
342   if (!phi || TREE_CODE (phi) != PHI_NODE)
343     abort();
344 #endif
345
346   for (i = 0; i < PHI_NUM_ARGS (phi); i++)
347     if (PHI_ARG_EDGE (phi, i) == e)
348       return i;
349
350   return -1;
351 }
352
353
354 /* Return the phi argument number for an edge.  */
355 static inline struct phi_arg_d *
356 phi_element_for_edge (tree phi, edge e)
357 {
358   int i;
359
360   i = phi_arg_from_edge (phi, e);
361   if (i != -1)
362     return &(PHI_ARG_ELT (phi, i));
363   else
364     return (struct phi_arg_d *)NULL;
365 }
366
367 /*  -----------------------------------------------------------------------  */
368
369 static inline bool
370 is_exec_stmt (tree t)
371 {
372   return (t && !IS_EMPTY_STMT (t) && t != error_mark_node);
373 }
374
375
376 /* Return true if this stmt can be the target of a control transfer stmt such
377    as a goto.  */
378 static inline bool
379 is_label_stmt (tree t)
380 {
381   if (t)
382     switch (TREE_CODE (t))
383       {
384         case LABEL_DECL:
385         case LABEL_EXPR:
386         case CASE_LABEL_EXPR:
387           return true;
388         default:
389           return false;
390       }
391   return false;
392 }
393
394 static inline bool
395 may_propagate_copy (tree dest, tree orig)
396 {
397   /* FIXME.  GIMPLE is allowing pointer assignments and comparisons of
398      pointers that have different alias sets.  This means that these
399      pointers will have different memory tags associated to them.
400      
401      If we allow copy propagation in these cases, statements de-referencing
402      the new pointer will now have a reference to a different memory tag
403      with potentially incorrect SSA information.
404
405      This was showing up in libjava/java/util/zip/ZipFile.java with code
406      like:
407
408         struct java.io.BufferedInputStream *T.660;
409         struct java.io.BufferedInputStream *T.647;
410         struct java.io.InputStream *is;
411         struct java.io.InputStream *is.662;
412         [ ... ]
413         T.660 = T.647;
414         is = T.660;     <-- This ought to be type-casted
415         is.662 = is;
416
417      Also, f/name.c exposed a similar problem with a COND_EXPR predicate
418      that was causing DOM to generate and equivalence with two pointers of
419      alias-incompatible types:
420
421         struct _ffename_space *n;
422         struct _ffename *ns;
423         [ ... ]
424         if (n == ns)
425           goto lab;
426         ...
427         lab:
428         return n;
429
430      I think that GIMPLE should emit the appropriate type-casts.  For the
431      time being, blocking copy-propagation in these cases is the safe thing
432      to do.  */
433   if (TREE_CODE (dest) == SSA_NAME
434       && TREE_CODE (orig) == SSA_NAME
435       && POINTER_TYPE_P (TREE_TYPE (dest))
436       && POINTER_TYPE_P (TREE_TYPE (orig)))
437     {
438       tree mt_dest = var_ann (SSA_NAME_VAR (dest))->type_mem_tag;
439       tree mt_orig = var_ann (SSA_NAME_VAR (orig))->type_mem_tag;
440       if (mt_dest && mt_orig && mt_dest != mt_orig)
441         return false;
442     }
443
444   /* If the destination is a SSA_NAME for a virtual operand, then we have
445      some special cases to handle.  */
446   if (TREE_CODE (dest) == SSA_NAME && !is_gimple_reg (dest))
447     {
448       /* If both operands are SSA_NAMEs referring to virtual operands, then
449          we can always propagate.  */
450       if (TREE_CODE (orig) == SSA_NAME)
451         {
452           if (!is_gimple_reg (orig))
453             return true;
454
455 #ifdef ENABLE_CHECKING
456           /* If we have one real and one virtual operand, then something has
457              gone terribly wrong.  */
458           if (is_gimple_reg (orig))
459             abort ();
460 #endif
461         }
462
463       /* We have a "copy" from something like a constant into a virtual
464          operand.  Reject these.  */
465       return false;
466     }
467
468   return (!SSA_NAME_OCCURS_IN_ABNORMAL_PHI (dest)
469           && (TREE_CODE (orig) != SSA_NAME
470               || !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (orig))
471           && !DECL_HARD_REGISTER (SSA_NAME_VAR (dest)));
472 }
473
474 static inline void
475 set_default_def (tree var, tree def)
476 {
477   var_ann_t ann = var_ann (var);
478   if (ann == NULL)
479     ann = create_var_ann (var);
480   ann->default_def = def;
481 }
482
483 static inline tree
484 default_def (tree var)
485 {
486   var_ann_t ann = var_ann (var);
487   return ann ? ann->default_def : NULL_TREE;
488 }
489
490 /* PHI nodes should contain only ssa_names and invariants.  A test
491    for ssa_name is definitely simpler; don't let invalid contents
492    slip in in the meantime.  */
493
494 static inline bool
495 phi_ssa_name_p (tree t)
496 {
497   if (TREE_CODE (t) == SSA_NAME)
498     return true;
499 #ifdef ENABLE_CHECKING
500   if (!is_gimple_min_invariant (t))
501     abort ();
502 #endif
503   return false;
504 }
505
506 /*  -----------------------------------------------------------------------  */
507
508 static inline block_stmt_iterator
509 bsi_start (basic_block bb)
510 {
511   block_stmt_iterator bsi;
512   if (bb->stmt_list)
513     bsi.tsi = tsi_start (bb->stmt_list);
514   else
515     {
516 #ifdef ENABLE_CHECKING
517       if (bb->index >= 0)
518         abort ();
519 #endif
520       bsi.tsi.ptr = NULL;
521       bsi.tsi.container = NULL;
522     }
523   bsi.bb = bb;
524   return bsi;
525 }
526
527 static inline block_stmt_iterator
528 bsi_last (basic_block bb)
529 {
530   block_stmt_iterator bsi;
531   if (bb->stmt_list)
532     bsi.tsi = tsi_last (bb->stmt_list);
533   else
534     {
535 #ifdef ENABLE_CHECKING
536       if (bb->index >= 0)
537         abort ();
538 #endif
539       bsi.tsi.ptr = NULL;
540       bsi.tsi.container = NULL;
541     }
542   bsi.bb = bb;
543   return bsi;
544 }
545
546 static inline bool
547 bsi_end_p (block_stmt_iterator i)
548 {
549   return tsi_end_p (i.tsi);
550 }
551
552 static inline void
553 bsi_next (block_stmt_iterator *i)
554 {
555   tsi_next (&i->tsi);
556 }
557
558 static inline void
559 bsi_prev (block_stmt_iterator *i)
560 {
561   tsi_prev (&i->tsi);
562 }
563
564 static inline tree
565 bsi_stmt (block_stmt_iterator i)
566 {
567   return tsi_stmt (i.tsi);
568 }
569
570 static inline tree *
571 bsi_stmt_ptr (block_stmt_iterator i)
572 {
573   return tsi_stmt_ptr (i.tsi);
574 }
575
576 static inline bool
577 may_be_aliased (tree var)
578 {
579   return (TREE_ADDRESSABLE (var)
580           || decl_function_context (var) != current_function_decl);
581 }
582
583 static inline bool
584 is_call_clobbered (tree var)
585 {
586   return needs_to_live_in_memory (var)
587          || bitmap_bit_p (call_clobbered_vars, var_ann (var)->uid);
588 }
589
590 static inline void
591 mark_call_clobbered (tree var)
592 {
593   var_ann_t ann = var_ann (var);
594   /* Call-clobbered variables need to live in memory.  */
595   DECL_NEEDS_TO_LIVE_IN_MEMORY_INTERNAL (var) = 1;
596   bitmap_set_bit (call_clobbered_vars, ann->uid);
597 }
598
599 static inline void
600 mark_non_addressable (tree var)
601 {
602   bitmap_clear_bit (call_clobbered_vars, var_ann (var)->uid);
603   DECL_NEEDS_TO_LIVE_IN_MEMORY_INTERNAL (var) = 0;
604   TREE_ADDRESSABLE (var) = 0;
605 }
606
607 #endif /* _TREE_FLOW_INLINE_H  */