This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH 1/3] SH-2A FDPIC: New pattern: use_initial_val
- From: Andrew Stubbs <ams at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 19 Aug 2010 17:08:18 +0100
- Subject: [PATCH 1/3] SH-2A FDPIC: New pattern: use_initial_val
This patch creates a new instruction pattern "use_initial_val".
The purpose of this patch is to allow late optimization passes to use
re-use existing pseudo-registers, even if the use of the register has
been optimized away in earlier passes.
This feature is required by our SH-2A FDPIC (to follow), but has been
split out here because it is target independent.
OK to commit?
Andrew Stubbs
2010-08-19 Bernd Schmidt <bernds@codesourcery.com>
gcc/
* Makefile.in: (mode-switching.o): Depend on integrate.h.
* doc/md.texi (Standard Pattern Names For Generation):
Document use_initial_val.
* integrate.c (initial_value_pair): Add new member "initialized".
(get_hard_reg_initial_val): Set initialized.
(emit_initial_value_sets): Emit result of gen_use_initial_val.
* mode-switching.c: Include integrate.h.
(rest_of_handle_mode_switching): Call emit_initial_value_sets.
---
src/gcc-mainline/gcc/Makefile.in | 3 ++-
src/gcc-mainline/gcc/doc/md.texi | 7 +++++++
src/gcc-mainline/gcc/integrate.c | 23 ++++++++++++++++++-----
src/gcc-mainline/gcc/mode-switching.c | 2 ++
4 files changed, 29 insertions(+), 6 deletions(-)
diff --git a/src/gcc-mainline/gcc/Makefile.in b/src/gcc-mainline/gcc/Makefile.in
index 49b0634..4c035a7 100644
--- a/src/gcc-mainline/gcc/Makefile.in
+++ b/src/gcc-mainline/gcc/Makefile.in
@@ -3119,7 +3119,8 @@ lcm.o : lcm.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(REGS_H) \
mode-switching.o : mode-switching.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(RTL_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h \
$(INSN_ATTR_H) $(RECOG_H) $(BASIC_BLOCK_H) $(TM_P_H) $(FUNCTION_H) \
- output.h $(TREE_PASS_H) $(TIMEVAR_H) $(DF_H) $(TARGET_H) $(EMIT_RTL_H)
+ output.h $(TREE_PASS_H) $(TIMEVAR_H) $(DF_H) $(TARGET_H) $(EMIT_RTL_H) \
+ integrate.h
tree-ssa-dce.o : tree-ssa-dce.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) \
$(TREE_FLOW_H) $(DIAGNOSTIC_H) $(TIMEVAR_H) $(TM_H) \
coretypes.h $(TREE_DUMP_H) $(TREE_PASS_H) $(FLAGS_H) $(BASIC_BLOCK_H) \
diff --git a/src/gcc-mainline/gcc/doc/md.texi b/src/gcc-mainline/gcc/doc/md.texi
index fd8423a..bc488eb 100644
--- a/src/gcc-mainline/gcc/doc/md.texi
+++ b/src/gcc-mainline/gcc/doc/md.texi
@@ -5196,6 +5196,13 @@ The @code{sibcall_epilogue} pattern must not clobber any arguments used for
parameter passing or any stack slots for arguments passed to the current
function.
+@cindex @code{use_initial_val} instruction pattern
+@item @samp{use_initial_val}
+This pattern, if defined, emits an insn that shows use a pseudo register
+created by @code{get_hard_reg_initial_val}. This is useful if a port may
+introduce additional uses of this pseudo in late optimization passes, when
+the initial ones may already have been optimized away.
+
@cindex @code{trap} instruction pattern
@item @samp{trap}
This pattern, if defined, signals an error, typically by causing some
diff --git a/src/gcc-mainline/gcc/integrate.c b/src/gcc-mainline/gcc/integrate.c
index dd75758..9a5c364 100644
--- a/src/gcc-mainline/gcc/integrate.c
+++ b/src/gcc-mainline/gcc/integrate.c
@@ -56,6 +56,7 @@ along with GCC; see the file COPYING3. If not see
typedef struct GTY(()) initial_value_pair {
rtx hard_reg;
rtx pseudo;
+ bool initialized;
} initial_value_pair;
typedef struct GTY(()) initial_value_struct {
int num_entries;
@@ -239,6 +240,7 @@ get_hard_reg_initial_val (enum machine_mode mode, unsigned int regno)
{
struct initial_value_struct *ivs;
rtx rv;
+ int entry;
rv = has_hard_reg_initial_val (mode, regno);
if (rv)
@@ -254,17 +256,19 @@ get_hard_reg_initial_val (enum machine_mode mode, unsigned int regno)
crtl->hard_reg_initial_vals = ivs;
}
- if (ivs->num_entries >= ivs->max_entries)
+ entry = ivs->num_entries++;
+ if (entry >= ivs->max_entries)
{
ivs->max_entries += 5;
ivs->entries = GGC_RESIZEVEC (initial_value_pair, ivs->entries,
ivs->max_entries);
}
- ivs->entries[ivs->num_entries].hard_reg = gen_rtx_REG (mode, regno);
- ivs->entries[ivs->num_entries].pseudo = gen_reg_rtx (mode);
+ ivs->entries[entry].hard_reg = gen_rtx_REG (mode, regno);
+ ivs->entries[entry].pseudo = gen_reg_rtx (mode);
+ ivs->entries[entry].initialized = false;
- return ivs->entries[ivs->num_entries++].pseudo;
+ return ivs->entries[entry].pseudo;
}
/* See if get_hard_reg_initial_val has been used to create a pseudo
@@ -299,7 +303,16 @@ emit_initial_value_sets (void)
start_sequence ();
for (i = 0; i < ivs->num_entries; i++)
- emit_move_insn (ivs->entries[i].pseudo, ivs->entries[i].hard_reg);
+ {
+ if (ivs->entries[i].initialized)
+ continue;
+ ivs->entries[i].initialized = true;
+ emit_move_insn (ivs->entries[i].pseudo, ivs->entries[i].hard_reg);
+#ifdef HAVE_use_initial_val
+ if (HAVE_use_initial_val)
+ emit_insn (gen_use_initial_val (ivs->entries[i].pseudo));
+#endif
+ }
seq = get_insns ();
end_sequence ();
diff --git a/src/gcc-mainline/gcc/mode-switching.c b/src/gcc-mainline/gcc/mode-switching.c
index 306fb5d..ce7e4d1 100644
--- a/src/gcc-mainline/gcc/mode-switching.c
+++ b/src/gcc-mainline/gcc/mode-switching.c
@@ -33,6 +33,7 @@ along with GCC; see the file COPYING3. If not see
#include "output.h"
#include "tm_p.h"
#include "function.h"
+#include "integrate.h"
#include "tree-pass.h"
#include "timevar.h"
#include "df.h"
@@ -753,6 +754,7 @@ rest_of_handle_mode_switching (void)
{
#ifdef OPTIMIZE_MODE_SWITCHING
optimize_mode_switching ();
+ emit_initial_value_sets ();
#endif /* OPTIMIZE_MODE_SWITCHING */
return 0;
}