This patch adds -m[no-]fuse-ifelse as new optimization, so that
the avr-ifelse pass can be deactivated.

Ok for trunk?

Johann

--

gcc/
        * config/avr/avr.opt (-mfuse-ifelse): New option.
        * config/avr/avr-passes.cc (avr_pass_ifelse::gate): Don't
        return true when avropt_fuse_ifelse is false.
        * config/avr/avr.opt.urls (mfuse-ifelse): Add URL.
        * common/config/avr/avr-common.cc (avr_option_optimization_table)
        [OPT_LEVELS_1_PLUS]: Set OPT_mfuse_ifelse to 1.
        * doc/invoke.texi (AVR Options): Document it.
diff --git a/gcc/common/config/avr/avr-common.cc b/gcc/common/config/avr/avr-common.cc
index 8d1923a72bf..fb4f05553d7 100644
--- a/gcc/common/config/avr/avr-common.cc
+++ b/gcc/common/config/avr/avr-common.cc
@@ -44,6 +44,7 @@ static const struct default_options avr_option_optimization_table[] =
     { OPT_LEVELS_1_PLUS, OPT_mmain_is_OS_task, NULL, 1 },
     { OPT_LEVELS_1_PLUS, OPT_mfuse_add_, NULL, 1 },
     { OPT_LEVELS_2_PLUS, OPT_mfuse_add_, NULL, 2 },
+    { OPT_LEVELS_1_PLUS, OPT_mfuse_ifelse, NULL, 1 },
     { OPT_LEVELS_1_PLUS, OPT_mfuse_move2, NULL, 1 },
     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_mfuse_move_, NULL, 3 },
     { OPT_LEVELS_2_PLUS, OPT_mfuse_move_, NULL, 23 },
diff --git a/gcc/config/avr/avr-passes.cc b/gcc/config/avr/avr-passes.cc
index 7dc6f2b77c1..9df3c0e945c 100644
--- a/gcc/config/avr/avr-passes.cc
+++ b/gcc/config/avr/avr-passes.cc
@@ -3324,7 +3324,7 @@ public:
 
   bool gate (function *) final override
   {
-    return optimize > 0;
+    return optimize > 0 && avropt_fuse_ifelse;
   }
 
   unsigned int execute (function *func) final override;
diff --git a/gcc/config/avr/avr.opt b/gcc/config/avr/avr.opt
index d56061b50b6..9c4be3ba93e 100644
--- a/gcc/config/avr/avr.opt
+++ b/gcc/config/avr/avr.opt
@@ -164,6 +164,10 @@ mfract-convert-truncate
 Target Mask(FRACT_CONV_TRUNC)
 Allow to use truncation instead of rounding towards zero for fractional fixed-point types.
 
+mfuse-ifelse
+Target Var(avropt_fuse_ifelse) Init(0) Optimization
+Optimize compare-branch-compare-branch sequences to compare-branch-branch.
+
 mfuse-move
 Target Alias(mfuse-move=, 23, 0) Optimization
 Optimization. Run a post-reload pass that tweaks move instructions.
diff --git a/gcc/config/avr/avr.opt.urls b/gcc/config/avr/avr.opt.urls
index 004f9c45175..9988336cd49 100644
--- a/gcc/config/avr/avr.opt.urls
+++ b/gcc/config/avr/avr.opt.urls
@@ -99,6 +99,9 @@ UrlSuffix(gcc/AVR-Options.html#index-mfract-convert-truncate)
 mfuse-move
 UrlSuffix(gcc/AVR-Options.html#index-mfuse-move)
 
+mfuse-ifelse
+UrlSuffix(gcc/AVR-Options.html#index-mfuse-ifelse)
+
 mfuse-move=
 UrlSuffix(gcc/AVR-Options.html#index-mfuse-move)
 
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 01925ecf30d..e7a5bfbf1e9 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -986,8 +986,9 @@ Objective-C and Objective-C++ Dialects}.
 
 @emph{AVR Options} (@ref{AVR Options})
 @gccoptlist{-mmcu=@var{mcu}  -mabsdata  -maccumulate-args -masm-len-notes
--mcvt  -mbranch-cost=@var{cost}  -mfuse-add=@var{level}  -mfuse-move=@var{level}
--mfuse-move2  -mcall-prologues  -mgas-isr-prologues  -mint8  -mflmap
+-mcvt  -mbranch-cost=@var{cost}  -mfuse-add=@var{level}  -mfuse-ifelse
+-mfuse-move=@var{level}  -mfuse-move2
+-mcall-prologues  -mgas-isr-prologues  -mint8  -mflmap
 -mdouble=@var{bits}  -mlong-double=@var{bits}  -mno-call-main
 -mn_flash=@var{size}  -mfract-convert-truncate  -mno-interrupts
 -mmain-is-OS_task  -mrelax  -mpmem-wrap-around
@@ -24596,6 +24597,12 @@ The default uses @code{@var{level}=1} for optimizations @option{-Og}
 and @option{-O1}, and @code{@var{level}=2} for higher optimizations.
 Valid values for @var{level} are @code{0}, @code{1} and @code{2}.
 
+@opindex mfuse-ifelse
+@item -mfuse-ifelse
+Optimize compare-branch-compare-branch sequences to compare-branch-branch,
+which typically occurs in if-else trees generated from dense switch statements.
+This option is enabled per default if optimization is on.
+
 @opindex mfuse-move
 @item -mfuse-move
 @itemx -mno-fuse-move

Reply via email to