This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: C++ PATCH: PR 16405
- From: Jason Merrill <jason at redhat dot com>
- To: Mark Mitchell <mark at codesourcery dot com>
- Cc: Richard Henderson <rth at redhat dot com>, gcc-patches at gcc dot gnu dot org
- Date: Wed, 12 Jan 2005 19:32:46 -0500
- Subject: Re: C++ PATCH: PR 16405
- References: <200412230812.iBN8CjP2028122@sethra.codesourcery.com><20041223105025.GA18181@redhat.com><41CAEF9F.6020304@codesourcery.com><20041223201100.GC19547@redhat.com><41CB27CF.6050406@codesourcery.com><xypacs4220s.fsf@miranda.boston.redhat.com><41CB2BC7.1050004@codesourcery.com><xyp652s216m.fsf@miranda.boston.redhat.com>
On Thu, 23 Dec 2004 15:45:53 -0500, Jason Merrill <jason@redhat.com> wrote:
> On Thu, 23 Dec 2004 12:34:15 -0800, Mark Mitchell <mark@codesourcery.com> wrote:
>
>> Jason Merrill wrote:
>>> On Thu, 23 Dec 2004 12:17:19 -0800, Mark Mitchell <mark@codesourcery.com> wrote:
>>>
>>>>Jason's trying to get me to move this code into gimplify_expr, which I'll
>>>>try, but, Jason, I'm going to leave NRV/inlining to you.
>>
>> Moving the code to gimplify_expr makes it run too late; that's not done for
>> the RHS of an assignment until after gimplify_modify_expr_rhs.
>
> OK, I suppose I can poke at that as well as the NRV issue.
Here's what I came up with; we already have a function that performs the
folding you wanted to do, and more, so I just call that. An early call is
also useful in gimplify_compound_lval, to expose more ARRAY_REFs.
Tested x86_64-pc-linux-gnu. Do you think this is appropriate for the trunk
at this time?
2005-01-12 Jason Merrill <jason@redhat.com>
* fold-const.c (fold_indirect_ref_1): Split out from...
(build_fold_indirect_ref): Here.
(fold_indirect_ref): New fn.
* gimplify.c (gimplify_compound_lval): Call fold_indirect_ref.
(gimplify_modify_expr_rhs): Likewise.
(gimplify_expr): Likewise.
*** fold-const.c.~1~ 2005-01-11 19:13:24.000000000 -0500
--- fold-const.c 2005-01-11 19:10:07.000000000 -0500
*************** build_fold_addr_expr (tree t)
*** 10845,10858 ****
/* Builds an expression for an indirection through T, simplifying some
cases. */
! tree
! build_fold_indirect_ref (tree t)
{
tree type = TREE_TYPE (TREE_TYPE (t));
tree sub = t;
tree subtype;
STRIP_NOPS (sub);
if (TREE_CODE (sub) == ADDR_EXPR)
{
tree op = TREE_OPERAND (sub, 0);
--- 10845,10862 ----
/* Builds an expression for an indirection through T, simplifying some
cases. */
! static tree
! fold_indirect_ref_1 (tree t)
{
tree type = TREE_TYPE (TREE_TYPE (t));
tree sub = t;
tree subtype;
STRIP_NOPS (sub);
+ subtype = TREE_TYPE (sub);
+ if (!POINTER_TYPE_P (subtype))
+ return NULL_TREE;
+
if (TREE_CODE (sub) == ADDR_EXPR)
{
tree op = TREE_OPERAND (sub, 0);
*************** build_fold_indirect_ref (tree t)
*** 10867,10873 ****
}
/* *(foo *)fooarrptr => (*fooarrptr)[0] */
- subtype = TREE_TYPE (sub);
if (TREE_CODE (TREE_TYPE (subtype)) == ARRAY_TYPE
&& lang_hooks.types_compatible_p (type, TREE_TYPE (TREE_TYPE (subtype))))
{
--- 10871,10876 ----
*************** build_fold_indirect_ref (tree t)
*** 10875,10881 ****
return build4 (ARRAY_REF, type, sub, size_zero_node, NULL_TREE, NULL_TREE);
}
! return build1 (INDIRECT_REF, type, t);
}
/* Strip non-trapping, non-side-effecting tree nodes from an expression
--- 10878,10906 ----
return build4 (ARRAY_REF, type, sub, size_zero_node, NULL_TREE, NULL_TREE);
}
! return NULL_TREE;
! }
!
! tree
! build_fold_indirect_ref (tree t)
! {
! tree sub = fold_indirect_ref_1 (t);
!
! if (sub)
! return sub;
! else
! return build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (t)), t);
! }
!
! tree
! fold_indirect_ref (tree t)
! {
! tree sub = fold_indirect_ref_1 (TREE_OPERAND (t, 0));
!
! if (sub)
! return sub;
! else
! return t;
}
/* Strip non-trapping, non-side-effecting tree nodes from an expression
*** gimplify.c.~1~ 2005-01-11 19:13:24.000000000 -0500
--- gimplify.c 2005-01-12 15:53:45.769811063 -0500
*************** gimplify_compound_lval (tree *expr_p, tr
*** 1433,1440 ****
VARRAY_GENERIC_PTR_NOGC_INIT (stack, 10, "stack");
/* We can handle anything that get_inner_reference can deal with. */
! for (p = expr_p; handled_component_p (*p); p = &TREE_OPERAND (*p, 0))
! VARRAY_PUSH_GENERIC_PTR_NOGC (stack, *p);
gcc_assert (VARRAY_ACTIVE_SIZE (stack));
--- 1433,1447 ----
VARRAY_GENERIC_PTR_NOGC_INIT (stack, 10, "stack");
/* We can handle anything that get_inner_reference can deal with. */
! for (p = expr_p; ; p = &TREE_OPERAND (*p, 0))
! {
! /* Fold INDIRECT_REFs now to turn them into ARRAY_REFs. */
! if (TREE_CODE (*p) == INDIRECT_REF)
! *p = fold_indirect_ref (*p);
! if (!handled_component_p (*p))
! break;
! VARRAY_PUSH_GENERIC_PTR_NOGC (stack, *p);
! }
gcc_assert (VARRAY_ACTIVE_SIZE (stack));
*************** gimplify_modify_expr_rhs (tree *expr_p,
*** 2816,2831 ****
This kind of code arises in C++ when an object is bound
to a const reference, and if "x" is a TARGET_EXPR we want
to take advantage of the optimization below. */
! tree pointer;
!
! pointer = TREE_OPERAND (*from_p, 0);
! STRIP_NOPS (pointer);
! if (TREE_CODE (pointer) == ADDR_EXPR
! && (lang_hooks.types_compatible_p
! (TREE_TYPE (TREE_OPERAND (pointer, 0)),
! TREE_TYPE (*from_p))))
{
! *from_p = TREE_OPERAND (pointer, 0);
ret = GS_OK;
}
else
--- 2823,2832 ----
This kind of code arises in C++ when an object is bound
to a const reference, and if "x" is a TARGET_EXPR we want
to take advantage of the optimization below. */
! tree t = fold_indirect_ref (*from_p);
! if (t != *from_p)
{
! *from_p = t;
ret = GS_OK;
}
else
*************** gimplify_expr (tree *expr_p, tree *pre_p
*** 3766,3774 ****
recalculate_side_effects (*expr_p);
break;
case ALIGN_INDIRECT_REF:
case MISALIGNED_INDIRECT_REF:
- case INDIRECT_REF:
ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
is_gimple_reg, fb_rvalue);
recalculate_side_effects (*expr_p);
--- 3786,3798 ----
recalculate_side_effects (*expr_p);
break;
+ case INDIRECT_REF:
+ *expr_p = fold_indirect_ref (*expr_p);
+ if (*expr_p != save_expr)
+ break;
+ /* else fall through. */
case ALIGN_INDIRECT_REF:
case MISALIGNED_INDIRECT_REF:
ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
is_gimple_reg, fb_rvalue);
recalculate_side_effects (*expr_p);
*** tree.h.~1~ 2005-01-11 19:13:24.000000000 -0500
--- tree.h 2005-01-11 19:10:18.000000000 -0500
*************** extern tree build_fold_addr_expr (tree);
*** 3522,3527 ****
--- 3522,3528 ----
tree fold_build_cleanup_point_expr (tree type, tree expr);
extern tree build_fold_addr_expr_with_type (tree, tree);
extern tree build_fold_indirect_ref (tree);
+ extern tree fold_indirect_ref (tree);
extern tree constant_boolean_node (int, tree);
extern tree build_low_bits_mask (tree, unsigned);