Hi, This patch adds support for va_arg_pack and va_arg_pack_len for instrumented functions into inliner. There are two things to do: 1) ignore bounds args when computing va_arg_pack_len 2) remove bounds args when expanding va_arg_pack in not instrumented call.
Thanks, Ilya -- 2014-08-15 Ilya Enkovich <ilya.enkov...@intel.com> * tree-inline.c (copy_bb): Properly handle bounds in va_arg_pack and va_arg_pack_len. diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index 6ec1a81..03e7e2f 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -1767,13 +1767,29 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale, gimple new_call; vec<tree> argarray; size_t nargs = gimple_call_num_args (id->gimple_call); - size_t n; + size_t n, i, nargs_to_copy; + bool remove_bounds = false; for (p = DECL_ARGUMENTS (id->src_fn); p; p = DECL_CHAIN (p)) nargs--; + /* Bounds should be removed from arg pack in case + we handle not instrumented call in instrumented + function. */ + nargs_to_copy = nargs; + if (gimple_call_with_bounds_p (id->gimple_call) + && !gimple_call_with_bounds_p (stmt)) + { + for (i = gimple_call_num_args (id->gimple_call) - nargs; + i < gimple_call_num_args (id->gimple_call); + i++) + if (POINTER_BOUNDS_P (gimple_call_arg (id->gimple_call, i))) + nargs_to_copy--; + remove_bounds = true; + } + /* Create the new array of arguments. */ - n = nargs + gimple_call_num_args (stmt); + n = nargs_to_copy + gimple_call_num_args (stmt); argarray.create (n); argarray.safe_grow_cleared (n); @@ -1782,11 +1798,26 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale, gimple_call_arg_ptr (stmt, 0), gimple_call_num_args (stmt) * sizeof (tree)); - /* Append the arguments passed in '...' */ - memcpy (argarray.address () + gimple_call_num_args (stmt), - gimple_call_arg_ptr (id->gimple_call, 0) - + (gimple_call_num_args (id->gimple_call) - nargs), - nargs * sizeof (tree)); + if (remove_bounds) + { + /* Append the rest of arguments removing bounds. */ + unsigned cur = gimple_call_num_args (stmt); + i = gimple_call_num_args (id->gimple_call) - nargs; + for (i = gimple_call_num_args (id->gimple_call) - nargs; + i < gimple_call_num_args (id->gimple_call); + i++) + if (!POINTER_BOUNDS_P (gimple_call_arg (id->gimple_call, i))) + argarray[cur++] = gimple_call_arg (id->gimple_call, i); + gcc_assert (cur == n); + } + else + { + /* Append the arguments passed in '...' */ + memcpy (argarray.address () + gimple_call_num_args (stmt), + gimple_call_arg_ptr (id->gimple_call, 0) + + (gimple_call_num_args (id->gimple_call) - nargs), + nargs * sizeof (tree)); + } new_call = gimple_build_call_vec (gimple_call_fn (stmt), argarray); @@ -1812,13 +1843,20 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale, { /* __builtin_va_arg_pack_len () should be replaced by the number of anonymous arguments. */ - size_t nargs = gimple_call_num_args (id->gimple_call); + size_t nargs = gimple_call_num_args (id->gimple_call), i; tree count, p; gimple new_stmt; for (p = DECL_ARGUMENTS (id->src_fn); p; p = DECL_CHAIN (p)) nargs--; + /* For instrumented calls we should ignore bounds. */ + for (i = gimple_call_num_args (id->gimple_call) - nargs; + i < gimple_call_num_args (id->gimple_call); + i++) + if (POINTER_BOUNDS_P (gimple_call_arg (id->gimple_call, i))) + nargs--; + count = build_int_cst (integer_type_node, nargs); new_stmt = gimple_build_assign (gimple_call_lhs (stmt), count); gsi_replace (©_gsi, new_stmt, false);