Hi,

Many RISC machines, as we know, have some restrictions on placing 
register-width constants in the source of load-immediate machine instructions, 
so the target must provide a solution for that in the machine description.

A naive way would be to solve it early, ie. to replace with read constants 
pooled in memory when expanding to RTL.

Alternatively, a more fancy approach would be to forgo placement in the 
constant pool until somewhere before the reload/LRA eg. the "split1" pass to 
give the optimization passes that involve immediates a chance to work.

If we choose the latter, we can expect better results with RTL if-conversion, 
constant folding, etc., but it often propagates constants that are too large in 
size to resolve to a simple load-immediate instruction.

This is because constant propagation has no way of telling about it, so this 
patch provides it.

===

This new target hook can be used to tell cprop whether or not to propagate
a constant depending on its contents.

For backwards compatibility, the default setting for this hook retains the
old behavior.

gcc/ChangeLog:

        * hooks.h (hook_bool_const_rtx_true): New prototype.
        * hooks.cc (hook_bool_const_rtx_true): New default hook.
        * target.def (constant_ok_for_cprop_p): New target hook.
        * cprop.cc (cprop_constant_p): Change to use the hook.
        * doc/tm.texi.in, (TARGET_CONSTANT_OK_FOR_CPROP_P): New @hook.
        * doc/tm.texi (TARGET_CONSTANT_OK_FOR_CPROP_P): New document.
---
 gcc/cprop.cc       |  4 +++-
 gcc/doc/tm.texi    | 12 ++++++++++++
 gcc/doc/tm.texi.in |  2 ++
 gcc/hooks.cc       |  7 +++++++
 gcc/hooks.h        |  1 +
 gcc/target.def     | 14 ++++++++++++++
 6 files changed, 39 insertions(+), 1 deletion(-)

diff --git a/gcc/cprop.cc b/gcc/cprop.cc
index 580f811545d..dfb1e88e9b4 100644
--- a/gcc/cprop.cc
+++ b/gcc/cprop.cc
@@ -40,6 +40,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "dbgcnt.h"
 #include "cfgloop.h"
 #include "gcse.h"
+#include "target.h"
 
 
 /* An obstack for our working variables.  */
@@ -249,7 +250,8 @@ insert_set_in_table (rtx dest, rtx src, rtx_insn *insn,
 static bool
 cprop_constant_p (const_rtx x)
 {
-  return CONSTANT_P (x) && (GET_CODE (x) != CONST || shared_const_p (x));
+  return CONSTANT_P (x) && targetm.constant_ok_for_cprop_p (x)
+        && (GET_CODE (x) != CONST || shared_const_p (x));
 }
 
 /* Determine whether the rtx X should be treated as a register that can
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 858bfb80cec..83151626a71 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -12187,6 +12187,18 @@ MIPS, where add-immediate takes a 16-bit signed value,
 is zero, which disables this optimization.
 @end deftypevr
 
+@deftypefn {Target Hook} bool TARGET_CONSTANT_OK_FOR_CPROP_P (const_rtx 
@var{cst})
+On some target machines, such as RISC ones, load-immediate instructions
+often have a limited range (for example, within signed 12 bits or less).
+Because they will be typically placed into the constant pool,
+unconditionally propagating constants that exceed such limit can lead to
+increased number of instruction and/or memory read access.
+This target hook should return @code{false} if @var{cst}, a candidate for
+constant propagation, is undesirable as a source for load-immediate
+instructions.
+The default version of this hook always returns @code{true}.
+@end deftypefn
+
 @deftypefn {Target Hook} {unsigned HOST_WIDE_INT} TARGET_ASAN_SHADOW_OFFSET 
(void)
 Return the offset bitwise ored into shifted address to get corresponding
 Address Sanitizer shadow memory address.  NULL if Address Sanitizer is not
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index 21b849ea32a..147331b0f53 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -7887,6 +7887,8 @@ and the associated definitions of those functions.
 
 @hook TARGET_CONST_ANCHOR
 
+@hook TARGET_CONSTANT_OK_FOR_CPROP_P
+
 @hook TARGET_ASAN_SHADOW_OFFSET
 
 @hook TARGET_MEMMODEL_CHECK
diff --git a/gcc/hooks.cc b/gcc/hooks.cc
index b29233f4f85..67bf3553d26 100644
--- a/gcc/hooks.cc
+++ b/gcc/hooks.cc
@@ -82,6 +82,13 @@ hook_bool_mode_true (machine_mode)
   return true;
 }
 
+/* Generic hook that takes (const_rtx) and returns true.  */
+bool
+hook_bool_const_rtx_true (const_rtx)
+{
+  return true;
+}
+
 /* Generic hook that takes (machine_mode, machine_mode) and returns true.  */
 bool
 hook_bool_mode_mode_true (machine_mode, machine_mode)
diff --git a/gcc/hooks.h b/gcc/hooks.h
index 1056e1e9e4d..d001f8fb9dc 100644
--- a/gcc/hooks.h
+++ b/gcc/hooks.h
@@ -30,6 +30,7 @@ extern bool hook_bool_bool_gcc_optionsp_false (bool, struct 
gcc_options *);
 extern bool hook_bool_const_int_const_int_true (const int, const int);
 extern bool hook_bool_mode_false (machine_mode);
 extern bool hook_bool_mode_true (machine_mode);
+extern bool hook_bool_const_rtx_true (const_rtx);
 extern bool hook_bool_mode_mode_true (machine_mode, machine_mode);
 extern bool hook_bool_mode_const_rtx_false (machine_mode, const_rtx);
 extern bool hook_bool_mode_const_rtx_true (machine_mode, const_rtx);
diff --git a/gcc/target.def b/gcc/target.def
index 4d49ffc2c88..8bf093ab0dc 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -4510,6 +4510,20 @@ MIPS, where add-immediate takes a 16-bit signed value,\n\
 is zero, which disables this optimization.",
  unsigned HOST_WIDE_INT, 0)
 
+DEFHOOK
+(constant_ok_for_cprop_p,
+ "On some target machines, such as RISC ones, load-immediate instructions\n\
+often have a limited range (for example, within signed 12 bits or less).\n\
+Because they will be typically placed into the constant pool,\n\
+unconditionally propagating constants that exceed such limit can lead to\n\
+increased number of instruction and/or memory read access.\n\
+This target hook should return @code{false} if @var{cst}, a candidate for\n\
+constant propagation, is undesirable as a source for load-immediate\n\
+instructions.\n\
+The default version of this hook always returns @code{true}.",
+ bool, (const_rtx cst),
+ hook_bool_const_rtx_true)
+
 /* Defines, which target-dependent bits (upper 16) are used by port  */
 DEFHOOK
 (memmodel_check,
-- 
2.20.1

Reply via email to