This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Incorrect code for __builtin_frame_address(0)
- From: James E Wilson <wilson at specifix dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 19 Aug 2005 14:21:53 -0700
- Subject: Re: [PATCH] Incorrect code for __builtin_frame_address(0)
- References: <Pine.LNX.4.61L.0506031315440.15600@blysk.ds.pg.gda.pl> <43040263.1030500@specifix.com>
James E Wilson wrote:
> I've attached patches for solutions 5 and 6. Unless someone recommends
> otherwise, I expect that I will go with solution 6. I haven't tested
> this patches yet, except on trivial testcases.
At this point, I've come to the conclusion that defining
INITIAL_FRAME_ADDRESS_RTX for every target really is the right solution
here. Also, it isn't safe to assume that frame_pointer_rtx is the right
value. It likely isn't. So we really need to do this one target at a
time. When enough targets have this defined, we can define the default
value to something useful like gcc_unreachable() to encourage people to
fix the rest.
But since I'm not going to do that work, we meanwhile need a workaround,
which is my solution 6 explained previously. I've added a comment, and
changed a variable name like Richard Henderson asked, and checked it in.
I tested this with a bootstrap and make check on an x86-linux box.
I've attached the patch I checked in for the record.
--
Jim Wilson, GNU Tools Support, http://www.specifix.com
2005-08-17 James E Wilson <wilson@specifix.com>
* builtins.c (expand_builtin_return_addr): Set
current_function_accesses_prior_frames when count != 0. Use
frame_pointer_rtx when count == 0.
* function.h (struct function): Add accesses_prior_frames field.
(current_function_accesses_prior_frames): Define.
* reload1.c (init_elim_table): Check
current_function_accesses_prior_frames.
* doc/tm.texi (INITIAL_FRAME_ADDRESS_RTX): Update docs.
Index: builtins.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/builtins.c,v
retrieving revision 1.470
diff -p -p -r1.470 builtins.c
*** builtins.c 16 Aug 2005 12:14:08 -0000 1.470
--- builtins.c 19 Aug 2005 01:51:26 -0000
*************** expand_builtin_return_addr (enum built_i
*** 485,491 ****
#ifdef INITIAL_FRAME_ADDRESS_RTX
rtx tem = INITIAL_FRAME_ADDRESS_RTX;
#else
! rtx tem = hard_frame_pointer_rtx;
#endif
/* Some machines need special handling before we can access
--- 485,506 ----
#ifdef INITIAL_FRAME_ADDRESS_RTX
rtx tem = INITIAL_FRAME_ADDRESS_RTX;
#else
! rtx tem;
!
! /* For a zero count, we don't care what frame address we return, so frame
! pointer elimination is OK, and using the soft frame pointer is OK.
! For a non-zero count, we require a stable offset from the current frame
! pointer to the previous one, so we must use the hard frame pointer, and
! we must disable frame pointer elimination. */
! if (count == 0)
! tem = frame_pointer_rtx;
! else
! {
! tem = hard_frame_pointer_rtx;
!
! /* Tell reload not to eliminate the frame pointer. */
! current_function_accesses_prior_frames = 1;
! }
#endif
/* Some machines need special handling before we can access
Index: function.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/function.h,v
retrieving revision 1.156
diff -p -p -r1.156 function.h
*** function.h 30 Jun 2005 00:47:48 -0000 1.156
--- function.h 19 Aug 2005 01:51:26 -0000
*************** struct function GTY(())
*** 394,399 ****
--- 394,403 ----
either as a subroutine or builtin. */
unsigned int calls_alloca : 1;
+ /* Nonzero if function being compiled called builtin_return_addr or
+ builtin_frame_address with non-zero count. */
+ unsigned int accesses_prior_frames : 1;
+
/* Nonzero if the function calls __builtin_eh_return. */
unsigned int calls_eh_return : 1;
*************** extern int trampolines_created;
*** 483,488 ****
--- 487,493 ----
#define current_function_returns_pointer (cfun->returns_pointer)
#define current_function_calls_setjmp (cfun->calls_setjmp)
#define current_function_calls_alloca (cfun->calls_alloca)
+ #define current_function_accesses_prior_frames (cfun->accesses_prior_frames)
#define current_function_calls_eh_return (cfun->calls_eh_return)
#define current_function_is_thunk (cfun->is_thunk)
#define current_function_args_info (cfun->args_info)
Index: reload1.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/reload1.c,v
retrieving revision 1.478
diff -p -p -r1.478 reload1.c
*** reload1.c 1 Aug 2005 03:54:47 -0000 1.478
--- reload1.c 19 Aug 2005 01:51:27 -0000
*************** init_elim_table (void)
*** 3492,3497 ****
--- 3492,3498 ----
sp-adjusting insns for this case. */
|| (current_function_calls_alloca
&& EXIT_IGNORE_STACK)
+ || current_function_accesses_prior_frames
|| FRAME_POINTER_REQUIRED);
num_eliminable = 0;
Index: doc/tm.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/tm.texi,v
retrieving revision 1.445
diff -p -p -r1.445 tm.texi
*** doc/tm.texi 16 Aug 2005 22:29:09 -0000 1.445
--- doc/tm.texi 19 Aug 2005 01:51:28 -0000
*************** machines. See @file{function.c} for det
*** 2812,2825 ****
@defmac INITIAL_FRAME_ADDRESS_RTX
A C expression whose value is RTL representing the address of the initial
! stack frame. This address is passed to @code{RETURN_ADDR_RTX} and
! @code{DYNAMIC_CHAIN_ADDRESS}.
! If you don't define this macro, the default is to return
! @code{hard_frame_pointer_rtx}.
! This default is usually correct unless @code{-fomit-frame-pointer} is in
! effect.
! Define this macro in order to make @code{__builtin_frame_address (0)} and
! @code{__builtin_return_address (0)} work even in absence of a hard frame pointer.
@end defmac
@defmac DYNAMIC_CHAIN_ADDRESS (@var{frameaddr})
--- 2812,2822 ----
@defmac INITIAL_FRAME_ADDRESS_RTX
A C expression whose value is RTL representing the address of the initial
! stack frame. This address is passed to @code{RETURN_ADDR_RTX} and
! @code{DYNAMIC_CHAIN_ADDRESS}. If you don't define this macro, a reasonable
! default value will be used. Define this macro in order to make frame pointer
! elimination work in the presence of @code{__builtin_frame_address (count)} and
! @code{__builtin_return_address (count)} for @code{count} not equal to zero.
@end defmac
@defmac DYNAMIC_CHAIN_ADDRESS (@var{frameaddr})