From 50f39ec6baac1dd48289fb11f8c81aadd772b76d Mon Sep 17 00:00:00 2001 From: pinskia Date: Mon, 5 May 2008 16:10:43 +0000 Subject: [PATCH] 2008-05-05 Andrew Pinski * 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 * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@134947 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 5 ++++ gcc/testsuite/ChangeLog | 8 ++++++ gcc/testsuite/gcc.dg/tree-ssa/forwprop-5.c | 21 ++++++++++++++++ gcc/testsuite/gcc.dg/tree-ssa/forwprop-6.c | 16 ++++++++++++ gcc/testsuite/gcc.dg/tree-ssa/forwprop-7.c | 14 +++++++++++ gcc/testsuite/gcc.dg/tree-ssa/forwprop-8.c | 16 ++++++++++++ gcc/testsuite/gcc.dg/tree-ssa/forwprop-9.c | 18 ++++++++++++++ gcc/tree-ssa-forwprop.c | 39 ++++++++++++++++++++++++++++++ 8 files changed, 137 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/forwprop-5.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/forwprop-6.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/forwprop-7.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/forwprop-8.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/forwprop-9.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 828666f7d59..41cc67209d1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2008-05-05 Andrew Pinski + + * 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 * config/i386/i386.md diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c65deaf2ad4..06f68c5a374 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2008-05-05 Andrew Pinski + + * 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 PR tree-optimization/36119 diff --git a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-5.c b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-5.c new file mode 100644 index 00000000000..710bc5dd114 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-5.c @@ -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" } } */ + diff --git a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-6.c b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-6.c new file mode 100644 index 00000000000..7df9f45ab17 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-6.c @@ -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" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-7.c b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-7.c new file mode 100644 index 00000000000..6b894b5b7c6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-7.c @@ -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" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-8.c b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-8.c new file mode 100644 index 00000000000..4e0751f8119 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-8.c @@ -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" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-9.c b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-9.c new file mode 100644 index 00000000000..70630d01a34 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-9.c @@ -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" } } */ diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c index e6402adce55..9fbf58d853d 100644 --- a/gcc/tree-ssa-forwprop.c +++ b/gcc/tree-ssa-forwprop.c @@ -124,6 +124,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(type2var) + + Or ptr = &x[0]; ptr2 = ptr + ; @@ -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 -- 2.11.0