static inline tree
first_referenced_var (referenced_var_iterator *iter)
{
- struct int_tree_map *itm;
- itm = (struct int_tree_map *) first_htab_element (&iter->hti,
- gimple_referenced_vars
- (cfun));
- if (!itm)
- return NULL;
- return itm->to;
+ return (tree) first_htab_element (&iter->hti,
+ gimple_referenced_vars (cfun));
}
/* Return true if we have hit the end of the referenced variables ITER is
static inline tree
next_referenced_var (referenced_var_iterator *iter)
{
- struct int_tree_map *itm;
- itm = (struct int_tree_map *) next_htab_element (&iter->hti);
- if (!itm)
- return NULL;
- return itm->to;
+ return (tree) next_htab_element (&iter->hti);
}
/* Fill up VEC with the variables in the referenced vars hashtable. */
static inline var_ann_t
var_ann (const_tree t)
{
- gcc_assert (t);
- gcc_assert (DECL_P (t));
- gcc_assert (TREE_CODE (t) != FUNCTION_DECL);
- if (!MTAG_P (t) && (TREE_STATIC (t) || DECL_EXTERNAL (t)))
+ var_ann_t ann;
+
+ if (!MTAG_P (t)
+ && (TREE_STATIC (t) || DECL_EXTERNAL (t)))
{
struct static_var_ann_d *sann
= ((struct static_var_ann_d *)
htab_find_with_hash (gimple_var_anns (cfun), t, DECL_UID (t)));
if (!sann)
return NULL;
- gcc_assert (sann->ann.common.type == VAR_ANN);
- return &sann->ann;
+ ann = &sann->ann;
}
- gcc_assert (!t->base.ann
- || t->base.ann->common.type == VAR_ANN);
+ else
+ {
+ if (!t->base.ann)
+ return NULL;
+ ann = (var_ann_t) t->base.ann;
+ }
+
+ gcc_assert (ann->common.type == VAR_ANN);
- return (var_ann_t) t->base.ann;
+ return ann;
}
/* Return the variable annotation for T, which must be a _DECL node.
/* Return the line number for EXPR, or return -1 if we have no line
number information for it. */
static inline int
-get_lineno (tree expr)
+get_lineno (const_tree expr)
{
if (expr == NULL_TREE)
return -1;
use_operand_p old = imm->imm_use;
#ifdef ENABLE_CHECKING
- /* If this assertion fails, it indicates the 'next' pointer has changed
- since we the last bump. This indicates that the list is being modified
+ /* If this assertion fails, it indicates the 'next' pointer has changed
+ since the last bump. This indicates that the list is being modified
via stmt changes, or SET_USE, or somesuch thing, and you need to be
using the SAFE version of the iterator. */
gcc_assert (imm->iter_node.next == old->next);
imm->imm_use = old->next;
if (end_readonly_imm_use_p (imm))
- return old;
+ return NULL_USE_OPERAND_P;
return imm->imm_use;
}
/* Return the PHI nodes for basic block BB, or NULL if there are no
PHI nodes. */
static inline tree
-phi_nodes (basic_block bb)
+phi_nodes (const_basic_block bb)
{
gcc_assert (!(bb->flags & BB_RTL));
if (!bb->il.tree)
return bsi;
}
-static inline const_block_stmt_iterator
-cbsi_start (const_basic_block bb)
-{
- const_block_stmt_iterator bsi;
- if (bb->index < NUM_FIXED_BLOCKS)
- {
- bsi.tsi.ptr = NULL;
- bsi.tsi.container = NULL;
- }
- else
- bsi.tsi = ctsi_start (bb_stmt_list (bb));
- bsi.bb = bb;
- return bsi;
-}
-
/* Return a block statement iterator that points to the first non-label
statement in block BB. */
return bsi;
}
-static inline const_block_stmt_iterator
-cbsi_last (const_basic_block bb)
-{
- const_block_stmt_iterator bsi;
-
- if (bb->index < NUM_FIXED_BLOCKS)
- {
- bsi.tsi.ptr = NULL;
- bsi.tsi.container = NULL;
- }
- else
- bsi.tsi = ctsi_last (bb_stmt_list (bb));
- bsi.bb = bb;
- return bsi;
-}
-
/* Return true if block statement iterator I has reached the end of
the basic block. */
static inline bool
return tsi_end_p (i.tsi);
}
-static inline bool
-cbsi_end_p (const_block_stmt_iterator i)
-{
- return ctsi_end_p (i.tsi);
-}
-
/* Modify block statement iterator I so that it is at the next
statement in the basic block. */
static inline void
tsi_next (&i->tsi);
}
-static inline void
-cbsi_next (const_block_stmt_iterator *i)
-{
- ctsi_next (&i->tsi);
-}
-
/* Modify block statement iterator I so that it is at the previous
statement in the basic block. */
static inline void
tsi_prev (&i->tsi);
}
-static inline void
-cbsi_prev (const_block_stmt_iterator *i)
-{
- ctsi_prev (&i->tsi);
-}
-
/* Return the statement that block statement iterator I is currently
at. */
static inline tree
return tsi_stmt (i.tsi);
}
-static inline const_tree
-cbsi_stmt (const_block_stmt_iterator i)
-{
- return ctsi_stmt (i.tsi);
-}
-
/* Return a pointer to the statement that block statement iterator I
is currently at. */
static inline tree *
static inline tree
get_subvar_at (tree var, unsigned HOST_WIDE_INT offset)
{
- subvar_t sv;
+ subvar_t sv = get_subvars_for_var (var);
+ int low, high;
- for (sv = get_subvars_for_var (var); sv; sv = sv->next)
- if (SFT_OFFSET (sv->var) == offset)
- return sv->var;
+ low = 0;
+ high = VEC_length (tree, sv) - 1;
+ while (low <= high)
+ {
+ int mid = (low + high) / 2;
+ tree subvar = VEC_index (tree, sv, mid);
+ if (SFT_OFFSET (subvar) == offset)
+ return subvar;
+ else if (SFT_OFFSET (subvar) < offset)
+ low = mid + 1;
+ else
+ high = mid - 1;
+ }
return NULL_TREE;
}
+
+/* Return the first subvariable in SV that overlaps [offset, offset + size[.
+ NULL_TREE is returned, if there is no overlapping subvariable, else *I
+ is set to the index in the SV vector of the first overlap. */
+
+static inline tree
+get_first_overlapping_subvar (subvar_t sv, unsigned HOST_WIDE_INT offset,
+ unsigned HOST_WIDE_INT size, unsigned int *i)
+{
+ int low = 0;
+ int high = VEC_length (tree, sv) - 1;
+ int mid;
+ tree subvar;
+
+ if (low > high)
+ return NULL_TREE;
+
+ /* Binary search for offset. */
+ do
+ {
+ mid = (low + high) / 2;
+ subvar = VEC_index (tree, sv, mid);
+ if (SFT_OFFSET (subvar) == offset)
+ {
+ *i = mid;
+ return subvar;
+ }
+ else if (SFT_OFFSET (subvar) < offset)
+ low = mid + 1;
+ else
+ high = mid - 1;
+ }
+ while (low <= high);
+
+ /* As we didn't find a subvar with offset, adjust to return the
+ first overlapping one. */
+ if (SFT_OFFSET (subvar) < offset
+ && SFT_OFFSET (subvar) + SFT_SIZE (subvar) <= offset)
+ {
+ mid += 1;
+ if ((unsigned)mid >= VEC_length (tree, sv))
+ return NULL_TREE;
+ subvar = VEC_index (tree, sv, mid);
+ }
+ else if (SFT_OFFSET (subvar) > offset
+ && size <= SFT_OFFSET (subvar) - offset)
+ {
+ mid -= 1;
+ if (mid < 0)
+ return NULL_TREE;
+ subvar = VEC_index (tree, sv, mid);
+ }
+
+ if (overlap_subvar (offset, size, subvar, NULL))
+ {
+ *i = mid;
+ return subvar;
+ }
+
+ return NULL_TREE;
+}
+
+
/* Return true if V is a tree that we can have subvars for.
Normally, this is any aggregate type. Also complex
types which are not gimple registers can have subvars. */
return false;
}
-
+
+/* Return true, if the two ranges [POS1, SIZE1] and [POS2, SIZE2]
+ overlap. SIZE1 and/or SIZE2 can be (unsigned)-1 in which case the
+ range is open-ended. Otherwise return false. */
+
+static inline bool
+ranges_overlap_p (unsigned HOST_WIDE_INT pos1,
+ unsigned HOST_WIDE_INT size1,
+ unsigned HOST_WIDE_INT pos2,
+ unsigned HOST_WIDE_INT size2)
+{
+ if (pos1 >= pos2
+ && (size2 == (unsigned HOST_WIDE_INT)-1
+ || pos1 < (pos2 + size2)))
+ return true;
+ if (pos2 >= pos1
+ && (size1 == (unsigned HOST_WIDE_INT)-1
+ || pos2 < (pos1 + size1)))
+ return true;
+
+ return false;
+}
+
+
/* Return true if OFFSET and SIZE define a range that overlaps with some
portion of the range of SV, a subvar. If there was an exact overlap,
*EXACT will be set to true upon return. */
{
return &fn->gimple_df->mem_ref_stats;
}
+
+/* Given an edge_var_map V, return the PHI arg definition. */
+
+static inline tree
+redirect_edge_var_map_def (edge_var_map *v)
+{
+ return v->def;
+}
+
+/* Given an edge_var_map V, return the PHI result. */
+
+static inline tree
+redirect_edge_var_map_result (edge_var_map *v)
+{
+ return v->result;
+}
#endif /* _TREE_FLOW_INLINE_H */