From e2e79a188a4aa19a783c3df89aa9cbd6444777c3 Mon Sep 17 00:00:00 2001 From: Richard Guenther Date: Wed, 26 Sep 2007 15:31:50 +0000 Subject: re PR tree-optimization/33563 (DSE removes non-dead store) 2007-09-26 Richard Guenther PR tree-optimization/33563 * tree-ssa-dse.c (get_use_of_stmt_lhs): Rename to ... (get_kill_of_stmt_lhs): ... this. Re-structure. Handle aggregate stores. (dse_optimize_stmt): Call get_kill_of_stmt_lhs instead of get_use_of_stmt_lhs. * gcc.dg/torture/pr33563.c: New testcase. From-SVN: r128815 --- gcc/tree-ssa-dse.c | 91 +++++++++++++++++++++++++++--------------------------- 1 file changed, 45 insertions(+), 46 deletions(-) (limited to 'gcc/tree-ssa-dse.c') diff --git a/gcc/tree-ssa-dse.c b/gcc/tree-ssa-dse.c index d7453dd..f5399f1 100644 --- a/gcc/tree-ssa-dse.c +++ b/gcc/tree-ssa-dse.c @@ -210,62 +210,62 @@ 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) +/* Return true if there is a stmt that kills the lhs of STMT and is in the + virtual def-use chain of STMT without a use inbetween the kill and STMT. + Returns false if no such stmt is found. + *FIRST_USE_P is set to the first use of the single virtual def of + STMT. *USE_P is set to the vop killed by *USE_STMT. */ + +static bool +get_kill_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; + tree lhs; - if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT) - return NULL_TREE; + gcc_assert (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT); 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 the use is not simple, give up. */ - if (TREE_CODE (*use_stmt) != GIMPLE_MODIFY_STMT - || get_call_expr_in (*use_stmt)) - return NULL_TREE; - + /* We now walk the chain of single uses of the single VDEFs. + We succeeded finding a kill if the lhs of the use stmt is + equal to the original lhs. We can keep walking to the next + use if there are no possible uses of the original lhs in + the stmt. */ 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); + tree use_lhs, use_rhs; + def_operand_p def_p; + + /* 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; + return false; - usevar = GIMPLE_STMT_OPERAND (*use_stmt, 0); - if (operand_equal_p (usevar, lhs, 0)) - return *use_stmt; + /* Get the single immediate use of the def. */ + if (!single_imm_use (DEF_FROM_PTR (def_p), first_use_p, &stmt)) + return false; + first_use_p = use_p; - 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 - || get_call_expr_in (*use_stmt)) - return NULL_TREE; + /* If there are possible hidden uses, give up. */ + if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT) + return false; + use_rhs = GIMPLE_STMT_OPERAND (stmt, 1); + if (TREE_CODE (use_rhs) == CALL_EXPR + || (!is_gimple_min_invariant (use_rhs) + && TREE_CODE (use_rhs) != SSA_NAME)) + return false; + + /* If the use stmts lhs matches the original lhs we have + found the kill, otherwise continue walking. */ + use_lhs = GIMPLE_STMT_OPERAND (stmt, 0); + if (operand_equal_p (use_lhs, lhs, 0)) + { + *use_stmt = stmt; + return true; + } } while (1); - - return NULL_TREE; } /* A helper of dse_optimize_stmt. @@ -448,8 +448,7 @@ dse_optimize_stmt (struct dom_walk_data *walk_data, 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) + if (!get_kill_of_stmt_lhs (stmt, &first_use_p, &use_p, &use_stmt)) { record_voperand_set (dse_gd->stores, &bd->stores, ann->uid); return; -- cgit v1.1