On Thu, Jun 1, 2017 at 10:52 PM, Martin Sebor <mse...@gmail.com> wrote: > While testing some otherwise unrelated enhancements in these areas > I noticed that calls to bzero and bcopy are not being handled as > efficiently as equivalent calls to memset and memcpy. Specifically, > redundant calls are not eliminated and the functions appear to be > treated as if they allowed their pointer arguments to escape. This > turned out to be due to the missing handling of the former two built > ins by the DSE and aliasing passes. > > The attached patch adds this handling so the cases I noted in the two > PRs are now handled.
+ /* The number of the size argument to one of the built-in functions + below. */ + unsigned sizargno = 2; /* Handle those builtin functions explicitly that do not act as escape points. See tree-ssa-structalias.c:find_func_aliases for the list of builtins we might need to handle here. */ @@ -2030,8 +2034,13 @@ call_may_clobber_ref_p_1 (gcall *call, ao_ref *ref) && gimple_call_builtin_p (call, BUILT_IN_NORMAL)) switch (DECL_FUNCTION_CODE (callee)) { - /* All the following functions clobber memory pointed to by - their first argument. */ + case BUILT_IN_BZERO: + sizargno = 1; + /* Fall through. */ + + /* With the exception of the bzero function above, all of + the following clobber memory pointed to by their first + argument. */ case BUILT_IN_STRCPY: case BUILT_IN_STRNCPY: case BUILT_IN_MEMCPY: @@ -2062,9 +2071,9 @@ call_may_clobber_ref_p_1 (gcall *call, ao_ref *ref) is strlen (dest) + n + 1 instead of n, resp. n + 1 at dest + strlen (dest), but strlen (dest) isn't known. */ - if (gimple_call_num_args (call) == 3 + if (gimple_call_num_args (call) > sizargno && DECL_FUNCTION_CODE (callee) != BUILT_IN_STRNCAT) - size = gimple_call_arg (call, 2); + size = gimple_call_arg (call, sizargno); ao_ref_init_from_ptr_and_size (&dref, gimple_call_arg (call, 0), size); please insted do if (DECL_FUNCTION_CODE (callee) == BUILT_IN_BZERO) size = gimple_call_Arg (call, 1); else if (gimple_call_num_args (call) == 3 ... instead of the above changes. Likewise in stmt_kills_ref_p. Likewise in initialize_ao_ref_for_dse I see no value in uglifying the code but instead do case BUILT_IN_BCOPY: { ao_ref_init_from_ptr_and_size (write, gimple_call_arg (stmt, 1), gimple_call_arg (stmt, 2)); return true; } and similar for BZERO. Similar in maybe_trim_memstar_call, for decrement_count simply pass in the tree * instead of the argno (and you can get rid of the stmt as well. + 1) Bzero and memset. */ + bool memset_p = false; if (is_gimple_reg_type (vr->type) - && gimple_call_builtin_p (def_stmt, BUILT_IN_MEMSET) - && integer_zerop (gimple_call_arg (def_stmt, 1)) - && tree_fits_uhwi_p (gimple_call_arg (def_stmt, 2)) + && (((memset_p = gimple_call_builtin_p (def_stmt, BUILT_IN_MEMSET)) + && integer_zerop (gimple_call_arg (def_stmt, 1)) + && tree_fits_uhwi_p (gimple_call_arg (def_stmt, 2))) + || gimple_call_builtin_p (def_stmt, BUILT_IN_BZERO)) you miss the tree_fits_uhwi_p check for bzero. Note I'd be _much_ more sympathetic to simply canonicalizing all of bzero and bcopy to memset / memmove and be done with all the above complexity. Richard. > Tested on x86_64-linux. > > Martin