diff options
author | Jakub Jelinek <jakub@redhat.com> | 2011-05-30 15:16:40 +0000 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2011-05-30 15:16:40 +0000 |
commit | 80060f7ac20e7d906a5b6f5c2781b5680beee64f (patch) | |
tree | 86aad644f1485615e297b0a91bae29b8499bf166 /gcc | |
parent | 17e99cdb2d3048641353093c53dd04e3e3f7e8aa (diff) | |
download | gcc-80060f7ac20e7d906a5b6f5c2781b5680beee64f.zip gcc-80060f7ac20e7d906a5b6f5c2781b5680beee64f.tar.gz gcc-80060f7ac20e7d906a5b6f5c2781b5680beee64f.tar.bz2 |
var-tracking.c (vt_add_function_parameter): Remap incoming MEMs with crtl->args.internal_arg_pointer based address to...
* var-tracking.c (vt_add_function_parameter): Remap incoming MEMs with
crtl->args.internal_arg_pointer based address to arg_pointer_rtx if
there is a DRAP register and arg_pointer_rtx is the CFA pointer.
(vt_init_cfa_base): Don't equate cfa_base_rtx if stack was realigned.
(vt_initialize): Initialize cfa_base_rtx if there is a DRAP register.
From-SVN: r174438
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/guality/drap.c | 30 | ||||
-rw-r--r-- | gcc/var-tracking.c | 57 |
4 files changed, 100 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4a800f0..12a6468 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2011-05-30 Jakub Jelinek <jakub@redhat.com> + Eric Botcazou <ebotcazou@adacore.com> + + * var-tracking.c (vt_add_function_parameter): Remap incoming MEMs with + crtl->args.internal_arg_pointer based address to arg_pointer_rtx if + there is a DRAP register and arg_pointer_rtx is the CFA pointer. + (vt_init_cfa_base): Don't equate cfa_base_rtx if stack was realigned. + (vt_initialize): Initialize cfa_base_rtx if there is a DRAP register. + 2011-05-30 Richard Guenther <rguenther@suse.de> * gimple.c (gimple_types_compatible_p_1): Compare record diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d7df19b..e80c1b2 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,9 +1,13 @@ +2011-05-30 Jakub Jelinek <jakub@redhat.com> + Eric Botcazou <ebotcazou@adacore.com> + + * gcc.dg/guality/drap.c: New test. + 2011-05-30 Richard Guenther <rguenther@suse.de> PR tree-optimization/49210 - * gnat.dg/boolean_subtype2.adb: New testcase. - * gnat.dg/boolean_subtype2.ads: Likewise. - * gnat.dg/boolean_subtype2_pkg.ads: Likewise. + * gnat.dg/boolean_subtype2.ad[sb]: New testcase. + * gnat.dg/boolean_subtype2_pkg.ads: New helper. 2011-05-30 Jakub Jelinek <jakub@redhat.com> diff --git a/gcc/testsuite/gcc.dg/guality/drap.c b/gcc/testsuite/gcc.dg/guality/drap.c new file mode 100644 index 0000000..573bb39 --- /dev/null +++ b/gcc/testsuite/gcc.dg/guality/drap.c @@ -0,0 +1,30 @@ +/* { 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) +{ +#ifdef __x86_64__ + asm volatile ("movq %%rsp, %%r10" : : : "r10"); +#else + asm volatile ("movl %%esp, %%ecx" : : : "ecx"); +#endif + return 0; +} + +__attribute__((noinline, noclone)) int +foo (int v0, int v1, int v2, int v3, int v4, int v5, int a, int b) +{ + __attribute__((aligned (32))) int c = bar (a, b); + v++; /* { dg-final { gdb-test 21 "a" "5" } } */ + return a + b + c; /* { dg-final { gdb-test 22 "b" "6" } } */ +} + +int +main (void) +{ + foo (0, 0, 0, 0, 0, 0, 5, 6); + return 0; +} diff --git a/gcc/var-tracking.c b/gcc/var-tracking.c index 5e7c2fc..2c16d08 100644 --- a/gcc/var-tracking.c +++ b/gcc/var-tracking.c @@ -8398,6 +8398,28 @@ vt_add_function_parameter (tree parm) if (GET_MODE (decl_rtl) == BLKmode || GET_MODE (incoming) == BLKmode) return; + /* If there is a DRAP register, rewrite the incoming location of parameters + passed on the stack into MEMs based on the argument pointer, as the DRAP + register can be reused for other purposes and we do not track locations + based on generic registers. But the prerequisite is that this argument + pointer be also the virtual CFA pointer, see vt_initialize. */ + if (MEM_P (incoming) + && stack_realign_drap + && arg_pointer_rtx == cfa_base_rtx + && (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))))) + { + HOST_WIDE_INT off = -FIRST_PARM_OFFSET (current_function_decl); + if (GET_CODE (XEXP (incoming, 0)) == PLUS) + off += INTVAL (XEXP (XEXP (incoming, 0), 1)); + incoming + = replace_equiv_address_nv (incoming, + plus_constant (arg_pointer_rtx, off)); + } + if (!vt_get_decl_and_offset (incoming, &decl, &offset)) { if (REG_P (incoming) || MEM_P (incoming)) @@ -8647,9 +8669,11 @@ 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 (!frame_pointer_needed) + vt_equate_reg_base_value (cfa_base_rtx, stack_pointer_rtx); + else if (!crtl->stack_realign_tried) + vt_equate_reg_base_value (cfa_base_rtx, hard_frame_pointer_rtx); + val = cselib_lookup_from_insn (cfa_base_rtx, GET_MODE (cfa_base_rtx), 1, VOIDmode, get_insns ()); preserve_value (val); @@ -8780,6 +8804,33 @@ vt_initialize (void) fp_cfa_offset = -1; } + /* If the stack is realigned and a DRAP register is used, we're going to + rewrite MEMs based on it representing incoming locations of parameters + passed on the stack into MEMs based on the argument pointer. Although + we aren't going to rewrite other MEMs, we still need to initialize the + virtual CFA pointer in order to ensure that the argument pointer will + be seen as a constant throughout the function. + + ??? This doesn't work if FRAME_POINTER_CFA_OFFSET is defined. */ + else if (stack_realign_drap) + { + 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 (); + } + } + if (frame_pointer_needed) { rtx insn; |