[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:
parent
ba9ce455bb
commit
ad50bc8d80
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user