This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Aliasing safety patch
- To: gcc-patches at gcc dot gnu dot org
- Subject: Aliasing safety patch
- From: kenner at vlsi1 dot ultra dot nyu dot edu (Richard Kenner)
- Date: Fri, 2 Jun 00 22:10:41 EDT
This came from discussions about the aliasing patch and makes it
conservative for language that don't handle aliasing:
Fri Jun 2 19:31:03 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
* alias.c (struct alias_set_entry): New field has_zero_child.
(mem_in_disjoint_alias_sets_p): Return 0 if set in either ase.
(get_alias_set): If language-dependent routine set TYPE_ALIAS_SET,
do nothing.
Call record_component_aliases for aggregate types.
(record_alias_subset): Set has_zero_child.
(record_component_aliases, case ARRAY_TYPE): Do nothing if
TYPE_NONALIASES_COMPONENT.
(record_component_aliases, case RECORD_TYPE): Test
DECL_NONADDRESSABLE_P.
* c-decl.c (grokdeclarator): Set DECL_NONADDRESSABLE_P instead
of TREE_ADDRESSABLE.
* calls.c (initialize_argument_information): Only test
TYPE_TRANSPARENT_UNION for UNION_TYPE.
* function.c (assign_parms): Likewise.
* integrate.c (function_cannot_inline_p): Likewise.
* stor-layout.c (finish_record_layout): Don't call
record_component_aliases.
* tree.h (struct tree_int_cst): Use struct tree_common.
(struct tree_real_cst, struct tree_string): Likewise.
(struct tree_complex, struct tree_identifier): Likewise.
(struct tree_list, struct tree_vec, struct tree_exp): Likewise.
(struct tree_block, struct tree_type, struct tree_decl): Likewise.
(TYPE_TRANSPARENT_UNION): Use UNION_TYPE_CHECK.
(TYPE_NONALIASES_COMPONENT): New macro.
(TYPE_AMBIENT_BOUNDEDNESS): Use FUNCTION_TYPE_CHECK.
(DECL_NONADDRESSABLE_P): New macro.
(struct tree_decl): Reorder bits for clarity of how many left;
add non_adressable.
* cp/cp-tree.h: Use struct tree_common instead of a char array.
* cp/decl.c (grokdeclarator): Set DECL_NONADDRESSABLE_P instead
of TREE_ADDRESSABLE.
*** alias.c 2000/06/01 16:18:18 1.84
--- alias.c 2000/06/02 23:12:35
*************** typedef struct alias_set_entry
*** 80,83 ****
--- 80,87 ----
`int', `double', `float', and `struct S'. */
splay_tree children;
+
+ /* Nonzero if would have a child of zero: this effectively makes this
+ alias set the same as alias set zero. */
+ int has_zero_child;
} *alias_set_entry;
*************** mems_in_disjoint_alias_sets_p (mem1, mem
*** 244,255 ****
/* See if the first alias set is a subset of the second. */
ase = get_alias_set_entry (MEM_ALIAS_SET (mem1));
! if (ase != 0 && splay_tree_lookup (ase->children,
! (splay_tree_key) MEM_ALIAS_SET (mem2)))
return 0;
/* Now do the same, but with the alias sets reversed. */
ase = get_alias_set_entry (MEM_ALIAS_SET (mem2));
! if (ase != 0 && splay_tree_lookup (ase->children,
! (splay_tree_key) MEM_ALIAS_SET (mem1)))
return 0;
--- 248,263 ----
/* See if the first alias set is a subset of the second. */
ase = get_alias_set_entry (MEM_ALIAS_SET (mem1));
! if (ase != 0
! && (ase->has_zero_child
! || splay_tree_lookup (ase->children,
! (splay_tree_key) MEM_ALIAS_SET (mem2))))
return 0;
/* Now do the same, but with the alias sets reversed. */
ase = get_alias_set_entry (MEM_ALIAS_SET (mem2));
! if (ase != 0
! && (ase->has_zero_child
! || splay_tree_lookup (ase->children,
! (splay_tree_key) MEM_ALIAS_SET (mem1))))
return 0;
*************** get_alias_set (t)
*** 413,417 ****
if (lang_get_alias_set != 0
&& (set = (*lang_get_alias_set) (t)) != -1)
! ;
/* There are no objects of FUNCTION_TYPE, so there's no point in
using up an alias set for them. (There are, of course, pointers
--- 421,430 ----
if (lang_get_alias_set != 0
&& (set = (*lang_get_alias_set) (t)) != -1)
! {
! /* If the alias set is now known, we are done. */
! if (TYPE_ALIAS_SET_KNOWN_P (t))
! return TYPE_ALIAS_SET (t);
! }
!
/* There are no objects of FUNCTION_TYPE, so there's no point in
using up an alias set for them. (There are, of course, pointers
*************** get_alias_set (t)
*** 424,427 ****
--- 437,446 ----
TYPE_ALIAS_SET (t) = set;
+
+ /* If this is an aggregate type, we must record any component aliasing
+ information. */
+ if (AGGREGATE_TYPE_P (t))
+ record_component_aliases (t);
+
return set;
}
*************** record_alias_subset (superset, subset)
*** 474,490 ****
}
! subset_entry = get_alias_set_entry (subset);
! /* If there is an entry for the subset, enter all of its children
! (if they are not already present) as children of the SUPERSET. */
! if (subset_entry)
! splay_tree_foreach (subset_entry->children,
! insert_subset_children,
! superset_entry->children);
!
! /* Enter the SUBSET itself as a child of the SUPERSET. */
! splay_tree_insert (superset_entry->children,
! (splay_tree_key) subset, 0);
}
--- 493,517 ----
}
+
+ if (subset == 0)
+ superset_entry->has_zero_child = 1;
+ else
+ {
+ subset_entry = get_alias_set_entry (subset);
+ /* If there is an entry for the subset, enter all of its children
+ (if they are not already present) as children of the SUPERSET. */
+ if (subset_entry)
+ {
+ if (subset_entry->has_zero_child)
+ superset_entry->has_zero_child = 1;
! splay_tree_foreach (subset_entry->children, insert_subset_children,
! superset_entry->children);
! }
! /* Enter the SUBSET itself as a child of the SUPERSET. */
! splay_tree_insert (superset_entry->children,
! (splay_tree_key) subset, 0);
! }
}
*************** record_component_aliases (type)
*** 500,504 ****
{
HOST_WIDE_INT superset = get_alias_set (type);
- HOST_WIDE_INT subset;
tree field;
--- 527,530 ----
*************** record_component_aliases (type)
*** 509,515 ****
{
case ARRAY_TYPE:
! subset = get_alias_set (TREE_TYPE (type));
! if (subset != 0)
! record_alias_subset (superset, subset);
break;
--- 535,540 ----
{
case ARRAY_TYPE:
! if (! TYPE_NONALIASED_COMPONENT (type))
! record_alias_subset (superset, get_alias_set (TREE_TYPE (type)));
break;
*************** record_component_aliases (type)
*** 518,526 ****
case QUAL_UNION_TYPE:
for (field = TYPE_FIELDS (type); field != 0; field = TREE_CHAIN (field))
! {
! subset = get_alias_set (TREE_TYPE (field));
! if (TREE_ADDRESSABLE (field) && subset != 0 && subset != superset)
! record_alias_subset (superset, subset);
! }
break;
--- 543,548 ----
case QUAL_UNION_TYPE:
for (field = TYPE_FIELDS (type); field != 0; field = TREE_CHAIN (field))
! if (! DECL_NONADDRESSABLE_P (field))
! record_alias_subset (superset, get_alias_set (TREE_TYPE (field)));
break;
*** c-decl.c 2000/06/01 09:44:37 1.115
--- c-decl.c 2000/06/02 23:12:50
*************** grokdeclarator (declarator, declspecs, d
*** 4700,4704 ****
}
decl = build_decl (FIELD_DECL, declarator, type);
! TREE_ADDRESSABLE (decl) = ! bitfield;
if (size_varies)
C_DECL_VARIABLE_SIZE (decl) = 1;
--- 4700,4705 ----
}
decl = build_decl (FIELD_DECL, declarator, type);
! DECL_NONADDRESSABLE_P (decl) = bitfield;
!
if (size_varies)
C_DECL_VARIABLE_SIZE (decl) = 1;
*** calls.c 2000/05/31 18:36:03 1.139
--- calls.c 2000/06/02 23:13:06
*************** initialize_argument_information (num_act
*** 1110,1114 ****
pass the first field of the union. We have already verified that
the modes are the same. */
! if (TYPE_TRANSPARENT_UNION (type))
type = TREE_TYPE (TYPE_FIELDS (type));
--- 1110,1114 ----
pass the first field of the union. We have already verified that
the modes are the same. */
! if (TREE_CODE (type) == UNION_TYPE && TYPE_TRANSPARENT_UNION (type))
type = TREE_TYPE (TYPE_FIELDS (type));
*** function.c 2000/05/31 18:36:03 1.202
--- function.c 2000/06/02 23:13:33
*************** assign_parms (fndecl)
*** 4232,4236 ****
verified that the modes are the same. */
if (DECL_TRANSPARENT_UNION (parm)
! || TYPE_TRANSPARENT_UNION (passed_type))
passed_type = TREE_TYPE (TYPE_FIELDS (passed_type));
--- 4232,4237 ----
verified that the modes are the same. */
if (DECL_TRANSPARENT_UNION (parm)
! || (TREE_CODE (passed_type) == UNION_TYPE
! && TYPE_TRANSPARENT_UNION (passed_type)))
passed_type = TREE_TYPE (TYPE_FIELDS (passed_type));
*** integrate.c 2000/06/01 01:12:19 1.108
--- integrate.c 2000/06/02 23:13:43
*************** function_cannot_inline_p (fndecl)
*** 202,206 ****
if (int_size_in_bytes (TREE_TYPE (parms)) < 0)
return N_("function with varying-size parameter cannot be inline");
! else if (TYPE_TRANSPARENT_UNION (TREE_TYPE (parms)))
return N_("function with transparent unit parameter cannot be inline");
}
--- 202,207 ----
if (int_size_in_bytes (TREE_TYPE (parms)) < 0)
return N_("function with varying-size parameter cannot be inline");
! else if (TREE_CODE (TREE_TYPE (parms)) == UNION_TYPE
! && TYPE_TRANSPARENT_UNION (TREE_TYPE (parms)))
return N_("function with transparent unit parameter cannot be inline");
}
*** stor-layout.c 2000/05/31 18:36:05 1.76
--- stor-layout.c 2000/06/02 23:13:49
*************** finish_record_layout (rli)
*** 1174,1180 ****
}
- /* Show any alias subsetting we need. */
- record_component_aliases (rli->t);
-
/* Clean up. */
free (rli);
--- 1174,1177 ----
*** tree.h 2000/05/31 20:53:37 1.175
--- tree.h 2000/06/02 23:14:04
*************** extern void tree_class_check_failed PARA
*** 672,676 ****
struct tree_int_cst
{
! char common[sizeof (struct tree_common)];
struct rtx_def *rtl; /* acts as link to register transfer language
(rtl) info */
--- 672,676 ----
struct tree_int_cst
{
! struct tree_common common;
struct rtx_def *rtl; /* acts as link to register transfer language
(rtl) info */
*************** struct tree_int_cst
*** 696,700 ****
struct tree_real_cst
{
! char common[sizeof (struct tree_common)];
struct rtx_def *rtl; /* acts as link to register transfer language
(rtl) info */
--- 696,700 ----
struct tree_real_cst
{
! struct tree_common common;
struct rtx_def *rtl; /* acts as link to register transfer language
(rtl) info */
*************** struct tree_real_cst
*** 708,712 ****
struct tree_string
{
! char common[sizeof (struct tree_common)];
struct rtx_def *rtl; /* acts as link to register transfer language
(rtl) info */
--- 708,712 ----
struct tree_string
{
! struct tree_common common;
struct rtx_def *rtl; /* acts as link to register transfer language
(rtl) info */
*************** struct tree_string
*** 721,725 ****
struct tree_complex
{
! char common[sizeof (struct tree_common)];
struct rtx_def *rtl; /* acts as link to register transfer language
(rtl) info */
--- 721,725 ----
struct tree_complex
{
! struct tree_common common;
struct rtx_def *rtl; /* acts as link to register transfer language
(rtl) info */
*************** struct tree_complex
*** 735,739 ****
struct tree_identifier
{
! char common[sizeof (struct tree_common)];
int length;
char *pointer;
--- 735,739 ----
struct tree_identifier
{
! struct tree_common common;
int length;
char *pointer;
*************** struct tree_identifier
*** 746,750 ****
struct tree_list
{
! char common[sizeof (struct tree_common)];
union tree_node *purpose;
union tree_node *value;
--- 746,750 ----
struct tree_list
{
! struct tree_common common;
union tree_node *purpose;
union tree_node *value;
*************** struct tree_list
*** 758,762 ****
struct tree_vec
{
! char common[sizeof (struct tree_common)];
int length;
union tree_node *a[1];
--- 758,762 ----
struct tree_vec
{
! struct tree_common common;
int length;
union tree_node *a[1];
*************** struct tree_vec
*** 814,818 ****
struct tree_exp
{
! char common[sizeof (struct tree_common)];
int complexity;
union tree_node *operands[1];
--- 814,818 ----
struct tree_exp
{
! struct tree_common common;
int complexity;
union tree_node *operands[1];
*************** struct tree_exp
*** 840,844 ****
struct tree_block
{
! char common[sizeof (struct tree_common)];
unsigned handler_block_flag : 1;
--- 840,844 ----
struct tree_block
{
! struct tree_common common;
unsigned handler_block_flag : 1;
*************** struct tree_block
*** 1008,1017 ****
/* Indicates that objects of this type must be initialized by calling a
function when they are created. */
! #define TYPE_NEEDS_CONSTRUCTING(NODE) (TYPE_CHECK (NODE)->type.needs_constructing_flag)
/* Indicates that objects of this type (a UNION_TYPE), should be passed
the same way that the first union alternative would be passed. */
! #define TYPE_TRANSPARENT_UNION(NODE) (TYPE_CHECK (NODE)->type.transparent_union_flag)
/* Indicated that objects of this type should be laid out in as
compact a way as possible. */
--- 1008,1024 ----
/* Indicates that objects of this type must be initialized by calling a
function when they are created. */
! #define TYPE_NEEDS_CONSTRUCTING(NODE) \
! (TYPE_CHECK (NODE)->type.needs_constructing_flag)
/* Indicates that objects of this type (a UNION_TYPE), should be passed
the same way that the first union alternative would be passed. */
! #define TYPE_TRANSPARENT_UNION(NODE) \
! (UNION_TYPE_CHECK (NODE)->type.transparent_union_flag)
+ /* For an ARRAY_TYPE, indicates that it is not permitted to
+ take the address of a component of the type. */
+ #define TYPE_NONALIASED_COMPONENT(NODE) \
+ (ARRAY_TYPE_CHECK (NODE)->type.transparent_union_flag)
+
/* Indicated that objects of this type should be laid out in as
compact a way as possible. */
*************** struct tree_block
*** 1071,1076 ****
useful for choosing default boundedness of function arguments for
non-prototype function decls and for varargs/stdarg lists. */
!
! #define TYPE_AMBIENT_BOUNDEDNESS(TYPE) (TYPE_CHECK (TYPE)->type.transparent_union_flag)
#define MAX_POINTER_DEPTH 2
--- 1078,1083 ----
useful for choosing default boundedness of function arguments for
non-prototype function decls and for varargs/stdarg lists. */
! #define TYPE_AMBIENT_BOUNDEDNESS(TYPE) \
! (FUNCTION_TYPE_CHECK (TYPE)->type.transparent_union_flag)
#define MAX_POINTER_DEPTH 2
*************** struct tree_block
*** 1079,1083 ****
struct tree_type
{
! char common[sizeof (struct tree_common)];
union tree_node *values;
union tree_node *size;
--- 1086,1090 ----
struct tree_type
{
! struct tree_common common;
union tree_node *values;
union tree_node *size;
*************** struct tree_type
*** 1523,1526 ****
--- 1530,1538 ----
#define DECL_NON_ADDR_CONST_P(NODE) (DECL_CHECK (NODE)->decl.non_addr_const_p)
+ /* Used in a FIELD_DECL to indicate that we cannot form the address of
+ this component. */
+ #define DECL_NONADDRESSABLE_P(NODE) \
+ (FIELD_DECL_CHECK (NODE)->decl.non_addressable)
+
/* Used to indicate an alias set for the memory pointed to by this
particular FIELD_DECL, PARM_DECL, or VAR_DECL, which must have
*************** struct tree_type
*** 1545,1549 ****
struct tree_decl
{
! char common[sizeof (struct tree_common)];
const char *filename;
int linenum;
--- 1557,1561 ----
struct tree_decl
{
! struct tree_common common;
const char *filename;
int linenum;
*************** struct tree_decl
*** 1576,1582 ****
unsigned malloc_flag : 1;
unsigned no_limit_stack : 1;
- unsigned pure_flag : 1;
ENUM_BITFIELD(built_in_class) built_in_class : 2;
unsigned pointer_depth : 2;
unsigned lang_flag_0 : 1;
--- 1588,1597 ----
unsigned malloc_flag : 1;
unsigned no_limit_stack : 1;
ENUM_BITFIELD(built_in_class) built_in_class : 2;
+
+ unsigned pure_flag : 1;
unsigned pointer_depth : 2;
+ unsigned non_addressable : 1;
+ /* Four unused bits. */
unsigned lang_flag_0 : 1;
*** cp/cp-tree.h 2000/06/02 05:45:34 1.469
--- cp/cp-tree.h 2000/06/02 23:14:26
*************** typedef struct
*** 300,304 ****
typedef struct
{
! char common[sizeof (struct tree_common)];
HOST_WIDE_INT index;
HOST_WIDE_INT level;
--- 300,304 ----
typedef struct
{
! struct tree_common common;
HOST_WIDE_INT index;
HOST_WIDE_INT level;
*************** typedef struct
*** 309,313 ****
typedef struct ptrmem_cst
{
! char common[sizeof (struct tree_common)];
/* This isn't used, but the middle-end expects all constants to have
this field. */
--- 309,313 ----
typedef struct ptrmem_cst
{
! struct tree_common common;
/* This isn't used, but the middle-end expects all constants to have
this field. */
*************** typedef struct ptrmem_cst
*** 352,356 ****
struct tree_binding
{
! char common[sizeof (struct tree_common)];
union {
tree scope;
--- 352,356 ----
struct tree_binding
{
! struct tree_common common;
union {
tree scope;
*************** struct tree_binding
*** 375,379 ****
struct tree_overload
{
! char common[sizeof (struct tree_common)];
tree function;
};
--- 375,379 ----
struct tree_overload
{
! struct tree_common common;
tree function;
};
*************** struct tree_overload
*** 392,396 ****
struct tree_wrapper
{
! char common[sizeof (struct tree_common)];
union {
void *ptr;
--- 392,396 ----
struct tree_wrapper
{
! struct tree_common common;
union {
void *ptr;
*************** struct tree_wrapper
*** 403,407 ****
struct tree_srcloc
{
! char common[sizeof (struct tree_common)];
const char *filename;
int linenum;
--- 403,407 ----
struct tree_srcloc
{
! struct tree_common common;
const char *filename;
int linenum;
*** cp/decl.c 2000/06/02 19:38:35 1.622
--- cp/decl.c 2000/06/02 23:15:15
*************** grokdeclarator (declarator, declspecs, d
*** 11597,11601 ****
{
decl = build_decl (FIELD_DECL, declarator, type);
! TREE_ADDRESSABLE (decl) = ! bitfield;
if (RIDBIT_SETP (RID_MUTABLE, specbits))
{
--- 11597,11601 ----
{
decl = build_decl (FIELD_DECL, declarator, type);
! DECL_NONADDRESSABLE_P (decl) = bitfield;
if (RIDBIT_SETP (RID_MUTABLE, specbits))
{