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]));