Re: Where to place warning about non-optimized tail and sibling calls
On Wed, 2023-08-02 at 13:16 -0400, Bradley Lucier wrote: > On 8/1/23 6:08 PM, David Malcolm wrote: > > FWIW I added it to support Scheme from libgccjit; > > Do you know of any Scheme using libgccjit? I don't. It's not Scheme, but in case it's relevant, Emacs is doing ahead-of- time compilation of its Emacs Lisp using libgccjit; see: https://akrl.sdf.org/gccemacs.html > > BTW, I tried to build mainline with --enable-coverage to see which > code > is executed with -foptimize-sibling-calls, but bootstrap fails with > [...snip...] Sorry, I don't have any special knowledge of this build failure. Dave
Re: Where to place warning about non-optimized tail and sibling calls
On 8/1/23 6:08 PM, David Malcolm wrote: FWIW I added it to support Scheme from libgccjit; Do you know of any Scheme using libgccjit? BTW, I tried to build mainline with --enable-coverage to see which code is executed with -foptimize-sibling-calls, but bootstrap fails with /home/lucier/programs/gcc/objdirs/gcc-mainline/./prev-gcc/xg++ -B/home/lucier/programs/gcc/objdirs/gcc-mainline/./prev-gcc/ -B/pkgs/gcc-mainline/x86_64-pc-linux-gnu/bin/ -nostdinc++ -B/home/lucier/programs/gcc/objdirs/gcc-mainline/prev-x86_64-pc-linux-gnu/libstdc++-v3/src/.libs -B/home/lucier/programs/gcc/objdirs/gcc-mainline/prev-x86_64-pc-linux-gnu/libstdc++-v3/libsupc++/.libs -I/home/lucier/programs/gcc/objdirs/gcc-mainline/prev-x86_64-pc-linux-gnu/libstdc++-v3/include/x86_64-pc-linux-gnu -I/home/lucier/programs/gcc/objdirs/gcc-mainline/prev-x86_64-pc-linux-gnu/libstdc++-v3/include -I/home/lucier/programs/gcc/gcc-mainline/libstdc++-v3/libsupc++ -L/home/lucier/programs/gcc/objdirs/gcc-mainline/prev-x86_64-pc-linux-gnu/libstdc++-v3/src/.libs -L/home/lucier/programs/gcc/objdirs/gcc-mainline/prev-x86_64-pc-linux-gnu/libstdc++-v3/libsupc++/.libs -fno-PIE -c -g -O2 -fno-checking -gtoggle -DIN_GCC -fprofile-arcs -ftest-coverage -frandom-seed=opts.o -O0 -fkeep-static-functions -fno-exceptions -fno-rtti -fasynchronous-unwind-tables -W -Wall -Wno-narrowing -Wwrite-strings -Wcast-qual -Wmissing-format-attribute -Wconditionally-supported -Woverloaded-virtual -pedantic -Wno-long-long -Wno-variadic-macros -Wno-overlength-strings -Werror -fno-common -DHAVE_CONFIG_H -fno-PIE -I. -I. -I../../../gcc-mainline/gcc -I../../../gcc-mainline/gcc/. -I../../../gcc-mainline/gcc/../include -I../../../gcc-mainline/gcc/../libcpp/include -I../../../gcc-mainline/gcc/../libcody -I../../../gcc-mainline/gcc/../libdecnumber -I../../../gcc-mainline/gcc/../libdecnumber/bid -I../libdecnumber -I../../../gcc-mainline/gcc/../libbacktrace -o opts.o -MT opts.o -MMD -MP -MF ./.deps/opts.TPo ../../../gcc-mainline/gcc/opts.cc ../../../gcc-mainline/gcc/opts.cc: In function 'void print_filtered_help(unsigned int, unsigned int, unsigned int, unsigned int, gcc_options*, unsigned int)': ../../../gcc-mainline/gcc/opts.cc:1687:26: error: ' ' directive output may be truncated writing 2 bytes into a region of size between 1 and 256 [-Werror=format-truncation=] 1687 | "%s %s", help, _(use_diagnosed_msg)); | ^~ ../../../gcc-mainline/gcc/opts.cc:1686:22: note: 'snprintf' output 3 or more bytes (assuming 258) into a destination of size 256 1686 | snprintf (new_help, sizeof new_help, | ~^~~ 1687 | "%s %s", help, _(use_diagnosed_msg)); | ~ cc1plus: all warnings being treated as errors
Re: Where to place warning about non-optimized tail and sibling calls
On 8/1/23 6:08 PM, David Malcolm wrote: Or from libgccjit. FWIW I added it to support Scheme from libgccjit; see this patch kit: https://gcc.gnu.org/ml/gcc-patches/2016-05/msg01287.html Perhaps there's a case for a frontend attribute for this. Dave Thanks. I thought a front-end warning might be enough, as one can add -Werror to the command line to fail if it can't optimize a sibling call. Is there a reasonable place to put a warning if flag_optimize_sibling_calls is true and a sibling call is *not* optimized? Brad
Re: Where to place warning about non-optimized tail and sibling calls
On Tue, 2023-08-01 at 20:20 +0200, Jose E. Marchesi via Gcc wrote: > > > > The Gambit Scheme->C compiler has an option to generate more > > > efficient > > > code if it knows that all tail and sibling calls in the generated > > > C > > > code will be optimized. If gcc does not, however, optimize a > > > tail or > > > sibling call, the generated C code may be incorrect (depending on > > > circumstances). > > > > clang supports a musttail attribute that you use in return > > statements. > > But AFAIK GCC doesn't support it. It would be nice if it did. > > I looked around a little. > > The GCC tree nodes for call expressions can be annotated as to > require > tail call optimization: > > /* Set on a CALL_EXPR if the call has been marked as requiring tail > call > optimization for correctness. */ > #define CALL_EXPR_MUST_TAIL_CALL(NODE) \ > (CALL_EXPR_CHECK (NODE)->base.static_flag) > > And this is checked in many different places in calls.cc. But at the > moment the only way to set that flag is via a compiler plugin. Or from libgccjit. FWIW I added it to support Scheme from libgccjit; see this patch kit: https://gcc.gnu.org/ml/gcc-patches/2016-05/msg01287.html Perhaps there's a case for a frontend attribute for this. Dave > An > example of such a plugin is part of the GCC testsuite: > > testsuite/gcc.dg/plugin/must_tail_call_plugin.c > > It may be possible to use a similar plugin in your Scheme-to-C > compiler... >
Re: Where to place warning about non-optimized tail and sibling calls
On 8/1/23 12:51 PM, Paul Koning wrote: How is it possible to write valid C that is correct only if some optimization is done? Perhaps "incorrect" was the wrong word. If sibling-call optimization is not done, then perhaps the program will blow out the stack, which would not happen if the optimization is done. Also, transforming sibling calls is an optimization for C, but for Scheme it's a part of the language. Translating Scheme to C has to take that into account: if there is no sibling-call optimization, then the Scheme code is translated to C code that uses a so-called trampoline; if there is sibling-call optimization that the Scheme compiler can rely on, then taking advantage of the optimization leads to faster Scheme code. Brad
Re: Where to place warning about non-optimized tail and sibling calls
>> The Gambit Scheme->C compiler has an option to generate more efficient >> code if it knows that all tail and sibling calls in the generated C >> code will be optimized. If gcc does not, however, optimize a tail or >> sibling call, the generated C code may be incorrect (depending on >> circumstances). > > clang supports a musttail attribute that you use in return statements. > But AFAIK GCC doesn't support it. It would be nice if it did. I looked around a little. The GCC tree nodes for call expressions can be annotated as to require tail call optimization: /* Set on a CALL_EXPR if the call has been marked as requiring tail call optimization for correctness. */ #define CALL_EXPR_MUST_TAIL_CALL(NODE) \ (CALL_EXPR_CHECK (NODE)->base.static_flag) And this is checked in many different places in calls.cc. But at the moment the only way to set that flag is via a compiler plugin. An example of such a plugin is part of the GCC testsuite: testsuite/gcc.dg/plugin/must_tail_call_plugin.c It may be possible to use a similar plugin in your Scheme-to-C compiler...
Re: Where to place warning about non-optimized tail and sibling calls
> The Gambit Scheme->C compiler has an option to generate more efficient > code if it knows that all tail and sibling calls in the generated C > code will be optimized. If gcc does not, however, optimize a tail or > sibling call, the generated C code may be incorrect (depending on > circumstances). clang supports a musttail attribute that you use in return statements. But AFAIK GCC doesn't support it. It would be nice if it did.
Re: Where to place warning about non-optimized tail and sibling calls
I'm puzzled. The fundamental rule of optimization is that it doesn't change the (defined) semantics of the program. How is it possible to write valid C that is correct only if some optimization is done? In other words, if it matters whether an optimization is done or not, that suggests to me you're writing code with undefined semantics, and the answer is not to do so. paul > On Aug 1, 2023, at 12:43 PM, Bradley Lucier via Gcc wrote: > > The Gambit Scheme->C compiler has an option to generate more efficient code > if it knows that all tail and sibling calls in the generated C code will be > optimized. If gcc does not, however, optimize a tail or sibling call, the > generated C code may be incorrect (depending on circumstances). > > So I would like to add a warning enabled by -Wdisabled-optimization so that > if -foptimize-sibling-calls is given and a tail or sibling call is not > optimized, then a warning is triggered. > > I don't quite know where to place the warning. It would be good if there > were one piece of code to identify all tail and sibling calls, and then > another piece that decides whether the optimization can be performed. > > I see code in gcc/tree-tailcall.cc > > suitable_for_tail_opt_p > suitable_for_tail_call_opt_p > > which are called by > > tree_optimize_tail_calls_1 > > which takes an argument > > opt_tailcalls > > and it's called in one place with opt_tailcalls true and in another place > with opt_tailcalls false. > > So I'm losing the plot here. > > There is other code dealing with tail calls in gcc/calls.cc I don't seem to > understand at all. > > Any advice? > > Brad
Where to place warning about non-optimized tail and sibling calls
The Gambit Scheme->C compiler has an option to generate more efficient code if it knows that all tail and sibling calls in the generated C code will be optimized. If gcc does not, however, optimize a tail or sibling call, the generated C code may be incorrect (depending on circumstances). So I would like to add a warning enabled by -Wdisabled-optimization so that if -foptimize-sibling-calls is given and a tail or sibling call is not optimized, then a warning is triggered. I don't quite know where to place the warning. It would be good if there were one piece of code to identify all tail and sibling calls, and then another piece that decides whether the optimization can be performed. I see code in gcc/tree-tailcall.cc suitable_for_tail_opt_p suitable_for_tail_call_opt_p which are called by tree_optimize_tail_calls_1 which takes an argument opt_tailcalls and it's called in one place with opt_tailcalls true and in another place with opt_tailcalls false. So I'm losing the plot here. There is other code dealing with tail calls in gcc/calls.cc I don't seem to understand at all. Any advice? Brad