aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2015-12-18 23:16:24 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2015-12-18 23:16:24 +0100
commita49de7a463519e8e3c7e903caef9e78604fd637d (patch)
tree9d8f68bcec113d5a41ce201bffd8fc2d69889feb
parentca2c1b328327f998338cfa4b9e902e439cf57278 (diff)
downloadgcc-a49de7a463519e8e3c7e903caef9e78604fd637d.zip
gcc-a49de7a463519e8e3c7e903caef9e78604fd637d.tar.gz
gcc-a49de7a463519e8e3c7e903caef9e78604fd637d.tar.bz2
re PR debug/68860 (FAIL: gcc.dg/guality/pr36728-1.c -flto -O3 -g line 17 arg1 == 1)
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
-rw-r--r--gcc/ChangeLog12
-rw-r--r--gcc/cgraph.c67
-rw-r--r--gcc/ipa-split.c94
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.dg/guality/pr68860-1.c54
-rw-r--r--gcc/testsuite/gcc.dg/guality/pr68860-2.c54
-rw-r--r--gcc/tree-inline.c129
7 files changed, 334 insertions, 82 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index acc5873..e045295 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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):
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index 5a9c2a2..98846fc 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -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
diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c
index f77ab52..ca82e3a 100644
--- a/gcc/ipa-split.c
+++ b/gcc/ipa-split.c
@@ -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,
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index d8202de..ceba598 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..8c8d835
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/guality/pr68860-1.c
@@ -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
index 0000000..070efbc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/guality/pr68860-2.c
@@ -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;
+}
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index dea23c7..36c96225 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -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);