This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR31146, unable to optimize loop with placement new
- From: Richard Guenther <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 2 May 2007 11:08:53 +0200 (CEST)
- Subject: [PATCH] Fix PR31146, unable to optimize loop with placement new
This fixes PR31146 where we could not optimize a loop like
template <class T>
struct Vec
{
Vec()
{
for (int i=0; i<3; ++i)
new (&a[i]) T(0);
}
T a[3];
};
because after inlining the new operator we end up with a null-pointer
check against the "wrong" variable:
double * D.2720_4 = &v.a[i_5];
void * __p_6 = D.2720_4;
double * iftmp.3_7 = (double *) __p_6;
if (iftmp.3_7 != 0B)
where you can see that (unfortunately) a conversion from double* to void*
is tree_ssa_useless, but a conversion the other way around is not which
is why only FRE can clean this up (and only because a double* type pointer
is available).
Fixed by making forwprop propagate along the single use chain in this
case. This reduces function sizes for inlining.
Boostrapped and tested on x86_64-unknown-linux-gnu, applied to mainline.
Richard.
2007-05-02 Richard Guenther <rguenther@suse.de>
PR tree-optimization/31146
* tree-ssa-forwprop.c (forward_propagate_addr_expr_1): New
argument, single_use_p. If we have a single use that is
a conversion to the definition rhs type, propagate that rhs.
(forward_propagate_addr_expr): Pass single_use_p argument
to forward_propagate_addr_expr_1.
* g++.dg/tree-ssa/pr31146-2.C: New testcase.
Index: tree-ssa-forwprop.c
===================================================================
*** tree-ssa-forwprop.c (revision 124328)
--- tree-ssa-forwprop.c (working copy)
*************** forward_propagate_addr_into_variable_arr
*** 559,565 ****
be not totally successful, yet things may have been changed). */
static bool
! forward_propagate_addr_expr_1 (tree name, tree def_rhs, tree use_stmt)
{
tree lhs, rhs, array_ref;
--- 559,566 ----
be not totally successful, yet things may have been changed). */
static bool
! forward_propagate_addr_expr_1 (tree name, tree def_rhs, tree use_stmt,
! bool single_use_p)
{
tree lhs, rhs, array_ref;
*************** forward_propagate_addr_expr_1 (tree name
*** 584,593 ****
/* Continue propagating into the RHS. */
}
! /* Trivial case. The use statement could be a trivial copy or a
useless conversion. Recurse to the uses of the lhs as copyprop does
not copy through differen variant pointers and FRE does not catch
! all useless conversions. */
else if ((TREE_CODE (lhs) == SSA_NAME
&& rhs == name)
|| ((TREE_CODE (rhs) == NOP_EXPR
--- 585,604 ----
/* Continue propagating into the RHS. */
}
! /* Trivial cases. The use statement could be a trivial copy or a
useless conversion. Recurse to the uses of the lhs as copyprop does
not copy through differen variant pointers and FRE does not catch
! all useless conversions. Treat the case of a single-use name and
! a conversion to def_rhs type separate, though. */
! else if (TREE_CODE (lhs) == SSA_NAME
! && (TREE_CODE (rhs) == NOP_EXPR
! || TREE_CODE (rhs) == CONVERT_EXPR)
! && TREE_TYPE (rhs) == TREE_TYPE (def_rhs)
! && single_use_p)
! {
! GIMPLE_STMT_OPERAND (use_stmt, 1) = unshare_expr (def_rhs);
! return true;
! }
else if ((TREE_CODE (lhs) == SSA_NAME
&& rhs == name)
|| ((TREE_CODE (rhs) == NOP_EXPR
*************** forward_propagate_addr_expr (tree name,
*** 702,707 ****
--- 713,719 ----
imm_use_iterator iter;
tree use_stmt;
bool all = true;
+ bool single_use_p = has_single_use (name);
FOR_EACH_IMM_USE_STMT (use_stmt, iter, name)
{
*************** forward_propagate_addr_expr (tree name,
*** 726,732 ****
push_stmt_changes (&use_stmt);
! result = forward_propagate_addr_expr_1 (name, rhs, use_stmt);
all &= result;
pop_stmt_changes (&use_stmt);
--- 738,745 ----
push_stmt_changes (&use_stmt);
! result = forward_propagate_addr_expr_1 (name, rhs, use_stmt,
! single_use_p);
all &= result;
pop_stmt_changes (&use_stmt);
Index: testsuite/g++.dg/tree-ssa/pr31146-2.C
===================================================================
*** testsuite/g++.dg/tree-ssa/pr31146-2.C (revision 0)
--- testsuite/g++.dg/tree-ssa/pr31146-2.C (revision 0)
***************
*** 0 ****
--- 1,24 ----
+ /* { dg-do compile } */
+ /* { dg-options "-O -fdump-tree-forwprop1" } */
+
+ #include <new>
+
+ template <class T>
+ struct Vec
+ {
+ Vec()
+ {
+ for (int i=0; i<3; ++i)
+ new (&a[i]) T(0);
+ }
+ T a[3];
+ };
+
+ double foo (void)
+ {
+ Vec<double> v;
+ return v.a[2];
+ }
+
+ /* { dg-final { scan-tree-dump "Replaced .*iftmp.* != 0B. with .1" "forwprop1" } } */
+ /* { dg-final { cleanup-tree-dump "forwprop1" } } */