Extend dse
From-SVN: r124651
This commit is contained in:
parent
cd2d8c70db
commit
8a8b05f463
4 changed files with 118 additions and 4 deletions
|
@ -1,3 +1,9 @@
|
|||
2007-05-13 Revital Eres <eres@il.ibm.com>
|
||||
|
||||
* tree-ssa-dse.c (get_use_of_stmt_lhs): New function
|
||||
which walks virtual def-use chains to find redundant stores.
|
||||
(dse_optimize_stmt): Call it.
|
||||
|
||||
2007-05-12 Steven Bosscher <steven@gcc.gnu.org>
|
||||
|
||||
* gcse.c (gcse_main): Do jump bypassing in CPROP2.
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
2007-05-13 Revital Eres <eres@il.ibm.com>
|
||||
|
||||
* gcc.dg/dse.c: New test.
|
||||
|
||||
2007-05-12 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/31797
|
||||
|
|
32
gcc/testsuite/gcc.dg/dse.c
Normal file
32
gcc/testsuite/gcc.dg/dse.c
Normal file
|
@ -0,0 +1,32 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -fdump-tree-dse-details" } */
|
||||
|
||||
#define N 256
|
||||
|
||||
struct
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
} S[100];
|
||||
|
||||
int z[100];
|
||||
|
||||
int
|
||||
foo (void)
|
||||
{
|
||||
int i;
|
||||
int x, y;
|
||||
|
||||
S[5].x = 0;
|
||||
S[5].y = 0;
|
||||
|
||||
x = 5 + z[0];
|
||||
y = z[0];
|
||||
|
||||
S[5].x = x;
|
||||
S[5].y = y;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump-times "Deleted dead store" 2 "dse1" } } */
|
||||
/* { dg-final { cleanup-tree-dump "dse*" } } */
|
||||
|
|
@ -237,6 +237,59 @@ memory_address_same (tree store1, tree store2)
|
|||
== NULL);
|
||||
}
|
||||
|
||||
/* Return the use stmt for the lhs of STMT following the virtual
|
||||
def-use chains. Returns the MODIFY_EXPR stmt which lhs is equal to
|
||||
the lhs of STMT or NULL_TREE if no such stmt can be found. */
|
||||
static tree
|
||||
get_use_of_stmt_lhs (tree stmt,
|
||||
use_operand_p * first_use_p,
|
||||
use_operand_p * use_p, tree * use_stmt)
|
||||
{
|
||||
tree usevar, lhs;
|
||||
def_operand_p def_p;
|
||||
|
||||
if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
|
||||
return NULL_TREE;
|
||||
|
||||
lhs = GIMPLE_STMT_OPERAND (stmt, 0);
|
||||
|
||||
/* The stmt must have a single VDEF. */
|
||||
def_p = SINGLE_SSA_DEF_OPERAND (stmt, SSA_OP_VDEF);
|
||||
if (def_p == NULL_DEF_OPERAND_P)
|
||||
return NULL_TREE;
|
||||
|
||||
if (!has_single_use (DEF_FROM_PTR (def_p)))
|
||||
return NULL_TREE;
|
||||
/* Get the immediate use of the def. */
|
||||
single_imm_use (DEF_FROM_PTR (def_p), use_p, use_stmt);
|
||||
gcc_assert (*use_p != NULL_USE_OPERAND_P);
|
||||
first_use_p = use_p;
|
||||
if (TREE_CODE (*use_stmt) != GIMPLE_MODIFY_STMT)
|
||||
return NULL_TREE;
|
||||
|
||||
do
|
||||
{
|
||||
/* Look at the use stmt and see if it's LHS matches
|
||||
stmt's lhs SSA_NAME. */
|
||||
def_p = SINGLE_SSA_DEF_OPERAND (*use_stmt, SSA_OP_VDEF);
|
||||
if (def_p == NULL_DEF_OPERAND_P)
|
||||
return NULL_TREE;
|
||||
|
||||
usevar = GIMPLE_STMT_OPERAND (*use_stmt, 0);
|
||||
if (operand_equal_p (usevar, lhs, 0))
|
||||
return *use_stmt;
|
||||
|
||||
if (!has_single_use (DEF_FROM_PTR (def_p)))
|
||||
return NULL_TREE;
|
||||
single_imm_use (DEF_FROM_PTR (def_p), use_p, use_stmt);
|
||||
gcc_assert (*use_p != NULL_USE_OPERAND_P);
|
||||
if (TREE_CODE (*use_stmt) != GIMPLE_MODIFY_STMT)
|
||||
return NULL_TREE;
|
||||
}
|
||||
while (1);
|
||||
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
/* A helper of dse_optimize_stmt.
|
||||
Given a GIMPLE_MODIFY_STMT in STMT, check that each VDEF has one
|
||||
|
@ -593,10 +646,29 @@ dse_optimize_stmt (struct dom_walk_data *walk_data,
|
|||
/* If this is a partial store into an aggregate, record it. */
|
||||
dse_record_partial_aggregate_store (stmt, dse_gd);
|
||||
|
||||
/* If we have precisely one immediate use at this point, then we may
|
||||
have found redundant store. Make sure that the stores are to
|
||||
the same memory location. This includes checking that any
|
||||
SSA-form variables in the address will have the same values. */
|
||||
if (use_p != NULL_USE_OPERAND_P
|
||||
&& bitmap_bit_p (dse_gd->stores, get_stmt_uid (use_stmt))
|
||||
&& (!operand_equal_p (GIMPLE_STMT_OPERAND (stmt, 0),
|
||||
GIMPLE_STMT_OPERAND (use_stmt, 0), 0)
|
||||
&& !dse_partial_kill_p (stmt, dse_gd))
|
||||
&& memory_address_same (stmt, use_stmt))
|
||||
{
|
||||
/* If we have precisely one immediate use at this point, but
|
||||
the stores are not to the same memory location then walk the
|
||||
virtual def-use chain to get the stmt which stores to that same
|
||||
memory location. */
|
||||
if (get_use_of_stmt_lhs (stmt, &first_use_p, &use_p, &use_stmt) ==
|
||||
NULL_TREE)
|
||||
{
|
||||
record_voperand_set (dse_gd->stores, &bd->stores, ann->uid);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we have precisely one immediate use at this point and the
|
||||
stores are to the same memory location or there is a chain of
|
||||
virtual uses from stmt and the stmt which stores to that same
|
||||
memory location, then we may have found redundant store. */
|
||||
if (use_p != NULL_USE_OPERAND_P
|
||||
&& bitmap_bit_p (dse_gd->stores, get_stmt_uid (use_stmt))
|
||||
&& (operand_equal_p (GIMPLE_STMT_OPERAND (stmt, 0),
|
||||
|
|
Loading…
Add table
Reference in a new issue