tree-flow-inline.h [plain text]
#ifndef _TREE_FLOW_INLINE_H
#define _TREE_FLOW_INLINE_H 1
static inline var_ann_t
var_ann (tree t)
{
#if defined ENABLE_CHECKING
if (t == NULL_TREE
|| !DECL_P (t)
|| (t->common.ann
&& t->common.ann->common.type != VAR_ANN))
abort ();
#endif
return (var_ann_t) t->common.ann;
}
static inline var_ann_t
get_var_ann (tree var)
{
var_ann_t ann = var_ann (var);
return (ann) ? ann : create_var_ann (var);
}
static inline stmt_ann_t
stmt_ann (tree t)
{
#if defined ENABLE_CHECKING
if (!is_gimple_stmt (t) && !is_essa_node (t))
abort ();
#endif
return (stmt_ann_t) t->common.ann;
}
static inline stmt_ann_t
get_stmt_ann (tree stmt)
{
stmt_ann_t ann = stmt_ann (stmt);
return (ann) ? ann : create_stmt_ann (stmt);
}
static inline ssa_name_ann_t
ssa_name_ann (tree t)
{
#if defined ENABLE_CHECKING
if (t == NULL_TREE
|| TREE_CODE (t) != SSA_NAME
|| (t->common.ann
&& t->common.ann->common.type != SSA_NAME_ANN))
abort ();
#endif
return (ssa_name_ann_t) t->common.ann;
}
static inline ssa_name_ann_t
get_ssa_name_ann (tree var)
{
ssa_name_ann_t ann = ssa_name_ann (var);
return (ann) ? ann : create_ssa_name_ann (var);
}
static inline enum tree_ann_type
ann_type (tree_ann ann)
{
return ann->common.type;
}
static inline basic_block
bb_for_stmt (tree t)
{
stmt_ann_t ann = stmt_ann (t);
return ann ? ann->bb : NULL;
}
static inline dependence_node
dg_node_for_stmt (tree t)
{
stmt_ann_t ann = stmt_ann (t);
return ann ? ann->dg_node : NULL;
}
static inline varray_type
may_aliases (tree var)
{
var_ann_t ann = var_ann (var);
return ann ? ann->may_aliases : NULL;
}
static inline bool
has_hidden_use (tree var)
{
var_ann_t ann = var_ann (var);
return ann ? ann->has_hidden_use : false;
}
static inline void
set_has_hidden_use (tree var)
{
var_ann_t ann = var_ann (var);
if (ann == NULL)
ann = create_var_ann (var);
ann->has_hidden_use = 1;
}
static inline int
get_lineno (tree expr)
{
if (expr == NULL_TREE)
return -1;
if (TREE_CODE (expr) == COMPOUND_EXPR)
expr = TREE_OPERAND (expr, 0);
if (! EXPR_LOCUS (expr))
return -1;
return EXPR_LINENO (expr);
}
static inline const char *
get_filename (tree expr)
{
if (expr == NULL_TREE)
return "???";
if (TREE_CODE (expr) == COMPOUND_EXPR)
expr = TREE_OPERAND (expr, 0);
if (EXPR_LOCUS (expr) && EXPR_FILENAME (expr))
return EXPR_FILENAME (expr);
else
return "???";
}
static inline void
modify_stmt (tree t)
{
stmt_ann_t ann = stmt_ann (t);
if (ann == NULL)
ann = create_stmt_ann (t);
ann->modified = 1;
}
static inline void
unmodify_stmt (tree t)
{
stmt_ann_t ann = stmt_ann (t);
if (ann == NULL)
ann = create_stmt_ann (t);
ann->modified = 0;
}
static inline bool
stmt_modified_p (tree t)
{
stmt_ann_t ann = stmt_ann (t);
return ann ? ann->modified : true;
}
static inline def_optype
get_def_ops (stmt_ann_t ann)
{
return ann ? ann->def_ops : NULL;
}
static inline use_optype
get_use_ops (stmt_ann_t ann)
{
return ann ? ann->use_ops : NULL;
}
static inline vdef_optype
get_vdef_ops (stmt_ann_t ann)
{
return ann ? ann->vdef_ops : NULL;
}
static inline vuse_optype
get_vuse_ops (stmt_ann_t ann)
{
return ann ? ann->vuse_ops : NULL;
}
static inline tree *
get_use_op_ptr (use_optype uses, unsigned int index)
{
#ifdef ENABLE_CHECKING
if (index >= uses->num_uses)
abort();
#endif
return uses->uses[index];
}
static inline tree *
get_def_op_ptr (def_optype defs, unsigned int index)
{
#ifdef ENABLE_CHECKING
if (index >= defs->num_defs)
abort();
#endif
return defs->defs[index];
}
static inline tree *
get_vdef_result_ptr(vdef_optype vdefs, unsigned int index)
{
#ifdef ENABLE_CHECKING
if (index >= vdefs->num_vdefs)
abort();
#endif
return &(vdefs->vdefs[index * 2]);
}
static inline tree *
get_vdef_op_ptr(vdef_optype vdefs, unsigned int index)
{
#ifdef ENABLE_CHECKING
if (index >= vdefs->num_vdefs)
abort();
#endif
return &(vdefs->vdefs[index * 2 + 1]);
}
static inline tree *
get_vuse_op_ptr(vuse_optype vuses, unsigned int index)
{
#ifdef ENABLE_CHECKING
if (index >= vuses->num_vuses)
abort();
#endif
return &(vuses->vuses[index]);
}
static inline void
start_ssa_stmt_operands (tree stmt ATTRIBUTE_UNUSED)
{
#ifdef ENABLE_CHECKING
verify_start_operands (stmt);
#endif
}
static inline bitmap
addresses_taken (tree stmt)
{
stmt_ann_t ann = stmt_ann (stmt);
return ann ? ann->addresses_taken : NULL;
}
static dataflow_t
get_immediate_uses (tree stmt)
{
stmt_ann_t ann = stmt_ann (stmt);
return ann ? ann->df : NULL;
}
static inline int
num_immediate_uses (dataflow_t df)
{
varray_type imm;
if (!df)
return 0;
imm = df->immediate_uses;
if (!imm)
return df->uses[1] ? 2 : 1;
return VARRAY_ACTIVE_SIZE (imm) + 2;
}
static inline tree
immediate_use (dataflow_t df, int num)
{
if (!df)
return NULL_TREE;
#ifdef ENABLE_CHECKING
if (num >= num_immediate_uses (df))
abort ();
#endif
if (num < 2)
return df->uses[num];
return VARRAY_TREE (df->immediate_uses, num - 2);
}
static inline bb_ann_t
bb_ann (basic_block bb)
{
return (bb_ann_t)bb->tree_annotations;
}
static inline tree
phi_nodes (basic_block bb)
{
if (bb->index < 0)
return NULL;
return bb_ann (bb)->phi_nodes;
}
static inline void
set_phi_nodes (basic_block bb, tree l)
{
tree phi;
bb_ann (bb)->phi_nodes = l;
for (phi = l; phi; phi = TREE_CHAIN (phi))
set_bb_for_stmt (phi, bb);
}
static inline int
phi_arg_from_edge (tree phi, edge e)
{
int i;
#if defined ENABLE_CHECKING
if (!phi || TREE_CODE (phi) != PHI_NODE)
abort();
#endif
for (i = 0; i < PHI_NUM_ARGS (phi); i++)
if (PHI_ARG_EDGE (phi, i) == e)
return i;
return -1;
}
static inline struct phi_arg_d *
phi_element_for_edge (tree phi, edge e)
{
int i;
i = phi_arg_from_edge (phi, e);
if (i != -1)
return &(PHI_ARG_ELT (phi, i));
else
return (struct phi_arg_d *)NULL;
}
static inline bool
is_exec_stmt (tree t)
{
return (t && !IS_EMPTY_STMT (t) && t != error_mark_node);
}
static inline bool
is_label_stmt (tree t)
{
if (t)
switch (TREE_CODE (t))
{
case LABEL_DECL:
case LABEL_EXPR:
case CASE_LABEL_EXPR:
return true;
default:
return false;
}
return false;
}
static inline bool
may_propagate_copy (tree dest, tree orig)
{
if (TREE_CODE (dest) == SSA_NAME
&& TREE_CODE (orig) == SSA_NAME
&& POINTER_TYPE_P (TREE_TYPE (dest))
&& POINTER_TYPE_P (TREE_TYPE (orig)))
{
tree mt_dest = var_ann (SSA_NAME_VAR (dest))->type_mem_tag;
tree mt_orig = var_ann (SSA_NAME_VAR (orig))->type_mem_tag;
if (mt_dest && mt_orig && mt_dest != mt_orig)
return false;
}
if (TREE_CODE (dest) == SSA_NAME && !is_gimple_reg (dest))
{
if (TREE_CODE (orig) == SSA_NAME)
{
if (!is_gimple_reg (orig))
return true;
#ifdef ENABLE_CHECKING
if (is_gimple_reg (orig))
abort ();
#endif
}
return false;
}
return (!SSA_NAME_OCCURS_IN_ABNORMAL_PHI (dest)
&& (TREE_CODE (orig) != SSA_NAME
|| !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (orig))
&& !DECL_HARD_REGISTER (SSA_NAME_VAR (dest)));
}
static inline void
set_default_def (tree var, tree def)
{
var_ann_t ann = var_ann (var);
if (ann == NULL)
ann = create_var_ann (var);
ann->default_def = def;
}
static inline tree
default_def (tree var)
{
var_ann_t ann = var_ann (var);
return ann ? ann->default_def : NULL_TREE;
}
static inline bool
phi_ssa_name_p (tree t)
{
if (TREE_CODE (t) == SSA_NAME)
return true;
#ifdef ENABLE_CHECKING
if (!is_gimple_min_invariant (t))
abort ();
#endif
return false;
}
static inline block_stmt_iterator
bsi_start (basic_block bb)
{
block_stmt_iterator bsi;
if (bb->stmt_list)
bsi.tsi = tsi_start (bb->stmt_list);
else
{
#ifdef ENABLE_CHECKING
if (bb->index >= 0)
abort ();
#endif
bsi.tsi.ptr = NULL;
bsi.tsi.container = NULL;
}
bsi.bb = bb;
return bsi;
}
static inline block_stmt_iterator
bsi_after_labels (basic_block bb)
{
block_stmt_iterator bsi;
tree_stmt_iterator next;
bsi.bb = bb;
if (!bb->stmt_list)
{
#ifdef ENABLE_CHECKING
if (bb->index >= 0)
abort ();
#endif
bsi.tsi.ptr = NULL;
bsi.tsi.container = NULL;
return bsi;
}
bsi.tsi = tsi_start (bb->stmt_list);
if (tsi_end_p (bsi.tsi))
return bsi;
if (TREE_CODE (tsi_stmt (bsi.tsi)) != LABEL_EXPR)
abort ();
next = bsi.tsi;
tsi_next (&next);
while (!tsi_end_p (next)
&& TREE_CODE (tsi_stmt (next)) == LABEL_EXPR)
{
bsi.tsi = next;
tsi_next (&next);
}
return bsi;
}
static inline block_stmt_iterator
bsi_last (basic_block bb)
{
block_stmt_iterator bsi;
if (bb->stmt_list)
bsi.tsi = tsi_last (bb->stmt_list);
else
{
#ifdef ENABLE_CHECKING
if (bb->index >= 0)
abort ();
#endif
bsi.tsi.ptr = NULL;
bsi.tsi.container = NULL;
}
bsi.bb = bb;
return bsi;
}
static inline bool
bsi_end_p (block_stmt_iterator i)
{
return tsi_end_p (i.tsi);
}
static inline void
bsi_next (block_stmt_iterator *i)
{
tsi_next (&i->tsi);
}
static inline void
bsi_prev (block_stmt_iterator *i)
{
tsi_prev (&i->tsi);
}
static inline tree
bsi_stmt (block_stmt_iterator i)
{
return tsi_stmt (i.tsi);
}
static inline tree *
bsi_stmt_ptr (block_stmt_iterator i)
{
return tsi_stmt_ptr (i.tsi);
}
static inline struct loop *
loop_of_stmt (tree stmt)
{
basic_block bb = bb_for_stmt (stmt);
if (!bb)
return NULL;
return bb->loop_father;
}
static inline bool
may_be_aliased (tree var)
{
return (TREE_ADDRESSABLE (var)
|| decl_function_context (var) != current_function_decl);
}
static inline bool
is_call_clobbered (tree var)
{
return needs_to_live_in_memory (var)
|| bitmap_bit_p (call_clobbered_vars, var_ann (var)->uid);
}
static inline void
mark_call_clobbered (tree var)
{
var_ann_t ann = var_ann (var);
DECL_NEEDS_TO_LIVE_IN_MEMORY_INTERNAL (var) = 1;
bitmap_set_bit (call_clobbered_vars, ann->uid);
}
static inline void
mark_non_addressable (tree var)
{
bitmap_clear_bit (call_clobbered_vars, var_ann (var)->uid);
DECL_NEEDS_TO_LIVE_IN_MEMORY_INTERNAL (var) = 0;
TREE_ADDRESSABLE (var) = 0;
}
#endif