[PATCH][varmap] Preserve variables at function arg expansion, cleanups

Richard Guenther rguenther@suse.de
Tue Nov 13 17:58:00 GMT 2007


This makes sure we retain variable names at the point of function arg
expansion so we get stuff like

(insn 2 5 3 2 t2.i:7 (set (reg/v:SI 59 [ l ])
        (reg:SI 5 di [ l ]) { i, l }) -1 (nil))

as those don't go through expand_expr_real.

Also this patch removes the code that modified REG_EXPR directly (and
thus broke the sharing of REG_ATTRS) in favor of some new helper 
functions.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to
var-mappings-branch.

Richard.

2007-11-13  Richard Guenther  <rguenther@suse.de>

	* rtl.h (set_reg_decl): Declare.
	* emit-rtl.c (set_reg_decl): New function.
	* expr.h (set_expr_vars): Declare.
	* expr.c (set_expr_vars): New helper function, split out from ...
	(expand_expr_real): Here.  Use set_reg_decl instead of messing
	with REG_EXPR directly.
	* function.h (assign_parm_setup_reg): Use set_expr_vars to get
	vars for function parameter pseudos.

	* gcc.dg/tree-ssa/vars-7.c: New testcase.

Index: expr.h
===================================================================
*** expr.h	(revision 130099)
--- expr.h	(working copy)
*************** expand_normal (tree exp)
*** 522,527 ****
--- 522,529 ----
  
  extern void expand_var (tree);
  
+ extern void set_expr_vars (rtx, tree);
+ 
  /* At the start of a function, record that we have no previously-pushed
     arguments waiting to be popped.  */
  extern void init_pending_stack_adjust (void);
Index: function.c
===================================================================
*** function.c	(revision 130099)
--- function.c	(working copy)
*************** assign_parm_setup_reg (struct assign_par
*** 2788,2793 ****
--- 2788,2796 ----
        data->stack_parm = NULL;
      }
  
+   /* Record vars for this parameter.  */
+   set_expr_vars (parmreg, parm);
+ 
    /* Mark the register as eliminable if we did no conversion and it was
       copied from memory at a fixed offset, and the arg pointer was not
       copied to a pseudo-reg.  If the arg pointer is a pseudo reg or the
Index: emit-rtl.c
===================================================================
*** emit-rtl.c	(revision 130135)
--- emit-rtl.c	(working copy)
*************** set_reg_attrs_for_parm (rtx parm_rtx, rt
*** 1043,1048 ****
--- 1043,1055 ----
      }
  }
  
+ /* Change the decl associated with REG to DECL.  */
+ void
+ set_reg_decl (rtx reg, tree decl)
+ {
+   REG_ATTRS (reg) = get_reg_attrs (decl, REG_OFFSET (reg));
+ }
+ 
  /* Assign the RTX X to declaration T.  */
  void
  set_decl_rtl (tree t, rtx x)
Index: rtl.h
===================================================================
*** rtl.h	(revision 130101)
--- rtl.h	(working copy)
*************** extern rtx emit_copy_of_insn_after (rtx,
*** 1479,1484 ****
--- 1479,1485 ----
  extern void set_reg_attrs_from_mem (rtx, rtx);
  extern void set_mem_attrs_from_reg (rtx, rtx);
  extern void set_reg_attrs_for_parm (rtx, rtx);
+ extern void set_reg_decl (rtx, tree);
  extern int mem_expr_equal_p (const_tree, const_tree);
  
  /* In rtl.c */
Index: testsuite/gcc.dg/tree-ssa/vars-7.c
===================================================================
*** testsuite/gcc.dg/tree-ssa/vars-7.c	(revision 0)
--- testsuite/gcc.dg/tree-ssa/vars-7.c	(revision 0)
***************
*** 0 ****
--- 1,24 ----
+ /* { dg-do compile } */
+ /* { dg-options "-O2 -fdump-tree-optimized-vars -fdump-rtl-expand" } */
+ 
+ static inline int foo(int i, int k)
+ {
+   int j = i*k;
+   return j;
+ }
+ int foobar(int l, int n)
+ {
+   int m = foo(l, n);
+   return m;
+ }
+ 
+ /* We want to retain both names for the parameters, l and i and k and n.  */
+ 
+ /* { dg-final { scan-tree-dump "n \\\* l E{ m }" "optimized" } } */
+ /* { dg-final { scan-tree-dump ": i l" "optimized" } } */
+ /* { dg-final { scan-tree-dump ": k n" "optimized" } } */
+ /* { dg-final { scan-rtl-dump "{ i, l }" "expand" } } */
+ /* { dg-final { scan-rtl-dump "{ k, n }" "expand" } } */
+ /* { dg-final { scan-rtl-dump "\\\[ m \\\]" "expand" } } */
+ /* { dg-final { cleanup-tree-dump "optimized" } } */
+ /* { dg-final { cleanup-rtl-dump "expand" } } */
Index: expr.c
===================================================================
*** expr.c	(revision 130133)
--- expr.c	(working copy)
*************** expand_expr_real_x (tree exp, rtx target
*** 7116,7121 ****
--- 7116,7162 ----
    return ret;
  }
  
+ /* Attach variable information to the (last generated) SET to REG
+    from the expression EXPR.  */
+ void
+ set_expr_vars (rtx reg, tree exp)
+ {
+   bitmap vars;
+   rtx insn, set;
+ 
+   vars = ssa_varmap_exprmap_lookup (exp);
+   if (!vars)
+     return;
+ 
+   insn = get_last_nonnote_insn ();
+   if (!insn
+       || !(set = single_set (insn))
+       || XEXP (set, 0) != reg)
+     return;
+ 
+   /* Found the set.  What we now can do is, if dest is a pseudo,
+      attach a user variable to it.  This makes it more interesting
+      to var-tracking.
+      ???  What about mems and MEM_EXPR?  */
+   if (REG_P (reg)
+       && (!REG_EXPR (reg)
+ 	  || DECL_ARTIFICIAL (REG_EXPR (reg))))
+     {
+       int uid = bitmap_first_set_bit (vars);
+       tree var = ssa_varmap_get_ref (uid);
+       if (var)
+ 	{
+ 	  set_reg_decl (reg, var);
+ 	  /* If this was the only set bit we can get
+ 	     away without attaching the bitmap to the SET.  */
+ 	  if (bitmap_single_bit_set_p (vars))
+ 	    return;
+ 	}
+     }
+ 
+   XBITMAP (set, 2) = vars;
+ }
+ 
  /* Generate code for computing expression EXP.
     An rtx for the computed value is returned.  The value is never null.
     In the case of a void EXP, const0_rtx is returned.  */
*************** rtx
*** 7123,7139 ****
  expand_expr_real (tree exp, rtx target, enum machine_mode tmode,
  		  enum expand_modifier modifier, rtx *alt_rtl)
  {
!   rtx result, dest, insn, set;
!   bitmap vars;
  
    result = expand_expr_real_x (exp, target, tmode, modifier, alt_rtl);
  
-   /* If there is no variable map attached to the expression, we
-      have done everything required.  */
-   vars = ssa_varmap_exprmap_lookup (exp);
-   if (!vars)
-     return result;
- 
    /* If we expanded an assignment, lookup the target RTX from the
       lhs tree.  */
    if (TREE_CODE (exp) == GIMPLE_MODIFY_STMT
--- 7164,7173 ----
  expand_expr_real (tree exp, rtx target, enum machine_mode tmode,
  		  enum expand_modifier modifier, rtx *alt_rtl)
  {
!   rtx result, dest;
  
    result = expand_expr_real_x (exp, target, tmode, modifier, alt_rtl);
  
    /* If we expanded an assignment, lookup the target RTX from the
       lhs tree.  */
    if (TREE_CODE (exp) == GIMPLE_MODIFY_STMT
*************** expand_expr_real (tree exp, rtx target, 
*** 7142,7174 ****
    else
      dest = result;
  
!   /* Now look for the last insn if this sets the result RTX.  */
!   insn = get_last_insn ();
!   if (insn
!       && (set = single_set (insn))
!       && XEXP (set, 0) == dest)
!     {
!       /* Found the set.  What we now can do is, if dest is a pseudo,
! 	 attach a user variable to it.  This makes it more interesting
! 	 to var-tracking.
! 	 ???  What about mems and MEM_EXPR?  */
!       if (REG_P (dest)
! 	  && REG_EXPR (dest)
! 	  && DECL_ARTIFICIAL (REG_EXPR (dest)))
! 	{
! 	  int uid = bitmap_first_set_bit (vars);
! 	  tree var = ssa_varmap_get_ref (uid);
! 	  if (var)
! 	    {
! 	      REG_ATTRS (dest)->decl = var;
! 	      /* If this was the only set bit we can get
! 		 away without attaching the bitmap to the SET.  */
! 	      if (bitmap_single_bit_set_p (vars))
! 		return result;
! 	    }
! 	}
!       XBITMAP (set, 2) = vars;
!     }
  
    return result;
  }
--- 7176,7183 ----
    else
      dest = result;
  
!   /* Associate the resulting rtx with the variable information for exp.  */
!   set_expr_vars (dest, exp);
  
    return result;
  }



More information about the Gcc-patches mailing list