This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH 4/7]: Ping3: Merge from Stack Branch - i386 backend changes
On Thu, May 29, 2008 at 11:16:23PM +0800, Joey Ye wrote:
> Jan, attahced patch addresses your comments about drap loading. Previous
> comments about find_drap_reg is still TODO.
>
Hi,
This is what I checked in stack branch. As Joeys said, we will
look into find_drap_reg later.
Thanks.
H.J.
---
Index: doc/tm.texi
===================================================================
--- doc/tm.texi (revision 136204)
+++ doc/tm.texi (working copy)
@@ -10504,6 +10504,11 @@ call stack unwinding. It is used in dec
and the associated definitions of those functions.
@end defmac
+@deftypefn {Target Hook} rtx TARGET_GET_DRAP_RTX (void)
+Define this macro to handle stack alignment and return an rtx for
+Dynamic Realign Argument Pointer if necessary.
+@end deftypefn
+
@deftypefn {Target Hook} {bool} TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS (void)
When optimization is disabled, this hook indicates whether or not
arguments should be allocated to stack slots. Normally, GCC allocates
Index: target.h
===================================================================
--- target.h (revision 136204)
+++ target.h (working copy)
@@ -831,6 +831,10 @@ struct gcc_target
current function. */
rtx (*internal_arg_pointer) (void);
+ /* Handle stack alignment and return an rtx for Dynamic Realign
+ Argument Pointer if necessary. */
+ rtx (*get_drap_rtx) (void);
+
/* Return true if all function parameters should be spilled to the
stack. */
bool (*allocate_stack_slots_for_args) (void);
Index: ChangeLog.stackalign
===================================================================
--- ChangeLog.stackalign (revision 136204)
+++ ChangeLog.stackalign (working copy)
@@ -1,3 +1,26 @@
+2008-05-30 Joey Ye <joey.ye@intel.com>
+ H.J. Lu <hongjiu.lu@intel.com>
+
+ * cfgexpand.c (handle_drap): Renamed to ...
+ (expand_stack_alignment): This. Call targetm.calls.get_drap_rtx
+ instead of targetm.calls.internal_arg_pointer for virtual
+ DRAP.
+ (tree_expand_cfg): Updated.
+
+ * target.h (gcc_target): Add get_drap_rtx.
+
+ * target-def.h (TARGET_GET_DRAP_RTX): New.
+ (TARGET_CALLS): Add TARGET_GET_DRAP_RTX.
+
+ * config/i386/i386.c (find_drap_reg): Add a FIXME to use an
+ unused call-clobbered register.
+ (ix86_internal_arg_pointer): Move stack alignment and virtual
+ drap processing to ...
+ (ix86_handle_drap): This. New.
+ (TARGET_GET_DRAP_RTX): New.
+
+ * doc/tm.texi (TARGET_GET_DRAP_RTX): New.
+
2008-05-29 H.J. Lu <hongjiu.lu@intel.com>
* reload1.c (mark_not_eliminable): Call clear_can_eliminate
Index: cfgexpand.c
===================================================================
--- cfgexpand.c (revision 136204)
+++ cfgexpand.c (working copy)
@@ -1870,9 +1870,9 @@ discover_nonconstant_array_refs (void)
virtual_incoming_args_rtx with the virtual register. */
static void
-handle_drap (void)
+expand_stack_alignment (void)
{
- rtx internal_arg_rtx;
+ rtx drap_rtx;
if (! SUPPORTS_STACK_ALIGNMENT)
return;
@@ -1883,19 +1883,14 @@ handle_drap (void)
|| crtl->calls_eh_return)
crtl->need_drap = true;
- /* Call targetm.calls.internal_arg_pointer again. This time it will
- return a virtual register if DRAP is needed. */
- internal_arg_rtx = targetm.calls.internal_arg_pointer ();
-
- /* Assertion to check internal_arg_pointer is set to the right rtx
- here. */
- gcc_assert (crtl->args.internal_arg_pointer
- == virtual_incoming_args_rtx);
+ /* Call targetm.calls.get_drap_rtx. */
+ gcc_assert (targetm.calls.get_drap_rtx != NULL);
+ drap_rtx = targetm.calls.get_drap_rtx ();
- /* Do nothing if no need to replace virtual_incoming_args_rtx. */
- if (crtl->args.internal_arg_pointer != internal_arg_rtx)
+ /* Do nothing if NULL is returned, which means DRAP is not needed. */
+ if (NULL != drap_rtx)
{
- crtl->args.internal_arg_pointer = internal_arg_rtx;
+ crtl->args.internal_arg_pointer = drap_rtx;
/* Call fixup_tail_casss to clean up REG_EQUIV note if DRAP is
needed. */
@@ -2013,7 +2008,7 @@ tree_expand_cfg (void)
compact_blocks ();
- handle_drap ();
+ expand_stack_alignment ();
#ifdef ENABLE_CHECKING
verify_flow_info ();
Index: target-def.h
===================================================================
--- target-def.h (revision 136204)
+++ target-def.h (working copy)
@@ -568,6 +568,7 @@
#define TARGET_FUNCTION_VALUE default_function_value
#define TARGET_INTERNAL_ARG_POINTER default_internal_arg_pointer
+#define TARGET_GET_DRAP_RTX NULL
#define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS hook_bool_void_true
#define TARGET_CALLS { \
@@ -589,6 +590,7 @@
TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN, \
TARGET_FUNCTION_VALUE, \
TARGET_INTERNAL_ARG_POINTER, \
+ TARGET_GET_DRAP_RTX, \
TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS \
}
Index: config/i386/i386.c
===================================================================
--- config/i386/i386.c (revision 136204)
+++ config/i386/i386.c (working copy)
@@ -6393,7 +6393,10 @@ pro_epilogue_adjust_stack (rtx dest, rtx
we just pick DI.
For x86_64, we just pick R13 directly.
- Return: the regno of choosed register. */
+ Return: the regno of choosed register.
+
+ FIXME: Can we use an unused call-clobbered register, similar to
+ ix86_select_alt_pic_regnum? */
static unsigned int
find_drap_reg (void)
@@ -6422,18 +6425,19 @@ find_drap_reg (void)
return DI_REG;
}
-/* Handle the TARGET_INTERNAL_ARG_POINTER hook. */
+/* Handle DRAP related code. Decide
+ 1. if stack alignment is needed based on stack alignment
+ estimation before reload.
+ 2. if DRAP is needed based on options and other conditions.
+
+ Return: NULL if no DRAP is needed.
+ An rtx for DRAP otherwise. */
static rtx
-ix86_internal_arg_pointer (void)
+ix86_handle_drap (void)
{
unsigned int preferred_stack_boundary;
- /* If called in "expand" pass, currently_expanding_to_rtl will
- be true */
- if (currently_expanding_to_rtl)
- return virtual_incoming_args_rtx;
-
/* Prefer the one specified at command line. */
ix86_incoming_stack_boundary
= (ix86_user_incoming_stack_boundary
@@ -6503,7 +6507,7 @@ ix86_internal_arg_pointer (void)
crtl->drap_reg = arg_ptr;
start_sequence ();
- drap_vreg = copy_to_reg(arg_ptr);
+ drap_vreg = copy_to_reg (arg_ptr);
seq = get_insns ();
end_sequence ();
@@ -6511,6 +6515,14 @@ ix86_internal_arg_pointer (void)
return drap_vreg;
}
else
+ return NULL;
+}
+
+/* Handle the TARGET_INTERNAL_ARG_POINTER hook. */
+
+static rtx
+ix86_internal_arg_pointer (void)
+{
return virtual_incoming_args_rtx;
}
@@ -26182,6 +26194,8 @@ x86_builtin_vectorization_cost (bool run
#define TARGET_PASS_BY_REFERENCE ix86_pass_by_reference
#undef TARGET_INTERNAL_ARG_POINTER
#define TARGET_INTERNAL_ARG_POINTER ix86_internal_arg_pointer
+#undef TARGET_GET_DRAP_RTX
+#define TARGET_GET_DRAP_RTX ix86_handle_drap
#undef TARGET_DWARF_HANDLE_FRAME_UNSPEC
#define TARGET_DWARF_HANDLE_FRAME_UNSPEC ix86_dwarf_handle_frame_unspec
#undef TARGET_STRICT_ARGUMENT_NAMING