@@ -54,6 +54,14 @@ typedef HARD_REG_ELT_TYPE HARD_REG_SET[H
#endif
+/* HARD_REG_SET wrapped into a structure, to make it possible to
+ use HARD_REG_SET even in APIs that should not include
+ hard-reg-set.h. */
+struct hard_reg_set_container
+{
+ HARD_REG_SET set;
+};
+
/* HARD_CONST is used to cast a constant to the appropriate type
for use with a HARD_REG_SET. */
@@ -92,6 +92,7 @@ extern bool target_default_pointer_addre
struct stdarg_info;
struct spec_info_def;
+struct hard_reg_set_container;
/* The struct used by the secondary_reload target hook. */
typedef struct secondary_reload_info
@@ -2644,6 +2644,14 @@ DEFHOOK
void, (bitmap regs),
hook_void_bitmap)
+/* Fill in additional registers set up by prologue into a regset. */
+DEFHOOK
+(set_up_by_prologue,
+ "This hook should add additional registers that are computed by the prologue\
+ to the hard regset for shrink-wrapping optimization purposes.",
+ void, (struct hard_reg_set_container *),
+ NULL)
+
/* Determine the type of unwind info to emit for debugging. */
DEFHOOK
(debug_unwind_info,
@@ -4959,6 +4959,10 @@ TARGET_STRUCT_VALUE_RTX, FRAME_POINTER_R
FRAME_POINTER_REGNUM, ARG_POINTER_REGNUM, and the PIC_OFFSET_TABLE_REGNUM.
@end deftypefn
+@deftypefn {Target Hook} void TARGET_SET_UP_BY_PROLOGUE (struct hard_reg_set_container *@var{})
+This hook should add additional registers that are computed by the prologue to the hard regset for shrink-wrapping optimization purposes.
+@end deftypefn
+
@node Stack Smashing Protection
@subsection Stack smashing protection
@cindex stack smashing protection
@@ -4906,6 +4906,8 @@ TARGET_STRUCT_VALUE_RTX, FRAME_POINTER_R
FRAME_POINTER_REGNUM, ARG_POINTER_REGNUM, and the PIC_OFFSET_TABLE_REGNUM.
@end deftypefn
+@hook TARGET_SET_UP_BY_PROLOGUE
+
@node Stack Smashing Protection
@subsection Stack smashing protection
@cindex stack smashing protection
@@ -5899,7 +5899,7 @@ thread_prologue_and_epilogue_insns (void
&& nonempty_prologue && !crtl->calls_eh_return)
{
HARD_REG_SET prologue_clobbered, prologue_used, live_on_edge;
- HARD_REG_SET set_up_by_prologue;
+ struct hard_reg_set_container set_up_by_prologue;
rtx p_insn;
VEC(basic_block, heap) *vec;
basic_block bb;
@@ -5939,18 +5939,22 @@ thread_prologue_and_epilogue_insns (void
vec = VEC_alloc (basic_block, heap, n_basic_blocks);
- CLEAR_HARD_REG_SET (set_up_by_prologue);
- add_to_hard_reg_set (&set_up_by_prologue, Pmode, STACK_POINTER_REGNUM);
- add_to_hard_reg_set (&set_up_by_prologue, Pmode, ARG_POINTER_REGNUM);
+ CLEAR_HARD_REG_SET (set_up_by_prologue.set);
+ add_to_hard_reg_set (&set_up_by_prologue.set, Pmode,
+ STACK_POINTER_REGNUM);
+ add_to_hard_reg_set (&set_up_by_prologue.set, Pmode, ARG_POINTER_REGNUM);
if (frame_pointer_needed)
- add_to_hard_reg_set (&set_up_by_prologue, Pmode,
+ add_to_hard_reg_set (&set_up_by_prologue.set, Pmode,
HARD_FRAME_POINTER_REGNUM);
if (pic_offset_table_rtx)
- add_to_hard_reg_set (&set_up_by_prologue, Pmode,
+ add_to_hard_reg_set (&set_up_by_prologue.set, Pmode,
PIC_OFFSET_TABLE_REGNUM);
if (stack_realign_drap && crtl->drap_reg)
- add_to_hard_reg_set (&set_up_by_prologue, GET_MODE (crtl->drap_reg),
+ add_to_hard_reg_set (&set_up_by_prologue.set,
+ GET_MODE (crtl->drap_reg),
REGNO (crtl->drap_reg));
+ if (targetm.set_up_by_prologue)
+ targetm.set_up_by_prologue (&set_up_by_prologue);
/* We don't use a different max size depending on
optimize_bb_for_speed_p because increasing shrink-wrapping
@@ -5968,7 +5972,7 @@ thread_prologue_and_epilogue_insns (void
if (NONDEBUG_INSN_P (insn))
{
if (requires_stack_frame_p (insn, prologue_used,
- set_up_by_prologue))
+ set_up_by_prologue.set))
{
if (bb == entry_edge->dest)
goto fail_shrinkwrap;
@@ -1227,6 +1227,7 @@ static bool rs6000_cannot_force_const_me
static bool rs6000_legitimate_constant_p (enum machine_mode, rtx);
static bool rs6000_save_toc_in_prologue_p (void);
static void rs6000_code_end (void) ATTRIBUTE_UNUSED;
+static void rs6000_set_up_by_prologue (struct hard_reg_set_container *);
/* Hash table stuff for keeping track of TOC entries. */
@@ -1392,6 +1393,9 @@ static const struct attribute_spec rs600
#define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
#endif
+#undef TARGET_SET_UP_BY_PROLOGUE
+#define TARGET_SET_UP_BY_PROLOGUE rs6000_set_up_by_prologue
+
#undef TARGET_HAVE_TLS
#define TARGET_HAVE_TLS HAVE_AS_TLS
@@ -27903,6 +27907,19 @@ rs6000_code_end (void)
current_function_decl = NULL;
}
+/* Add r30 to hard reg set if the prologue sets it up and it is not
+ pic_offset_table_rtx. */
+
+static void
+rs6000_set_up_by_prologue (struct hard_reg_set_container *set)
+{
+ if (!TARGET_SINGLE_PIC_BASE
+ && TARGET_TOC
+ && TARGET_MINIMAL_TOC
+ && get_pool_size () != 0)
+ add_to_hard_reg_set (&set->set, Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
+}
+
struct gcc_target targetm = TARGET_INITIALIZER;
#include "gt-rs6000.h"