diff mbox

PATCH: [5 Regression] r219037 caused FAIL: gcc.dg/pr44194-1.c

Message ID 20141231141317.GA575@gmail.com
State New
Headers show

Commit Message

H.J. Lu Dec. 31, 2014, 2:13 p.m. UTC
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(-)

Comments

John David Anglin Jan. 3, 2015, 5:35 p.m. UTC | #1
On Wed, 31 Dec 2014, H.J. Lu wrote:

> -      /* 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;

Instead of falling through to code designed to handle normal calls, it
would be better to treat them separately.  Potentially, there are other
optimizations that may be applicable.  If a sibcall doesn't read from
the frame, add_non_frame_wild_read() can be called.  This would restore
the x86 optimization.

Dave
H.J. Lu Jan. 3, 2015, 7:48 p.m. UTC | #2
On Sat, Jan 3, 2015 at 9:35 AM, John David Anglin
<dave@hiauly1.hia.nrc.ca> wrote:
> On Wed, 31 Dec 2014, H.J. Lu wrote:
>
>> -      /* 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;
>
> Instead of falling through to code designed to handle normal calls, it
> would be better to treat them separately.  Potentially, there are other
> optimizations that may be applicable.  If a sibcall doesn't read from
> the frame, add_non_frame_wild_read() can be called.  This would restore
> the x86 optimization.
>

That will a new optimization.  I am trying to restore the old behavior on
x86 with minimum impact in stage 3.
John David Anglin Jan. 3, 2015, 8:10 p.m. UTC | #3
On 2015-01-03, at 2:48 PM, H.J. Lu wrote:

> On Sat, Jan 3, 2015 at 9:35 AM, John David Anglin
> <dave@hiauly1.hia.nrc.ca> wrote:
>> On Wed, 31 Dec 2014, H.J. Lu wrote:
>> 
>>> -      /* 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;
>> 
>> Instead of falling through to code designed to handle normal calls, it
>> would be better to treat them separately.  Potentially, there are other
>> optimizations that may be applicable.  If a sibcall doesn't read from
>> the frame, add_non_frame_wild_read() can be called.  This would restore
>> the x86 optimization.
>> 
> 
> That will a new optimization.  I am trying to restore the old behavior on
> x86 with minimum impact in stage 3.


Not really.  In gcc.dg/pr44194-1.c, the sibcall was not a const function and this case
was covered by this hunk of code:

      else
        /* Every other call, including pure functions, may read any memory
           that is not relative to the frame.  */
        add_non_frame_wild_read (bb_info);

Dave
--
John David Anglin	dave.anglin@bell.net
diff mbox

Patch

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 */