/* Alias analysis for GNU C
- Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
+ Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
Free Software Foundation, Inc.
Contributed by John Carr (jfc@mit.edu).
static int nonlocal_set_p_1 (rtx *, void *);
static int nonlocal_set_p (rtx);
static void memory_modified_1 (rtx, rtx, void *);
+static void record_alias_subset (HOST_WIDE_INT, HOST_WIDE_INT);
/* Set up all info needed to perform alias analysis on memory references. */
}
}
-/* Return 1 if all the nested component references handled by
- get_inner_reference in T are such that we can address the object in T. */
+/* Return true if all nested component references handled by
+ get_inner_reference in T are such that we should use the alias set
+ provided by the object at the heart of T.
-int
-can_address_p (tree t)
+ This is true for non-addressable components (which don't have their
+ own alias set), as well as components of objects in alias set zero.
+ This later point is a special case wherein we wish to override the
+ alias set used by the component, but we don't have per-FIELD_DECL
+ assignable alias sets. */
+
+bool
+component_uses_parent_alias_set (tree t)
{
- /* If we're at the end, it is vacuously addressable. */
- if (! handled_component_p (t))
- return 1;
+ while (1)
+ {
+ /* If we're at the end, it vacuously uses its own alias set. */
+ if (!handled_component_p (t))
+ return false;
- /* Bitfields are never addressable. */
- else if (TREE_CODE (t) == BIT_FIELD_REF)
- return 0;
+ switch (TREE_CODE (t))
+ {
+ case COMPONENT_REF:
+ if (DECL_NONADDRESSABLE_P (TREE_OPERAND (t, 1)))
+ return true;
+ break;
- /* Fields are addressable unless they are marked as nonaddressable or
- the containing type has alias set 0. */
- else if (TREE_CODE (t) == COMPONENT_REF
- && ! DECL_NONADDRESSABLE_P (TREE_OPERAND (t, 1))
- && get_alias_set (TREE_TYPE (TREE_OPERAND (t, 0))) != 0
- && can_address_p (TREE_OPERAND (t, 0)))
- return 1;
+ case ARRAY_REF:
+ case ARRAY_RANGE_REF:
+ if (TYPE_NONALIASED_COMPONENT (TREE_TYPE (TREE_OPERAND (t, 0))))
+ return true;
+ break;
- /* Likewise for arrays. */
- else if ((TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
- && ! TYPE_NONALIASED_COMPONENT (TREE_TYPE (TREE_OPERAND (t, 0)))
- && get_alias_set (TREE_TYPE (TREE_OPERAND (t, 0))) != 0
- && can_address_p (TREE_OPERAND (t, 0)))
- return 1;
+ case REALPART_EXPR:
+ case IMAGPART_EXPR:
+ break;
- return 0;
+ default:
+ /* Bitfields and casts are never addressable. */
+ return true;
+ }
+
+ t = TREE_OPERAND (t, 0);
+ if (get_alias_set (TREE_TYPE (t)) == 0)
+ return true;
+ }
}
/* Return the alias set for T, which may be either a type or an
}
/* Check for accesses through restrict-qualified pointers. */
- if (TREE_CODE (inner) == INDIRECT_REF)
+ if (INDIRECT_REF_P (inner))
{
tree decl = find_base_decl (TREE_OPERAND (inner, 0));
type, then we would believe that other subsets
of the pointed-to type (such as fields of that
type) do not conflict with the type pointed to
- by the restricted pointer. */
+ by the restricted pointer. */
DECL_POINTER_ALIAS_SET (decl)
= pointed_to_alias_set;
else
/* Otherwise, pick up the outermost object that we could have a pointer
to, processing conversions as above. */
- while (handled_component_p (t) && ! can_address_p (t))
+ while (component_uses_parent_alias_set (t))
{
t = TREE_OPERAND (t, 0);
STRIP_NOPS (t);
It is illegal for SUPERSET to be zero; everything is implicitly a
subset of alias set zero. */
-void
+static void
record_alias_subset (HOST_WIDE_INT superset, HOST_WIDE_INT subset)
{
alias_set_entry superset_entry;
where SIZE is the size in bytes of the memory reference. If ADDR
is not modified by the memory reference then ADDR is returned. */
-rtx
+static rtx
addr_side_effect_eval (rtx addr, int size, int n_refs)
{
int offset = 0;
aliases_everything_p (rtx mem)
{
if (GET_CODE (XEXP (mem, 0)) == AND)
- /* If the address is an AND, its very hard to know at what it is
+ /* If the address is an AND, it's very hard to know at what it is
actually pointing. */
return 1;
moffsetx = adjust_offset_for_component_ref (exprx, moffsetx);
exprx = t;
}
- else if (TREE_CODE (exprx) == INDIRECT_REF)
+ else if (INDIRECT_REF_P (exprx))
{
exprx = TREE_OPERAND (exprx, 0);
if (flag_argument_noalias < 2
moffsety = adjust_offset_for_component_ref (expry, moffsety);
expry = t;
}
- else if (TREE_CODE (expry) == INDIRECT_REF)
+ else if (INDIRECT_REF_P (expry))
{
expry = TREE_OPERAND (expry, 0);
if (flag_argument_noalias < 2
/* Read-only memory is by definition never modified, and therefore can't
conflict with anything. We don't expect to find read-only set on MEM,
- but stupid user tricks can produce them, so don't abort. */
+ but stupid user tricks can produce them, so don't die. */
if (MEM_READONLY_P (x))
return 0;
/* Read-only memory is by definition never modified, and therefore can't
conflict with anything. We don't expect to find read-only set on MEM,
- but stupid user tricks can produce them, so don't abort. */
+ but stupid user tricks can produce them, so don't die. */
if (MEM_READONLY_P (x))
return 0;
/* Return true when INSN possibly modify memory contents of MEM
- (ie address can be modified). */
+ (i.e. address can be modified). */
bool
memory_modified_in_insn_p (rtx mem, rtx insn)
{