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)
{
gcc_assert (t);
gcc_assert (DECL_P (t));
gcc_assert (!t->common.ann || t->common.ann->common.type == VAR_ANN);
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)
{
#ifdef ENABLE_CHECKING
gcc_assert (is_gimple_stmt (t));
#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 enum tree_ann_type
ann_type (tree_ann_t ann)
{
return ann->common.type;
}
static inline basic_block
bb_for_stmt (tree t)
{
stmt_ann_t ann;
if (TREE_CODE (t) == PHI_NODE)
return PHI_BB (t);
ann = stmt_ann (t);
return ann ? ann->bb : NULL;
}
static inline varray_type
may_aliases (tree var)
{
var_ann_t ann = var_ann (var);
return ann ? ann->may_aliases : NULL;
}
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_HAS_LOCATION (expr))
return -1;
return EXPR_LINENO (expr);
}
static inline const char *
get_filename (tree expr)
{
const char *filename;
if (expr == NULL_TREE)
return "???";
if (TREE_CODE (expr) == COMPOUND_EXPR)
expr = TREE_OPERAND (expr, 0);
if (EXPR_HAS_LOCATION (expr) && (filename = EXPR_FILENAME (expr)))
return filename;
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->operands.def_ops : NULL;
}
static inline use_optype
get_use_ops (stmt_ann_t ann)
{
return ann ? ann->operands.use_ops : NULL;
}
static inline v_may_def_optype
get_v_may_def_ops (stmt_ann_t ann)
{
return ann ? ann->operands.v_may_def_ops : NULL;
}
static inline vuse_optype
get_vuse_ops (stmt_ann_t ann)
{
return ann ? ann->operands.vuse_ops : NULL;
}
static inline v_must_def_optype
get_v_must_def_ops (stmt_ann_t ann)
{
return ann ? ann->operands.v_must_def_ops : NULL;
}
static inline tree
get_use_from_ptr (use_operand_p use)
{
return *(use.use);
}
static inline tree
get_def_from_ptr (def_operand_p def)
{
return *(def.def);
}
static inline use_operand_p
get_use_op_ptr (use_optype uses, unsigned int index)
{
gcc_assert (index < uses->num_uses);
return uses->uses[index];
}
static inline def_operand_p
get_def_op_ptr (def_optype defs, unsigned int index)
{
gcc_assert (index < defs->num_defs);
return defs->defs[index];
}
static inline def_operand_p
get_v_may_def_result_ptr(v_may_def_optype v_may_defs, unsigned int index)
{
def_operand_p op;
gcc_assert (index < v_may_defs->num_v_may_defs);
op.def = &(v_may_defs->v_may_defs[index].def);
return op;
}
static inline use_operand_p
get_v_may_def_op_ptr(v_may_def_optype v_may_defs, unsigned int index)
{
use_operand_p op;
gcc_assert (index < v_may_defs->num_v_may_defs);
op.use = &(v_may_defs->v_may_defs[index].use);
return op;
}
static inline use_operand_p
get_vuse_op_ptr(vuse_optype vuses, unsigned int index)
{
use_operand_p op;
gcc_assert (index < vuses->num_vuses);
op.use = &(vuses->vuses[index]);
return op;
}
static inline def_operand_p
get_v_must_def_result_ptr (v_must_def_optype v_must_defs, unsigned int index)
{
def_operand_p op;
gcc_assert (index < v_must_defs->num_v_must_defs);
op.def = &(v_must_defs->v_must_defs[index].def);
return op;
}
static inline use_operand_p
get_v_must_def_kill_ptr (v_must_def_optype v_must_defs, unsigned int index)
{
use_operand_p op;
gcc_assert (index < v_must_defs->num_v_must_defs);
op.use = &(v_must_defs->v_must_defs[index].use);
return op;
}
static inline def_operand_p
get_phi_result_ptr (tree phi)
{
def_operand_p op;
op.def = &(PHI_RESULT_TREE (phi));
return op;
}
static inline use_operand_p
get_phi_arg_def_ptr (tree phi, int i)
{
use_operand_p op;
op.use = &(PHI_ARG_DEF_TREE (phi, i));
return op;
}
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;
if (TREE_CODE (stmt) == PHI_NODE)
return PHI_DF (stmt);
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
gcc_assert (num < num_immediate_uses (df));
#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 = PHI_CHAIN (phi))
set_bb_for_stmt (phi, bb);
}
static inline int
phi_arg_from_edge (tree phi, edge e)
{
int i;
gcc_assert (phi);
gcc_assert (TREE_CODE (phi) == PHI_NODE);
for (i = 0; i < PHI_NUM_ARGS (phi); i++)
if (PHI_ARG_EDGE (phi, i) == e)
return i;
return -1;
}
static inline void
set_is_used (tree var)
{
var_ann_t ann = get_var_ann (var);
ann->used = 1;
}
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 void
set_default_def (tree var, tree def)
{
var_ann_t ann = get_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
gcc_assert (is_gimple_min_invariant (t));
#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
{
gcc_assert (bb->index < 0);
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)
{
gcc_assert (bb->index < 0);
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;
gcc_assert (TREE_CODE (tsi_stmt (bsi.tsi)) == LABEL_EXPR);
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
{
gcc_assert (bb->index < 0);
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_containing_stmt (tree stmt)
{
basic_block bb = bb_for_stmt (stmt);
if (!bb)
return NULL;
return bb->loop_father;
}
static inline bool
is_call_clobbered (tree var)
{
return is_global_var (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);
if (ann->mem_tag_kind != NOT_A_TAG)
DECL_EXTERNAL (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);
TREE_ADDRESSABLE (var) = 0;
}
static inline tree_ann_t
tree_ann (tree t)
{
return t->common.ann;
}
static inline tree_ann_t
get_tree_ann (tree t)
{
tree_ann_t ann = tree_ann (t);
return (ann) ? ann : create_tree_ann (t);
}
static inline bool
op_iter_done (ssa_op_iter *ptr)
{
return ptr->done;
}
static inline use_operand_p
op_iter_next_use (ssa_op_iter *ptr)
{
if (ptr->use_i < ptr->num_use)
{
return USE_OP_PTR (ptr->ops->use_ops, (ptr->use_i)++);
}
if (ptr->vuse_i < ptr->num_vuse)
{
return VUSE_OP_PTR (ptr->ops->vuse_ops, (ptr->vuse_i)++);
}
if (ptr->v_mayu_i < ptr->num_v_mayu)
{
return V_MAY_DEF_OP_PTR (ptr->ops->v_may_def_ops,
(ptr->v_mayu_i)++);
}
if (ptr->v_mustu_i < ptr->num_v_mustu)
{
return V_MUST_DEF_KILL_PTR (ptr->ops->v_must_def_ops,
(ptr->v_mustu_i)++);
}
ptr->done = true;
return NULL_USE_OPERAND_P;
}
static inline def_operand_p
op_iter_next_def (ssa_op_iter *ptr)
{
if (ptr->def_i < ptr->num_def)
{
return DEF_OP_PTR (ptr->ops->def_ops, (ptr->def_i)++);
}
if (ptr->v_mustd_i < ptr->num_v_mustd)
{
return V_MUST_DEF_RESULT_PTR (ptr->ops->v_must_def_ops,
(ptr->v_mustd_i)++);
}
if (ptr->v_mayd_i < ptr->num_v_mayd)
{
return V_MAY_DEF_RESULT_PTR (ptr->ops->v_may_def_ops,
(ptr->v_mayd_i)++);
}
ptr->done = true;
return NULL_DEF_OPERAND_P;
}
static inline tree
op_iter_next_tree (ssa_op_iter *ptr)
{
if (ptr->use_i < ptr->num_use)
{
return USE_OP (ptr->ops->use_ops, (ptr->use_i)++);
}
if (ptr->vuse_i < ptr->num_vuse)
{
return VUSE_OP (ptr->ops->vuse_ops, (ptr->vuse_i)++);
}
if (ptr->v_mayu_i < ptr->num_v_mayu)
{
return V_MAY_DEF_OP (ptr->ops->v_may_def_ops, (ptr->v_mayu_i)++);
}
if (ptr->v_mustu_i < ptr->num_v_mustu)
{
return V_MUST_DEF_KILL (ptr->ops->v_must_def_ops, (ptr->v_mustu_i)++);
}
if (ptr->def_i < ptr->num_def)
{
return DEF_OP (ptr->ops->def_ops, (ptr->def_i)++);
}
if (ptr->v_mustd_i < ptr->num_v_mustd)
{
return V_MUST_DEF_RESULT (ptr->ops->v_must_def_ops,
(ptr->v_mustd_i)++);
}
if (ptr->v_mayd_i < ptr->num_v_mayd)
{
return V_MAY_DEF_RESULT (ptr->ops->v_may_def_ops,
(ptr->v_mayd_i)++);
}
ptr->done = true;
return NULL;
}
static inline void
op_iter_init (ssa_op_iter *ptr, tree stmt, int flags)
{
stmt_operands_p ops;
stmt_ann_t ann = get_stmt_ann (stmt);
ops = &(ann->operands);
ptr->done = false;
ptr->ops = ops;
ptr->num_def = (flags & SSA_OP_DEF) ? NUM_DEFS (ops->def_ops) : 0;
ptr->num_use = (flags & SSA_OP_USE) ? NUM_USES (ops->use_ops) : 0;
ptr->num_vuse = (flags & SSA_OP_VUSE) ? NUM_VUSES (ops->vuse_ops) : 0;
ptr->num_v_mayu = (flags & SSA_OP_VMAYUSE)
? NUM_V_MAY_DEFS (ops->v_may_def_ops) : 0;
ptr->num_v_mayd = (flags & SSA_OP_VMAYDEF)
? NUM_V_MAY_DEFS (ops->v_may_def_ops) : 0;
ptr->num_v_mustu = (flags & SSA_OP_VMUSTDEFKILL)
? NUM_V_MUST_DEFS (ops->v_must_def_ops) : 0;
ptr->num_v_mustd = (flags & SSA_OP_VMUSTDEF)
? NUM_V_MUST_DEFS (ops->v_must_def_ops) : 0;
ptr->def_i = 0;
ptr->use_i = 0;
ptr->vuse_i = 0;
ptr->v_mayu_i = 0;
ptr->v_mayd_i = 0;
ptr->v_mustu_i = 0;
ptr->v_mustd_i = 0;
}
static inline use_operand_p
op_iter_init_use (ssa_op_iter *ptr, tree stmt, int flags)
{
op_iter_init (ptr, stmt, flags);
return op_iter_next_use (ptr);
}
static inline def_operand_p
op_iter_init_def (ssa_op_iter *ptr, tree stmt, int flags)
{
op_iter_init (ptr, stmt, flags);
return op_iter_next_def (ptr);
}
static inline tree
op_iter_init_tree (ssa_op_iter *ptr, tree stmt, int flags)
{
op_iter_init (ptr, stmt, flags);
return op_iter_next_tree (ptr);
}
static inline void
op_iter_next_mustdef (use_operand_p *kill, def_operand_p *def, ssa_op_iter *ptr)
{
if (ptr->v_mustu_i < ptr->num_v_mustu)
{
*def = V_MUST_DEF_RESULT_PTR (ptr->ops->v_must_def_ops, ptr->v_mustu_i);
*kill = V_MUST_DEF_KILL_PTR (ptr->ops->v_must_def_ops, (ptr->v_mustu_i)++);
return;
}
else
{
*def = NULL_DEF_OPERAND_P;
*kill = NULL_USE_OPERAND_P;
}
ptr->done = true;
return;
}
static inline void
op_iter_next_maydef (use_operand_p *use, def_operand_p *def, ssa_op_iter *ptr)
{
if (ptr->v_mayu_i < ptr->num_v_mayu)
{
*def = V_MAY_DEF_RESULT_PTR (ptr->ops->v_may_def_ops, ptr->v_mayu_i);
*use = V_MAY_DEF_OP_PTR (ptr->ops->v_may_def_ops, (ptr->v_mayu_i)++);
return;
}
else
{
*def = NULL_DEF_OPERAND_P;
*use = NULL_USE_OPERAND_P;
}
ptr->done = true;
return;
}
static inline void
op_iter_init_maydef (ssa_op_iter *ptr, tree stmt, use_operand_p *use,
def_operand_p *def)
{
op_iter_init (ptr, stmt, SSA_OP_VMAYUSE);
op_iter_next_maydef (use, def, ptr);
}
static inline void
op_iter_init_mustdef (ssa_op_iter *ptr, tree stmt, use_operand_p *kill,
def_operand_p *def)
{
op_iter_init (ptr, stmt, SSA_OP_VMUSTDEFKILL);
op_iter_next_mustdef (kill, def, ptr);
}
#endif