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

Reply via email to