summaryrefslogtreecommitdiff
path: root/gcc/gimplify.c
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2007-05-01 13:18:01 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2007-05-01 11:18:01 +0000
commitfe9821b88c042f37973f4ab2866a52dcb676446c (patch)
treebd72595e8b02806708c943137cbe687e4482667d /gcc/gimplify.c
parent8b11009bad1b794283984fc806198e3cf29dbed3 (diff)
downloadgcc-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.c27
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)))
{