On Tue, Dec 13, 2016 at 05:41:09PM +0530, Prathamesh Kulkarni wrote: > --- a/gcc/tree-ssa-strlen.c > +++ b/gcc/tree-ssa-strlen.c > @@ -2222,6 +2222,90 @@ handle_char_store (gimple_stmt_iterator *gsi) > return true; > } > > +/* Try to fold strstr (s, t) eq/ne s to memcmp (s, t, strlen (t)) eq/ne 0. > */ > + > +static void > +fold_strstr_to_memcmp (enum tree_code code, tree rhs1, tree rhs2, gimple > *stmt)
You can drop code argument here, see below. And I'd say it is better to do the if (TREE_CODE (rhs1) != SSA_NAME || TREE_CODE (rhs2) != SSA_NAME) return; here than repeat it in all the callers. > + if (gimple_assign_rhs_code (stmt) == COND_EXPR) > + { > + tree cond = gimple_assign_rhs1 (stmt); > + TREE_SET_CODE (cond, code); TREE_CODE (cond) is already code, so no need to set it again. > + gcond *cond = as_a<gcond *> (stmt); > + gimple_cond_set_lhs (cond, memcmp_lhs); > + gimple_cond_set_rhs (cond, zero); > + gimple_cond_set_code (cond, code); And gimple_cond_code (cond) == code here too. > + update_stmt (cond); > + } You can perhaps move the update_stmt (stmt); to a single spot after all the 3 cases are handled. > + if (cond_code == EQ_EXPR || cond_code == NE_EXPR) > + { > + tree rhs1 = TREE_OPERAND (cond, 0); > + tree rhs2 = TREE_OPERAND (cond, 1); While it is necessary to check cond_code here and in the other spots similarly, because otherwise you don't know if it has 2 arguments etc., you can avoid the SSA_NAME tests here. > + if (TREE_CODE (rhs1) == SSA_NAME > + && TREE_CODE (rhs2) == SSA_NAME) > + fold_strstr_to_memcmp (cond_code, rhs1, rhs2, stmt); > + } > + } > + else if (code == EQ_EXPR || code == NE_EXPR) > + { > + tree rhs1 = gimple_assign_rhs1 (stmt); > + tree rhs2 = gimple_assign_rhs2 (stmt); > + > + if (TREE_CODE (rhs1) == SSA_NAME > + && TREE_CODE (rhs2) == SSA_NAME) And here. > + fold_strstr_to_memcmp (code, rhs1, rhs2, stmt); > + } > + } > + else if (TREE_CODE (lhs) != SSA_NAME && !TREE_SIDE_EFFECTS (lhs)) > { > tree type = TREE_TYPE (lhs); > if (TREE_CODE (type) == ARRAY_TYPE) > @@ -2316,6 +2427,17 @@ strlen_optimize_stmt (gimple_stmt_iterator *gsi) > } > } > } > + else if (gcond *cond = dyn_cast<gcond *> (stmt)) > + { > + enum tree_code code = gimple_cond_code (cond); > + tree lhs = gimple_cond_lhs (stmt); > + tree rhs = gimple_cond_rhs (stmt); > + > + if ((code == EQ_EXPR || code == NE_EXPR) > + && TREE_CODE (lhs) == SSA_NAME > + && TREE_CODE (rhs) == SSA_NAME) And here. > + fold_strstr_to_memcmp (code, lhs, rhs, stmt); > + } > > if (gimple_vdef (stmt)) > maybe_invalidate (stmt); Otherwise LGTM, but it would be nice to cover also the COND_EXPR case by a testcase (can be done incrementally). Jakub