summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkkojima <kkojima@138bc75d-0d04-0410-961f-82ee72b054a4>2005-06-29 01:24:27 +0000
committerkkojima <kkojima@138bc75d-0d04-0410-961f-82ee72b054a4>2005-06-29 01:24:27 +0000
commitedf54f2a2e8d02cf6b2a56d863e971bb480d60bc (patch)
tree6e5206234e2011fe87ca88acfe08dfbe38d900ca
parent2a165e7bfb330347cf62a01108dcd0b656dd9975 (diff)
downloadgcc-edf54f2a2e8d02cf6b2a56d863e971bb480d60bc.tar.gz
* target.h (gcc_target): New field allocate_initial_value.
* target-def.h (TARGET_ALLOCATE_INITIAL_VALUE): New macro. (TARGET_INITIALIZER): Include it. * integrate.c (allocate_initial_values): Use targetm.allocate_initial_value. * system.h: Poison ALLOCATE_INITIAL_VALUE. * config/sh/sh-protos.h (sh_pr_n_sets): Delete. * config/sh/sh.c (sh_pr_n_sets): Make it static. (sh_allocate_initila_value): New function. (TARGET_ALLOCATE_INITIAL_VALUE): Override default. * config/sh/sh.h (ALLOCATE_INITIAL_VALUE): Delete. * doc/tm.texi (TARGET_ALLOCATE_INITIAL_VALUE): Rename and update from ALLOCATE_INITIAL_VALUE. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@101411 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog16
-rw-r--r--gcc/config/sh/sh-protos.h1
-rw-r--r--gcc/config/sh/sh.c33
-rw-r--r--gcc/config/sh/sh.h12
-rw-r--r--gcc/doc/tm.texi16
-rw-r--r--gcc/integrate.c67
-rw-r--r--gcc/system.h3
-rw-r--r--gcc/target-def.h2
-rw-r--r--gcc/target.h4
9 files changed, 99 insertions, 55 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index aaf27cfc07b..7c733de66ff 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,19 @@
+2005-06-29 Kaz Kojima <kkojima@gcc.gnu.org>
+
+ * target.h (gcc_target): New field allocate_initial_value.
+ * target-def.h (TARGET_ALLOCATE_INITIAL_VALUE): New macro.
+ (TARGET_INITIALIZER): Include it.
+ * integrate.c (allocate_initial_values): Use
+ targetm.allocate_initial_value.
+ * system.h: Poison ALLOCATE_INITIAL_VALUE.
+ * config/sh/sh-protos.h (sh_pr_n_sets): Delete.
+ * config/sh/sh.c (sh_pr_n_sets): Make it static.
+ (sh_allocate_initila_value): New function.
+ (TARGET_ALLOCATE_INITIAL_VALUE): Override default.
+ * config/sh/sh.h (ALLOCATE_INITIAL_VALUE): Delete.
+ * doc/tm.texi (TARGET_ALLOCATE_INITIAL_VALUE): Rename and
+ update from ALLOCATE_INITIAL_VALUE.
+
2005-06-28 Richard Henderson <rth@redhat.com>
* tree-vectorizer.c (vect_is_simple_reduction): Compare types
diff --git a/gcc/config/sh/sh-protos.h b/gcc/config/sh/sh-protos.h
index abfd2c4ddb1..564c1bee2cf 100644
--- a/gcc/config/sh/sh-protos.h
+++ b/gcc/config/sh/sh-protos.h
@@ -132,7 +132,6 @@ extern int sh_need_epilogue (void);
extern void sh_set_return_address (rtx, rtx);
extern int initial_elimination_offset (int, int);
extern int fldi_ok (void);
-extern int sh_pr_n_sets (void);
extern int sh_hard_regno_rename_ok (unsigned int, unsigned int);
extern int sh_cfun_interrupt_handler_p (void);
extern int sh_attr_renesas_p (tree);
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index 9500364cc45..300c104d3b8 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -271,6 +271,8 @@ static int sh_address_cost (rtx);
#ifdef TARGET_ADJUST_UNROLL_MAX
static int sh_adjust_unroll_max (struct loop *, int, int, int, int);
#endif
+static int sh_pr_n_sets (void);
+static rtx sh_allocate_initial_value (rtx);
static int shmedia_target_regs_stack_space (HARD_REG_SET *);
static int shmedia_reserve_space_for_target_registers_p (int, HARD_REG_SET *);
static int shmedia_target_regs_stack_adjust (HARD_REG_SET *);
@@ -422,6 +424,8 @@ static int hard_regs_intersect_p (HARD_REG_SET *, HARD_REG_SET *);
#define TARGET_RTX_COSTS sh_rtx_costs
#undef TARGET_ADDRESS_COST
#define TARGET_ADDRESS_COST sh_address_cost
+#undef TARGET_ALLOCATE_INITIAL_VALUE
+#define TARGET_ALLOCATE_INITIAL_VALUE sh_allocate_initial_value
#undef TARGET_MACHINE_DEPENDENT_REORG
#define TARGET_MACHINE_DEPENDENT_REORG sh_reorg
@@ -8348,16 +8352,41 @@ flow_dependent_p_1 (rtx x, rtx pat ATTRIBUTE_UNUSED, void *data)
*pinsn = NULL_RTX;
}
-/* For use by ALLOCATE_INITIAL_VALUE. Note that sh.md contains some
+/* For use by sh_allocate_initial_value. Note that sh.md contains some
'special function' patterns (type sfunc) that clobber pr, but that
do not look like function calls to leaf_function_p. Hence we must
do this extra check. */
-int
+static int
sh_pr_n_sets (void)
{
return REG_N_SETS (TARGET_SHMEDIA ? PR_MEDIA_REG : PR_REG);
}
+/* Return where to allocate pseudo for a given hard register initial
+ value. */
+static rtx
+sh_allocate_initial_value (rtx hard_reg)
+{
+ rtx x;
+
+ if (REGNO (hard_reg) == (TARGET_SHMEDIA ? PR_MEDIA_REG : PR_REG))
+ {
+ if (current_function_is_leaf
+ && ! sh_pr_n_sets ()
+ && ! (TARGET_SHCOMPACT
+ && ((current_function_args_info.call_cookie
+ & ~ CALL_COOKIE_RET_TRAMP (1))
+ || current_function_has_nonlocal_label)))
+ x = hard_reg;
+ else
+ x = gen_rtx_MEM (Pmode, return_address_pointer_rtx);
+ }
+ else
+ x = NULL_RTX;
+
+ return x;
+}
+
/* This function returns "2" to indicate dual issue for the SH4
processor. To be used by the DFA pipeline description. */
static int
diff --git a/gcc/config/sh/sh.h b/gcc/config/sh/sh.h
index fafa09e2631..c803d554d0a 100644
--- a/gcc/config/sh/sh.h
+++ b/gcc/config/sh/sh.h
@@ -3360,18 +3360,6 @@ extern struct rtx_def *sp_switch;
2:\n" TEXT_SECTION_ASM_OP);
#endif /* (defined CRT_BEGIN || defined CRT_END) && ! __SHMEDIA__ */
-#define ALLOCATE_INITIAL_VALUE(hard_reg) \
- (REGNO (hard_reg) == (TARGET_SHMEDIA ? PR_MEDIA_REG : PR_REG) \
- ? (current_function_is_leaf \
- && ! sh_pr_n_sets () \
- && ! (TARGET_SHCOMPACT \
- && ((current_function_args_info.call_cookie \
- & ~ CALL_COOKIE_RET_TRAMP (1)) \
- || current_function_has_nonlocal_label)) \
- ? (hard_reg) \
- : gen_rtx_MEM (Pmode, return_address_pointer_rtx)) \
- : NULL_RTX)
-
#define SIMULTANEOUS_PREFETCHES 2
/* FIXME: middle-end support for highpart optimizations is missing. */
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index dca9ad63459..2c51ef2fe37 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -9445,14 +9445,14 @@ filling of delay slots can result in branches being redirected, and this
may in turn cause a branch offset to overflow.
@end defmac
-@defmac ALLOCATE_INITIAL_VALUE (@var{hard_reg})
+@deftypefn {Target Hook} rtx TARGET_ALLOCATE_INITIAL_VALUE (rtx @var{hard_reg})
When the initial value of a hard register has been copied in a pseudo
register, it is often not necessary to actually allocate another register
to this pseudo register, because the original hard register or a stack slot
-it has been saved into can be used. @code{ALLOCATE_INITIAL_VALUE}, if
-defined, is called at the start of register allocation once for each
-hard register that had its initial value copied by using
+it has been saved into can be used. @code{TARGET_ALLOCATE_INITIAL_VALUE}
+is called at the start of register allocation once for each hard register
+that had its initial value copied by using
@code{get_func_hard_reg_initial_val} or @code{get_hard_reg_initial_val}.
Possible values are @code{NULL_RTX}, if you don't want
to do any special allocation, a @code{REG} rtx---that would typically be
@@ -9460,10 +9460,12 @@ the hard register itself, if it is known not to be clobbered---or a
@code{MEM}.
If you are returning a @code{MEM}, this is only a hint for the allocator;
it might decide to use another register anyways.
-You may use @code{current_function_leaf_function} in the definition of the
-macro, functions that use @code{REG_N_SETS}, to determine if the hard
+You may use @code{current_function_leaf_function} in the hook, functions
+that use @code{REG_N_SETS}, to determine if the hard
register in question will not be clobbered.
-@end defmac
+The default value of this hook is @code{NULL}, which disables any special
+allocation.
+@end deftypefn
@defmac TARGET_OBJECT_SUFFIX
Define this macro to be a C string representing the suffix for object
diff --git a/gcc/integrate.c b/gcc/integrate.c
index bacba73c5fc..28da1157855 100644
--- a/gcc/integrate.c
+++ b/gcc/integrate.c
@@ -376,47 +376,50 @@ emit_initial_value_sets (void)
void
allocate_initial_values (rtx *reg_equiv_memory_loc ATTRIBUTE_UNUSED)
{
-#ifdef ALLOCATE_INITIAL_VALUE
- struct initial_value_struct *ivs = cfun->hard_reg_initial_vals;
- int i;
-
- if (ivs == 0)
- return;
-
- for (i = 0; i < ivs->num_entries; i++)
+ if (targetm.allocate_initial_value)
{
- int regno = REGNO (ivs->entries[i].pseudo);
- rtx x = ALLOCATE_INITIAL_VALUE (ivs->entries[i].hard_reg);
+ struct initial_value_struct *ivs = cfun->hard_reg_initial_vals;
+ int i;
- if (x && REG_N_SETS (REGNO (ivs->entries[i].pseudo)) <= 1)
+ if (ivs == 0)
+ return;
+
+ for (i = 0; i < ivs->num_entries; i++)
{
- if (MEM_P (x))
- reg_equiv_memory_loc[regno] = x;
- else
+ int regno = REGNO (ivs->entries[i].pseudo);
+ rtx x = targetm.allocate_initial_value (ivs->entries[i].hard_reg);
+
+ if (x && REG_N_SETS (REGNO (ivs->entries[i].pseudo)) <= 1)
{
- basic_block bb;
- int new_regno;
-
- gcc_assert (REG_P (x));
- new_regno = REGNO (x);
- reg_renumber[regno] = new_regno;
- /* Poke the regno right into regno_reg_rtx so that even
- fixed regs are accepted. */
- REGNO (ivs->entries[i].pseudo) = new_regno;
- /* Update global register liveness information. */
- FOR_EACH_BB (bb)
+ if (MEM_P (x))
+ reg_equiv_memory_loc[regno] = x;
+ else
{
- struct rtl_bb_info *info = bb->il.rtl;
-
- if (REGNO_REG_SET_P(info->global_live_at_start, regno))
- SET_REGNO_REG_SET (info->global_live_at_start, new_regno);
- if (REGNO_REG_SET_P(info->global_live_at_end, regno))
- SET_REGNO_REG_SET (info->global_live_at_end, new_regno);
+ basic_block bb;
+ int new_regno;
+
+ gcc_assert (REG_P (x));
+ new_regno = REGNO (x);
+ reg_renumber[regno] = new_regno;
+ /* Poke the regno right into regno_reg_rtx so that even
+ fixed regs are accepted. */
+ REGNO (ivs->entries[i].pseudo) = new_regno;
+ /* Update global register liveness information. */
+ FOR_EACH_BB (bb)
+ {
+ struct rtl_bb_info *info = bb->il.rtl;
+
+ if (REGNO_REG_SET_P(info->global_live_at_start, regno))
+ SET_REGNO_REG_SET (info->global_live_at_start,
+ new_regno);
+ if (REGNO_REG_SET_P(info->global_live_at_end, regno))
+ SET_REGNO_REG_SET (info->global_live_at_end,
+ new_regno);
+ }
}
}
}
}
-#endif
}
#include "gt-integrate.h"
diff --git a/gcc/system.h b/gcc/system.h
index a4882926b0d..3b33db102be 100644
--- a/gcc/system.h
+++ b/gcc/system.h
@@ -692,7 +692,8 @@ extern void fancy_abort (const char *, int, const char *) ATTRIBUTE_NORETURN;
HANDLE_PRAGMA_REDEFINE_EXTNAME HANDLE_PRAGMA_EXTERN_PREFIX \
MUST_PASS_IN_STACK FUNCTION_ARG_PASS_BY_REFERENCE \
VECTOR_MODE_SUPPORTED_P TARGET_SUPPORTS_HIDDEN \
- FUNCTION_ARG_PARTIAL_NREGS ASM_OUTPUT_DWARF_DTPREL
+ FUNCTION_ARG_PARTIAL_NREGS ASM_OUTPUT_DWARF_DTPREL \
+ ALLOCATE_INITIAL_VALUE
/* Other obsolete target macros, or macros that used to be in target
headers and were not used, and may be obsolete or may never have
diff --git a/gcc/target-def.h b/gcc/target-def.h
index 447b5c3cd92..18e3040874e 100644
--- a/gcc/target-def.h
+++ b/gcc/target-def.h
@@ -362,6 +362,7 @@ Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#define TARGET_ALIGN_ANON_BITFIELD hook_bool_void_false
#define TARGET_RTX_COSTS hook_bool_rtx_int_int_intp_false
#define TARGET_MANGLE_FUNDAMENTAL_TYPE hook_constcharptr_tree_null
+#define TARGET_ALLOCATE_INITIAL_VALUE NULL
#ifndef TARGET_INIT_LIBFUNCS
#define TARGET_INIT_LIBFUNCS hook_void_void
@@ -566,6 +567,7 @@ Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
TARGET_VECTOR_OPAQUE_P, \
TARGET_RTX_COSTS, \
TARGET_ADDRESS_COST, \
+ TARGET_ALLOCATE_INITIAL_VALUE, \
TARGET_DWARF_REGISTER_SPAN, \
TARGET_FIXED_CONDITION_CODE_REGS, \
TARGET_CC_MODES_COMPATIBLE, \
diff --git a/gcc/target.h b/gcc/target.h
index 65e50caef29..b3c6ee9d78a 100644
--- a/gcc/target.h
+++ b/gcc/target.h
@@ -446,6 +446,10 @@ struct gcc_target
invalid addresses. */
int (* address_cost) (rtx x);
+ /* Return where to allocate pseudo for a given hard register initial
+ value. */
+ rtx (* allocate_initial_value) (rtx x);
+
/* Given a register, this hook should return a parallel of registers
to represent where to find the register pieces. Define this hook
if the register and its mode are represented in Dwarf in