1 /* Inline functions for tree-flow.h
2 Copyright (C) 2001, 2003 Free Software Foundation, Inc.
3 Contributed by Diego Novillo <dnovillo@redhat.com>
5 This file is part of GCC.
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)
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.
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. */
22 #ifndef _TREE_FLOW_INLINE_H
23 #define _TREE_FLOW_INLINE_H 1
25 /* Inline functions for manipulating various data structures defined in
26 tree-flow.h. See tree-flow.h for documentation. */
28 static inline var_ann_t
31 #if defined ENABLE_CHECKING
35 && t->common.ann->common.type != VAR_ANN))
39 return (var_ann_t) t->common.ann;
42 static inline var_ann_t
43 get_var_ann (tree var)
45 var_ann_t ann = var_ann (var);
46 return (ann) ? ann : create_var_ann (var);
49 static inline stmt_ann_t
52 #if defined ENABLE_CHECKING
53 if (!is_gimple_stmt (t) && !is_essa_node (t))
57 return (stmt_ann_t) t->common.ann;
60 static inline stmt_ann_t
61 get_stmt_ann (tree stmt)
63 stmt_ann_t ann = stmt_ann (stmt);
64 return (ann) ? ann : create_stmt_ann (stmt);
68 static inline enum tree_ann_type
69 ann_type (tree_ann ann)
71 return ann->common.type;
74 static inline basic_block
77 stmt_ann_t ann = stmt_ann (t);
78 return ann ? ann->bb : NULL;
81 static inline varray_type
82 may_aliases (tree var)
84 var_ann_t ann = var_ann (var);
85 return ann ? ann->may_aliases : NULL;
89 has_hidden_use (tree var)
91 var_ann_t ann = var_ann (var);
92 return ann ? ann->has_hidden_use : false;
96 set_has_hidden_use (tree var)
98 var_ann_t ann = var_ann (var);
100 ann = create_var_ann (var);
101 ann->has_hidden_use = 1;
105 get_lineno (tree expr)
107 if (expr == NULL_TREE)
110 if (TREE_CODE (expr) == COMPOUND_EXPR)
111 expr = TREE_OPERAND (expr, 0);
113 if (! EXPR_LOCUS (expr))
116 return EXPR_LINENO (expr);
119 static inline const char *
120 get_filename (tree expr)
122 if (expr == NULL_TREE)
125 if (TREE_CODE (expr) == COMPOUND_EXPR)
126 expr = TREE_OPERAND (expr, 0);
128 if (EXPR_LOCUS (expr) && EXPR_FILENAME (expr))
129 return EXPR_FILENAME (expr);
137 stmt_ann_t ann = stmt_ann (t);
139 ann = create_stmt_ann (t);
144 unmodify_stmt (tree t)
146 stmt_ann_t ann = stmt_ann (t);
148 ann = create_stmt_ann (t);
153 stmt_modified_p (tree t)
155 stmt_ann_t ann = stmt_ann (t);
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
160 return ann ? ann->modified : true;
163 static inline def_optype
164 get_def_ops (stmt_ann_t ann)
166 return ann ? ann->def_ops : NULL;
169 static inline use_optype
170 get_use_ops (stmt_ann_t ann)
172 return ann ? ann->use_ops : NULL;
175 static inline vdef_optype
176 get_vdef_ops (stmt_ann_t ann)
178 return ann ? ann->vdef_ops : NULL;
181 static inline vuse_optype
182 get_vuse_ops (stmt_ann_t ann)
184 return ann ? ann->vuse_ops : NULL;
188 get_use_op_ptr (use_optype uses, unsigned int index)
190 #ifdef ENABLE_CHECKING
191 if (index >= uses->num_uses)
194 return uses->uses[index];
198 get_def_op_ptr (def_optype defs, unsigned int index)
200 #ifdef ENABLE_CHECKING
201 if (index >= defs->num_defs)
204 return defs->defs[index];
208 get_vdef_result_ptr(vdef_optype vdefs, unsigned int index)
210 #ifdef ENABLE_CHECKING
211 if (index >= vdefs->num_vdefs)
214 return &(vdefs->vdefs[index * 2]);
218 get_vdef_op_ptr(vdef_optype vdefs, unsigned int index)
220 #ifdef ENABLE_CHECKING
221 if (index >= vdefs->num_vdefs)
224 return &(vdefs->vdefs[index * 2 + 1]);
228 get_vuse_op_ptr(vuse_optype vuses, unsigned int index)
230 #ifdef ENABLE_CHECKING
231 if (index >= vuses->num_vuses)
234 return &(vuses->vuses[index]);
238 start_ssa_stmt_operands (tree stmt ATTRIBUTE_UNUSED)
240 #ifdef ENABLE_CHECKING
241 verify_start_operands (stmt);
246 addresses_taken (tree stmt)
248 stmt_ann_t ann = stmt_ann (stmt);
249 return ann ? ann->addresses_taken : NULL;
253 get_immediate_uses (tree stmt)
255 stmt_ann_t ann = stmt_ann (stmt);
256 return ann ? ann->df : NULL;
260 num_immediate_uses (dataflow_t df)
267 imm = df->immediate_uses;
269 return df->uses[1] ? 2 : 1;
271 return VARRAY_ACTIVE_SIZE (imm) + 2;
275 immediate_use (dataflow_t df, int num)
280 #ifdef ENABLE_CHECKING
281 if (num >= num_immediate_uses (df))
285 return df->uses[num];
286 return VARRAY_TREE (df->immediate_uses, num - 2);
289 static inline bb_ann_t
290 bb_ann (basic_block bb)
292 return (bb_ann_t)bb->tree_annotations;
296 phi_nodes (basic_block bb)
300 return bb_ann (bb)->phi_nodes;
303 /* Set list of phi nodes of a basic block BB to L. */
306 set_phi_nodes (basic_block bb, tree l)
310 bb_ann (bb)->phi_nodes = l;
311 for (phi = l; phi; phi = TREE_CHAIN (phi))
312 set_bb_for_stmt (phi, bb);
315 /* Return the phi index number for an edge. */
317 phi_arg_from_edge (tree phi, edge e)
320 #if defined ENABLE_CHECKING
321 if (!phi || TREE_CODE (phi) != PHI_NODE)
325 for (i = 0; i < PHI_NUM_ARGS (phi); i++)
326 if (PHI_ARG_EDGE (phi, i) == e)
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)
339 i = phi_arg_from_edge (phi, e);
341 return &(PHI_ARG_ELT (phi, i));
343 return (struct phi_arg_d *)NULL;
346 /* ----------------------------------------------------------------------- */
349 is_exec_stmt (tree t)
351 return (t && !IS_EMPTY_STMT (t) && t != error_mark_node);
355 /* Return true if this stmt can be the target of a control transfer stmt such
358 is_label_stmt (tree t)
361 switch (TREE_CODE (t))
365 case CASE_LABEL_EXPR:
374 may_propagate_copy (tree dest, tree orig)
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.
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.
384 This was showing up in libjava/java/util/zip/ZipFile.java with code
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;
393 is = T.660; <-- This ought to be type-casted
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:
400 struct _ffename_space *n;
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
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)))
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)
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))
427 /* If both operands are SSA_NAMEs referring to virtual operands, then
428 we can always propagate. */
429 if (TREE_CODE (orig) == SSA_NAME)
431 if (!is_gimple_reg (orig))
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))
442 /* We have a "copy" from something like a constant into a virtual
443 operand. Reject these. */
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)));
454 set_default_def (tree var, tree def)
456 var_ann_t ann = var_ann (var);
458 ann = create_var_ann (var);
459 ann->default_def = def;
463 default_def (tree var)
465 var_ann_t ann = var_ann (var);
466 return ann ? ann->default_def : NULL_TREE;
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. */
474 phi_ssa_name_p (tree t)
476 if (TREE_CODE (t) == SSA_NAME)
478 #ifdef ENABLE_CHECKING
479 if (!is_gimple_min_invariant (t))
485 /* ----------------------------------------------------------------------- */
487 static inline block_stmt_iterator
488 bsi_start (basic_block bb)
490 block_stmt_iterator bsi;
492 bsi.tsi = tsi_start (bb->stmt_list);
495 #ifdef ENABLE_CHECKING
500 bsi.tsi.container = NULL;
506 static inline block_stmt_iterator
507 bsi_last (basic_block bb)
509 block_stmt_iterator bsi;
511 bsi.tsi = tsi_last (bb->stmt_list);
514 #ifdef ENABLE_CHECKING
519 bsi.tsi.container = NULL;
526 bsi_end_p (block_stmt_iterator i)
528 return tsi_end_p (i.tsi);
532 bsi_next (block_stmt_iterator *i)
538 bsi_prev (block_stmt_iterator *i)
544 bsi_stmt (block_stmt_iterator i)
546 return tsi_stmt (i.tsi);
550 bsi_stmt_ptr (block_stmt_iterator i)
552 return tsi_stmt_ptr (i.tsi);
556 may_be_aliased (tree var)
558 return (TREE_ADDRESSABLE (var)
559 || decl_function_context (var) != current_function_decl);
563 is_call_clobbered (tree var)
565 return needs_to_live_in_memory (var)
566 || bitmap_bit_p (call_clobbered_vars, var_ann (var)->uid);
570 mark_call_clobbered (tree var)
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);
579 mark_non_addressable (tree var)
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;
586 #endif /* _TREE_FLOW_INLINE_H */