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