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 <ja...@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