mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-01-26 07:34:00 +08:00
tree-ssa-alias.c (fieldoff_t): Remove.
* tree-ssa-alias.c (fieldoff_t): Remove. (fieldoff_s): typedef the structure itself. Create a vector of objects. (push_fields_onto_fieldstack): Return count of fields pushed. Remove peeling of first field. Adjust. (fieldoff_compare): Adjust. (create_overlap_variables_for): Adjust. From-SVN: r98723
This commit is contained in:
parent
9821b2576f
commit
2845f02a6f
@ -1,3 +1,13 @@
|
||||
2005-04-25 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
* tree-ssa-alias.c (fieldoff_t): Remove.
|
||||
(fieldoff_s): typedef the structure itself. Create a vector of
|
||||
objects.
|
||||
(push_fields_onto_fieldstack): Return count of fields pushed.
|
||||
Remove peeling of first field. Adjust.
|
||||
(fieldoff_compare): Adjust.
|
||||
(create_overlap_variables_for): Adjust.
|
||||
|
||||
2005-04-25 Joseph S. Myers <joseph@codesourcery.com>
|
||||
|
||||
* doc/invoke.texi (Blackfin Options): Avoid empty @opindex line.
|
||||
|
@ -2789,11 +2789,10 @@ typedef struct fieldoff
|
||||
{
|
||||
tree field;
|
||||
HOST_WIDE_INT offset;
|
||||
} *fieldoff_t;
|
||||
} fieldoff_s;
|
||||
|
||||
DEF_VEC_P (fieldoff_t); /* FIXME: This can be a vector of struct
|
||||
fieldoff objects (nathan 2005/04/15) */
|
||||
DEF_VEC_ALLOC_P(fieldoff_t,heap);
|
||||
DEF_VEC_O (fieldoff_s);
|
||||
DEF_VEC_ALLOC_O(fieldoff_s,heap);
|
||||
|
||||
/* Return the position, in bits, of FIELD_DECL from the beginning of its
|
||||
structure.
|
||||
@ -2815,71 +2814,52 @@ bitpos_of_field (const tree fdecl)
|
||||
/* Given a TYPE, and a vector of field offsets FIELDSTACK, push all the fields
|
||||
of TYPE onto fieldstack, recording their offsets along the way.
|
||||
OFFSET is used to keep track of the offset in this entire structure, rather
|
||||
than just the immediately containing structure. */
|
||||
than just the immediately containing structure. Returns the number
|
||||
of fields pushed. */
|
||||
|
||||
static void
|
||||
push_fields_onto_fieldstack (tree type, VEC(fieldoff_t,heap) **fieldstack,
|
||||
static int
|
||||
push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack,
|
||||
HOST_WIDE_INT offset)
|
||||
{
|
||||
fieldoff_t pair;
|
||||
tree field = TYPE_FIELDS (type);
|
||||
if (!field)
|
||||
return;
|
||||
if (var_can_have_subvars (field)
|
||||
&& TREE_CODE (field) == FIELD_DECL)
|
||||
{
|
||||
size_t before = VEC_length (fieldoff_t, *fieldstack);
|
||||
/* Empty structures may have actual size, like in C++. So see if we
|
||||
actually end up pushing a field, and if not, if the size is nonzero,
|
||||
push the field onto the stack */
|
||||
push_fields_onto_fieldstack (TREE_TYPE (field), fieldstack, offset);
|
||||
if (before == VEC_length (fieldoff_t, *fieldstack)
|
||||
&& DECL_SIZE (field)
|
||||
&& !integer_zerop (DECL_SIZE (field)))
|
||||
{
|
||||
pair = xmalloc (sizeof (struct fieldoff));
|
||||
pair->field = field;
|
||||
pair->offset = offset;
|
||||
VEC_safe_push (fieldoff_t, heap, *fieldstack, pair);
|
||||
}
|
||||
}
|
||||
else if (TREE_CODE (field) == FIELD_DECL)
|
||||
{
|
||||
pair = xmalloc (sizeof (struct fieldoff));
|
||||
pair->field = field;
|
||||
pair->offset = offset + bitpos_of_field (field);
|
||||
VEC_safe_push (fieldoff_t, heap, *fieldstack, pair);
|
||||
}
|
||||
for (field = TREE_CHAIN (field); field; field = TREE_CHAIN (field))
|
||||
{
|
||||
if (TREE_CODE (field) != FIELD_DECL)
|
||||
continue;
|
||||
if (var_can_have_subvars (field))
|
||||
{
|
||||
size_t before = VEC_length (fieldoff_t, *fieldstack);
|
||||
push_fields_onto_fieldstack (TREE_TYPE (field), fieldstack,
|
||||
offset + bitpos_of_field (field));
|
||||
/* Empty structures may have actual size, like in C++. So see if we
|
||||
actually end up pushing a field, and if not, if the size is nonzero,
|
||||
push the field onto the stack */
|
||||
if (before == VEC_length (fieldoff_t, *fieldstack)
|
||||
&& DECL_SIZE (field)
|
||||
&& !integer_zerop (DECL_SIZE (field)))
|
||||
{
|
||||
pair = xmalloc (sizeof (struct fieldoff));
|
||||
pair->field = field;
|
||||
pair->offset = offset + bitpos_of_field (field);
|
||||
VEC_safe_push (fieldoff_t, heap, *fieldstack, pair);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pair = xmalloc (sizeof (struct fieldoff));
|
||||
pair->field = field;
|
||||
pair->offset = offset + bitpos_of_field (field);
|
||||
VEC_safe_push (fieldoff_t, heap, *fieldstack, pair);
|
||||
}
|
||||
}
|
||||
tree field;
|
||||
int count = 0;
|
||||
|
||||
/* Although there is nothing wrong per se with a structure whose
|
||||
first field does not start at offset 0, there appeared to be an
|
||||
Ada bug where the first field's offset was not zero, but the
|
||||
field itself was at offset zero. Make sure that doesn't
|
||||
reoccur. */
|
||||
gcc_assert (!TYPE_FIELDS (type)
|
||||
|| TREE_CODE (TYPE_FIELDS (type)) != FIELD_DECL
|
||||
|| !bitpos_of_field (TYPE_FIELDS (type)));
|
||||
for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
|
||||
if (TREE_CODE (field) == FIELD_DECL)
|
||||
{
|
||||
bool push = false;
|
||||
|
||||
if (!var_can_have_subvars (field))
|
||||
push = true;
|
||||
else if (!(push_fields_onto_fieldstack
|
||||
(TREE_TYPE (field), fieldstack,
|
||||
offset + bitpos_of_field (field)))
|
||||
&& DECL_SIZE (field)
|
||||
&& !integer_zerop (DECL_SIZE (field)))
|
||||
/* Empty structures may have actual size, like in C++. So
|
||||
see if we didn't push any subfields and the size is
|
||||
nonzero, push the field onto the stack */
|
||||
push = true;
|
||||
|
||||
if (push)
|
||||
{
|
||||
fieldoff_s *pair;
|
||||
|
||||
pair = VEC_safe_push (fieldoff_s, heap, *fieldstack, NULL);
|
||||
pair->field = field;
|
||||
pair->offset = offset + bitpos_of_field (field);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
@ -2922,22 +2902,21 @@ get_or_create_used_part_for (size_t uid)
|
||||
return up;
|
||||
}
|
||||
|
||||
/* qsort comparison function for two fieldoff_t's PA and PB */
|
||||
/* qsort comparison function for two fieldoff's PA and PB */
|
||||
|
||||
static int
|
||||
fieldoff_compare (const void *pa, const void *pb)
|
||||
{
|
||||
const fieldoff_t foa = *(fieldoff_t *)pa;
|
||||
const fieldoff_t fob = *(fieldoff_t *)pb;
|
||||
const fieldoff_s *foa = (const fieldoff_s *)pa;
|
||||
const fieldoff_s *fob = (const fieldoff_s *)pb;
|
||||
HOST_WIDE_INT foasize, fobsize;
|
||||
|
||||
if (foa->offset != fob->offset)
|
||||
return foa->offset - fob->offset;
|
||||
|
||||
foasize = TREE_INT_CST_LOW (DECL_SIZE (foa->field));
|
||||
fobsize = TREE_INT_CST_LOW (DECL_SIZE (fob->field));
|
||||
if (foasize != fobsize)
|
||||
return foasize - fobsize;
|
||||
return 0;
|
||||
return foasize - fobsize;
|
||||
}
|
||||
|
||||
/* Given an aggregate VAR, create the subvariables that represent its
|
||||
@ -2946,7 +2925,7 @@ fieldoff_compare (const void *pa, const void *pb)
|
||||
static void
|
||||
create_overlap_variables_for (tree var)
|
||||
{
|
||||
VEC(fieldoff_t,heap) *fieldstack = NULL;
|
||||
VEC(fieldoff_s,heap) *fieldstack = NULL;
|
||||
used_part_t up;
|
||||
size_t uid = var_ann (var)->uid;
|
||||
|
||||
@ -2955,10 +2934,10 @@ create_overlap_variables_for (tree var)
|
||||
|
||||
up = used_portions[uid];
|
||||
push_fields_onto_fieldstack (TREE_TYPE (var), &fieldstack, 0);
|
||||
if (VEC_length (fieldoff_t, fieldstack) != 0)
|
||||
if (VEC_length (fieldoff_s, fieldstack) != 0)
|
||||
{
|
||||
subvar_t *subvars;
|
||||
fieldoff_t fo;
|
||||
fieldoff_s *fo;
|
||||
bool notokay = false;
|
||||
int fieldcount = 0;
|
||||
int i;
|
||||
@ -2975,7 +2954,7 @@ create_overlap_variables_for (tree var)
|
||||
currently don't. Doing so would require some extra changes to
|
||||
tree-ssa-operands.c. */
|
||||
|
||||
for (i = 0; VEC_iterate (fieldoff_t, fieldstack, i, fo); i++)
|
||||
for (i = 0; VEC_iterate (fieldoff_s, fieldstack, i, fo); i++)
|
||||
{
|
||||
if (!DECL_SIZE (fo->field)
|
||||
|| TREE_CODE (DECL_SIZE (fo->field)) != INTEGER_CST
|
||||
@ -3012,34 +2991,29 @@ create_overlap_variables_for (tree var)
|
||||
notokay = true;
|
||||
}
|
||||
|
||||
|
||||
/* Cleanup after ourselves if we can't create overlap variables. */
|
||||
/* Bail out, if we can't create overlap variables. */
|
||||
if (notokay)
|
||||
{
|
||||
while (VEC_length (fieldoff_t, fieldstack) != 0)
|
||||
{
|
||||
fo = VEC_pop (fieldoff_t, fieldstack);
|
||||
free (fo);
|
||||
}
|
||||
VEC_free (fieldoff_t, heap, fieldstack);
|
||||
VEC_free (fieldoff_s, heap, fieldstack);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Otherwise, create the variables. */
|
||||
subvars = lookup_subvars_for_var (var);
|
||||
|
||||
qsort (VEC_address (fieldoff_t, fieldstack),
|
||||
VEC_length (fieldoff_t, fieldstack),
|
||||
sizeof (fieldoff_t),
|
||||
qsort (VEC_address (fieldoff_s, fieldstack),
|
||||
VEC_length (fieldoff_s, fieldstack),
|
||||
sizeof (fieldoff_s),
|
||||
fieldoff_compare);
|
||||
|
||||
while (VEC_length (fieldoff_t, fieldstack) != 0)
|
||||
for (i = VEC_length (fieldoff_s, fieldstack);
|
||||
VEC_iterate (fieldoff_s, fieldstack, --i, fo);)
|
||||
{
|
||||
subvar_t sv;
|
||||
HOST_WIDE_INT fosize;
|
||||
var_ann_t ann;
|
||||
tree currfotype;
|
||||
|
||||
fo = VEC_pop (fieldoff_t, fieldstack);
|
||||
fosize = TREE_INT_CST_LOW (DECL_SIZE (fo->field));
|
||||
currfotype = TREE_TYPE (fo->field);
|
||||
|
||||
@ -3053,10 +3027,7 @@ create_overlap_variables_for (tree var)
|
||||
|| (fo->offset == lastfooffset
|
||||
&& fosize == lastfosize
|
||||
&& currfotype == lastfotype))
|
||||
{
|
||||
free (fo);
|
||||
continue;
|
||||
}
|
||||
continue;
|
||||
sv = ggc_alloc (sizeof (struct subvar));
|
||||
sv->offset = fo->offset;
|
||||
sv->size = fosize;
|
||||
@ -3071,7 +3042,6 @@ create_overlap_variables_for (tree var)
|
||||
fprintf (dump_file, " size " HOST_WIDE_INT_PRINT_DEC,
|
||||
sv->size);
|
||||
fprintf (dump_file, "\n");
|
||||
|
||||
}
|
||||
|
||||
/* We need to copy the various flags from var to sv->var, so that
|
||||
@ -3097,7 +3067,6 @@ create_overlap_variables_for (tree var)
|
||||
lastfooffset = fo->offset;
|
||||
lastfosize = fosize;
|
||||
*subvars = sv;
|
||||
free (fo);
|
||||
}
|
||||
|
||||
/* Once we have created subvars, the original is no longer call
|
||||
@ -3108,10 +3077,9 @@ create_overlap_variables_for (tree var)
|
||||
marking subvars of global variables as call clobbered for us
|
||||
to start, since they are global as well. */
|
||||
clear_call_clobbered (var);
|
||||
|
||||
}
|
||||
|
||||
VEC_free (fieldoff_t, heap, fieldstack);
|
||||
VEC_free (fieldoff_s, heap, fieldstack);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user