This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Incorrect code for __builtin_frame_address(0)


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})

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]