OSDN Git Service

Move SSA_NAME annotations into tree_ssa_name.
[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 vdef_optype
176 get_vdef_ops (stmt_ann_t ann)
177 {
178   return ann ? ann->vdef_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 tree *
188 get_use_op_ptr (use_optype uses, unsigned int index)
189 {
190 #ifdef ENABLE_CHECKING
191   if (index >= uses->num_uses)
192     abort();
193 #endif
194   return uses->uses[index];
195 }
196
197 static inline tree *
198 get_def_op_ptr (def_optype defs, unsigned int index)
199 {
200 #ifdef ENABLE_CHECKING
201   if (index >= defs->num_defs)
202     abort();
203 #endif
204   return defs->defs[index];
205 }
206
207 static inline tree *
208 get_vdef_result_ptr(vdef_optype vdefs, unsigned int index)
209 {
210 #ifdef ENABLE_CHECKING
211   if (index >= vdefs->num_vdefs)
212     abort();
213 #endif
214   return &(vdefs->vdefs[index * 2]);
215 }
216
217 static inline tree *
218 get_vdef_op_ptr(vdef_optype vdefs, unsigned int index)
219 {
220 #ifdef ENABLE_CHECKING
221   if (index >= vdefs->num_vdefs)
222     abort();
223 #endif
224   return &(vdefs->vdefs[index * 2 + 1]);
225 }
226
227 static inline tree *
228 get_vuse_op_ptr(vuse_optype vuses, unsigned int index)
229 {
230 #ifdef ENABLE_CHECKING
231   if (index >= vuses->num_vuses)
232     abort();
233 #endif
234   return &(vuses->vuses[index]);
235 }
236
237 static inline void
238 start_ssa_stmt_operands (tree stmt ATTRIBUTE_UNUSED)
239 {
240 #ifdef ENABLE_CHECKING
241   verify_start_operands (stmt);
242 #endif
243 }
244
245 static inline bitmap
246 addresses_taken (tree stmt)
247 {
248   stmt_ann_t ann = stmt_ann (stmt);
249   return ann ? ann->addresses_taken : NULL;
250 }
251
252 static dataflow_t
253 get_immediate_uses (tree stmt)
254 {
255   stmt_ann_t ann = stmt_ann (stmt);
256   return ann ? ann->df : NULL;
257 }
258
259 static inline int
260 num_immediate_uses (dataflow_t df)
261 {
262   varray_type imm;
263
264   if (!df)
265     return 0;
266
267   imm = df->immediate_uses;
268   if (!imm)
269     return df->uses[1] ? 2 : 1;
270
271   return VARRAY_ACTIVE_SIZE (imm) + 2;
272 }
273
274 static inline tree
275 immediate_use (dataflow_t df, int num)
276 {
277   if (!df)
278     return NULL_TREE;
279
280 #ifdef ENABLE_CHECKING
281   if (num >= num_immediate_uses (df))
282     abort ();
283 #endif
284   if (num < 2)
285     return df->uses[num];
286   return VARRAY_TREE (df->immediate_uses, num - 2);
287 }
288
289 static inline bb_ann_t
290 bb_ann (basic_block bb)
291 {
292   return (bb_ann_t)bb->tree_annotations;
293 }
294
295 static inline tree
296 phi_nodes (basic_block bb)
297 {
298   if (bb->index < 0)
299     return NULL;
300   return bb_ann (bb)->phi_nodes;
301 }
302
303 /* Set list of phi nodes of a basic block BB to L.  */
304
305 static inline void
306 set_phi_nodes (basic_block bb, tree l)
307 {
308   tree phi;
309
310   bb_ann (bb)->phi_nodes = l;
311   for (phi = l; phi; phi = TREE_CHAIN (phi))
312     set_bb_for_stmt (phi, bb);
313 }
314
315 /* Return the phi index number for an edge.  */
316 static inline int
317 phi_arg_from_edge (tree phi, edge e)
318 {
319   int i;
320 #if defined ENABLE_CHECKING
321   if (!phi || TREE_CODE (phi) != PHI_NODE)
322     abort();
323 #endif
324
325   for (i = 0; i < PHI_NUM_ARGS (phi); i++)
326     if (PHI_ARG_EDGE (phi, i) == e)
327       return i;
328
329   return -1;
330 }
331
332
333 /* Return the phi argument number for an edge.  */
334 static inline struct phi_arg_d *
335 phi_element_for_edge (tree phi, edge e)
336 {
337   int i;
338
339   i = phi_arg_from_edge (phi, e);
340   if (i != -1)
341     return &(PHI_ARG_ELT (phi, i));
342   else
343     return (struct phi_arg_d *)NULL;
344 }
345
346 /*  -----------------------------------------------------------------------  */
347
348 static inline bool
349 is_exec_stmt (tree t)
350 {
351   return (t && !IS_EMPTY_STMT (t) && t != error_mark_node);
352 }
353
354
355 /* Return true if this stmt can be the target of a control transfer stmt such
356    as a goto.  */
357 static inline bool
358 is_label_stmt (tree t)
359 {
360   if (t)
361     switch (TREE_CODE (t))
362       {
363         case LABEL_DECL:
364         case LABEL_EXPR:
365         case CASE_LABEL_EXPR:
366           return true;
367         default:
368           return false;
369       }
370   return false;
371 }
372
373 static inline bool
374 may_propagate_copy (tree dest, tree orig)
375 {
376   /* FIXME.  GIMPLE is allowing pointer assignments and comparisons of
377      pointers that have different alias sets.  This means that these
378      pointers will have different memory tags associated to them.
379      
380      If we allow copy propagation in these cases, statements de-referencing
381      the new pointer will now have a reference to a different memory tag
382      with potentially incorrect SSA information.
383
384      This was showing up in libjava/java/util/zip/ZipFile.java with code
385      like:
386
387         struct java.io.BufferedInputStream *T.660;
388         struct java.io.BufferedInputStream *T.647;
389         struct java.io.InputStream *is;
390         struct java.io.InputStream *is.662;
391         [ ... ]
392         T.660 = T.647;
393         is = T.660;     <-- This ought to be type-casted
394         is.662 = is;
395
396      Also, f/name.c exposed a similar problem with a COND_EXPR predicate
397      that was causing DOM to generate and equivalence with two pointers of
398      alias-incompatible types:
399
400         struct _ffename_space *n;
401         struct _ffename *ns;
402         [ ... ]
403         if (n == ns)
404           goto lab;
405         ...
406         lab:
407         return n;
408
409      I think that GIMPLE should emit the appropriate type-casts.  For the
410      time being, blocking copy-propagation in these cases is the safe thing
411      to do.  */
412   if (TREE_CODE (dest) == SSA_NAME
413       && TREE_CODE (orig) == SSA_NAME
414       && POINTER_TYPE_P (TREE_TYPE (dest))
415       && POINTER_TYPE_P (TREE_TYPE (orig)))
416     {
417       tree mt_dest = var_ann (SSA_NAME_VAR (dest))->type_mem_tag;
418       tree mt_orig = var_ann (SSA_NAME_VAR (orig))->type_mem_tag;
419       if (mt_dest && mt_orig && mt_dest != mt_orig)
420         return false;
421     }
422
423   /* If the destination is a SSA_NAME for a virtual operand, then we have
424      some special cases to handle.  */
425   if (TREE_CODE (dest) == SSA_NAME && !is_gimple_reg (dest))
426     {
427       /* If both operands are SSA_NAMEs referring to virtual operands, then
428          we can always propagate.  */
429       if (TREE_CODE (orig) == SSA_NAME)
430         {
431           if (!is_gimple_reg (orig))
432             return true;
433
434 #ifdef ENABLE_CHECKING
435           /* If we have one real and one virtual operand, then something has
436              gone terribly wrong.  */
437           if (is_gimple_reg (orig))
438             abort ();
439 #endif
440         }
441
442       /* We have a "copy" from something like a constant into a virtual
443          operand.  Reject these.  */
444       return false;
445     }
446
447   return (!SSA_NAME_OCCURS_IN_ABNORMAL_PHI (dest)
448           && (TREE_CODE (orig) != SSA_NAME
449               || !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (orig))
450           && !DECL_HARD_REGISTER (SSA_NAME_VAR (dest)));
451 }
452
453 static inline void
454 set_default_def (tree var, tree def)
455 {
456   var_ann_t ann = var_ann (var);
457   if (ann == NULL)
458     ann = create_var_ann (var);
459   ann->default_def = def;
460 }
461
462 static inline tree
463 default_def (tree var)
464 {
465   var_ann_t ann = var_ann (var);
466   return ann ? ann->default_def : NULL_TREE;
467 }
468
469 /* PHI nodes should contain only ssa_names and invariants.  A test
470    for ssa_name is definitely simpler; don't let invalid contents
471    slip in in the meantime.  */
472
473 static inline bool
474 phi_ssa_name_p (tree t)
475 {
476   if (TREE_CODE (t) == SSA_NAME)
477     return true;
478 #ifdef ENABLE_CHECKING
479   if (!is_gimple_min_invariant (t))
480     abort ();
481 #endif
482   return false;
483 }
484
485 /*  -----------------------------------------------------------------------  */
486
487 static inline block_stmt_iterator
488 bsi_start (basic_block bb)
489 {
490   block_stmt_iterator bsi;
491   if (bb->stmt_list)
492     bsi.tsi = tsi_start (bb->stmt_list);
493   else
494     {
495 #ifdef ENABLE_CHECKING
496       if (bb->index >= 0)
497         abort ();
498 #endif
499       bsi.tsi.ptr = NULL;
500       bsi.tsi.container = NULL;
501     }
502   bsi.bb = bb;
503   return bsi;
504 }
505
506 static inline block_stmt_iterator
507 bsi_last (basic_block bb)
508 {
509   block_stmt_iterator bsi;
510   if (bb->stmt_list)
511     bsi.tsi = tsi_last (bb->stmt_list);
512   else
513     {
514 #ifdef ENABLE_CHECKING
515       if (bb->index >= 0)
516         abort ();
517 #endif
518       bsi.tsi.ptr = NULL;
519       bsi.tsi.container = NULL;
520     }
521   bsi.bb = bb;
522   return bsi;
523 }
524
525 static inline bool
526 bsi_end_p (block_stmt_iterator i)
527 {
528   return tsi_end_p (i.tsi);
529 }
530
531 static inline void
532 bsi_next (block_stmt_iterator *i)
533 {
534   tsi_next (&i->tsi);
535 }
536
537 static inline void
538 bsi_prev (block_stmt_iterator *i)
539 {
540   tsi_prev (&i->tsi);
541 }
542
543 static inline tree
544 bsi_stmt (block_stmt_iterator i)
545 {
546   return tsi_stmt (i.tsi);
547 }
548
549 static inline tree *
550 bsi_stmt_ptr (block_stmt_iterator i)
551 {
552   return tsi_stmt_ptr (i.tsi);
553 }
554
555 static inline bool
556 may_be_aliased (tree var)
557 {
558   return (TREE_ADDRESSABLE (var)
559           || decl_function_context (var) != current_function_decl);
560 }
561
562 static inline bool
563 is_call_clobbered (tree var)
564 {
565   return needs_to_live_in_memory (var)
566          || bitmap_bit_p (call_clobbered_vars, var_ann (var)->uid);
567 }
568
569 static inline void
570 mark_call_clobbered (tree var)
571 {
572   var_ann_t ann = var_ann (var);
573   /* Call-clobbered variables need to live in memory.  */
574   DECL_NEEDS_TO_LIVE_IN_MEMORY_INTERNAL (var) = 1;
575   bitmap_set_bit (call_clobbered_vars, ann->uid);
576 }
577
578 static inline void
579 mark_non_addressable (tree var)
580 {
581   bitmap_clear_bit (call_clobbered_vars, var_ann (var)->uid);
582   DECL_NEEDS_TO_LIVE_IN_MEMORY_INTERNAL (var) = 0;
583   TREE_ADDRESSABLE (var) = 0;
584 }
585
586 #endif /* _TREE_FLOW_INLINE_H  */