+2004-12-03 Richard Henderson <rth@redhat.com>
+
+ * 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 <rth@redhat.com>
* doc/tm.texi (TARGET_BUILD_BUILTIN_VA_LIST): New.
}
}
-/* 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:
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;
}
}
/* 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);
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 */
|| 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. */
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;
}
/* 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); */
\f
/* rtl.h and tree.h were included. */
--- /dev/null
+/* { 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 ();
+}