[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