[patch] Fix var-tracking with dynamic stack realignment on x86
Jakub Jelinek
jakub@redhat.com
Mon May 23 18:17:00 GMT 2011
On Mon, May 23, 2011 at 11:33:42AM +0200, Eric Botcazou wrote:
> > Anyway, IMHO the desired outcome is that the
> > parameters will have DW_OP_fbreg {0,4} as their location, so perhaps the
> > DRAP register needs to be remapped somehow during adjust_insn.
>
> So you don't care about their location during the prologue?
Here is an alternative, almost completely untested, patch, which
uses DW_OP_fbreg <N> for the arguments of dynamically realigned functions.
draptest.c now works...
2011-05-23 Jakub Jelinek <jakub@redhat.com>
* var-tracking.c (vt_add_function_parameter): Remap incoming
MEMs with crtl->args.internal_arg_pointer based address
if stack_realign_drap to arg_pointer_rtx.
(vt_init_cfa_base): Add equate argument, don't equate cfa_base_rtx
to hfp/sp if it is false.
(vt_initialize): Adjust vt_init_cfa_base callers, don't call
vt_init_cfa_base if frame_pointer_needed, but fp_cfa_offset is -1,
set fp_cfa_offset to -1 if fp/argp hasn't been eliminated.
* gcc.dg/guality/draptest.c: New test.
--- gcc/var-tracking.c.jj 2011-05-23 10:48:19.000000000 +0200
+++ gcc/var-tracking.c 2011-05-23 18:30:18.000000000 +0200
@@ -8449,6 +8449,8 @@ vt_get_decl_and_offset (rtx rtl, tree *d
return false;
}
+static void vt_init_cfa_base (bool);
+
/* Insert function parameter PARM in IN and OUT sets of ENTRY_BLOCK. */
static void
@@ -8471,6 +8473,46 @@ vt_add_function_parameter (tree parm)
if (GET_MODE (decl_rtl) == BLKmode || GET_MODE (incoming) == BLKmode)
return;
+ if (MEM_P (incoming)
+ && stack_realign_drap
+ && frame_pointer_needed
+ && crtl->stack_realign_tried
+ && (XEXP (incoming, 0) == crtl->args.internal_arg_pointer
+ || (GET_CODE (XEXP (incoming, 0)) == PLUS
+ && XEXP (XEXP (incoming, 0), 0)
+ == crtl->args.internal_arg_pointer
+ && CONST_INT_P (XEXP (XEXP (incoming, 0), 1)))))
+ {
+ rtx new_addr;
+ if (cfa_base_rtx == NULL_RTX)
+ {
+ rtx reg, elim;
+
+#ifdef FRAME_POINTER_CFA_OFFSET
+ reg = frame_pointer_rtx;
+#else
+ reg = arg_pointer_rtx;
+#endif
+ elim = eliminate_regs (reg, VOIDmode, NULL_RTX);
+ if (elim != reg)
+ {
+ if (GET_CODE (elim) == PLUS)
+ elim = XEXP (elim, 0);
+ if (elim == hard_frame_pointer_rtx)
+ vt_init_cfa_base (false);
+ }
+ }
+
+ if (cfa_base_rtx)
+ {
+ HOST_WIDE_INT off = -FIRST_PARM_OFFSET (current_function_decl);
+ new_addr = plus_constant (arg_pointer_rtx,
+ (GET_CODE (XEXP (incoming, 0)) == PLUS
+ ? INTVAL (XEXP (XEXP (incoming, 0), 1))
+ : 0) + off);
+ incoming = replace_equiv_address_nv (incoming, new_addr);
+ }
+ }
if (!vt_get_decl_and_offset (incoming, &decl, &offset))
{
if (REG_P (incoming) || MEM_P (incoming))
@@ -8698,7 +8740,7 @@ note_register_arguments (rtx insn)
has been eliminated. */
static void
-vt_init_cfa_base (void)
+vt_init_cfa_base (bool equate)
{
cselib_val *val;
@@ -8720,9 +8762,10 @@ vt_init_cfa_base (void)
/* Tell alias analysis that cfa_base_rtx should share
find_base_term value with stack pointer or hard frame pointer. */
- vt_equate_reg_base_value (cfa_base_rtx,
- frame_pointer_needed
- ? hard_frame_pointer_rtx : stack_pointer_rtx);
+ if (equate)
+ vt_equate_reg_base_value (cfa_base_rtx,
+ frame_pointer_needed
+ ? hard_frame_pointer_rtx : stack_pointer_rtx);
val = cselib_lookup_from_insn (cfa_base_rtx, GET_MODE (cfa_base_rtx), 1,
VOIDmode, get_insns ());
preserve_value (val);
@@ -8814,7 +8857,7 @@ vt_initialize (void)
if (GET_CODE (elim) == PLUS)
elim = XEXP (elim, 0);
if (elim == stack_pointer_rtx)
- vt_init_cfa_base ();
+ vt_init_cfa_base (true);
}
}
else if (!crtl->stack_realign_tried)
@@ -8841,6 +8884,8 @@ vt_initialize (void)
else
prologue_bb = single_succ (ENTRY_BLOCK_PTR);
}
+ else
+ fp_cfa_offset = -1;
}
if (frame_pointer_needed)
{
@@ -8944,9 +8989,10 @@ vt_initialize (void)
if (bb == prologue_bb
&& hard_frame_pointer_adjustment == -1
&& RTX_FRAME_RELATED_P (insn)
- && fp_setter (insn))
+ && fp_setter (insn)
+ && fp_cfa_offset != -1)
{
- vt_init_cfa_base ();
+ vt_init_cfa_base (true);
hard_frame_pointer_adjustment = fp_cfa_offset;
}
}
--- gcc/testsuite/gcc.dg/guality/draptest.c.jj 2011-05-23 18:32:16.000000000 +0200
+++ gcc/testsuite/gcc.dg/guality/draptest.c 2011-05-23 14:55:25.000000000 +0200
@@ -0,0 +1,27 @@
+/* { dg-do run { target { i?86-*-* x86_64-*-* } } } */
+/* { dg-options "-g -mforce-drap" } */
+
+volatile int v;
+
+__attribute__((noinline, noclone)) int
+bar (int a, int b)
+{
+ int t = 0;
+ asm volatile ("" : "+c" (t));
+ return 0;
+}
+
+__attribute__((noinline, noclone)) int
+foo (int a, int b)
+{
+ __attribute__((aligned (32))) int c = bar (a, b);
+ v++; /* { dg-final { gdb-test 18 "a" "5" } } */
+ return a + b + c; /* { dg-final { gdb-test 18 "b" "6" } } */
+}
+
+int
+main ()
+{
+ foo (5, 6);
+ return 0;
+}
Jakub
More information about the Gcc-patches
mailing list