This patch adds a new command-line flag "-fshrink-wrap-separate", a status flag "shrink_wrapped_separate", hooks for abstracting the target components, and documentation for all those.
2016-06-07 Segher Boessenkool <seg...@kernel.crashing.org> * common.opt (-fshrink-wrap-separate): New flag. * doc/invoke.texi: Document it. * doc/tm.texi.in (Shrink-wrapping separate components): New subsection. * doc/tm.texi: Regenerate. * emit-rtl.h (struct rtl_data): New field shrink_wrapped_separate. * target.def (shrink_wrap): New hook vector. (get_separate_components, components_for_bb, disqualify_components, emit_prologue_components, emit_epilogue_components, set_handled_components): New hooks. --- gcc/common.opt | 4 ++++ gcc/doc/invoke.texi | 11 ++++++++++- gcc/doc/tm.texi | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++ gcc/doc/tm.texi.in | 29 +++++++++++++++++++++++++++ gcc/emit-rtl.h | 4 ++++ gcc/target.def | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 158 insertions(+), 1 deletion(-) diff --git a/gcc/common.opt b/gcc/common.opt index 8a292ed..97d305f 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -2168,6 +2168,10 @@ Common Report Var(flag_shrink_wrap) Optimization Emit function prologues only before parts of the function that need it, rather than at the top of the function. +fshrink-wrap-separate +Common Report Var(flag_shrink_wrap_separate) Init(1) Optimization +Shrink-wrap parts of the prologue and epilogue separately. + fsignaling-nans Common Report Var(flag_signaling_nans) Optimization SetByCombined Disable optimizations observable by IEEE signaling NaNs. diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 22001f9..2ea1727 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -397,7 +397,8 @@ Objective-C and Objective-C++ Dialects}. -fschedule-insns -fschedule-insns2 -fsection-anchors @gol -fselective-scheduling -fselective-scheduling2 @gol -fsel-sched-pipelining -fsel-sched-pipelining-outer-loops @gol --fsemantic-interposition -fshrink-wrap -fsignaling-nans @gol +-fsemantic-interposition -fshrink-wrap -fshrink-wrap-separate @gol +-fsignaling-nans @gol -fsingle-precision-constant -fsplit-ivs-in-unroller @gol -fsplit-paths @gol -fsplit-wide-types -fssa-backprop -fssa-phiopt @gol @@ -6322,6 +6323,7 @@ compilation time. -fmove-loop-invariants @gol -freorder-blocks @gol -fshrink-wrap @gol +-fshrink-wrap-separate @gol -fsplit-wide-types @gol -fssa-backprop @gol -fssa-phiopt @gol @@ -7231,6 +7233,13 @@ Emit function prologues only before parts of the function that need it, rather than at the top of the function. This flag is enabled by default at @option{-O} and higher. +@item -fshrink-wrap-separate +@opindex fshrink-wrap-separate +Shrink-wrap separate parts of the prologue and epilogue separately, so that +those parts are only executed when needed. +This option is on by default, but has no effect unless @option{-fshrink-wrap} +is also turned on. + @item -fcaller-saves @opindex fcaller-saves Enable allocation of values to registers that are clobbered by diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 9edb006..5a5c5cab 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -2924,6 +2924,7 @@ This describes the stack layout and calling conventions. * Function Entry:: * Profiling:: * Tail Calls:: +* Shrink-wrapping separate components:: * Stack Smashing Protection:: * Miscellaneous Register Hooks:: @end menu @@ -4852,6 +4853,59 @@ This hook should add additional registers that are computed by the prologue to t True if a function's return statements should be checked for matching the function's return type. This includes checking for falling off the end of a non-void function. Return false if no such check should be made. @end deftypefn +@node Shrink-wrapping separate components +@subsection Shrink-wrapping separate components +@cindex shrink-wrapping separate components + +The prologue does a lot of separate things: save callee-saved registers, +do whatever needs to be done to be able to call things (save the return +address, align the stack, whatever; different for each target), set up a +stack frame, do whatever needs to be done for the static chain (if anything), +set up registers for PIC, etc. Using the following hooks those prologue +or epilogue components can be shrink-wrapped separately, so that the +initialization (and possibly teardown) those components do is not done on +execution paths where it is unnecessary. + +What exactly those components are is up to the target code; the generic +code treats them abstractly. + +@deftypefn {Target Hook} sbitmap TARGET_SHRINK_WRAP_GET_SEPARATE_COMPONENTS (void) +This hook should return an @code{sbitmap} with the bits set for those +components that can be separately shrink-wrapped in the current function. +Return @code{NULL} if the current function should not get any separate +shrink-wrapping. +Don't define this hook if it would always return @code{NULL}. +If it is defined, the other hooks in this group have to be defined as well. +@end deftypefn + +@deftypefn {Target Hook} sbitmap TARGET_SHRINK_WRAP_COMPONENTS_FOR_BB (basic_block) +This hook should return an @code{sbitmap} with the bits set for those +components where either the prologue component has to be executed before +the @code{basic_block}, or the epilogue component after it, or both. +@end deftypefn + +@deftypefn {Target Hook} void TARGET_SHRINK_WRAP_DISQUALIFY_COMPONENTS (sbitmap @var{components}, edge @var{e}, sbitmap @var{edge_components}, bool @var{is_prologue}) +This hook should clear the bits in the @var{components} bitmap for those +components in @var{edge_components} that the target cannot handle on edge +@var{e}, where @var{is_prologue} says if this is for a prologue or an +epilogue instead. +@end deftypefn + +@deftypefn {Target Hook} void TARGET_SHRINK_WRAP_EMIT_PROLOGUE_COMPONENTS (sbitmap) +Emit prologue insns for the components indicated by the parameter. +@end deftypefn + +@deftypefn {Target Hook} void TARGET_SHRINK_WRAP_EMIT_EPILOGUE_COMPONENTS (sbitmap) +Emit epilogue insns for the components indicated by the parameter. +@end deftypefn + +@deftypefn {Target Hook} void TARGET_SHRINK_WRAP_SET_HANDLED_COMPONENTS (sbitmap) +Mark the components in the parameter as handled, so that the +@code{prologue} and @code{epilogue} named patterns know to ignore those +components. The target code should not hang on to the @code{sbitmap}, it +will be deleted after this call. +@end deftypefn + @node Stack Smashing Protection @subsection Stack smashing protection @cindex stack smashing protection diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index a72c3d8..aaa11e6 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -2530,6 +2530,7 @@ This describes the stack layout and calling conventions. * Function Entry:: * Profiling:: * Tail Calls:: +* Shrink-wrapping separate components:: * Stack Smashing Protection:: * Miscellaneous Register Hooks:: @end menu @@ -3789,6 +3790,34 @@ the function prologue. Normally, the profiling code comes after. @hook TARGET_WARN_FUNC_RETURN +@node Shrink-wrapping separate components +@subsection Shrink-wrapping separate components +@cindex shrink-wrapping separate components + +The prologue does a lot of separate things: save callee-saved registers, +do whatever needs to be done to be able to call things (save the return +address, align the stack, whatever; different for each target), set up a +stack frame, do whatever needs to be done for the static chain (if anything), +set up registers for PIC, etc. Using the following hooks those prologue +or epilogue components can be shrink-wrapped separately, so that the +initialization (and possibly teardown) those components do is not done on +execution paths where it is unnecessary. + +What exactly those components are is up to the target code; the generic +code treats them abstractly. + +@hook TARGET_SHRINK_WRAP_GET_SEPARATE_COMPONENTS + +@hook TARGET_SHRINK_WRAP_COMPONENTS_FOR_BB + +@hook TARGET_SHRINK_WRAP_DISQUALIFY_COMPONENTS + +@hook TARGET_SHRINK_WRAP_EMIT_PROLOGUE_COMPONENTS + +@hook TARGET_SHRINK_WRAP_EMIT_EPILOGUE_COMPONENTS + +@hook TARGET_SHRINK_WRAP_SET_HANDLED_COMPONENTS + @node Stack Smashing Protection @subsection Stack smashing protection @cindex stack smashing protection diff --git a/gcc/emit-rtl.h b/gcc/emit-rtl.h index 39dfce9..001f775 100644 --- a/gcc/emit-rtl.h +++ b/gcc/emit-rtl.h @@ -254,6 +254,10 @@ struct GTY(()) rtl_data { /* True if we performed shrink-wrapping for the current function. */ bool shrink_wrapped; + /* True if we performed shrink-wrapping for separate components for + the current function. */ + bool shrink_wrapped_separate; + /* Nonzero if function being compiled doesn't modify the stack pointer (ignoring the prologue and epilogue). This is only valid after pass_stack_ptr_mod has run. */ diff --git a/gcc/target.def b/gcc/target.def index 929d9ea..b951aec 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -5773,6 +5773,63 @@ DEFHOOK bool, (tree), hook_bool_tree_true) +#undef HOOK_PREFIX +#define HOOK_PREFIX "TARGET_SHRINK_WRAP_" +HOOK_VECTOR (TARGET_SHRINK_WRAP_HOOKS, shrink_wrap) + +DEFHOOK +(get_separate_components, + "This hook should return an @code{sbitmap} with the bits set for those\n\ +components that can be separately shrink-wrapped in the current function.\n\ +Return @code{NULL} if the current function should not get any separate\n\ +shrink-wrapping.\n\ +Don't define this hook if it would always return @code{NULL}.\n\ +If it is defined, the other hooks in this group have to be defined as well.", + sbitmap, (void), + NULL) + +DEFHOOK +(components_for_bb, + "This hook should return an @code{sbitmap} with the bits set for those\n\ +components where either the prologue component has to be executed before\n\ +the @code{basic_block}, or the epilogue component after it, or both.", + sbitmap, (basic_block), + NULL) + +DEFHOOK +(disqualify_components, + "This hook should clear the bits in the @var{components} bitmap for those\n\ +components in @var{edge_components} that the target cannot handle on edge\n\ +@var{e}, where @var{is_prologue} says if this is for a prologue or an\n\ +epilogue instead.", + void, (sbitmap components, edge e, sbitmap edge_components, bool is_prologue), + NULL) + +DEFHOOK +(emit_prologue_components, + "Emit prologue insns for the components indicated by the parameter.", + void, (sbitmap), + NULL) + +DEFHOOK +(emit_epilogue_components, + "Emit epilogue insns for the components indicated by the parameter.", + void, (sbitmap), + NULL) + +DEFHOOK +(set_handled_components, + "Mark the components in the parameter as handled, so that the\n\ +@code{prologue} and @code{epilogue} named patterns know to ignore those\n\ +components. The target code should not hang on to the @code{sbitmap}, it\n\ +will be deleted after this call.", + void, (sbitmap), + NULL) + +HOOK_VECTOR_END (shrink_wrap) +#undef HOOK_PREFIX +#define HOOK_PREFIX "TARGET_" + /* Determine the type of unwind info to emit for debugging. */ DEFHOOK (debug_unwind_info, -- 1.9.3