From 94e23f53d700769c453d31881c089d06cde823dd Mon Sep 17 00:00:00 2001
From: Richard Sandiford <richard.sandiford@linaro.org>
Date: Wed, 13 Sep 2017 17:04:08 +0000
Subject: Turn SECONDARY_MEMORY_NEEDED_MODE into a target hook

This includes a change to LRA.  Previously the code was:

    if (sclass == NO_REGS && dclass == NO_REGS)
      return false;
  #ifdef SECONDARY_MEMORY_NEEDED
    if (SECONDARY_MEMORY_NEEDED (sclass, dclass, GET_MODE (src))
  #ifdef SECONDARY_MEMORY_NEEDED_MODE
        && ((sclass != NO_REGS && dclass != NO_REGS)
            || GET_MODE (src) != SECONDARY_MEMORY_NEEDED_MODE (GET_MODE (src)))
  #endif
        )
      {
        *sec_mem_p = true;
        return false;
      }
  #endif

in which the positioning of the second ifdef meant that defining
SECONDARY_MEMORY_NEEDED_MODE to its default value was not a no-op:
without a definition, we would consider using secondary reloads for
mem<-reg and reg<-mem reloads even if the secondary memory has the
same mode as the original mem, while defining it would avoid this.
The latter behaviour seems correct.

The default is different for reload and LRA.  For LRA the default is
to use the original mode, while reload promotes smaller-than-word
integral modes to word mode:

  if (GET_MODE_BITSIZE (mode) < BITS_PER_WORD && INTEGRAL_MODE_P (mode))
    mode = mode_for_size (BITS_PER_WORD,
                          GET_MODE_CLASS (mode), 0).require ();

Some of the ports that have switched to LRA seemed to have
SECONDARY_MEMORY_NEEDED_MDOEs based on the old reload definition,
and still referred to the reload.c:get_secondary_mem function in
the comments.  The patch just keeps them as-is.

2017-09-13  Richard Sandiford  <richard.sandiford@linaro.org>
	    Alan Hayward  <alan.hayward@arm.com>
	    David Sherwood  <david.sherwood@arm.com>

gcc/
	* target.def (secondary_memory_needed_mode): New hook:
	* targhooks.c (default_secondary_memory_needed_mode): Declare.
	* targhooks.h (default_secondary_memory_needed_mode): New function.
	* doc/tm.texi.in (SECONDARY_MEMORY_NEEDED_MODE): Replace with...
	(TARGET_SECONDARY_MEMORY_NEEDED_MODE): ...this.
	* doc/tm.texi: Regenerate.
	* lra-constraints.c (check_and_process_move): Use
	targetm.secondary_memory_needed_mode instead of
	TARGET_SECONDARY_MEMORY_NEEDED_MODE.
	(curr_insn_transform): Likewise.
	* reload.c (get_secondary_mem): Likewise.
	* config/alpha/alpha.h (SECONDARY_MEMORY_NEEDED_MODE): Delete.
	* config/alpha/alpha.c (alpha_secondary_memory_needed_mode): New
	function.
	(TARGET_SECONDARY_MEMORY_NEEDED_MODE): Redefine.
	* config/i386/i386.h (SECONDARY_MEMORY_NEEDED_MODE): Delete.
	* config/i386/i386.c (ix86_secondary_memory_needed_mode): New function.
	(TARGET_SECONDARY_MEMORY_NEEDED_MODE): Redefine.
	* config/powerpcspe/powerpcspe.h (SECONDARY_MEMORY_NEEDED_MODE):
	Delete.
	* config/powerpcspe/powerpcspe-protos.h
	(rs6000_secondary_memory_needed_mode): Delete.
	* config/powerpcspe/powerpcspe.c
	(TARGET_SECONDARY_MEMORY_NEEDED_MODE): Redefine.
	(rs6000_secondary_memory_needed_mode): Make static.
	* config/rs6000/rs6000.h (SECONDARY_MEMORY_NEEDED_MODE): Delete.
	* config/rs6000/rs6000-protos.h (rs6000_secondary_memory_needed_mode):
	Delete.
	* config/rs6000/rs6000.c (TARGET_SECONDARY_MEMORY_NEEDED_MODE):
	Redefine.
	(rs6000_secondary_memory_needed_mode): Make static.
	* config/s390/s390.h (SECONDARY_MEMORY_NEEDED_MODE): Delete.
	* config/s390/s390.c (s390_secondary_memory_needed_mode): New function.
	(TARGET_SECONDARY_MEMORY_NEEDED_MODE): Redefine.
	* config/sparc/sparc.h (SECONDARY_MEMORY_NEEDED_MODE): Delete.
	* config/sparc/sparc.c (TARGET_SECONDARY_MEMORY_NEEDED_MODE):
	Redefine.
	(sparc_secondary_memory_needed_mode): New function.
	* system.h (TARGET_SECONDARY_MEMORY_NEEDED_MODE): Poison.

Co-Authored-By: Alan Hayward <alan.hayward@arm.com>
Co-Authored-By: David Sherwood <david.sherwood@arm.com>

From-SVN: r252455
---
 gcc/target.def | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

(limited to 'gcc/target.def')

diff --git a/gcc/target.def b/gcc/target.def
index 6462c94..7abb74e 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -5265,6 +5265,30 @@ forwarding logic, you can set @code{sri->extra_cost} to a negative amount.",
   secondary_reload_info *sri),
  default_secondary_reload)
 
+DEFHOOK
+(secondary_memory_needed_mode,
+ "If @code{SECONDARY_MEMORY_NEEDED} tells the compiler to use memory\n\
+when moving between two particular registers of mode @var{mode},\n\
+this hook specifies the mode that the memory should have.\n\
+\n\
+The default depends on @code{TARGET_LRA_P}.  Without LRA, the default\n\
+is to use a word-sized mode for integral modes that are smaller than a\n\
+a word.  This is right thing to do on most machines because it ensures\n\
+that all bits of the register are copied and prevents accesses to the\n\
+registers in a narrower mode, which some machines prohibit for\n\
+floating-point registers.\n\
+\n\
+However, this default behavior is not correct on some machines, such as\n\
+the DEC Alpha, that store short integers in floating-point registers\n\
+differently than in integer registers.  On those machines, the default\n\
+widening will not work correctly and you must define this hook to\n\
+suppress that widening in some cases.  See the file @file{alpha.c} for\n\
+details.\n\
+\n\
+With LRA, the default is to use @var{mode} unmodified.",
+ machine_mode, (machine_mode mode),
+ default_secondary_memory_needed_mode)
+
 /* Given an rtx X being reloaded into a reg required to be in class CLASS,
    return the class of reg to actually use.  */
 DEFHOOK
-- 
cgit v1.1

