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:
Mark Mitchell 1998-09-28 07:44:12 +00:00 committed by Mark Mitchell
parent 7d0756fbf1
commit ece320145f
3 changed files with 62 additions and 37 deletions

View File

@ -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.

View File

@ -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);
}

View File

@ -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 ();