OSDN Git Service

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