This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Fix inliner INDIRECT_EXPR <ADDR_EXPR> handling (PR c/34668)
- From: "Richard Guenther" <richard dot guenther at gmail dot com>
- To: "Jakub Jelinek" <jakub at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Thu, 10 Jan 2008 11:43:34 +0100
- Subject: Re: [PATCH] Fix inliner INDIRECT_EXPR <ADDR_EXPR> handling (PR c/34668)
- References: <20080110090408.GM15450@devserv.devel.redhat.com>
On Jan 10, 2008 10:04 AM, Jakub Jelinek <jakub@redhat.com> wrote:
> Hi!
>
> This patch fixes an inlining issue with IMA. &optab_table[0] is parsed
> as ADDR_EXPR with struct optab * type of optab_table which has
> struct optab [1] ARRAY_TYPE. Later on IMA changes the type of optab_table
> to ARRAY_TYPE of a different struct optab (from the other CU), but
> the type of ADDR_EXPR stays. When inlining creates INDIRECT_REF
> <ADDR_EXPR>, copy_body_r doesn't try to build_fold_indirect_ref,
> but calls fold_indirect_ref_1 and if that didn't optimize something,
> forcefully removes both INDIRECT_REF and ADDR_EXPR, which is IMHO a bad
> thing, because it doesn't care about the types.
> Without IMA this works, because fold_indirect_ref_1 folds the address
> of the *&optab_table into optable_table[0]:
> /* *(foo *)&fooarray => fooarray[0] */
> else if (TREE_CODE (optype) == ARRAY_TYPE
> && type == TREE_TYPE (optype))
> {
> tree type_domain = TYPE_DOMAIN (optype);
> tree min_val = size_zero_node;
> if (type_domain && TYPE_MIN_VALUE (type_domain))
> min_val = TYPE_MIN_VALUE (type_domain);
> return build4 (ARRAY_REF, type, op, min_val, NULL_TREE, NULL_TREE);
> }
> but on this testcase it unfortunately doesn't trigger, because the
> types are just compatible, not identical. copy_body_r is the only
> direct user of fold_indirect_ref_1, in all other cases this folding is
> just an optimization, as when it is not folded, INDIRECT_REF is created
> or the original INDIRECT_REF is kept. But in tree-inline.c if
> fold_indirect_ref_1 returns NULL, it will
> if (TREE_CODE (new) == ADDR_EXPR)
> *tp = TREE_OPERAND (new, 0);
> forcefully, not bothering to check types. Changing fold_indirect_ref_1
> to work with types_compatible_p would be probably too expensive.
I don't think so. The code should read
/* *(foo *)&fooarray => fooarray[0] */
else if (TREE_CODE (optype) == ARRAY_TYPE
&& useless_type_conversion_p (type, TREE_TYPE (optype)))
{
tree type_domain = TYPE_DOMAIN (optype);
tree min_val = size_zero_node;
if (type_domain && TYPE_MIN_VALUE (type_domain))
min_val = TYPE_MIN_VALUE (type_domain);
return build4 (ARRAY_REF, TREE_TYPE (optype), op, min_val,
NULL_TREE, NULL_TREE);
}
and similar in fold_indirect_ref_rhs - where it already _does_ look like that.
Would this fix it?
Thanks,
Richard.