On Wed, Dec 07, 2016 at 05:02:46PM +0530, Prathamesh Kulkarni wrote:
> + if (arg1_len == NULL_TREE)
> + {
> + gimple_stmt_iterator gsi;
> + tree strlen_decl;
> + gimple *strlen_call;
> +
> + strlen_decl = builtin_decl_explicit
> (BUILT_IN_STRLEN);
> + strlen_call = gimple_build_call (strlen_decl, 1,
> + arg1);
> + arg1_len = make_ssa_name (size_type_node);
> + gimple_call_set_lhs (strlen_call, arg1_len);
> + update_stmt (strlen_call);
> + gsi = gsi_for_stmt (call_stmt);
> + gsi_insert_before (&gsi, strlen_call,
> GSI_SAME_STMT);
> + }
Why? If the strlen isn't readily available, do you really think it is
always a win to replace one call with 2 calls? The string you want to do
strlen on can be huge, the haystack could be empty or very short, etc.
I'd just punt if strlen isn't known.
> +
> + gimple_stmt_iterator gsi = gsi_for_stmt (call_stmt);
> + tree memcmp_decl = builtin_decl_explicit
> (BUILT_IN_MEMCMP);
> + gcall *memcmp_call
> + = gimple_build_call (memcmp_decl, 3, arg0, arg1,
> + arg1_len);
> + tree memcmp_lhs = make_ssa_name (integer_type_node);
> + gimple_call_set_lhs (memcmp_call, memcmp_lhs);
> + update_stmt (memcmp_call);
> + gsi_remove (&gsi, true);
> + gsi_insert_before (&gsi, memcmp_call, GSI_SAME_STMT);
> +
> + gsi = gsi_for_stmt (stmt);
> + tree zero = build_zero_cst (TREE_TYPE (memcmp_lhs));
> + gassign *ga = gimple_build_assign (lhs, code,
> + memcmp_lhs, zero);
> + gsi_replace (&gsi, ga, false);
> + update_ssa (TODO_update_ssa);
And this is certainly even more wrong than the old TODO_update_ssa at the
end of the pass, now you'll do it for every single replacement in the
function. Why do you need it? The old call stmt has gimple_vdef and
gimple_vuse, so just copy those over, see how e.g.
replace_call_with_call_and_fold in gimple-fold.c does that.
If you don't add strlen, you need to move the vdef/vuse from stmt to
memcmp_call, if you really want to add strlen (see above note though),
then that call should have a vuse added (same vuse as the stmt originally
had).
Jakub