[multiple changes]

2004-12-22  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>

        * trans.c (mark_visited): Set TYPE_SIZES_GIMPLIFIED.

2004-12-22  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>

        * tree.h (TYPE_SIZES_GIMPLIFIED): New.
        * function.c (gimplify_parm_type): Don't gimplify type if already done.
        * gimplify.c (gimplify_decl_expr): Likewise.
        (gimplify_type_sizes): Set TYPE_SIZES_GIMPLIFIED.  Examine nested
        array types.

2004-12-22  Richard Henderson  <rth@redhat.com>

        * gimplify.c (eval_save_expr): Remove.
        (gimplify_one_sizepos): Unshare expr before gimplifying.
        * stor-layout.c (variable_size): Revert 2004-12-19 change.
        (layout_decl): Revert 2004-12-18 change.
        (layout_type): Revert 2004-12-21 change.

From-SVN: r92495
This commit is contained in:
Richard Henderson 2004-12-22 10:51:24 -08:00
parent ba9ce455bb
commit ad50bc8d80
7 changed files with 77 additions and 36 deletions

View File

@ -1,3 +1,19 @@
2004-12-22 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
* tree.h (TYPE_SIZES_GIMPLIFIED): New.
* function.c (gimplify_parm_type): Don't gimplify type if already done.
* gimplify.c (gimplify_decl_expr): Likewise.
(gimplify_type_sizes): Set TYPE_SIZES_GIMPLIFIED. Examine nested
array types.
2004-12-22 Richard Henderson <rth@redhat.com>
* gimplify.c (eval_save_expr): Remove.
(gimplify_one_sizepos): Unshare expr before gimplifying.
* stor-layout.c (variable_size): Revert 2004-12-19 change.
(layout_decl): Revert 2004-12-18 change.
(layout_type): Revert 2004-12-21 change.
2004-12-22 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
* tree-sra.c (type_can_be_decomposed_p): Reject variable sized types.

View File

@ -1,3 +1,7 @@
2004-12-22 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
* trans.c (mark_visited): Set TYPE_SIZES_GIMPLIFIED.
2004-12-19 Richard Henderson <rth@redhat.com>
* trans.c (gigi): Update gimplify_body call.

View File

@ -4283,9 +4283,10 @@ add_decl_expr (tree gnu_decl, Entity_Id gnat_entity)
}
}
/* Utility function to mark nodes with TREE_VISITED. Called from walk_tree.
We use this to indicate all variable sizes and positions in global types
may not be shared by any subprogram. */
/* Utility function to mark nodes with TREE_VISITED and types as having their
sized gimplified. Called from walk_tree. We use this to indicate all
variable sizes and positions in global types may not be shared by any
subprogram. */
static tree
mark_visited (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
@ -4298,6 +4299,9 @@ mark_visited (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
else if (!TYPE_IS_DUMMY_P (*tp))
TREE_VISITED (*tp) = 1;
if (TYPE_P (*tp))
TYPE_SIZES_GIMPLIFIED (*tp) = 1;
return NULL_TREE;
}

View File

@ -3172,7 +3172,8 @@ gimplify_parm_type (tree *tp, int *walk_subtrees, void *data)
{
if (POINTER_TYPE_P (t))
*walk_subtrees = 1;
else if (TYPE_SIZE (t) && !TREE_CONSTANT (TYPE_SIZE (t)))
else if (TYPE_SIZE (t) && !TREE_CONSTANT (TYPE_SIZE (t))
&& !TYPE_SIZES_GIMPLIFIED (t))
{
gimplify_type_sizes (t, (tree *) data);
*walk_subtrees = 1;

View File

@ -996,7 +996,12 @@ gimplify_decl_expr (tree *stmt_p)
of the emitted code: see mx_register_decls(). */
tree t, args, addr, ptr_type;
gimplify_type_sizes (TREE_TYPE (decl), stmt_p);
/* ??? We really shouldn't need to gimplify the type of the variable
since it already should have been done. But leave this here
for now to avoid disrupting too many things at once. */
if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (decl)))
gimplify_type_sizes (TREE_TYPE (decl), stmt_p);
gimplify_one_sizepos (&DECL_SIZE (decl), stmt_p);
gimplify_one_sizepos (&DECL_SIZE_UNIT (decl), stmt_p);
@ -4180,7 +4185,17 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
void
gimplify_type_sizes (tree type, tree *list_p)
{
tree field;
tree field, t;
/* Note that we do not check for TYPE_SIZES_GIMPLIFIED already set because
that's not supposed to happen on types where gimplifcation does anything.
We should assert that it isn't set, but we can indeed be called multiple
times on pointers. Unfortunately, this includes fat pointers which we
can't easily test for. We could pass TYPE down to gimplify_one_sizepos
and test there, but it doesn't seem worth it. */
/* We first do the main variant, then copy into any other variants. */
type = TYPE_MAIN_VARIANT (type);
switch (TREE_CODE (type))
{
@ -4194,11 +4209,22 @@ gimplify_type_sizes (tree type, tree *list_p)
case REAL_TYPE:
gimplify_one_sizepos (&TYPE_MIN_VALUE (type), list_p);
gimplify_one_sizepos (&TYPE_MAX_VALUE (type), list_p);
for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
{
TYPE_MIN_VALUE (t) = TYPE_MIN_VALUE (type);
TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (type);
TYPE_SIZES_GIMPLIFIED (t) = 1;
}
break;
case ARRAY_TYPE:
/* These anonymous types don't have declarations, so handle them here. */
gimplify_type_sizes (TYPE_DOMAIN (type), list_p);
/* These types may not have declarations, so handle them here. */
if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (type)))
gimplify_type_sizes (TREE_TYPE (type), list_p);
if (!TYPE_SIZES_GIMPLIFIED (TYPE_DOMAIN (type)))
gimplify_type_sizes (TYPE_DOMAIN (type), list_p);
break;
case RECORD_TYPE:
@ -4215,23 +4241,15 @@ gimplify_type_sizes (tree type, tree *list_p)
gimplify_one_sizepos (&TYPE_SIZE (type), list_p);
gimplify_one_sizepos (&TYPE_SIZE_UNIT (type), list_p);
}
/* A subroutine of gimplify_one_sizepos, called via walk_tree. Evaluate
the expression if it's a SAVE_EXPR and add it to the statement list
in DATA. */
static tree
eval_save_expr (tree *tp, int *walk_subtrees, void *data)
{
if (TREE_CODE (*tp) == SAVE_EXPR)
for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
{
*walk_subtrees = 0;
gimplify_and_add (*tp, (tree *) data);
TYPE_SIZE (t) = TYPE_SIZE (type);
TYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (type);
TYPE_SIZES_GIMPLIFIED (t) = 1;
}
else if (TYPE_P (*tp) || DECL_P (*tp))
*walk_subtrees = 0;
return NULL;
TYPE_SIZES_GIMPLIFIED (type) = 1;
}
/* A subroutine of gimplify_type_sizes to make sure that *EXPR_P,
@ -4251,7 +4269,8 @@ gimplify_one_sizepos (tree *expr_p, tree *stmt_p)
|| CONTAINS_PLACEHOLDER_P (*expr_p))
return;
walk_tree (expr_p, eval_save_expr, stmt_p, NULL);
*expr_p = unshare_expr (*expr_p);
gimplify_expr (expr_p, stmt_p, NULL, is_gimple_val, fb_rvalue);
}
#ifdef ENABLE_CHECKING

View File

@ -125,19 +125,11 @@ variable_size (tree size)
just return SIZE unchanged. Likewise for self-referential sizes and
constant sizes. */
if (TREE_CONSTANT (size)
|| TREE_CODE (size) == SAVE_EXPR
|| lang_hooks.decls.global_bindings_p () < 0
|| CONTAINS_PLACEHOLDER_P (size))
return size;
/* Force creation of a SAVE_EXPR. This solves (1) code duplication
problems between parent and nested functions that occasionally can't
be cleaned up because of portions of the expression escaping the
parent function via the FRAME object, and (2) tree sharing problems
between the type system and the gimple code, which can leak SSA_NAME
objects into e.g. TYPE_SIZE, which cause heartburn when emitting
debug information. */
size = build1 (SAVE_EXPR, TREE_TYPE (size), size);
size = save_expr (size);
/* If an array with a variable number of elements is declared, and
the elements require destruction, we will emit a cleanup for the
@ -333,8 +325,8 @@ layout_decl (tree decl, unsigned int known_align)
if (DECL_SIZE (decl) == 0)
{
DECL_SIZE (decl) = unshare_expr (TYPE_SIZE (type));
DECL_SIZE_UNIT (decl) = unshare_expr (TYPE_SIZE_UNIT (type));
DECL_SIZE (decl) = TYPE_SIZE (type);
DECL_SIZE_UNIT (decl) = TYPE_SIZE_UNIT (type);
}
else if (DECL_SIZE_UNIT (decl) == 0)
DECL_SIZE_UNIT (decl)
@ -1644,8 +1636,8 @@ layout_type (tree type)
if (index && TYPE_MAX_VALUE (index) && TYPE_MIN_VALUE (index)
&& TYPE_SIZE (element))
{
tree ub = unshare_expr (TYPE_MAX_VALUE (index));
tree lb = unshare_expr (TYPE_MIN_VALUE (index));
tree ub = TYPE_MAX_VALUE (index);
tree lb = TYPE_MIN_VALUE (index);
tree length;
tree element_size;

View File

@ -368,6 +368,8 @@ struct tree_common GTY(())
all expressions
all decls
all constants
TYPE_SIZES_GIMPLIFIED
..._TYPE
unsigned_flag:
@ -934,6 +936,9 @@ extern void tree_operand_check_failed (int, enum tree_code,
also appear in an expression or decl where the value is constant. */
#define TREE_CONSTANT(NODE) (NON_TYPE_CHECK (NODE)->common.constant_flag)
/* Nonzero if NODE, a type, has had its sizes gimplified. */
#define TYPE_SIZES_GIMPLIFIED(NODE) (TYPE_CHECK (NODE)->common.constant_flag)
/* In a decl (most significantly a FIELD_DECL), means an unsigned field. */
#define DECL_UNSIGNED(NODE) (DECL_CHECK (NODE)->common.unsigned_flag)