aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorGeorg-Johann Lay <avr@gjlay.de>2024-08-30 19:38:30 +0200
committerGeorg-Johann Lay <avr@gjlay.de>2024-08-31 20:30:40 +0200
commitdf89afbb7732bdf9f003af0020a46b6deb3c4eeb (patch)
treed4c3a4a9aa1ad79e3cbf167542220208130aa7f9 /gcc
parent60fc5501ddc77d496f1584532c29d209eea13734 (diff)
downloadgcc-df89afbb7732bdf9f003af0020a46b6deb3c4eeb.zip
gcc-df89afbb7732bdf9f003af0020a46b6deb3c4eeb.tar.gz
gcc-df89afbb7732bdf9f003af0020a46b6deb3c4eeb.tar.bz2
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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/avr/avr-passes.cc7
-rw-r--r--gcc/config/avr/avr-passes.def21
2 files changed, 28 insertions, 0 deletions
diff --git a/gcc/config/avr/avr-passes.cc b/gcc/config/avr/avr-passes.cc
index 58b132b..8a71b57 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 3be82e0..cd89d67 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. */