diff options
author | Jan Hubicka <jh@suse.cz> | 2007-05-01 13:18:01 +0200 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2007-05-01 11:18:01 +0000 |
commit | fe9821b88c042f37973f4ab2866a52dcb676446c (patch) | |
tree | bd72595e8b02806708c943137cbe687e4482667d /gcc/gimplify.c | |
parent | 8b11009bad1b794283984fc806198e3cf29dbed3 (diff) | |
download | gcc-fe9821b88c042f37973f4ab2866a52dcb676446c.tar.gz |
tree.h (maybe_fold_offset_to_component_ref): Remove.
* tree.h (maybe_fold_offset_to_component_ref): Remove.
(maybe_fold_offset_to_reference): Declare.
* fold-const.c (fold_unary): Do not fold
(type *)&A into &A->field_of_type_and_offset_0
* tree-ssa-ccp.c (maybe_fold_offset_to_array_ref): When base type
size is unknown, give up.
(maybe_fold_offset_to_component_ref): Ignore firelds with unknown
offsets.
(maybe_fold_offset_to_reference): New.
(maybe_fold_stmt_indirect): Use it.
(fold_stmt_r): Fold (type *)&A+offset into A->field_if_type_and_offset.
* gimplify.c (gimplify_conversion): Canonicalize conversions to
field references.
(gimplify_expr): Likewise for plus_expr.
From-SVN: r124323
Diffstat (limited to 'gcc/gimplify.c')
-rw-r--r-- | gcc/gimplify.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/gcc/gimplify.c b/gcc/gimplify.c index 0b6ec34d974..805c3020272 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -1617,6 +1617,7 @@ canonicalize_addr_expr (tree *expr_p) static enum gimplify_status gimplify_conversion (tree *expr_p) { + tree tem; gcc_assert (TREE_CODE (*expr_p) == NOP_EXPR || TREE_CODE (*expr_p) == CONVERT_EXPR); @@ -1627,6 +1628,17 @@ gimplify_conversion (tree *expr_p) if (tree_ssa_useless_type_conversion (*expr_p)) *expr_p = TREE_OPERAND (*expr_p, 0); + /* Attempt to avoid NOP_EXPR by producing reference to a subtype. + For example this fold (subclass *)&A into &A->subclass avoiding + a need for statement. */ + if (TREE_CODE (*expr_p) == NOP_EXPR + && POINTER_TYPE_P (TREE_TYPE (*expr_p)) + && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (*expr_p, 0))) + && (tem = maybe_fold_offset_to_reference + (TREE_OPERAND (*expr_p, 0), + integer_zero_node, TREE_TYPE (TREE_TYPE (*expr_p))))) + *expr_p = build_fold_addr_expr_with_type (tem, TREE_TYPE (*expr_p)); + /* If we still have a conversion at the toplevel, then canonicalize some constructs. */ if (TREE_CODE (*expr_p) == NOP_EXPR || TREE_CODE (*expr_p) == CONVERT_EXPR) @@ -5857,6 +5869,21 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p, ret = GS_ALL_DONE; break; + case PLUS_EXPR: + /* Convert ((type *)A)+offset into &A->field_of_type_and_offset. + The second is gimple immediate saving a need for extra statement. + */ + if (POINTER_TYPE_P (TREE_TYPE (*expr_p)) + && TREE_CODE (TREE_OPERAND (*expr_p, 1)) == INTEGER_CST + && (tmp = maybe_fold_offset_to_reference + (TREE_OPERAND (*expr_p, 0), TREE_OPERAND (*expr_p, 1), + TREE_TYPE (TREE_TYPE (*expr_p))))) + { + *expr_p = build_fold_addr_expr_with_type (tmp, + TREE_TYPE (*expr_p)); + break; + } + /* FALLTHRU */ default: switch (TREE_CODE_CLASS (TREE_CODE (*expr_p))) { |