Message ID | 20141231141317.GA575@gmail.com |
---|---|
State | New |
Headers | show |
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
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.
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 --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 */