return false;
}
-/* Advance the hashtable iterator pointed by HTI to the next element of the
+/* Advance the hashtable iterator pointed to by HTI to the next element of the
hashtable. */
static inline void *
first_referenced_var (referenced_var_iterator *iter)
{
struct int_tree_map *itm;
- itm = first_htab_element (&iter->hti, referenced_vars);
+ itm = (struct int_tree_map *) first_htab_element (&iter->hti,
+ referenced_vars);
if (!itm)
return NULL;
return itm->to;
next_referenced_var (referenced_var_iterator *iter)
{
struct int_tree_map *itm;
- itm = next_htab_element (&iter->hti);
+ itm = (struct int_tree_map *) next_htab_element (&iter->hti);
if (!itm)
return NULL;
return itm->to;
{
gcc_assert (t);
gcc_assert (DECL_P (t));
+ gcc_assert (TREE_CODE (t) != FUNCTION_DECL);
gcc_assert (!t->common.ann || t->common.ann->common.type == VAR_ANN);
return (var_ann_t) t->common.ann;
return (ann) ? ann : create_var_ann (var);
}
+/* Return the function annotation for T, which must be a FUNCTION_DECL node.
+ Return NULL if the function annotation doesn't already exist. */
+static inline function_ann_t
+function_ann (tree t)
+{
+ gcc_assert (t);
+ gcc_assert (TREE_CODE (t) == FUNCTION_DECL);
+ gcc_assert (!t->common.ann || t->common.ann->common.type == FUNCTION_ANN);
+
+ return (function_ann_t) t->common.ann;
+}
+
+/* Return the function annotation for T, which must be a FUNCTION_DECL node.
+ Create the function annotation if it doesn't exist. */
+static inline function_ann_t
+get_function_ann (tree var)
+{
+ function_ann_t ann = function_ann (var);
+ return (ann) ? ann : create_function_ann (var);
+}
+
/* Return the statement annotation for T, which must be a statement
node. Return NULL if the statement annotation doesn't exist. */
static inline stmt_ann_t
/* Return the may_aliases varray for variable VAR, or NULL if it has
no may aliases. */
-static inline varray_type
+static inline VEC(tree, gc) *
may_aliases (tree var)
{
var_ann_t ann = var_ann (var);
}
}
-/* Set the value of a use pointed by USE to VAL. */
+/* Set the value of a use pointed to by USE to VAL. */
static inline void
set_ssa_use_from_ptr (use_operand_p use, tree val)
{
return false;
}
-/* Set the default definition for VAR to DEF. */
-static inline void
-set_default_def (tree var, tree def)
-{
- var_ann_t ann = get_var_ann (var);
- ann->default_def = def;
-}
-
-/* Return the default definition for variable VAR, or NULL if none
- exists. */
-static inline tree
-default_def (tree var)
-{
- var_ann_t ann = var_ann (var);
- return ann ? ann->default_def : NULL_TREE;
-}
-
/* PHI nodes should contain only ssa_names and invariants. A test
for ssa_name is definitely simpler; don't let invalid contents
slip in in the meantime. */
bsi.tsi = tsi_start (bb->stmt_list);
else
{
- gcc_assert (bb->index < 0);
+ gcc_assert (bb->index < NUM_FIXED_BLOCKS);
bsi.tsi.ptr = NULL;
bsi.tsi.container = NULL;
}
return bsi;
}
-/* Return a block statement iterator that points to the last label in
- block BB. */
+/* Return a block statement iterator that points to the first non-label
+ statement in block BB. */
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;
- }
+ block_stmt_iterator bsi = bsi_start (bb);
- bsi.tsi = tsi_start (bb->stmt_list);
- if (tsi_end_p (bsi.tsi))
- return bsi;
-
- /* Ensure that there are some labels. The rationale is that we want
- to insert after the bsi that is returned, and these insertions should
- be placed at the start of the basic block. This would not work if the
- first statement was not label; rather fail here than enable the user
- proceed in wrong way. */
- 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);
- }
+ while (!bsi_end_p (bsi) && TREE_CODE (bsi_stmt (bsi)) == LABEL_EXPR)
+ bsi_next (&bsi);
return bsi;
}
bsi.tsi = tsi_last (bb->stmt_list);
else
{
- gcc_assert (bb->index < 0);
+ gcc_assert (bb->index < NUM_FIXED_BLOCKS);
bsi.tsi.ptr = NULL;
bsi.tsi.container = NULL;
}
static inline bool
is_call_clobbered (tree var)
{
- return is_global_var (var)
- || bitmap_bit_p (call_clobbered_vars, DECL_UID (var));
+ return bitmap_bit_p (call_clobbered_vars, DECL_UID (var));
}
/* Mark variable VAR as being clobbered by function calls. */
static inline void
-mark_call_clobbered (tree var)
+mark_call_clobbered (tree var, unsigned int escape_type)
{
- var_ann_t ann = var_ann (var);
- /* If VAR is a memory tag, then we need to consider it a global
- variable. This is because the pointer that VAR represents has
- been found to point to either an arbitrary location or to a known
- location in global memory. */
- if (ann->mem_tag_kind != NOT_A_TAG && ann->mem_tag_kind != STRUCT_FIELD)
- DECL_EXTERNAL (var) = 1;
+ var_ann (var)->escape_mask |= escape_type;
bitmap_set_bit (call_clobbered_vars, DECL_UID (var));
- ssa_call_clobbered_cache_valid = false;
- ssa_ro_call_cache_valid = false;
}
/* Clear the call-clobbered attribute from variable VAR. */
clear_call_clobbered (tree var)
{
var_ann_t ann = var_ann (var);
- if (ann->mem_tag_kind != NOT_A_TAG && ann->mem_tag_kind != STRUCT_FIELD)
- DECL_EXTERNAL (var) = 0;
+ ann->escape_mask = 0;
+ if (MTAG_P (var) && TREE_CODE (var) != STRUCT_FIELD_TAG)
+ MTAG_GLOBAL (var) = 0;
bitmap_clear_bit (call_clobbered_vars, DECL_UID (var));
- ssa_call_clobbered_cache_valid = false;
- ssa_ro_call_cache_valid = false;
}
/* Mark variable VAR as being non-addressable. */
{
bitmap_clear_bit (call_clobbered_vars, DECL_UID (var));
TREE_ADDRESSABLE (var) = 0;
- ssa_call_clobbered_cache_valid = false;
- ssa_ro_call_cache_valid = false;
}
/* Return the common annotation for T. Return NULL if the annotation
/* This functions clears the iterator PTR, and marks it done. This is normally
- used to prevent warnings in the compile about might be uninitailzied
+ used to prevent warnings in the compile about might be uninitialized
components. */
static inline void
/* If there is a single operand in STMT matching FLAGS, return it. Otherwise
- return NULL. PTR is the iterator to use. */
+ return NULL. */
static inline tree
single_ssa_tree_operand (tree stmt, int flags)
{
/* If there is a single operand in STMT matching FLAGS, return it. Otherwise
- return NULL. PTR is the iterator to use. */
+ return NULL. */
static inline use_operand_p
single_ssa_use_operand (tree stmt, int flags)
{
/* If there is a single operand in STMT matching FLAGS, return it. Otherwise
- return NULL. PTR is the iterator to use. */
+ return NULL. */
static inline def_operand_p
single_ssa_def_operand (tree stmt, int flags)
{
/* If there is a single operand in STMT matching FLAGS, return it. Otherwise
- return NULL. PTR is the iterator to use. */
+ return NULL. */
static inline bool
zero_ssa_operands (tree stmt, int flags)
{
{
if (TREE_CODE (var) == SSA_NAME)
var = SSA_NAME_VAR (var);
+
+ if (MTAG_P (var))
+ return TREE_READONLY (var) && (TREE_STATIC (var) || MTAG_GLOBAL (var));
+
return TREE_READONLY (var) && (TREE_STATIC (var) || DECL_EXTERNAL (var));
}
-/* Return true if REF, a COMPONENT_REF, has an ARRAY_REF somewhere in it. */
+/* Return true if REF, an ARRAY_REF, has an INDIRECT_REF somewhere in it. */
+
+static inline bool
+array_ref_contains_indirect_ref (tree ref)
+{
+ gcc_assert (TREE_CODE (ref) == ARRAY_REF);
+
+ do {
+ ref = TREE_OPERAND (ref, 0);
+ } while (handled_component_p (ref));
+
+ return TREE_CODE (ref) == INDIRECT_REF;
+}
+
+/* Return true if REF, a handled component reference, has an ARRAY_REF
+ somewhere in it. */
static inline bool
ref_contains_array_ref (tree ref)
{
- while (handled_component_p (ref))
- {
- if (TREE_CODE (ref) == ARRAY_REF)
- return true;
- ref = TREE_OPERAND (ref, 0);
- }
+ gcc_assert (handled_component_p (ref));
+
+ do {
+ if (TREE_CODE (ref) == ARRAY_REF)
+ return true;
+ ref = TREE_OPERAND (ref, 0);
+ } while (handled_component_p (ref));
+
return false;
}
}
/* Return true if V is a tree that we can have subvars for.
- Normally, this is any aggregate type, however, due to implementation
- limitations ATM, we exclude array types as well. */
+ Normally, this is any aggregate type. Also complex
+ types which are not gimple registers can have subvars. */
static inline bool
var_can_have_subvars (tree v)
{
- return (AGGREGATE_TYPE_P (TREE_TYPE (v)) &&
- TREE_CODE (TREE_TYPE (v)) != ARRAY_TYPE);
+ /* Non decls or memory tags can never have subvars. */
+ if (!DECL_P (v) || MTAG_P (v))
+ return false;
+
+ /* Aggregates can have subvars. */
+ if (AGGREGATE_TYPE_P (TREE_TYPE (v)))
+ return true;
+
+ /* Complex types variables which are not also a gimple register can
+ have subvars. */
+ if (TREE_CODE (TREE_TYPE (v)) == COMPLEX_TYPE
+ && !DECL_COMPLEX_GIMPLE_REG_P (v))
+ return true;
+
+ return false;
}
{
return true;
}
- else if (offset < sv->offset && (offset + size > sv->offset))
+ else if (offset < sv->offset && (size > sv->offset - offset))
{
return true;
}