diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 36f9530bb74..b507d6d46d6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2004-12-03 Richard Henderson + + * alias.c (component_uses_parent_alias_set): Rename from + can_address_p. Return bool. Reverse the sense of the result. + Reinstate the check for alias set zero. + (get_alias_set): Update to match. + * alias.h (component_uses_parent_alias_set): Likewise. + * emit-rtl.c (set_mem_attributes_minus_bitpos): Likewise. + * expr.c (expand_assignment): Likewise. + * expr.h: Remove commented out prototypes that were moved to alias.h. + 2004-12-03 Richard Henderson * doc/tm.texi (TARGET_BUILD_BUILTIN_VA_LIST): New. diff --git a/gcc/alias.c b/gcc/alias.c index 3246082af23..e2b7adf156f 100644 --- a/gcc/alias.c +++ b/gcc/alias.c @@ -378,29 +378,36 @@ find_base_decl (tree t) } } -/* 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) { while (1) { - /* If we're at the end, it is vacuously addressable. */ + /* If we're at the end, it vacuously uses its own alias set. */ if (!handled_component_p (t)) - return true; + return false; switch (TREE_CODE (t)) { case COMPONENT_REF: if (DECL_NONADDRESSABLE_P (TREE_OPERAND (t, 1))) - return false; + return true; break; case ARRAY_REF: case ARRAY_RANGE_REF: if (TYPE_NONALIASED_COMPONENT (TREE_TYPE (TREE_OPERAND (t, 0)))) - return false; + return true; break; case REALPART_EXPR: @@ -409,10 +416,12 @@ can_address_p (tree t) default: /* Bitfields and casts are never addressable. */ - return false; + return true; } t = TREE_OPERAND (t, 0); + if (get_alias_set (TREE_TYPE (t)) == 0) + return true; } } @@ -515,7 +524,7 @@ get_alias_set (tree t) /* 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); diff --git a/gcc/alias.h b/gcc/alias.h index ea78e808a62..58fe0bd17d4 100644 --- a/gcc/alias.h +++ b/gcc/alias.h @@ -25,6 +25,6 @@ extern HOST_WIDE_INT new_alias_set (void); extern HOST_WIDE_INT get_varargs_alias_set (void); extern HOST_WIDE_INT get_frame_alias_set (void); extern void record_base_value (unsigned int, rtx, int); -extern int can_address_p (tree); +extern bool component_uses_parent_alias_set (tree); #endif /* GCC_ALIAS_H */ diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c index d722f90ad69..6858f987ad6 100644 --- a/gcc/emit-rtl.c +++ b/gcc/emit-rtl.c @@ -1546,9 +1546,9 @@ set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp, || TREE_CODE (t) == SAVE_EXPR) t = TREE_OPERAND (t, 0); - /* If this expression can't be addressed (e.g., it contains a reference - to a non-addressable field), show we don't change its alias set. */ - if (! can_address_p (t)) + /* If this expression uses it's parent's alias set, mark it such + that we won't change it. */ + if (component_uses_parent_alias_set (t)) MEM_KEEP_ALIAS_SET_P (ref) = 1; /* If this is a decl, set the attributes of the MEM from it. */ diff --git a/gcc/expr.c b/gcc/expr.c index ec25713c5e9..1a431458991 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -3810,8 +3810,7 @@ expand_assignment (tree to, tree from) done for MEM. Also set MEM_KEEP_ALIAS_SET_P if needed. */ if (volatilep) MEM_VOLATILE_P (to_rtx) = 1; - - if (!can_address_p (to)) + if (component_uses_parent_alias_set (to)) MEM_KEEP_ALIAS_SET_P (to_rtx) = 1; } diff --git a/gcc/expr.h b/gcc/expr.h index 780ad4dfdd4..64dccd069bd 100644 --- a/gcc/expr.h +++ b/gcc/expr.h @@ -530,11 +530,6 @@ extern unsigned int case_values_threshold (void); /* Functions from alias.c */ #include "alias.h" -/* extern HOST_WIDE_INT get_varargs_alias_set (void); */ -/* extern HOST_WIDE_INT get_frame_alias_set (void); */ -/* extern void record_base_value (unsigned int, rtx, int); */ -/* extern HOST_WIDE_INT new_alias_set (void); */ -/* extern int can_address_p (tree); */ /* rtl.h and tree.h were included. */ diff --git a/gcc/testsuite/gcc.dg/attr-may-alias-1.c b/gcc/testsuite/gcc.dg/attr-may-alias-1.c new file mode 100644 index 00000000000..30e2bca6f48 --- /dev/null +++ b/gcc/testsuite/gcc.dg/attr-may-alias-1.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-final { scan-assembler "dont_delete" } } */ + +typedef struct { int x; } __attribute__((may_alias)) S; + +extern void dont_delete (void); + +void f(S *s, float *f) +{ + s->x = 1; + *f = 0; + if (s->x != 1) + dont_delete (); +}