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.",

Reply via email to