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