https://gcc.gnu.org/g:826dd85cb9f368608a9890046cd701f7530d7315
commit 826dd85cb9f368608a9890046cd701f7530d7315 Author: Michael Matz <m...@suse.de> Date: Wed Jul 10 17:10:18 2024 +0200 Add target hook shrink_wrap.cleanup_components when the shrink wrapping infrastructure removed components the target might need to remove even more for dependency reasons. x86 for instance needs to remove the frame-allocation component when some register components are removed. Diff: --- gcc/config/i386/i386.cc | 17 +++++++++++++++++ gcc/doc/tm.texi | 8 ++++++++ gcc/doc/tm.texi.in | 2 ++ gcc/shrink-wrap.cc | 10 ++++++++++ gcc/target.def | 10 ++++++++++ 5 files changed, 47 insertions(+) diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc index 8c9505d53a75..36202b7dcb07 100644 --- a/gcc/config/i386/i386.cc +++ b/gcc/config/i386/i386.cc @@ -10927,6 +10927,21 @@ ix86_disqualify_components (sbitmap components, edge e, sbitmap, bool) bitmap_clear_bit (components, SW_FRAME); } +/* Implements TARGET_SHRINK_WRAP_CLEANUP_COMPONENTS. The infrastructure + has removed some components (noted in REMOVED), this cleans out any + further components that can't be shrink wrapped separately + anymore. */ + +static void +ix86_cleanup_components (sbitmap components, sbitmap removed) +{ + /* If separate shrink wrapping removed any register components + then we must also removed SW_FRAME. */ + bitmap_clear_bit (removed, SW_FRAME); + if (!bitmap_empty_p (removed)) + bitmap_clear_bit (components, SW_FRAME); +} + /* Helper for frame allocation. This resets cfun->machine->fs to reflect the state at the first instruction before prologue (i.e. the call just happened). */ @@ -11107,6 +11122,8 @@ ix86_set_handled_components (sbitmap) #define TARGET_SHRINK_WRAP_COMPONENTS_FOR_BB ix86_components_for_bb #undef TARGET_SHRINK_WRAP_DISQUALIFY_COMPONENTS #define TARGET_SHRINK_WRAP_DISQUALIFY_COMPONENTS ix86_disqualify_components +#undef TARGET_SHRINK_WRAP_CLEANUP_COMPONENTS +#define TARGET_SHRINK_WRAP_CLEANUP_COMPONENTS ix86_cleanup_components #undef TARGET_SHRINK_WRAP_EMIT_PROLOGUE_COMPONENTS #define TARGET_SHRINK_WRAP_EMIT_PROLOGUE_COMPONENTS ix86_emit_prologue_components #undef TARGET_SHRINK_WRAP_EMIT_EPILOGUE_COMPONENTS diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index c8b8b126b242..201c8b9f94da 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -5352,6 +5352,14 @@ components in @var{edge_components} that the target cannot handle on edge epilogue instead. @end deftypefn +@deftypefn {Target Hook} void TARGET_SHRINK_WRAP_CLEANUP_COMPONENTS (sbitmap @var{components}, sbitmap @var{removed}) +This hook is called after the shrink wrapping infrastructure disqualified +components for various reasons (e.g. because an unsplittable edge would +have to be split). If there are interdependencies between components the +target can remove those from @var{components} whose dependencies are in +@var{removed}. If this hook would do nothing it doesn't need to be defined. +@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 diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index 658e1e63371e..f23e6ff3e455 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -3787,6 +3787,8 @@ generic code. @hook TARGET_SHRINK_WRAP_DISQUALIFY_COMPONENTS +@hook TARGET_SHRINK_WRAP_CLEANUP_COMPONENTS + @hook TARGET_SHRINK_WRAP_EMIT_PROLOGUE_COMPONENTS @hook TARGET_SHRINK_WRAP_EMIT_EPILOGUE_COMPONENTS diff --git a/gcc/shrink-wrap.cc b/gcc/shrink-wrap.cc index 2bec492c2a57..db5c1f24d11c 100644 --- a/gcc/shrink-wrap.cc +++ b/gcc/shrink-wrap.cc @@ -1432,6 +1432,9 @@ disqualify_problematic_components (sbitmap components) { auto_sbitmap pro (SBITMAP_SIZE (components)); auto_sbitmap epi (SBITMAP_SIZE (components)); + auto_sbitmap old (SBITMAP_SIZE (components)); + + bitmap_copy (old, components); basic_block bb; FOR_EACH_BB_FN (bb, cfun) @@ -1496,6 +1499,13 @@ disqualify_problematic_components (sbitmap components) } } } + + /* If the target needs to know that we removed some components, + tell it. */ + bitmap_and_compl (old, old, components); + if (targetm.shrink_wrap.cleanup_components + && !bitmap_empty_p (old)) + targetm.shrink_wrap.cleanup_components (components, old); } /* Place code for prologues and epilogues for COMPONENTS where we can put diff --git a/gcc/target.def b/gcc/target.def index fdad7bbc93e2..ac26e8ed38d7 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -6872,6 +6872,16 @@ epilogue instead.", void, (sbitmap components, edge e, sbitmap edge_components, bool is_prologue), NULL) +DEFHOOK +(cleanup_components, + "This hook is called after the shrink wrapping infrastructure disqualified\n\ +components for various reasons (e.g. because an unsplittable edge would\n\ +have to be split). If there are interdependencies between components the\n\ +target can remove those from @var{components} whose dependencies are in\n\ +@var{removed}. If this hook would do nothing it doesn't need to be defined.", + void, (sbitmap components, sbitmap removed), + NULL) + DEFHOOK (emit_prologue_components, "Emit prologue insns for the components indicated by the parameter.",