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 (&copy_gsi, new_stmt, false);

Reply via email to