From patchwork Thu Aug 19 16:08:18 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [1/3] SH-2A FDPIC: New pattern: use_initial_val Date: Thu, 19 Aug 2010 06:08:18 -0000 From: Andrew Stubbs X-Patchwork-Id: 62190 Message-Id: <4C6D56F2.3060204@codesourcery.com> To: gcc-patches@gcc.gnu.org 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 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; }