aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog23
-rw-r--r--gcc/Makefile.in9
-rw-r--r--gcc/config/s390/s390.c2
-rw-r--r--gcc/doc/tm.texi13
-rw-r--r--gcc/reload.c21
-rw-r--r--gcc/target-def.h3
-rw-r--r--gcc/target.h2
-rw-r--r--gcc/targhooks.c39
-rw-r--r--gcc/targhooks.h3
9 files changed, 111 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 515b590..dd9854a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,26 @@
+2003-11-02 Richard Sandiford <rsandifo@redhat.com>
+
+ * Makefile.in (targhooks.o, reload.o): Update dependencies.
+ (GTFILES): Add targhooks.c.
+ (gt-targhooks.h): New rule; depend on s-gtype.
+ * target.h (direct_pool_load_p): New hook.
+ * target-def.h (TARGET_DIRECT_POOL_LOAD_P): New macro.
+ (TARGET_INITIALIZER): Include it.
+ * targhooks.h (default_direct_pool_load_p): Declare.
+ (hook_bool_machine_mode_true): Declare.
+ * targhooks.c: Include insn-config.h, recog.h, ggc.h and
+ gt-targhooks.h.
+ (pool_symbol): New variable.
+ (default_direct_pool_load_p): New function.
+ (hook_bool_machine_mode_true): New function.
+ * reload.c: Include target.h.
+ (find_reloads): If an alternative will force a constant into memory,
+ count an extra reload if constant pool symbols are not valid
+ addresses. If an alternative uses memory to move values between
+ registers, count the move as two reloads rather than one.
+ * config/s390/s390.c (TARGET_DIRECT_POOL_LOAD_P): Define.
+ * doc/tm.texi (TARGET_DIRECT_POOL_LOAD_P): Document.
+
2003-11-02 Eric Botcazou <ebotcazou@libertysurf.fr>
PR optimization/12799
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 94627e2..88184f3 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1522,7 +1522,7 @@ opts.o : opts.c opts.h options.h toplev.h $(CONFIG_H) $(SYSTEM_H) \
output.h $(DIAGNOSTIC_H) $(TM_P_H) $(INSN_ATTR_H) intl.h
targhooks.o : targhooks.c targhooks.h $(CONFIG_H) $(SYSTEM_H) \
coretypes.h $(TREE_H) $(TM_H) $(RTL_H) $(TM_P_H) function.h \
- output.h toplev.h
+ output.h toplev.h insn-config.h $(RECOG_H) $(GGC_H) gt-targhooks.h
toplev.o : toplev.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) $(RTL_H) \
function.h flags.h xcoffout.h input.h $(INSN_ATTR_H) output.h $(DIAGNOSTIC_H) \
@@ -1765,7 +1765,7 @@ ra-rewrite.o : ra-rewrite.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H)
output.h except.h ra.h reload.h insn-config.h
reload.o : reload.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) flags.h output.h \
$(EXPR_H) $(OPTABS_H) reload.h $(RECOG_H) hard-reg-set.h insn-config.h \
- $(REGS_H) function.h real.h toplev.h $(TM_P_H)
+ $(REGS_H) function.h real.h toplev.h $(TM_P_H) $(TARGET_H)
reload1.o : reload1.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) real.h flags.h \
$(EXPR_H) $(OPTABS_H) reload.h $(REGS_H) hard-reg-set.h insn-config.h \
$(BASIC_BLOCK_H) $(RECOG_H) output.h function.h toplev.h $(TM_P_H) \
@@ -2074,7 +2074,8 @@ GTFILES = $(srcdir)/input.h $(srcdir)/coretypes.h $(srcdir)/cpplib.h \
$(srcdir)/profile.c $(srcdir)/ra-build.c $(srcdir)/regclass.c \
$(srcdir)/reg-stack.c $(srcdir)/cfglayout.c $(srcdir)/langhooks.c \
$(srcdir)/sdbout.c $(srcdir)/stmt.c $(srcdir)/stor-layout.c \
- $(srcdir)/stringpool.c $(srcdir)/tree.c $(srcdir)/varasm.c \
+ $(srcdir)/stringpool.c $(srcdir)/targhooks.c $(srcdir)/tree.c \
+ $(srcdir)/varasm.c \
$(out_file) \
@all_gtfiles@
@@ -2091,7 +2092,7 @@ gt-expr.h gt-sdbout.h gt-optabs.h gt-bitmap.h \
gt-dwarf2out.h gt-ra-build.h gt-reg-stack.h gt-dwarf2asm.h \
gt-dbxout.h gt-c-common.h gt-c-decl.h gt-c-parse.h \
gt-c-pragma.h gtype-c.h gt-input.h gt-cfglayout.h \
-gt-stringpool.h gt-langhooks.h : s-gtype ; @true
+gt-stringpool.h gt-targhooks.h gt-langhooks.h : s-gtype ; @true
gtyp-gen.h: Makefile
echo "/* This file is machine generated. Do not edit. */" > tmp-gtyp.h
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index 67020f0..ede221e 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -134,6 +134,8 @@ static tree s390_build_builtin_va_list (void);
#define TARGET_RTX_COSTS s390_rtx_costs
#undef TARGET_ADDRESS_COST
#define TARGET_ADDRESS_COST s390_address_cost
+#undef TARGET_DIRECT_POOL_LOAD_P
+#define TARGET_DIRECT_POOL_LOAD_P hook_bool_machine_mode_true
#undef TARGET_MACHINE_DEPENDENT_REORG
#define TARGET_MACHINE_DEPENDENT_REORG s390_reorg
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 09f8295..51167f8 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -5402,6 +5402,19 @@ should probably only be given to addresses with different numbers of
registers on machines with lots of registers.
@end deftypefn
+@deftypefn {Target Hook} bool TARGET_DIRECT_POOL_LOAD_P (enum machine_mode @var{m})
+This hook should return true if values of mode @var{m} can usually be loaded
+directly from the constant pool, without using an intermediate register
+to hold the address.
+
+The hook is only a heuristic, it has no bearing on correctness.
+If it returns false, reload will be less likely to force constants
+into memory.
+
+The default definition returns true if an ordinary local symbol is
+a valid address.
+@end deftypefn
+
@node Scheduling
@section Adjusting the Instruction Scheduler
diff --git a/gcc/reload.c b/gcc/reload.c
index 8bd68c5..13dd25e 100644
--- a/gcc/reload.c
+++ b/gcc/reload.c
@@ -104,6 +104,7 @@ a register with any other reload. */
#include "output.h"
#include "function.h"
#include "toplev.h"
+#include "target.h"
#ifndef REGNO_MODE_OK_FOR_BASE_P
#define REGNO_MODE_OK_FOR_BASE_P(REGNO, MODE) REGNO_OK_FOR_BASE_P (REGNO)
@@ -3369,6 +3370,11 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
const_to_mem = 1;
if (this_alternative[i] != (int) NO_REGS)
losers++;
+
+ /* If constant pool symbols are not valid addresses,
+ count an extra reload for the address. */
+ if (!targetm.direct_pool_load_p (operand_mode[i]))
+ losers++;
}
/* If we can't reload this value at all, reject this
@@ -3394,6 +3400,21 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
&& ! const_to_mem)
bad = 1;
+#ifdef SECONDARY_MEMORY_NEEDED
+ /* If this alternative would use memory to move a value
+ between registers, it would need two reloads, one for
+ the load and one for the store. Account for the extra
+ reload here. */
+ if (GET_CODE (operand) == REG
+ && REGNO (operand) < FIRST_PSEUDO_REGISTER
+ && this_alternative[i] != NO_REGS
+ && (SECONDARY_MEMORY_NEEDED
+ (this_alternative[i],
+ REGNO_REG_CLASS (REGNO (operand)),
+ GET_MODE (operand))))
+ losers++;
+#endif
+
/* We prefer to reload pseudos over reloading other things,
since such reloads may be able to be eliminated later.
If we are reloading a SCRATCH, we won't be generating any
diff --git a/gcc/target-def.h b/gcc/target-def.h
index 4d091f2..c4eeb93 100644
--- a/gcc/target-def.h
+++ b/gcc/target-def.h
@@ -262,6 +262,8 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
/* In cse.c. */
#define TARGET_ADDRESS_COST default_address_cost
+#define TARGET_DIRECT_POOL_LOAD_P default_direct_pool_load_p
+
/* In builtins.c. */
#define TARGET_INIT_BUILTINS hook_void_void
#define TARGET_EXPAND_BUILTIN default_expand_builtin
@@ -377,6 +379,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
TARGET_VECTOR_OPAQUE_P, \
TARGET_RTX_COSTS, \
TARGET_ADDRESS_COST, \
+ TARGET_DIRECT_POOL_LOAD_P, \
TARGET_DWARF_REGISTER_SPAN, \
TARGET_MACHINE_DEPENDENT_REORG, \
TARGET_BUILD_BUILTIN_VA_LIST, \
diff --git a/gcc/target.h b/gcc/target.h
index c77d40f..fbea520 100644
--- a/gcc/target.h
+++ b/gcc/target.h
@@ -370,6 +370,8 @@ struct gcc_target
invalid addresses. */
int (* address_cost) (rtx x);
+ bool (* direct_pool_load_p) (enum machine_mode);
+
/* 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
diff --git a/gcc/targhooks.c b/gcc/targhooks.c
index 1000abb..9be6786 100644
--- a/gcc/targhooks.c
+++ b/gcc/targhooks.c
@@ -61,6 +61,9 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "target.h"
#include "tm_p.h"
#include "target-def.h"
+#include "insn-config.h"
+#include "recog.h"
+#include "ggc.h"
void
default_external_libcall (rtx fun ATTRIBUTE_UNUSED)
@@ -196,9 +199,45 @@ default_pretend_outgoing_varargs_named(CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED)
#endif
}
+/* A SYMBOL_REF for a local symbol. Used by default_direct_pool_load_p. */
+
+static GTY(()) rtx pool_symbol;
+
+/* See whether a local symbol is a valid address for MODE. If so, assume
+ that constant pool symbols are also valid addresses, otherwise assume
+ that they aren't.
+
+ ??? This is only an approximation. We can't test constant pool
+ symbols directly without forcing something into the constant pool. */
+
+bool
+default_direct_pool_load_p (enum machine_mode mode)
+{
+ if (pool_symbol == 0)
+ {
+ char label[256];
+
+ ASM_GENERATE_INTERNAL_LABEL (label, "LC", 0);
+ pool_symbol = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (label));
+ SYMBOL_REF_FLAGS (pool_symbol) = SYMBOL_FLAG_LOCAL;
+ }
+ return memory_address_p (mode, pool_symbol);
+}
+
/* Generic hook that takes a CUMULATIVE_ARGS pointer and returns true. */
+
bool
hook_bool_CUMULATIVE_ARGS_true (CUMULATIVE_ARGS * a ATTRIBUTE_UNUSED)
{
return true;
}
+
+/* Generic hook that takes a machine mode and returns true. */
+
+bool
+hook_bool_machine_mode_true (enum machine_mode a ATTRIBUTE_UNUSED)
+{
+ return true;
+}
+
+#include "gt-targhooks.h"
diff --git a/gcc/targhooks.h b/gcc/targhooks.h
index 724abe8..f188ce2 100644
--- a/gcc/targhooks.h
+++ b/gcc/targhooks.h
@@ -32,4 +32,7 @@ extern void default_setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode
extern bool default_strict_argument_naming (CUMULATIVE_ARGS *);
extern bool default_pretend_outgoing_varargs_named (CUMULATIVE_ARGS *);
+extern bool default_direct_pool_load_p (enum machine_mode);
+
extern bool hook_bool_CUMULATIVE_ARGS_true (CUMULATIVE_ARGS *);
+extern bool hook_bool_machine_mode_true (enum machine_mode);