Hi! Here is an updated version of the support patch for the tree-ssa-strlen.c optimization. The only change is the propagation of gimple_block to the new call from the old call, otherwise Wobjsize-1.c testcase fails when we optimize that __strcpy_chk into __memcpy_chk, but don't propagate its BLOCK. Perhaps gimplify_and_update_call_from_tree and update_call_from_tree should do it as well, for all the statements without gimple_block it creates (can do that as a follow-up).
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2011-09-15 Jakub Jelinek <ja...@redhat.com> * gimple-fold.c (gimplify_and_update_call_from_tree): Set gctx.into_ssa after push_gimplify_context. * gimple.c (gimple_build_call_valist): New function. * gimple.h (gimple_build_call_valist): New prototype. * tree-ssa-propagate.c (finish_update_gimple_call): New function. (update_gimple_call): Likewise. (update_call_from_tree): Use finish_update_gimple_call. * tree-ssa-propagate.h (update_gimple_call): New prototype. --- gcc/gimple-fold.c.jj 2011-09-15 12:18:54.000000000 +0200 +++ gcc/gimple-fold.c 2011-09-15 12:23:58.000000000 +0200 @@ -551,6 +551,7 @@ gimplify_and_update_call_from_tree (gimp reaching_vuse = gimple_vuse (stmt); push_gimplify_context (&gctx); + gctx.into_ssa = gimple_in_ssa_p (cfun); if (lhs == NULL_TREE) { --- gcc/gimple.c.jj 2011-09-15 12:18:37.000000000 +0200 +++ gcc/gimple.c 2011-09-15 12:23:58.000000000 +0200 @@ -215,9 +215,10 @@ gimple_call_reset_alias_info (gimple s) pt_solution_reset (gimple_call_clobber_set (s)); } -/* Helper for gimple_build_call, gimple_build_call_vec and - gimple_build_call_from_tree. Build the basic components of a - GIMPLE_CALL statement to function FN with NARGS arguments. */ +/* Helper for gimple_build_call, gimple_build_call_valist, + gimple_build_call_vec and gimple_build_call_from_tree. Build the basic + components of a GIMPLE_CALL statement to function FN with NARGS + arguments. */ static inline gimple gimple_build_call_1 (tree fn, unsigned nargs) @@ -272,6 +273,26 @@ gimple_build_call (tree fn, unsigned nar } +/* Build a GIMPLE_CALL statement to function FN. NARGS is the number of + arguments. AP contains the arguments. */ + +gimple +gimple_build_call_valist (tree fn, unsigned nargs, va_list ap) +{ + gimple call; + unsigned i; + + gcc_assert (TREE_CODE (fn) == FUNCTION_DECL || is_gimple_call_addr (fn)); + + call = gimple_build_call_1 (fn, nargs); + + for (i = 0; i < nargs; i++) + gimple_call_set_arg (call, i, va_arg (ap, tree)); + + return call; +} + + /* Helper for gimple_build_call_internal and gimple_build_call_internal_vec. Build the basic components of a GIMPLE_CALL statement to internal function FN with NARGS arguments. */ --- gcc/gimple.h.jj 2011-09-15 12:18:54.000000000 +0200 +++ gcc/gimple.h 2011-09-15 12:23:58.000000000 +0200 @@ -831,6 +831,7 @@ gimple gimple_build_debug_source_bind_st gimple gimple_build_call_vec (tree, VEC(tree, heap) *); gimple gimple_build_call (tree, unsigned, ...); +gimple gimple_build_call_valist (tree, unsigned, va_list); gimple gimple_build_call_internal (enum internal_fn, unsigned, ...); gimple gimple_build_call_internal_vec (enum internal_fn, VEC(tree, heap) *); gimple gimple_build_call_from_tree (tree); --- gcc/tree-ssa-propagate.c.jj 2011-09-15 12:18:37.000000000 +0200 +++ gcc/tree-ssa-propagate.c 2011-09-15 16:46:54.000000000 +0200 @@ -1,5 +1,5 @@ /* Generic SSA value propagation engine. - Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 + Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. Contributed by Diego Novillo <dnovi...@redhat.com> @@ -673,6 +673,40 @@ move_ssa_defining_stmt_for_defs (gimple } } +/* Helper function for update_gimple_call and update_call_from_tree. + A GIMPLE_CALL STMT is being replaced with GIMPLE_CALL NEW_STMT. */ + +static void +finish_update_gimple_call (gimple_stmt_iterator *si_p, gimple new_stmt, + gimple stmt) +{ + gimple_call_set_lhs (new_stmt, gimple_call_lhs (stmt)); + move_ssa_defining_stmt_for_defs (new_stmt, stmt); + gimple_set_vuse (new_stmt, gimple_vuse (stmt)); + gimple_set_vdef (new_stmt, gimple_vdef (stmt)); + gimple_set_location (new_stmt, gimple_location (stmt)); + if (gimple_block (new_stmt) == NULL_TREE) + gimple_set_block (new_stmt, gimple_block (stmt)); + gsi_replace (si_p, new_stmt, false); +} + +/* Update a GIMPLE_CALL statement at iterator *SI_P to call to FN + with number of arguments NARGS, where the arguments in GIMPLE form + follow NARGS argument. */ + +bool +update_gimple_call (gimple_stmt_iterator *si_p, tree fn, int nargs, ...) +{ + va_list ap; + gimple new_stmt, stmt = gsi_stmt (*si_p); + + gcc_assert (is_gimple_call (stmt)); + va_start (ap, nargs); + new_stmt = gimple_build_call_valist (fn, nargs, ap); + finish_update_gimple_call (si_p, new_stmt, stmt); + va_end (ap); + return true; +} /* Update a GIMPLE_CALL statement at iterator *SI_P to reflect the value of EXPR, which is expected to be the result of folding the @@ -689,14 +723,8 @@ move_ssa_defining_stmt_for_defs (gimple bool update_call_from_tree (gimple_stmt_iterator *si_p, tree expr) { - tree lhs; - gimple stmt = gsi_stmt (*si_p); - gcc_assert (is_gimple_call (stmt)); - - lhs = gimple_call_lhs (stmt); - if (valid_gimple_call_p (expr)) { /* The call has simplified to another call. */ @@ -716,18 +744,14 @@ update_call_from_tree (gimple_stmt_itera } new_stmt = gimple_build_call_vec (fn, args); - gimple_call_set_lhs (new_stmt, lhs); - move_ssa_defining_stmt_for_defs (new_stmt, stmt); - gimple_set_vuse (new_stmt, gimple_vuse (stmt)); - gimple_set_vdef (new_stmt, gimple_vdef (stmt)); - gimple_set_location (new_stmt, gimple_location (stmt)); - gsi_replace (si_p, new_stmt, false); + finish_update_gimple_call (si_p, new_stmt, stmt); VEC_free (tree, heap, args); return true; } else if (valid_gimple_rhs_p (expr)) { + tree lhs = gimple_call_lhs (stmt); gimple new_stmt; /* The call has simplified to an expression --- gcc/tree-ssa-propagate.h.jj 2011-09-15 12:18:37.000000000 +0200 +++ gcc/tree-ssa-propagate.h 2011-09-15 12:23:58.000000000 +0200 @@ -1,6 +1,7 @@ /* Data structures and function declarations for the SSA value propagation engine. - Copyright (C) 2004, 2005, 2007, 2008, 2010 Free Software Foundation, Inc. + Copyright (C) 2004, 2005, 2007, 2008, 2010, 2011 + Free Software Foundation, Inc. Contributed by Diego Novillo <dnovi...@redhat.com> This file is part of GCC. @@ -72,6 +73,7 @@ typedef tree (*ssa_prop_get_value_fn) (t void ssa_propagate (ssa_prop_visit_stmt_fn, ssa_prop_visit_phi_fn); bool valid_gimple_rhs_p (tree); void move_ssa_defining_stmt_for_defs (gimple, gimple); +bool update_gimple_call (gimple_stmt_iterator *, tree, int, ...); bool update_call_from_tree (gimple_stmt_iterator *, tree); bool stmt_makes_single_store (gimple); bool substitute_and_fold (ssa_prop_get_value_fn, ssa_prop_fold_stmt_fn, bool); Jakub