To fix a wrong code bug on HPPA with sibcall optimization, r219037 changes DSE to treat sibcall as though it does a wild read. However, it causes a regression on x86:
FAIL: gcc.dg/pr44194-1.c scan-rtl-dump dse1 "global deletions = (2|3)" FAIL: gcc.dg/pr44194-1.c scan-rtl-dump-not final "insn[: ][^\n]*set \\(mem(?![^\n]*scratch)" This patch adds a sibcall_wild_read_p target hook, which returns true if a sibcall have a wild read. It defaults to SIBLING_CALL_P. I added hook_bool_rtx_insn_false and define TARGET_SIBCALL_WILD_READ_P as hook_bool_rtx_insn_false for x86. This patch restores the old behavior before r219037. Tested on x86. OK for trunk? Thanks. H.J. --- PR middle-end/64388 * dse.c (scan_insn): Call targetm.sibcall_wild_read_p to check if a sibcall may have a wild read. * hooks.c (hook_bool_rtx_insn_false): New. * hooks.h (hook_bool_rtx_insn_false): Likewise. * targhooks.c (default_sibcall_wild_read_p): Likewise. * targhooks.h (default_sibcall_wild_read_p): Likewise. * target.def (sibcall_wild_read_p): A new hook. * config/i386/i386.c (TARGET_SIBCALL_WILD_READ_P): New. Defined to hook_bool_rtx_insn_false. * doc/tm.texi: Regenerated. * doc/tm.texi.in: Add hook for TARGET_SIBCALL_WILD_READ_P. --- gcc/ChangeLog | 15 +++++++++++++++ gcc/config/i386/i386.c | 3 +++ gcc/doc/tm.texi | 5 +++++ gcc/doc/tm.texi.in | 2 ++ gcc/dse.c | 7 +------ gcc/hooks.c | 6 ++++++ gcc/hooks.h | 1 + gcc/target.def | 8 ++++++++ gcc/targhooks.c | 12 ++++++++++++ gcc/targhooks.h | 2 ++ 10 files changed, 55 insertions(+), 6 deletions(-) diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 162fe26..9909391 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -51711,6 +51711,9 @@ ix86_initialize_bounds (tree var, tree lb, tree ub, tree *stmts) #undef TARGET_FUNCTION_OK_FOR_SIBCALL #define TARGET_FUNCTION_OK_FOR_SIBCALL ix86_function_ok_for_sibcall +#undef TARGET_SIBCALL_WILD_READ_P +#define TARGET_SIBCALL_WILD_READ_P hook_bool_rtx_insn_false + #undef TARGET_MEMMODEL_CHECK #define TARGET_MEMMODEL_CHECK ix86_memmodel_check diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index a3fda45..1a78f05 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -2857,6 +2857,11 @@ machines with non orthogonal register usage for addressing, such as SH, this hook can be used to avoid excessive spilling. @end deftypefn +@deftypefn {Target Hook} bool TARGET_SIBCALL_WILD_READ_P (rtx_insn *@var{insn}) +A target hook which returns @code{true} if a sibcall @var{insn} may +have a wild read. +@end deftypefn + @deftypefn {Target Hook} bool TARGET_LEGITIMIZE_ADDRESS_DISPLACEMENT (rtx *@var{disp}, rtx *@var{offset}, machine_mode @var{mode}) A target hook which returns @code{true} if *@var{disp} is legitimezed to valid address displacement with subtracting *@var{offset} diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index 20c0129..0358235 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -2483,6 +2483,8 @@ as below: @hook TARGET_CANNOT_SUBSTITUTE_MEM_EQUIV_P +@hook TARGET_SIBCALL_WILD_READ_P + @hook TARGET_LEGITIMIZE_ADDRESS_DISPLACEMENT @hook TARGET_SPILL_CLASS diff --git a/gcc/dse.c b/gcc/dse.c index 3a7f31c..c0e1a0c 100644 --- a/gcc/dse.c +++ b/gcc/dse.c @@ -2483,12 +2483,7 @@ scan_insn (bb_info_t bb_info, rtx_insn *insn) insn_info->cannot_delete = true; - /* Arguments for a sibling call that are pushed to memory are passed - using the incoming argument pointer of the current function. These - may or may not be frame related depending on the target. Since - argument pointer related stores are not currently tracked, we treat - a sibling call as though it does a wild read. */ - if (SIBLING_CALL_P (insn)) + if (targetm.sibcall_wild_read_p (insn)) { add_wild_read (bb_info); return; diff --git a/gcc/hooks.c b/gcc/hooks.c index f698d1d..7ac6c8a 100644 --- a/gcc/hooks.c +++ b/gcc/hooks.c @@ -320,6 +320,12 @@ hook_bool_rtx_insn_true (rtx_insn *insn ATTRIBUTE_UNUSED) } bool +hook_bool_rtx_insn_false (rtx_insn *insn ATTRIBUTE_UNUSED) +{ + return false; +} + +bool hook_bool_rtx_false (rtx a ATTRIBUTE_UNUSED) { return false; diff --git a/gcc/hooks.h b/gcc/hooks.h index b1b312d..988724c 100644 --- a/gcc/hooks.h +++ b/gcc/hooks.h @@ -54,6 +54,7 @@ extern bool hook_bool_const_tree_hwi_hwi_const_tree_true (const_tree, HOST_WIDE_INT, const_tree); extern bool hook_bool_rtx_insn_true (rtx_insn *); +extern bool hook_bool_rtx_insn_false (rtx_insn *); extern bool hook_bool_rtx_false (rtx); extern bool hook_bool_rtx_insn_int_false (rtx_insn *, int); extern bool hook_bool_uintp_uintp_false (unsigned int *, unsigned int *); diff --git a/gcc/target.def b/gcc/target.def index 6258b3a..68c126a 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -5051,6 +5051,14 @@ as SH, this hook can be used to avoid excessive spilling.", bool, (rtx subst), hook_bool_rtx_false) +/* This target hook allows the backend to optimize sibcall in DSE. */ +DEFHOOK +(sibcall_wild_read_p, + "A target hook which returns @code{true} if a sibcall @var{insn} may\n\ +have a wild read.", + bool, (rtx_insn *insn), + default_sibcall_wild_read_p) + /* This target hook allows the backend to legitimize base plus displacement addressing. */ DEFHOOK diff --git a/gcc/targhooks.c b/gcc/targhooks.c index eedcc80..45dd0bb 100644 --- a/gcc/targhooks.c +++ b/gcc/targhooks.c @@ -1921,4 +1921,16 @@ can_use_doloop_if_innermost (const widest_int &, const widest_int &, return loop_depth == 1; } +/* Arguments for a sibling call that are pushed to memory are passed + using the incoming argument pointer of the current function. These + may or may not be frame related depending on the target. Since + argument pointer related stores are not currently tracked, we treat + a sibling call as though it does a wild read. */ + +bool +default_sibcall_wild_read_p (rtx_insn *insn) +{ + return SIBLING_CALL_P (insn); +} + #include "gt-targhooks.h" diff --git a/gcc/targhooks.h b/gcc/targhooks.h index 26e4f5f..e8f4dc0c 100644 --- a/gcc/targhooks.h +++ b/gcc/targhooks.h @@ -239,4 +239,6 @@ extern void default_setup_incoming_vararg_bounds (cumulative_args_t ca ATTRIBUTE tree type ATTRIBUTE_UNUSED, int *pretend_arg_size ATTRIBUTE_UNUSED, int second_time ATTRIBUTE_UNUSED); + +extern bool default_sibcall_wild_read_p (rtx_insn *); #endif /* GCC_TARGHOOKS_H */ -- 1.9.3