re PR debug/68860 (FAIL: gcc.dg/guality/pr36728-1.c -flto -O3 -g line 17 arg1...
authorJakub Jelinek <jakub@redhat.com>
Fri, 18 Dec 2015 22:16:24 +0000 (23:16 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Fri, 18 Dec 2015 22:16:24 +0000 (23:16 +0100)
PR debug/68860
* ipa-split.c (split_function): Only perform caller side
modifications for decl_debug_args here.
* cgraph.c: Include gimplify.h.
(cgraph_edge::redirect_call_stmt_to_callee): Add caller side
debug stmts for decl_debug_args.  Spelling fix in a comment.
* tree-inline.c (tree_function_versioning): Populate decl_debug_args
for args_to_skip arguments and add callee side debug stmts.
Formatting fixes.  Avoid shadowing i variable.

* gcc.dg/guality/pr68860-1.c: New test.
* gcc.dg/guality/pr68860-2.c: New test.

From-SVN: r231840

gcc/ChangeLog
gcc/cgraph.c
gcc/ipa-split.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/guality/pr68860-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/guality/pr68860-2.c [new file with mode: 0644]
gcc/tree-inline.c

index acc5873..e045295 100644 (file)
@@ -1,3 +1,15 @@
+2015-12-18  Jakub Jelinek  <jakub@redhat.com>
+
+       PR debug/68860
+       * ipa-split.c (split_function): Only perform caller side
+       modifications for decl_debug_args here.
+       * cgraph.c: Include gimplify.h.
+       (cgraph_edge::redirect_call_stmt_to_callee): Add caller side
+       debug stmts for decl_debug_args.  Spelling fix in a comment.
+       * tree-inline.c (tree_function_versioning): Populate decl_debug_args
+       for args_to_skip arguments and add callee side debug stmts.
+       Formatting fixes.  Avoid shadowing i variable.
+
 2015-12-18  Nathan Sidwell  <nathan@acm.org>
 
        * config/nvptx/nvptx.c (nvptx_maybe_convert_symbolic_operand):
index 5a9c2a2..98846fc 100644 (file)
@@ -58,6 +58,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "params.h"
 #include "tree-chkp.h"
 #include "context.h"
+#include "gimplify.h"
 
 /* FIXME: Only for PROP_loops, but cgraph shouldn't have to know about this.  */
 #include "tree-pass.h"
@@ -1275,7 +1276,7 @@ cgraph_edge::redirect_call_stmt_to_callee (void)
       if (decl)
        e = e->resolve_speculation (decl);
       /* If types do not match, speculation was likely wrong. 
-         The direct edge was posisbly redirected to the clone with a different
+         The direct edge was possibly redirected to the clone with a different
         signature.  We did not update the call statement yet, so compare it 
         with the reference that still points to the proper type.  */
       else if (!gimple_check_call_matching_types (e->call_stmt,
@@ -1420,6 +1421,70 @@ cgraph_edge::redirect_call_stmt_to_callee (void)
        SSA_NAME_DEF_STMT (gimple_vdef (new_stmt)) = new_stmt;
 
       gsi = gsi_for_stmt (e->call_stmt);
+
+      /* For optimized away parameters, add on the caller side
+        before the call
+        DEBUG D#X => parm_Y(D)
+        stmts and associate D#X with parm in decl_debug_args_lookup
+        vector to say for debug info that if parameter parm had been passed,
+        it would have value parm_Y(D).  */
+      if (e->callee->clone.combined_args_to_skip && MAY_HAVE_DEBUG_STMTS)
+       {
+         vec<tree, va_gc> **debug_args
+           = decl_debug_args_lookup (e->callee->decl);
+         tree old_decl = gimple_call_fndecl (e->call_stmt);
+         if (debug_args && old_decl)
+           {
+             tree parm;
+             unsigned i = 0, num;
+             unsigned len = vec_safe_length (*debug_args);
+             unsigned nargs = gimple_call_num_args (e->call_stmt);
+             for (parm = DECL_ARGUMENTS (old_decl), num = 0;
+                  parm && num < nargs;
+                  parm = DECL_CHAIN (parm), num++)
+               if (bitmap_bit_p (e->callee->clone.combined_args_to_skip, num)
+                   && is_gimple_reg (parm))
+                 {
+                   unsigned last = i;
+
+                   while (i < len && (**debug_args)[i] != DECL_ORIGIN (parm))
+                     i += 2;
+                   if (i >= len)
+                     {
+                       i = 0;
+                       while (i < last
+                              && (**debug_args)[i] != DECL_ORIGIN (parm))
+                         i += 2;
+                       if (i >= last)
+                         continue;
+                     }
+                   tree ddecl = (**debug_args)[i + 1];
+                   tree arg = gimple_call_arg (e->call_stmt, num);
+                   if (!useless_type_conversion_p (TREE_TYPE (ddecl),
+                                                   TREE_TYPE (arg)))
+                     {
+                       tree rhs1;
+                       if (!fold_convertible_p (TREE_TYPE (ddecl), arg))
+                         continue;
+                       if (TREE_CODE (arg) == SSA_NAME
+                           && gimple_assign_cast_p (SSA_NAME_DEF_STMT (arg))
+                           && (rhs1
+                               = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (arg)))
+                           && useless_type_conversion_p (TREE_TYPE (ddecl),
+                                                         TREE_TYPE (rhs1)))
+                         arg = rhs1;
+                       else
+                         arg = fold_convert (TREE_TYPE (ddecl), arg);
+                     }
+
+                   gimple *def_temp
+                     = gimple_build_debug_bind (ddecl, unshare_expr (arg),
+                                                e->call_stmt);
+                   gsi_insert_before (&gsi, def_temp, GSI_SAME_STMT);
+                 }
+           }
+       }
+
       gsi_replace (&gsi, new_stmt, false);
       /* We need to defer cleaning EH info on the new statement to
          fixup-cfg.  We may not have dominator information at this point
index f77ab52..ca82e3a 100644 (file)
@@ -1209,7 +1209,6 @@ split_function (basic_block return_bb, struct split_point *split_point,
   gimple *last_stmt = NULL;
   unsigned int i;
   tree arg, ddef;
-  vec<tree, va_gc> **debug_args = NULL;
 
   if (dump_file)
     {
@@ -1432,73 +1431,38 @@ split_function (basic_block return_bb, struct split_point *split_point,
      vector to say for debug info that if parameter parm had been passed,
      it would have value parm_Y(D).  */
   if (args_to_skip)
-    for (parm = DECL_ARGUMENTS (current_function_decl), num = 0;
-        parm; parm = DECL_CHAIN (parm), num++)
-      if (bitmap_bit_p (args_to_skip, num)
-         && is_gimple_reg (parm))
-       {
-         tree ddecl;
-         gimple *def_temp;
-
-         /* This needs to be done even without MAY_HAVE_DEBUG_STMTS,
-            otherwise if it didn't exist before, we'd end up with
-            different SSA_NAME_VERSIONs between -g and -g0.  */
-         arg = get_or_create_ssa_default_def (cfun, parm);
-         if (!MAY_HAVE_DEBUG_STMTS)
-           continue;
-
-         if (debug_args == NULL)
-           debug_args = decl_debug_args_insert (node->decl);
-         ddecl = make_node (DEBUG_EXPR_DECL);
-         DECL_ARTIFICIAL (ddecl) = 1;
-         TREE_TYPE (ddecl) = TREE_TYPE (parm);
-         DECL_MODE (ddecl) = DECL_MODE (parm);
-         vec_safe_push (*debug_args, DECL_ORIGIN (parm));
-         vec_safe_push (*debug_args, ddecl);
-         def_temp = gimple_build_debug_bind (ddecl, unshare_expr (arg),
-                                             call);
-         gsi_insert_after (&gsi, def_temp, GSI_NEW_STMT);
-       }
-  /* And on the callee side, add
-     DEBUG D#Y s=> parm
-     DEBUG var => D#Y
-     stmts to the first bb where var is a VAR_DECL created for the
-     optimized away parameter in DECL_INITIAL block.  This hints
-     in the debug info that var (whole DECL_ORIGIN is the parm PARM_DECL)
-     is optimized away, but could be looked up at the call site
-     as value of D#X there.  */
-  if (debug_args != NULL)
     {
-      unsigned int i;
-      tree var, vexpr;
-      gimple_stmt_iterator cgsi;
-      gimple *def_temp;
-
-      push_cfun (DECL_STRUCT_FUNCTION (node->decl));
-      var = BLOCK_VARS (DECL_INITIAL (node->decl));
-      i = vec_safe_length (*debug_args);
-      cgsi = gsi_after_labels (single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun)));
-      do
+      vec<tree, va_gc> **debug_args = NULL;
+      unsigned i = 0, len = 0;
+      if (MAY_HAVE_DEBUG_STMTS)
        {
-         i -= 2;
-         while (var != NULL_TREE
-                && DECL_ABSTRACT_ORIGIN (var) != (**debug_args)[i])
-           var = TREE_CHAIN (var);
-         if (var == NULL_TREE)
-           break;
-         vexpr = make_node (DEBUG_EXPR_DECL);
-         parm = (**debug_args)[i];
-         DECL_ARTIFICIAL (vexpr) = 1;
-         TREE_TYPE (vexpr) = TREE_TYPE (parm);
-         DECL_MODE (vexpr) = DECL_MODE (parm);
-         def_temp = gimple_build_debug_source_bind (vexpr, parm,
-                                                    NULL);
-         gsi_insert_before (&cgsi, def_temp, GSI_SAME_STMT);
-         def_temp = gimple_build_debug_bind (var, vexpr, NULL);
-         gsi_insert_before (&cgsi, def_temp, GSI_SAME_STMT);
+         debug_args = decl_debug_args_lookup (node->decl);
+         if (debug_args)
+           len = vec_safe_length (*debug_args);
        }
-      while (i);
-      pop_cfun ();
+      for (parm = DECL_ARGUMENTS (current_function_decl), num = 0;
+          parm; parm = DECL_CHAIN (parm), num++)
+       if (bitmap_bit_p (args_to_skip, num) && is_gimple_reg (parm))
+         {
+           tree ddecl;
+           gimple *def_temp;
+
+           /* This needs to be done even without MAY_HAVE_DEBUG_STMTS,
+              otherwise if it didn't exist before, we'd end up with
+              different SSA_NAME_VERSIONs between -g and -g0.  */
+           arg = get_or_create_ssa_default_def (cfun, parm);
+           if (!MAY_HAVE_DEBUG_STMTS || debug_args == NULL)
+             continue;
+
+           while (i < len && (**debug_args)[i] != DECL_ORIGIN (parm))
+             i += 2;
+           if (i >= len)
+             continue;
+           ddecl = (**debug_args)[i + 1];
+           def_temp
+             = gimple_build_debug_bind (ddecl, unshare_expr (arg), call);
+           gsi_insert_after (&gsi, def_temp, GSI_NEW_STMT);
+         }
     }
 
   /* We avoid address being taken on any variable used by split part,
index d8202de..ceba598 100644 (file)
@@ -1,3 +1,9 @@
+2015-12-18  Jakub Jelinek  <jakub@redhat.com>
+
+       PR debug/68860
+       * gcc.dg/guality/pr68860-1.c: New test.
+       * gcc.dg/guality/pr68860-2.c: New test.
+
 2015-12-18  Nathan Sidwell  <nathan@acm.org>
 
        * lib/target-supports.exp (check_effective_target_cilkplus): Not nvptx.
diff --git a/gcc/testsuite/gcc.dg/guality/pr68860-1.c b/gcc/testsuite/gcc.dg/guality/pr68860-1.c
new file mode 100644 (file)
index 0000000..8c8d835
--- /dev/null
@@ -0,0 +1,54 @@
+/* PR debug/68860 */
+/* { dg-do run } */
+/* { dg-options "-g" } */
+
+#include "../nop.h"
+
+static int __attribute__((noinline))
+foo (int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7, int arg8)
+{
+  char *x = __builtin_alloca (arg7);
+  int __attribute__ ((aligned(32))) y;
+
+  y = 2;
+  asm (NOP : "=m" (y) : "m" (y));
+  x[0] = 25 + arg8;
+  asm volatile (NOP : "=m" (x[0]) : "m" (x[0]));
+  return y;
+}
+
+/* On s390(x) r2 and r3 are (depending on the optimization level) used
+   when adjusting the addresses in order to meet the alignment
+   requirements above.  They usually hold the function arguments arg1
+   and arg2.  So it is expected that these values are unavailable in
+   some of these tests.  */
+
+/* { dg-final { gdb-test 14 "arg1" "1" { target { ! "s390*-*-*" } } } } */
+/* { dg-final { gdb-test 14 "arg2" "2" { target { ! "s390*-*-*" } } } } */
+/* { dg-final { gdb-test 14 "arg3" "3" } } */
+/* { dg-final { gdb-test 14 "arg4" "4" } } */
+/* { dg-final { gdb-test 14 "arg5" "5" } } */
+/* { dg-final { gdb-test 14 "arg6" "6" } } */
+/* { dg-final { gdb-test 14 "arg7" "30" } } */
+/* { dg-final { gdb-test 14 "arg8" "7" } } */
+/* { dg-final { gdb-test 14 "y" "2" } } */
+/* { dg-final { gdb-test 16 "arg1" "1" { target { ! "s390*-*-*" } } } } */
+/* { dg-final { gdb-test 16 "arg2" "2" { target { ! "s390*-*-*" } } } } */
+/* { dg-final { gdb-test 16 "arg3" "3" } } */
+/* { dg-final { gdb-test 16 "arg4" "4" } } */
+/* { dg-final { gdb-test 16 "arg5" "5" } } */
+/* { dg-final { gdb-test 16 "arg6" "6" } } */
+/* { dg-final { gdb-test 16 "arg7" "30" } } */
+/* { dg-final { gdb-test 16 "arg8" "7" } } */
+/* { dg-final { gdb-test 16 "*x" "(char) 32" } } */
+/* { dg-final { gdb-test 16 "y" "2" } } */
+
+int
+main ()
+{
+  int l = 0;
+  asm volatile ("" : "=r" (l) : "0" (l));
+  foo (l + 1, l + 2, l + 3, l + 4, l + 5, l + 6, l + 30, 7);
+  asm volatile ("" :: "r" (l));
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/guality/pr68860-2.c b/gcc/testsuite/gcc.dg/guality/pr68860-2.c
new file mode 100644 (file)
index 0000000..070efbc
--- /dev/null
@@ -0,0 +1,54 @@
+/* PR debug/68860 */
+/* { dg-do run } */
+/* { dg-options "-g" } */
+
+#include "../nop.h"
+
+int __attribute__((noinline))
+foo (int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7, int arg8)
+{
+  char *x = __builtin_alloca (arg7);
+  int __attribute__ ((aligned(32))) y;
+
+  y = 2;
+  asm (NOP : "=m" (y) : "m" (y));
+  x[0] = 25 + arg8;
+  asm volatile (NOP : "=m" (x[0]) : "m" (x[0]));
+  return y;
+}
+
+/* On s390(x) r2 and r3 are (depending on the optimization level) used
+   when adjusting the addresses in order to meet the alignment
+   requirements above.  They usually hold the function arguments arg1
+   and arg2.  So it is expected that these values are unavailable in
+   some of these tests.  */
+
+/* { dg-final { gdb-test 14 "arg1" "1" { target { ! "s390*-*-*" } } } } */
+/* { dg-final { gdb-test 14 "arg2" "2" { target { ! "s390*-*-*" } } } } */
+/* { dg-final { gdb-test 14 "arg3" "3" } } */
+/* { dg-final { gdb-test 14 "arg4" "4" } } */
+/* { dg-final { gdb-test 14 "arg5" "5" } } */
+/* { dg-final { gdb-test 14 "arg6" "6" } } */
+/* { dg-final { gdb-test 14 "arg7" "30" } } */
+/* { dg-final { gdb-test 14 "arg8" "7" } } */
+/* { dg-final { gdb-test 14 "y" "2" } } */
+/* { dg-final { gdb-test 16 "arg1" "1" { target { ! "s390*-*-*" } } } } */
+/* { dg-final { gdb-test 16 "arg2" "2" { target { ! "s390*-*-*" } } } } */
+/* { dg-final { gdb-test 16 "arg3" "3" } } */
+/* { dg-final { gdb-test 16 "arg4" "4" } } */
+/* { dg-final { gdb-test 16 "arg5" "5" } } */
+/* { dg-final { gdb-test 16 "arg6" "6" } } */
+/* { dg-final { gdb-test 16 "arg7" "30" } } */
+/* { dg-final { gdb-test 16 "arg8" "7" } } */
+/* { dg-final { gdb-test 16 "*x" "(char) 32" } } */
+/* { dg-final { gdb-test 16 "y" "2" } } */
+
+int
+main ()
+{
+  int l = 0;
+  asm volatile ("" : "=r" (l) : "0" (l));
+  foo (l + 1, l + 2, l + 3, l + 4, l + 5, l + 6, l + 30, 7);
+  asm volatile ("" :: "r" (l));
+  return 0;
+}
index dea23c7..36c9622 100644 (file)
@@ -5668,6 +5668,7 @@ tree_function_versioning (tree old_decl, tree new_decl,
   basic_block old_entry_block, bb;
   auto_vec<gimple *, 10> init_stmts;
   tree vars = NULL_TREE;
+  bitmap debug_args_to_skip = args_to_skip;
 
   gcc_assert (TREE_CODE (old_decl) == FUNCTION_DECL
              && TREE_CODE (new_decl) == FUNCTION_DECL);
@@ -5740,9 +5741,8 @@ tree_function_versioning (tree old_decl, tree new_decl,
   /* Copy the function's static chain.  */
   p = DECL_STRUCT_FUNCTION (old_decl)->static_chain_decl;
   if (p)
-    DECL_STRUCT_FUNCTION (new_decl)->static_chain_decl =
-      copy_static_chain (DECL_STRUCT_FUNCTION (old_decl)->static_chain_decl,
-                        &id);
+    DECL_STRUCT_FUNCTION (new_decl)->static_chain_decl
+      = copy_static_chain (p, &id);
 
   /* If there's a tree_map, prepare for substitution.  */
   if (tree_map)
@@ -5752,29 +5752,39 @@ tree_function_versioning (tree old_decl, tree new_decl,
        replace_info = (*tree_map)[i];
        if (replace_info->replace_p)
          {
+           int parm_num = -1;
            if (!replace_info->old_tree)
              {
-               int i = replace_info->parm_num;
+               int p = replace_info->parm_num;
                tree parm;
-               tree req_type;
+               tree req_type, new_type;
 
-               for (parm = DECL_ARGUMENTS (old_decl); i; parm = DECL_CHAIN (parm))
-                 i --;
+               for (parm = DECL_ARGUMENTS (old_decl); p;
+                    parm = DECL_CHAIN (parm))
+                 p--;
                replace_info->old_tree = parm;
+               parm_num = replace_info->parm_num;
                req_type = TREE_TYPE (parm);
-               if (!useless_type_conversion_p (req_type, TREE_TYPE (replace_info->new_tree)))
+               new_type = TREE_TYPE (replace_info->new_tree);
+               if (!useless_type_conversion_p (req_type, new_type))
                  {
                    if (fold_convertible_p (req_type, replace_info->new_tree))
-                     replace_info->new_tree = fold_build1 (NOP_EXPR, req_type, replace_info->new_tree);
-                   else if (TYPE_SIZE (req_type) == TYPE_SIZE (TREE_TYPE (replace_info->new_tree)))
-                     replace_info->new_tree = fold_build1 (VIEW_CONVERT_EXPR, req_type, replace_info->new_tree);
+                     replace_info->new_tree
+                       = fold_build1 (NOP_EXPR, req_type,
+                                      replace_info->new_tree);
+                   else if (TYPE_SIZE (req_type) == TYPE_SIZE (new_type))
+                     replace_info->new_tree
+                       = fold_build1 (VIEW_CONVERT_EXPR, req_type,
+                                      replace_info->new_tree);
                    else
                      {
                        if (dump_file)
                          {
                            fprintf (dump_file, "    const ");
-                           print_generic_expr (dump_file, replace_info->new_tree, 0);
-                           fprintf (dump_file, "  can't be converted to param ");
+                           print_generic_expr (dump_file,
+                                               replace_info->new_tree, 0);
+                           fprintf (dump_file,
+                                    "  can't be converted to param ");
                            print_generic_expr (dump_file, parm, 0);
                            fprintf (dump_file, "\n");
                          }
@@ -5792,14 +5802,38 @@ tree_function_versioning (tree old_decl, tree new_decl,
                                            &vars);
                if (init)
                  init_stmts.safe_push (init);
+               if (MAY_HAVE_DEBUG_STMTS && args_to_skip)
+                 {
+                   if (parm_num == -1)
+                     {
+                       tree parm;
+                       int p;
+                       for (parm = DECL_ARGUMENTS (old_decl), p = 0; parm;
+                            parm = DECL_CHAIN (parm), p++)
+                         if (parm == replace_info->old_tree)
+                           {
+                             parm_num = p;
+                             break;
+                           }
+                     }
+                   if (parm_num != -1)
+                     {
+                       if (debug_args_to_skip == args_to_skip)
+                         {
+                           debug_args_to_skip = BITMAP_ALLOC (NULL);
+                           bitmap_copy (debug_args_to_skip, args_to_skip);
+                         }
+                       bitmap_clear_bit (debug_args_to_skip, parm_num);
+                     }
+                 }
              }
          }
       }
   /* Copy the function's arguments.  */
   if (DECL_ARGUMENTS (old_decl) != NULL_TREE)
-    DECL_ARGUMENTS (new_decl) =
-      copy_arguments_for_versioning (DECL_ARGUMENTS (old_decl), &id,
-                                    args_to_skip, &vars);
+    DECL_ARGUMENTS (new_decl)
+      copy_arguments_for_versioning (DECL_ARGUMENTS (old_decl), &id,
+                                      args_to_skip, &vars);
 
   DECL_INITIAL (new_decl) = remap_blocks (DECL_INITIAL (id.src_fn), &id);
   BLOCK_SUPERCONTEXT (DECL_INITIAL (new_decl)) = new_decl;
@@ -5914,6 +5948,69 @@ tree_function_versioning (tree old_decl, tree new_decl,
        }
     }
 
+  if (debug_args_to_skip && MAY_HAVE_DEBUG_STMTS)
+    {
+      tree parm;
+      vec<tree, va_gc> **debug_args = NULL;
+      unsigned int len = 0;
+      for (parm = DECL_ARGUMENTS (old_decl), i = 0;
+          parm; parm = DECL_CHAIN (parm), i++)
+       if (bitmap_bit_p (debug_args_to_skip, i) && is_gimple_reg (parm))
+         {
+           tree ddecl;
+
+           if (debug_args == NULL)
+             {
+               debug_args = decl_debug_args_insert (new_decl);
+               len = vec_safe_length (*debug_args);
+             }
+           ddecl = make_node (DEBUG_EXPR_DECL);
+           DECL_ARTIFICIAL (ddecl) = 1;
+           TREE_TYPE (ddecl) = TREE_TYPE (parm);
+           DECL_MODE (ddecl) = DECL_MODE (parm);
+           vec_safe_push (*debug_args, DECL_ORIGIN (parm));
+           vec_safe_push (*debug_args, ddecl);
+         }
+      if (debug_args != NULL)
+       {
+         /* On the callee side, add
+            DEBUG D#Y s=> parm
+            DEBUG var => D#Y
+            stmts to the first bb where var is a VAR_DECL created for the
+            optimized away parameter in DECL_INITIAL block.  This hints
+            in the debug info that var (whole DECL_ORIGIN is the parm
+            PARM_DECL) is optimized away, but could be looked up at the
+            call site as value of D#X there.  */
+         tree var = vars, vexpr;
+         gimple_stmt_iterator cgsi
+           = gsi_after_labels (single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun)));
+         gimple *def_temp;
+         var = vars;
+         i = vec_safe_length (*debug_args);
+         do
+           {
+             i -= 2;
+             while (var != NULL_TREE
+                    && DECL_ABSTRACT_ORIGIN (var) != (**debug_args)[i])
+               var = TREE_CHAIN (var);
+             if (var == NULL_TREE)
+               break;
+             vexpr = make_node (DEBUG_EXPR_DECL);
+             parm = (**debug_args)[i];
+             DECL_ARTIFICIAL (vexpr) = 1;
+             TREE_TYPE (vexpr) = TREE_TYPE (parm);
+             DECL_MODE (vexpr) = DECL_MODE (parm);
+             def_temp = gimple_build_debug_bind (var, vexpr, NULL);
+             gsi_insert_before (&cgsi, def_temp, GSI_NEW_STMT);
+             def_temp = gimple_build_debug_source_bind (vexpr, parm, NULL);
+             gsi_insert_before (&cgsi, def_temp, GSI_NEW_STMT);
+           }
+         while (i > len);
+       }
+    }
+
+  if (debug_args_to_skip && debug_args_to_skip != args_to_skip)
+    BITMAP_FREE (debug_args_to_skip);
   free_dominance_info (CDI_DOMINATORS);
   free_dominance_info (CDI_POST_DOMINATORS);