On 07/05/2018 01:39 PM, Richard Biener wrote:
> On Thu, Jul 5, 2018 at 1:25 PM Tom de Vries <tdevr...@suse.de> wrote:
>>
>> [ was: Re: [testsuite/guality, committed] Prevent optimization of local in
>> vla-1.c ]
>>
>> On Wed, Jul 04, 2018 at 02:32:27PM +0200, Tom de Vries wrote:
>>> On 07/03/2018 11:05 AM, Tom de Vries wrote:
>>>> On 07/02/2018 10:16 AM, Jakub Jelinek wrote:
>>>>> On Mon, Jul 02, 2018 at 09:44:04AM +0200, Richard Biener wrote:

<SNIP>

>> [debug] Handle references to skipped params in remap_ssa_name
>>
>> 2018-07-05  Tom de Vries  <tdevr...@suse.de>
>>
>>         * tree-inline.c (remap_ssa_name): Handle references to skipped
>>         params.
>>
>> ---
>>  gcc/tree-inline.c | 17 +++++++++++++++--
>>  1 file changed, 15 insertions(+), 2 deletions(-)
>>
>> diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
>> index 427ef959740..0fa996cab49 100644
>> --- a/gcc/tree-inline.c
>> +++ b/gcc/tree-inline.c
>> @@ -204,11 +204,22 @@ remap_ssa_name (tree name, copy_body_data *id)
>>           gimple *def_temp;
>>           gimple_stmt_iterator gsi;
>>           tree val = SSA_NAME_VAR (name);
>> +         bool skipped_parm_decl = false;
>>
>>           n = id->decl_map->get (val);
>>           if (n != NULL)
>> -           val = *n;
>> -         if (TREE_CODE (val) != PARM_DECL)
>> +           {
>> +             if (TREE_CODE (*n) == DEBUG_EXPR_DECL)
>> +               return *n;
>> +
>> +             if (TREE_CODE (*n) == VAR_DECL
>> +                 && DECL_ABSTRACT_ORIGIN (*n)
>> +                 && TREE_CODE (DECL_ABSTRACT_ORIGIN (*n)) == PARM_DECL)
>> +               skipped_parm_decl = true;
>> +             else
>> +               val = *n;
>> +           }
>> +         if (TREE_CODE (val) != PARM_DECL && !skipped_parm_decl)
> 
> I wonder if this cannot be more easily set up in copy_arguments_for_versioning
> which already does
> 
>     else if (!id->decl_map->get (arg))
>       {
>         /* Make an equivalent VAR_DECL.  If the argument was used
>            as temporary variable later in function, the uses will be
>            replaced by local variable.  */
>         tree var = copy_decl_to_var (arg, id);
>         insert_decl_map (id, arg, var);
>         /* Declare this new variable.  */
>         DECL_CHAIN (var) = *vars;
>         *vars = var;
>       }
> 
> which just misses to re-map the default def of the PARM_DECL (in case it 
> exists)
> to the same(?) var?

I've updated the patch to add a debug expr here in
copy_arguments_for_versioning for every parameter that has a default
def, and to use that debug expr in remap_ssa_name.

> All remaining uses should be in debug stmts (I hope).

I ran into a test-case where that was not the case, so I had to handle
that in remap_ssa_name, the comment in the patch describes that in more
detail.

Bootstrapped and reg-tested on x86_64.

OK for trunk?

Thanks,
- Tom
[debug] Handle references to skipped params in remap_ssa_name

When compiling guality/vla-1.c with -O3 -g, vla a in f1 is optimized away, but
f1 still contains a debug expression describing the upper bound of the vla
(D.1914):
...
     __attribute__((noinline))
     f1 (intD.6 iD.1900)
     {
       <bb 2>
       saved_stack.1_2 = __builtin_stack_save ();
       # DEBUG BEGIN_STMT
       # DEBUG D#3 => i_1(D) + 1
       # DEBUG D#2 => (long intD.8) D#3
       # DEBUG D#1 => D#2 + -1
       # DEBUG D.1914 => (sizetype) D#1
...

Then f1 is cloned to a version f1.constprop with no parameters, eliminating
parameter i, and 'DEBUG D#3 => i_1(D) + 1' turns into 'D#3 => NULL'.
Consequently, print sizeof (a) yields '0' in gdb.

This patch fixes that by defining debug expressions for default defs of
eliminated parameters in copy_arguments_for_versioning:
...
     __attribute__((noinline))
     f1.constprop ()
     {
       intD.6 iD.1949;

       <bb 3>
       # DEBUG D#8 s=> iD.1900
       # DEBUG iD.1949 => D#8
+      # DEBUG D#6 s=> iD.1900

       <bb 2>
       saved_stack.1_1 = __builtin_stack_save ();
       # DEBUG BEGIN_STMT
-      # DEBUG D#3 => NULL
+      # DEBUG D#3 => D#6 + 1
       # DEBUG D#2 => (long intD.8) D#3
       # DEBUG D#1 => D#2 + -1
       # DEBUG D.1951 => (sizetype) D#1
...

The inserted debug expression (D#6) is a duplicate of the debug expression
that will be inserted after copy_body in tree_function_versioning (D#8), so the
patch contains a todo to fix the duplication.

Bootstrapped and reg-tested on x86_64.

2018-07-05  Tom de Vries  <tdevr...@suse.de>

	* tree-inline.c (create_debug_expr): Factor out of ...
	(remap_ssa_name): ... here.  Use debug expr only for debug uses.
	(copy_arguments_for_versioning): Add debug expr mapping for skipped
	param default defs.
	(tree_function_versioning): Insert statements defining debug exprs.

---
 gcc/tree-inline.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 58 insertions(+), 8 deletions(-)

diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 427ef959740..11440f49cf0 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -179,6 +179,24 @@ insert_debug_decl_map (copy_body_data *id, tree key, tree value)
    context.  */
 static int processing_debug_stmt = 0;
 
+/* Create a DEBUG_EXPR_DECL based on NAME, and return it.  Create a
+   debug_source_bind assigning VAL to the DEBUG_EXPR_DECL, and return it in
+   STMT.  */
+
+static tree
+create_debug_expr (tree name, tree val, gimple **stmt)
+{
+  tree vexpr = make_node (DEBUG_EXPR_DECL);
+
+  *stmt = gimple_build_debug_source_bind (vexpr, val, NULL);
+
+  DECL_ARTIFICIAL (vexpr) = 1;
+  TREE_TYPE (vexpr) = TREE_TYPE (name);
+  SET_DECL_MODE (vexpr, DECL_MODE (SSA_NAME_VAR (name)));
+
+  return vexpr;
+}
+
 /* Construct new SSA name for old NAME. ID is the inline context.  */
 
 static tree
@@ -191,7 +209,19 @@ remap_ssa_name (tree name, copy_body_data *id)
 
   n = id->decl_map->get (name);
   if (n)
-    return unshare_expr (*n);
+    {
+      if (TREE_CODE (*n) == DEBUG_EXPR_DECL && !processing_debug_stmt)
+	/* This is triggered for f.i. pr48063.c, which contains undefined
+	   behaviour: a mismatch between argument and parameter type.
+	   Consequently, when cloning, the uses of the parameter are not
+	   replaced by the mismatched argument, and we end up with non-debug
+	   uses of the parameter.  Don't use the debug expr in such a case, and
+	   let the use be mapped using the local variable that was introduced
+	   as substitution of the parameter.  */
+	;
+      else
+	return unshare_expr (*n);
+    }
 
   if (processing_debug_stmt)
     {
@@ -200,7 +230,6 @@ remap_ssa_name (tree name, copy_body_data *id)
 	  && id->entry_bb == NULL
 	  && single_succ_p (ENTRY_BLOCK_PTR_FOR_FN (cfun)))
 	{
-	  tree vexpr = make_node (DEBUG_EXPR_DECL);
 	  gimple *def_temp;
 	  gimple_stmt_iterator gsi;
 	  tree val = SSA_NAME_VAR (name);
@@ -213,10 +242,8 @@ remap_ssa_name (tree name, copy_body_data *id)
 	      processing_debug_stmt = -1;
 	      return name;
 	    }
-	  def_temp = gimple_build_debug_source_bind (vexpr, val, NULL);
-	  DECL_ARTIFICIAL (vexpr) = 1;
-	  TREE_TYPE (vexpr) = TREE_TYPE (name);
-	  SET_DECL_MODE (vexpr, DECL_MODE (SSA_NAME_VAR (name)));
+
+	  tree vexpr = create_debug_expr (name, val, &def_temp);
 	  gsi = gsi_after_labels (single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun)));
 	  gsi_insert_before (&gsi, def_temp, GSI_SAME_STMT);
 	  return vexpr;
@@ -5544,7 +5571,8 @@ copy_decl_maybe_to_var (tree decl, copy_body_data *id)
 /* Return a copy of the function's argument tree.  */
 static tree
 copy_arguments_for_versioning (tree orig_parm, copy_body_data * id,
-			       bitmap args_to_skip, tree *vars)
+			       bitmap args_to_skip, tree *vars, tree old_decl,
+			       gimple_seq *stmts)
 {
   tree arg, *parg;
   tree new_parm = NULL;
@@ -5572,6 +5600,20 @@ copy_arguments_for_versioning (tree orig_parm, copy_body_data * id,
         /* Declare this new variable.  */
         DECL_CHAIN (var) = *vars;
         *vars = var;
+
+	if (!MAY_HAVE_DEBUG_BIND_STMTS)
+	  continue;
+
+	tree def = ssa_default_def (DECL_STRUCT_FUNCTION (old_decl), arg);
+	if (!def)
+	  continue;
+
+	gimple *def_stmt;
+	tree vexpr = create_debug_expr (def, arg, &def_stmt);
+	/* TODO: Reuse vexpr in debug_args_to_skip loop in
+	   tree_function_versioning.  */
+	insert_decl_map (id, def, vexpr);
+	gimple_seq_add_stmt (stmts, def_stmt);
       }
   return new_parm;
 }
@@ -5905,10 +5947,12 @@ tree_function_versioning (tree old_decl, tree new_decl,
 	  }
       }
   /* Copy the function's arguments.  */
+  gimple_seq arg_stmts = NULL;
   if (DECL_ARGUMENTS (old_decl) != NULL_TREE)
     DECL_ARGUMENTS (new_decl)
       = copy_arguments_for_versioning (DECL_ARGUMENTS (old_decl), &id,
-				       args_to_skip, &vars);
+				       args_to_skip, &vars, old_decl,
+				       &arg_stmts);
 
   DECL_INITIAL (new_decl) = remap_blocks (DECL_INITIAL (id.src_fn), &id);
   BLOCK_SUPERCONTEXT (DECL_INITIAL (new_decl)) = new_decl;
@@ -5969,6 +6013,12 @@ tree_function_versioning (tree old_decl, tree new_decl,
     insert_init_stmt (&id, bb, init_stmts.pop ());
   update_clone_info (&id);
 
+  if (arg_stmts)
+    {
+      gimple_stmt_iterator gsi = gsi_last_bb (bb);
+      gsi_insert_seq_after (&gsi, arg_stmts, GSI_CONTINUE_LINKING);
+    }
+
   /* Remap the nonlocal_goto_save_area, if any.  */
   if (cfun->nonlocal_goto_save_area)
     {

Reply via email to