tree-ssa-forwprop.c (forward_propagate_addr_expr_1): If we have the same size types for...

2008-05-05  Andrew Pinski  <Andrew.Pinski@playstation.sony.com>

        * tree-ssa-forwprop.c (forward_propagate_addr_expr_1): If we have the
        same size types for the indirect reference on the rhs, then create a VCE.

2008-05-05  Andrew Pinski  <andrew.pinski@playstation.sony.com>

        * gcc.dg/tree-ssa/forwprop-5.c: New testcase.
        * gcc.dg/tree-ssa/forwprop-6.c: New testcase.
        * gcc.dg/tree-ssa/forwprop-7.c: New testcase.
        * gcc.dg/tree-ssa/forwprop-8.c: New testcase.
        * gcc.dg/tree-ssa/forwprop-9.c: New testcase.

From-SVN: r134947
This commit is contained in:
Andrew Pinski 2008-05-05 09:10:43 -07:00 committed by Andrew Pinski
parent 8c32cbc921
commit e06f0ff9f8
8 changed files with 137 additions and 0 deletions

View file

@ -1,3 +1,8 @@
2008-05-05 Andrew Pinski <Andrew.Pinski@playstation.sony.com>
* tree-ssa-forwprop.c (forward_propagate_addr_expr_1): If we have the
same size types for the indirect reference on the rhs, then create a VCE.
2008-05-05 Uros Bizjak <ubizjak@gmail.com>
* config/i386/i386.md

View file

@ -1,3 +1,11 @@
2008-05-05 Andrew Pinski <andrew.pinski@playstation.sony.com>
* gcc.dg/tree-ssa/forwprop-5.c: New testcase.
* gcc.dg/tree-ssa/forwprop-6.c: New testcase.
* gcc.dg/tree-ssa/forwprop-7.c: New testcase.
* gcc.dg/tree-ssa/forwprop-8.c: New testcase.
* gcc.dg/tree-ssa/forwprop-9.c: New testcase.
2008-05-05 Ira Rosen <irar@il.ibm.com>
PR tree-optimization/36119

View file

@ -0,0 +1,21 @@
/* { dg-do compile } */
/* { dg-options "-O1 -fdump-tree-forwprop1 -w" } */
#define vector __attribute__((vector_size(16) ))
struct VecClass
{
vector float v;
};
vector float foo( vector float v )
{
vector float x = v;
x = x + x;
struct VecClass y = *(struct VecClass*)&x;
return y.v;
}
/* We should be able to convert the cast to a VCE in forwprop1. */
/* { dg-final { scan-tree-dump-times "VIEW_CONVERT_EXPR" 1 "forwprop1"} } */
/* { dg-final { cleanup-tree-dump "forwprop1" } } */

View file

@ -0,0 +1,16 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-forwprop1 -W -Wall" } */
int b;
void f(void)
{
float a;
a = 1;
b = *(int*)&a; /* { dg-warning "aliasing" } */
}
/* We should be able to convert the cast to a VCE in forwprop1,
even if there is an aliasing violation. */
/* { dg-final { scan-tree-dump-times "VIEW_CONVERT_EXPR" 1 "forwprop1"} } */
/* { dg-final { cleanup-tree-dump "forwprop1" } } */

View file

@ -0,0 +1,14 @@
/* { dg-do compile } */
/* { dg-options "-O1 -fdump-tree-forwprop1 -W -Wall" } */
int i;
int foo(void)
{
volatile int *p = (volatile int *)&i;
return *p + *p;
}
/* We should not convert the cast to a VCE in forwprop1 as we have a volatile reference. */
/* { dg-final { scan-tree-dump-times "VIEW_CONVERT_EXPR" 0 "forwprop1"} } */
/* { dg-final { scan-tree-dump-times "volatile int" 2 "forwprop1"} } */
/* { dg-final { cleanup-tree-dump "forwprop1" } } */

View file

@ -0,0 +1,16 @@
/* { dg-do compile } */
/* { dg-options "-O1 -fdump-tree-forwprop1 -W -Wall" } */
struct X { int a[5]; };
int foo(struct X *q)
{
int (*pointer)[5] = &q->a;
return (*pointer)[0];
}
/* We should have propragated &q->a into (*pointer). */
/* { dg-final { scan-tree-dump-times "pointer" 0 "forwprop1"} } */
/* { dg-final { scan-tree-dump "->a\\\[0\\\]" "forwprop1" } } */
/* { dg-final { cleanup-tree-dump "forwprop1" } } */

View file

@ -0,0 +1,18 @@
/* { dg-do compile } */
/* { dg-options "-O1 -fdump-tree-final_cleanup -W -Wall -fno-early-inlining" } */
int b;
unsigned a;
static inline int *g(void)
{
a = 1;
return (int*)&a;
}
void f(void)
{
b = *g();
}
/* We should have converted the assignments to two = 1. */
/* { dg-final { scan-tree-dump-times " = 1" 2 "final_cleanup"} } */
/* { dg-final { cleanup-tree-dump "final_cleanup" } } */

View file

@ -123,6 +123,14 @@ along with GCC; see the file COPYING3. If not see
res = x->y->z;
Or
ptr = (type1*)&type2var;
res = *ptr
Will get turned into (if type1 and type2 are the same size
and neither have volatile on them):
res = VIEW_CONVERT_EXPR<type1>(type2var)
Or
ptr = &x[0];
@ -642,6 +650,37 @@ forward_propagate_addr_expr_1 (tree name, tree def_rhs, tree use_stmt,
return true;
}
/* Now see if the RHS node is an INDIRECT_REF using NAME. If so,
propagate the ADDR_EXPR into the use of NAME and try to
create a VCE and fold the result. */
if (TREE_CODE (rhs) == INDIRECT_REF
&& TREE_OPERAND (rhs, 0) == name
&& TYPE_SIZE (TREE_TYPE (rhs))
&& TYPE_SIZE (TREE_TYPE (TREE_OPERAND (def_rhs, 0)))
/* We should not convert volatile loads to non volatile loads. */
&& !TYPE_VOLATILE (TREE_TYPE (rhs))
&& !TYPE_VOLATILE (TREE_TYPE (TREE_OPERAND (def_rhs, 0)))
&& operand_equal_p (TYPE_SIZE (TREE_TYPE (rhs)),
TYPE_SIZE (TREE_TYPE (TREE_OPERAND (def_rhs, 0))), 0))
{
bool res = true;
tree new_rhs = unshare_expr (TREE_OPERAND (def_rhs, 0));
new_rhs = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (rhs), new_rhs);
/* If we have folded the VCE, then we have to create a new statement. */
if (TREE_CODE (new_rhs) != VIEW_CONVERT_EXPR)
{
block_stmt_iterator bsi = bsi_for_stmt (use_stmt);
new_rhs = force_gimple_operand_bsi (&bsi, new_rhs, true, NULL, true, BSI_SAME_STMT);
/* As we change the deference to a SSA_NAME, we need to return false to make sure that
the statement does not get removed. */
res = false;
}
*rhsp = new_rhs;
fold_stmt_inplace (use_stmt);
tidy_after_forward_propagate_addr (use_stmt);
return res;
}
/* If the use of the ADDR_EXPR is not a POINTER_PLUS_EXPR, there
is nothing to do. */
if (TREE_CODE (rhs) != POINTER_PLUS_EXPR