For architectures with likely spilled register classes, neither
register allocator is guaranteed
to succeed when using optimization.  If you have just a few files to
compile, you can try
by hand which compiler options will succeed and still give reasonable
code, but for large projects,
hand-tweaking library / program build rules on a file-by-file basis is
time intensive and does not
scale well across different build environments and compiler versions.

The attached patch adds a new option -fretry-compilation that allows
you to specify a list - or
lists - of options to use for a compilation retry, which is
implemented in the compiler driver.

Bootstrapped on x86_64-pc-linux-gnu.
2021-05-16  Joern Rennecke  <joern.renne...@embecosm.com>

        * common.opt: New option -fretry-compilation=.
        * gcc.c (execute): Implement -fretry-compilation.
        * doc/invoke.texi: Document -fretry-compilation.

diff --git a/gcc/common.opt b/gcc/common.opt
index a75b44ee47e..d4db372572f 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -1446,6 +1446,10 @@ Common Driver Var(flag_report_bug)
 Collect and dump debug information into temporary file if ICE in C/C++
 compiler occurred.
 
+fretry-compilation=
+Common Driver RejectNegative Joined Var(retry_compilation_str)
+If the compiler fails, retry with named options appeded.  Separate multiple 
options with ',', and multiple alternatives with ':' .
+
 fdump-internal-locations
 Common Var(flag_dump_locations) Init(0)
 Dump detailed information on GCC's internal representation of source code 
locations.
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 519881509a6..8f94fd1aa42 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -541,6 +541,7 @@ Objective-C and Objective-C++ Dialects}.
 -freorder-blocks-algorithm=@var{algorithm} @gol
 -freorder-blocks-and-partition  -freorder-functions @gol
 -frerun-cse-after-loop  -freschedule-modulo-scheduled-loops @gol
+-fretry-compilation=@var{option-list} @gol
 -frounding-math  -fsave-optimization-record @gol
 -fsched2-use-superblocks  -fsched-pressure @gol
 -fsched-spec-load  -fsched-spec-load-dangerous @gol
@@ -10796,6 +10797,44 @@ Perform a number of minor optimizations that are 
relatively expensive.
 
 Enabled at levels @option{-O2}, @option{-O3}, @option{-Os}.
 
+@item -fretry-compilation=@var{option-list}
+@opindex -fretry-compilation
+If the compilation fails, retry with additional options as specified in
+@var{option-list}.  This is actally implemented in the compiler driver,
+but the purpose is that you can use options that sporadically fail, and
+in that case, fall back to another option combination.  This is useful
+e.g. when you compile a large program or library and don't want to tweak
+the rules for each object file.
+option-list can specify one or options in a comma-separated list that are
+added at the end of the option list in a retry.  Multiple retries can be
+separated with a colon.  For example,
+@smallexample
+@option{-O3} @option{-fstd=c90} 
@option{-fretry-compilation=-mno-lra:-fno-tree-partial-pre,-fno-web:-O0}
+@end smallexample
+
+Will first run the compiler with the options
+@smallexample
+@option{-O3} @option{-fstd=c90}
+@end smallexample
+
+If that fails, it will re-try the compilation with:
+
+@smallexample
+@option{-O3} @option{-fstd=c90} @option{-mno-lra}
+@end smallexample
+
+If that too fails, it will re-try compilation with:
+
+@smallexample
+@option{-O3} @option{-fstd=c90} @option{-fno-tree-partial-pre} 
@option{-fno-web}
+@end smallexample
+
+And finally, if that too fails, it will re-try compilation with:
+
+@smallexample
+@option{-O3} @option{-fstd=c90} @option{-O0}
+@end smallexample
+
 @item -free
 @opindex free
 Attempt to remove redundant extension instructions.  This is especially
diff --git a/gcc/gcc.c b/gcc/gcc.c
index 4c1a659d5e8..7b056ac2840 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -3286,6 +3286,9 @@ execute (void)
        n_commands++;
       }
 
+ retry:
+  bool retry_compilation_p = false;
+
   /* If -v, print what we are about to do, and maybe query.  */
 
   if (verbose_flag)
@@ -3506,6 +3509,12 @@ execute (void)
              try_generate_repro (commands[0].argv);
            if (WEXITSTATUS (status) > greatest_status)
              greatest_status = WEXITSTATUS (status);
+           if (retry_compilation_str
+               && WEXITSTATUS (status) == ICE_EXIT_CODE
+               && i == 0
+               && (p = strrchr (commands[0].argv[0], DIR_SEPARATOR))
+               && ! strncmp (p + 1, "cc1", 3))
+             retry_compilation_p = true;
            ret_code = -1;
          }
 
@@ -3561,6 +3570,40 @@ execute (void)
          }
       }
 
+    commands[0].argv = argbuf.address ();
+    while (retry_compilation_p)
+      {
+       int nargs, n_extra;
+       const char *p, *q, **new_argv;
+       for (nargs = 0; commands[0].argv[nargs] != NULL; ++nargs)
+         /* Only retry compiler ICEs, not preprocessor ones.  */
+         if (! strcmp (commands[0].argv[nargs], "-E"))
+           retry_compilation_p = false;
+
+       if (!retry_compilation_p)
+         break;
+
+       for (n_extra = 0, p = retry_compilation_str;
+            p && *p != ':'; n_extra++, p = strpbrk (p + 1, ",:"));
+
+       new_argv = XALLOCAVEC (const char *, nargs + 2 + n_extra);
+       memcpy (new_argv, commands[0].argv,
+               (nargs + 1) * sizeof (const char *));
+       for (p = retry_compilation_str; p && *p != ':'; )
+         {
+           q = p;
+           if (*q == ',')
+             q++;
+           p = strpbrk (q, ",:");
+           new_argv[nargs++] = (p ? xstrndup (q, p-q) : q);
+         }
+       new_argv[nargs] = NULL;
+       commands[0].argv = new_argv;
+       retry_compilation_str = (p ? p + 1 : p);
+
+       goto retry;
+      }
+
    if (commands[0].argv[0] != commands[0].prog)
      free (CONST_CAST (char *, commands[0].argv[0]));
 

Reply via email to