https://gcc.gnu.org/g:df89afbb7732bdf9f003af0020a46b6deb3c4eeb

commit r15-3340-gdf89afbb7732bdf9f003af0020a46b6deb3c4eeb
Author: Georg-Johann Lay <a...@gjlay.de>
Date:   Fri Aug 30 19:38:30 2024 +0200

    AVR: Run pass avr-fuse-add a second time after pass_cprop_hardreg.
    
    gcc/
            * config/avr/avr-passes.cc (avr_pass_fuse_add) <clone>: Override.
            * config/avr/avr-passes.def (avr_pass_fuse_add): Run again
            after pass_cprop_hardreg.

Diff:
---
 gcc/config/avr/avr-passes.cc  |  7 +++++++
 gcc/config/avr/avr-passes.def | 21 +++++++++++++++++++++
 2 files changed, 28 insertions(+)

diff --git a/gcc/config/avr/avr-passes.cc b/gcc/config/avr/avr-passes.cc
index 58b132b64bec..8a71b57ada10 100644
--- a/gcc/config/avr/avr-passes.cc
+++ b/gcc/config/avr/avr-passes.cc
@@ -1026,6 +1026,13 @@ public:
     this->name = name;
   }
 
+  // Cloning is required because we are running one instance of the pass
+  // before peephole2. and a second one after cprop_hardreg.
+  opt_pass * clone () final override
+  {
+    return make_avr_pass_fuse_add (m_ctxt);
+  }
+
   bool gate (function *) final override
   {
     return optimize && avr_fuse_add > 0;
diff --git a/gcc/config/avr/avr-passes.def b/gcc/config/avr/avr-passes.def
index 3be82e027101..cd89d6737276 100644
--- a/gcc/config/avr/avr-passes.def
+++ b/gcc/config/avr/avr-passes.def
@@ -26,6 +26,27 @@
 
 INSERT_PASS_BEFORE (pass_peephole2, 1, avr_pass_fuse_add);
 
+/* There are cases where avr-fuse-add doesn't find POST_INC cases because
+   the RTL code at that time is too long-winded, and moves registers back and
+   forth (which seems to be the same reason for why pass auto_inc_dec cannot
+   find POST_INC, either).  Some of that long-windedness is cleaned up very
+   late in pass cprop_hardreg, which opens up new opportunities to find post
+   increments.  An example is the following function from AVR-LibC's qsort:
+
+   void swapfunc (char *a, char *b, int n)
+   {
+       do
+       {
+           char tmp = *a;
+           *a++ = *b;
+           *b++ = tmp;
+       } while (--n > 0);
+   }
+
+   Hence, run avr-fuse-add twice; the second time after cprop_hardreg.  */
+
+INSERT_PASS_AFTER (pass_cprop_hardreg, 1, avr_pass_fuse_add);
+
 /* An analysis pass that runs prior to prologue / epilogue generation.
    Computes cfun->machine->gasisr.maybe which is used in prologue and
    epilogue generation provided -mgas-isr-prologues is on.  */

Reply via email to