c-common.c (c_get_alias_set): Tighten slightly for FUNCTION_TYPEs and ARRAY_TYPEs.
* c-common.c (c_get_alias_set): Tighten slightly for FUNCTION_TYPEs and ARRAY_TYPEs. Tidy up. Improve support for type-punning. * expr.c (store_field): Add alias_set parameter. Set the MEM_ALIAS_SET accordingly, if the target is a MEM. (expand_assignment): Use it. (store_constructor_field): Pass 0. (expand_expr): Likewise. From-SVN: r22620
This commit is contained in:
parent
7d0756fbf1
commit
ece320145f
@ -1,3 +1,13 @@
|
||||
Mon Sep 28 07:43:34 1998 Mark Mitchell <mark@markmitchell.com>
|
||||
|
||||
* c-common.c (c_get_alias_set): Tighten slightly for FUNCTION_TYPEs
|
||||
and ARRAY_TYPEs. Tidy up. Improve support for type-punning.
|
||||
* expr.c (store_field): Add alias_set parameter. Set the
|
||||
MEM_ALIAS_SET accordingly, if the target is a MEM.
|
||||
(expand_assignment): Use it.
|
||||
(store_constructor_field): Pass 0.
|
||||
(expand_expr): Likewise.
|
||||
|
||||
Mon Sep 28 07:54:03 1998 Catherine Moore <clm@cygnus.com>
|
||||
|
||||
* flags.h: Add flag_data_sections.
|
||||
|
@ -2990,14 +2990,13 @@ c_get_alias_set (t)
|
||||
return 0;
|
||||
|
||||
type = (TREE_CODE_CLASS (TREE_CODE (t)) == 't')
|
||||
? t : TREE_TYPE (t);
|
||||
? t : TREE_TYPE (t);
|
||||
|
||||
if (type == error_mark_node)
|
||||
return 0;
|
||||
|
||||
if (TYPE_ALIAS_SET_KNOWN_P (type))
|
||||
/* If we've already calculated the value, just return it. */
|
||||
return TYPE_ALIAS_SET (type);
|
||||
/* Deal with special cases first; for certain kinds of references
|
||||
we're interested in more than just the type. */
|
||||
|
||||
if (TREE_CODE (t) == BIT_FIELD_REF)
|
||||
/* Perhaps reads and writes to this piece of data alias fields
|
||||
@ -3005,6 +3004,7 @@ c_get_alias_set (t)
|
||||
let's just assume that bitfields can alias everything, which is
|
||||
the conservative assumption. */
|
||||
return 0;
|
||||
|
||||
if (TREE_CODE (t) == COMPONENT_REF
|
||||
&& TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0))) == UNION_TYPE)
|
||||
/* Permit type-punning when accessing a union, provided the
|
||||
@ -3014,13 +3014,16 @@ c_get_alias_set (t)
|
||||
GCC extension, albeit a common and useful one; the C standard
|
||||
says that such accesses have implementation-defined behavior. */
|
||||
return 0;
|
||||
|
||||
/* From here on, only the type matters. */
|
||||
|
||||
if (TYPE_ALIAS_SET_KNOWN_P (type))
|
||||
/* If we've already calculated the value, just return it. */
|
||||
return TYPE_ALIAS_SET (type);
|
||||
else if (TYPE_MAIN_VARIANT (type) != type)
|
||||
{
|
||||
/* The C standard specifically allows aliasing between
|
||||
cv-qualified variants of types. */
|
||||
TYPE_ALIAS_SET (type) = c_get_alias_set (TYPE_MAIN_VARIANT (type));
|
||||
return TYPE_ALIAS_SET (type);
|
||||
}
|
||||
/* The C standard specifically allows aliasing between
|
||||
cv-qualified variants of types. */
|
||||
TYPE_ALIAS_SET (type) = c_get_alias_set (TYPE_MAIN_VARIANT (type));
|
||||
else if (TREE_CODE (type) == INTEGER_TYPE)
|
||||
{
|
||||
tree signed_variant;
|
||||
@ -3031,34 +3034,37 @@ c_get_alias_set (t)
|
||||
signed_variant = signed_type (type);
|
||||
|
||||
if (signed_variant != type)
|
||||
{
|
||||
TYPE_ALIAS_SET (type) = c_get_alias_set (signed_variant);
|
||||
return TYPE_ALIAS_SET (type);
|
||||
}
|
||||
TYPE_ALIAS_SET (type) = c_get_alias_set (signed_variant);
|
||||
else if (signed_variant == signed_char_type_node)
|
||||
/* The C standard guarantess that any object may be accessed
|
||||
via an lvalue that has character type. We don't have to
|
||||
check for unsigned_char_type_node or char_type_node because
|
||||
we are specifically looking at the signed variant. */
|
||||
{
|
||||
TYPE_ALIAS_SET (type) = 0;
|
||||
return TYPE_ALIAS_SET (type);
|
||||
}
|
||||
TYPE_ALIAS_SET (type) = 0;
|
||||
}
|
||||
else if (TREE_CODE (type) == ARRAY_TYPE)
|
||||
/* Anything that can alias one of the array elements can alias
|
||||
the entire array as well. */
|
||||
TYPE_ALIAS_SET (type) = c_get_alias_set (TREE_TYPE (type));
|
||||
else if (TREE_CODE (type) == FUNCTION_TYPE)
|
||||
/* 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 and references to functions, but that's
|
||||
different.) */
|
||||
TYPE_ALIAS_SET (type) = 0;
|
||||
else if (TREE_CODE (type) == RECORD_TYPE
|
||||
|| TREE_CODE (type) == UNION_TYPE)
|
||||
{
|
||||
/* If TYPE is a struct or union type then we're reading or
|
||||
writing an entire struct. Thus, we don't know anything about
|
||||
aliasing. (In theory, such an access can only alias objects
|
||||
whose type is the same as one of the fields, recursively, but
|
||||
we don't yet make any use of that information.) */
|
||||
TYPE_ALIAS_SET (type) = 0;
|
||||
return TYPE_ALIAS_SET (type);
|
||||
}
|
||||
/* If TYPE is a struct or union type then we're reading or
|
||||
writing an entire struct. Thus, we don't know anything about
|
||||
aliasing. (In theory, such an access can only alias objects
|
||||
whose type is the same as one of the fields, recursively, but
|
||||
we don't yet make any use of that information.) */
|
||||
TYPE_ALIAS_SET (type) = 0;
|
||||
|
||||
if (!TYPE_ALIAS_SET_KNOWN_P (type))
|
||||
/* TYPE is something we haven't seen before. Put it in a new
|
||||
alias set. */
|
||||
TYPE_ALIAS_SET (type) = new_alias_set ();
|
||||
|
||||
/* TYPE is something we haven't seen before. Put it in a new alias
|
||||
set. */
|
||||
TYPE_ALIAS_SET (type) = new_alias_set ();
|
||||
return TYPE_ALIAS_SET (type);
|
||||
}
|
||||
|
23
gcc/expr.c
23
gcc/expr.c
@ -168,7 +168,8 @@ static void store_constructor_field PROTO((rtx, int, int, enum machine_mode,
|
||||
tree, tree, int));
|
||||
static void store_constructor PROTO((tree, rtx, int));
|
||||
static rtx store_field PROTO((rtx, int, int, enum machine_mode, tree,
|
||||
enum machine_mode, int, int, int));
|
||||
enum machine_mode, int, int,
|
||||
int, int));
|
||||
static enum memory_use_mode
|
||||
get_memory_usage_from_modifier PROTO((enum expand_modifier));
|
||||
static tree save_noncopied_parts PROTO((tree, tree));
|
||||
@ -3223,7 +3224,8 @@ expand_assignment (to, from, want_value, suggest_reg)
|
||||
unsignedp,
|
||||
/* Required alignment of containing datum. */
|
||||
alignment,
|
||||
int_size_in_bytes (TREE_TYPE (tem)));
|
||||
int_size_in_bytes (TREE_TYPE (tem)),
|
||||
get_alias_set (to));
|
||||
preserve_temp_slots (result);
|
||||
free_temp_slots ();
|
||||
pop_temp_slots ();
|
||||
@ -3805,7 +3807,7 @@ store_constructor_field (target, bitsize, bitpos,
|
||||
else
|
||||
store_field (target, bitsize, bitpos, mode, exp,
|
||||
VOIDmode, 0, TYPE_ALIGN (type) / BITS_PER_UNIT,
|
||||
int_size_in_bytes (type));
|
||||
int_size_in_bytes (type), 0);
|
||||
}
|
||||
|
||||
/* Store the value of constructor EXP into the rtx TARGET.
|
||||
@ -4385,11 +4387,15 @@ store_constructor (exp, target, cleared)
|
||||
In this case, UNSIGNEDP must be nonzero if the value is an unsigned type.
|
||||
|
||||
ALIGN is the alignment that TARGET is known to have, measured in bytes.
|
||||
TOTAL_SIZE is the size in bytes of the structure, or -1 if varying. */
|
||||
TOTAL_SIZE is the size in bytes of the structure, or -1 if varying.
|
||||
|
||||
ALIAS_SET is the alias set for the destination. This value will
|
||||
(in general) be different from that for TARGET, since TARGET is a
|
||||
reference to the containing structure. */
|
||||
|
||||
static rtx
|
||||
store_field (target, bitsize, bitpos, mode, exp, value_mode,
|
||||
unsignedp, align, total_size)
|
||||
unsignedp, align, total_size, alias_set)
|
||||
rtx target;
|
||||
int bitsize, bitpos;
|
||||
enum machine_mode mode;
|
||||
@ -4398,6 +4404,7 @@ store_field (target, bitsize, bitpos, mode, exp, value_mode,
|
||||
int unsignedp;
|
||||
int align;
|
||||
int total_size;
|
||||
int alias_set;
|
||||
{
|
||||
HOST_WIDE_INT width_mask = 0;
|
||||
|
||||
@ -4433,7 +4440,7 @@ store_field (target, bitsize, bitpos, mode, exp, value_mode,
|
||||
emit_move_insn (object, target);
|
||||
|
||||
store_field (blk_object, bitsize, bitpos, mode, exp, VOIDmode, 0,
|
||||
align, total_size);
|
||||
align, total_size, alias_set);
|
||||
|
||||
/* Even though we aren't returning target, we need to
|
||||
give it the updated value. */
|
||||
@ -4548,6 +4555,7 @@ store_field (target, bitsize, bitpos, mode, exp, value_mode,
|
||||
(bitpos
|
||||
/ BITS_PER_UNIT))));
|
||||
MEM_IN_STRUCT_P (to_rtx) = 1;
|
||||
MEM_ALIAS_SET (to_rtx) = alias_set;
|
||||
|
||||
return store_expr (exp, to_rtx, value_mode != VOIDmode);
|
||||
}
|
||||
@ -6614,7 +6622,8 @@ expand_expr (exp, target, tmode, modifier)
|
||||
store_field (target, GET_MODE_BITSIZE (TYPE_MODE (valtype)), 0,
|
||||
TYPE_MODE (valtype), TREE_OPERAND (exp, 0),
|
||||
VOIDmode, 0, 1,
|
||||
int_size_in_bytes (TREE_TYPE (TREE_OPERAND (exp, 0))));
|
||||
int_size_in_bytes (TREE_TYPE (TREE_OPERAND (exp, 0))),
|
||||
0);
|
||||
else
|
||||
abort ();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user