This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Another BLOCK issue - PR56570


This PR shows that when SRA creates DECL_DEBUG_EXPRs with locations
(and blocks) this does not work with inlining.  The reason is that
the inliner does not bother to copy vars used only in lhs of
debug-stmts (eek) and thus ends up sharing DECL_DEBUG_EXPRs
(and not re-mapping them and their location blocks).  Maybe
a recipie for further desaster ... (who knows).  I didn't manage
to get it to "properly" copy things, but basically

  else if (TREE_CODE (t) == VAR_DECL
           && !is_global_var (t)
           && !pointer_map_contains (id->decl_map, t))
    /* T is a non-localized variable.  */;

doesn't work - vars can be not in local-decls (which we all remap)
due to remove-unused-locals.  Thus we end up not remapping the
debug var (and refer to the other functions DECL_DEBUG_EXPR).

The following avoids the DECL_DEBUG_EXPR issue by clearing
all location information from it (it's unused anyway).
The above code should nevertheless be inspected ...

I took the liberty to sync the MEM_REF code from the two nearly
identical tree copying routines (eh ...), it was my first guess
as to what goes wrong.

Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.

For 4.9 we'd want a verify_no_location eventually which we can
use to recurse here.

Any comments about the above code?

Thanks,
Richard.

2013-03-08  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/56570
	* tree-cfg.c (verify_expr_location_1): Verify locations for
	DECL_DEBUG_EXPR.
	* tree-sra.c (create_access_replacement): Strip locations
	from DECL_DEBUG_EXPRs.
	* tree-inline.c (copy_tree_body_r): Sync MEM_REF code from ...
	remap_gimple_op_r.

Index: gcc/tree-cfg.c
===================================================================
*** gcc/tree-cfg.c	(revision 196542)
--- gcc/tree-cfg.c	(working copy)
*************** verify_expr_location_1 (tree *tp, int *w
*** 4523,4528 ****
--- 4523,4537 ----
  {
    struct pointer_set_t *blocks = (struct pointer_set_t *) data;
  
+   if (TREE_CODE (*tp) == VAR_DECL
+       && DECL_DEBUG_EXPR_IS_FROM (*tp))
+     {
+       tree t = DECL_DEBUG_EXPR (*tp);
+       tree addr = walk_tree (&t, verify_expr_location_1, blocks, NULL);
+       if (addr)
+ 	return addr;
+     }
+ 
    if (!EXPR_P (*tp))
      {
        *walk_subtrees = false;
Index: gcc/tree-sra.c
===================================================================
*** gcc/tree-sra.c	(revision 196541)
--- gcc/tree-sra.c	(working copy)
*************** create_access_replacement (struct access
*** 1917,1923 ****
        && !DECL_ARTIFICIAL (access->base))
      {
        char *pretty_name = make_fancy_name (access->expr);
!       tree debug_expr = unshare_expr (access->expr), d;
        bool fail = false;
  
        DECL_NAME (repl) = get_identifier (pretty_name);
--- 1917,1923 ----
        && !DECL_ARTIFICIAL (access->base))
      {
        char *pretty_name = make_fancy_name (access->expr);
!       tree debug_expr = unshare_expr_without_location (access->expr), d;
        bool fail = false;
  
        DECL_NAME (repl) = get_identifier (pretty_name);
Index: gcc/tree-inline.c
===================================================================
*** gcc/tree-inline.c	(revision 196542)
--- gcc/tree-inline.c	(working copy)
*************** copy_tree_body_r (tree *tp, int *walk_su
*** 1092,1113 ****
  	}
        else if (TREE_CODE (*tp) == MEM_REF)
  	{
! 	  /* We need to re-canonicalize MEM_REFs from inline substitutions
! 	     that can happen when a pointer argument is an ADDR_EXPR.  */
! 	  tree decl = TREE_OPERAND (*tp, 0);
! 	  tree *n;
  
! 	  n = (tree *) pointer_map_contains (id->decl_map, decl);
! 	  if (n)
! 	    {
! 	      tree old = *tp;
! 	      *tp = fold_build2 (MEM_REF, TREE_TYPE (*tp),
! 				 unshare_expr (*n), TREE_OPERAND (*tp, 1));
! 	      TREE_THIS_VOLATILE (*tp) = TREE_THIS_VOLATILE (old);
! 	      TREE_NO_WARNING (*tp) = TREE_NO_WARNING (old);
! 	      *walk_subtrees = 0;
! 	      return NULL;
! 	    }
  	}
  
        /* Here is the "usual case".  Copy this tree node, and then
--- 1092,1113 ----
  	}
        else if (TREE_CODE (*tp) == MEM_REF)
  	{
! 	  tree ptr = TREE_OPERAND (*tp, 0);
! 	  tree type = remap_type (TREE_TYPE (*tp), id);
! 	  tree old = *tp;
  
! 	  /* We need to re-canonicalize MEM_REFs from inline substitutions
! 	     that can happen when a pointer argument is an ADDR_EXPR.
! 	     Recurse here manually to allow that.  */
! 	  walk_tree (&ptr, copy_tree_body_r, data, NULL);
! 	  *tp = fold_build2 (MEM_REF, type,
! 			     ptr, TREE_OPERAND (*tp, 1));
! 	  TREE_THIS_NOTRAP (*tp) = TREE_THIS_NOTRAP (old);
! 	  TREE_THIS_VOLATILE (*tp) = TREE_THIS_VOLATILE (old);
! 	  TREE_SIDE_EFFECTS (*tp) = TREE_SIDE_EFFECTS (old);
! 	  TREE_NO_WARNING (*tp) = TREE_NO_WARNING (old);
! 	  *walk_subtrees = 0;
! 	  return NULL;
  	}
  
        /* Here is the "usual case".  Copy this tree node, and then


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]