diff options
author | Jeff Law <law@redhat.com> | 2019-06-26 15:36:27 -0600 |
---|---|---|
committer | Jeff Law <law@gcc.gnu.org> | 2019-06-26 15:36:27 -0600 |
commit | 3fe0ddc88334f9afd622458653a6d103948994bd (patch) | |
tree | e8a0a198a8f1f0670e7862902b0f7deceeef4afd /gcc/tree-ssa-alias.c | |
parent | 9f962469cabc7fdc2ee830125a5cb4e61e1632e4 (diff) | |
download | gcc-3fe0ddc88334f9afd622458653a6d103948994bd.zip gcc-3fe0ddc88334f9afd622458653a6d103948994bd.tar.gz gcc-3fe0ddc88334f9afd622458653a6d103948994bd.tar.bz2 |
re PR tree-optimization/90883 (Generated code is worse if returned struct is unnamed)
PR tree-optimization/90883
* tree-ssa-alias.c (stmt_kills_ref_p): Handle BUILT_IN_CALLOC.
* tree-ssa-dse.c: Update various comments to distinguish between
dead and redundant stores.
(initialize_ao_ref_for_dse): Handle BUILT_IN_CALLOC.
(dse_optimize_redundant_stores): New function.
(delete_dead_or_redundant_call): Renamed from delete_dead_call.
Distinguish between dead and redundant calls in dump output. All
callers updated.
(delete_dead_or_redundant_assignment): Similarly for assignments.
(dse_optimize_stmt): Handle _CHK variants. For statements which
store 0 into multiple memory locations, try to prove a subsequent
store is redundant.
PR tree-optimization/90883
* g++.dg/tree-ssa/pr90883.C: New test.
* gcc.dg/tree-ssa/ssa-dse-36.c: New test.
From-SVN: r272717
Diffstat (limited to 'gcc/tree-ssa-alias.c')
-rw-r--r-- | gcc/tree-ssa-alias.c | 27 |
1 files changed, 25 insertions, 2 deletions
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c index 48f7364..6e7db2b 100644 --- a/gcc/tree-ssa-alias.c +++ b/gcc/tree-ssa-alias.c @@ -2849,13 +2849,36 @@ stmt_kills_ref_p (gimple *stmt, ao_ref *ref) case BUILT_IN_MEMSET_CHK: case BUILT_IN_STRNCPY: case BUILT_IN_STPNCPY: + case BUILT_IN_CALLOC: { /* For a must-alias check we need to be able to constrain the access properly. */ if (!ref->max_size_known_p ()) return false; - tree dest = gimple_call_arg (stmt, 0); - tree len = gimple_call_arg (stmt, 2); + tree dest; + tree len; + + /* In execution order a calloc call will never kill + anything. However, DSE will (ab)use this interface + to ask if a calloc call writes the same memory locations + as a later assignment, memset, etc. So handle calloc + in the expected way. */ + if (DECL_FUNCTION_CODE (callee) == BUILT_IN_CALLOC) + { + tree arg0 = gimple_call_arg (stmt, 0); + tree arg1 = gimple_call_arg (stmt, 1); + if (TREE_CODE (arg0) != INTEGER_CST + || TREE_CODE (arg1) != INTEGER_CST) + return false; + + dest = gimple_call_lhs (stmt); + len = fold_build2 (MULT_EXPR, TREE_TYPE (arg0), arg0, arg1); + } + else + { + dest = gimple_call_arg (stmt, 0); + len = gimple_call_arg (stmt, 2); + } if (!poly_int_tree_p (len)) return false; tree rbase = ref->base; |