On Thu, Feb 29, 2024 at 6:15 AM Jan Hubicka <hubi...@ucw.cz> wrote: > > > On Thu, Feb 29, 2024 at 02:31:05PM +0100, Jan Hubicka wrote: > > > I agree that debugability of user core dumps is important here. > > > > > > I guess an ideal solution would be to change codegen of noreturn functions > > > to callee save all registers. Performance of prologue of noreturn > > > function is not too important. THen we can stop caller saving registers > > > and still get reasonable backtraces. > > > > I don't think that is possible. > > While both C and C++ require that if [[noreturn]] attribute is used on > > some function declaration, it must be used on the first declaration and > > also if some function is [[noreturn]] in one TU, it must be [[noreturn]] > > in all other TUs which declare the same function. > > But, we have no such requirement for __attribute__((noreturn)), there it > > is a pure optimization, it can be declared just on the caller side as an > > optimization hint the function will not return, or just on the callee side > > where the compiler will actually verify it doesn't return, or both. > > And, the attribute is not part of function type, so even in standard C/C++, > > one can use > > extern void bar (); > > [[noreturn]] void foo () > > { > > for (;;) bar (); > > } > > void (*fn) () = foo; > > void baz () > > { > > fn (); > > } > > As you can call the noreturn function directly or indirectly, changing > > calling conventions based on noreturn vs. no-noreturn is IMHO not possible. > > I am not wed to the idea (just it appeared to me as an option to > disabling this optimization by default). I still think it may make sense. > > Making noreturn calles to save caller saved register is compatible with > the default ABI. If noreturn is missing on caller side, then caller will > save reigsters as usual. Noreturn callee will save them again, which is > pointless, but everything should work as usual and extra cost of saving > should not matter in practice. This is also the case of indirect call > of noreturn function where you miss annotation on caller side. > > If noreturn is missing on callee side, we will lose information on > functions arguments in backtrace, but the code will still work > (especially if we save BP register to make code backtraceable). This is > scenario that probably can be avoided in practice where it matters (such > as in glibc abort whose implementation is annotated). > > Noreturn already leads to some information loss in backtraces. I tend to > get surprised from time to time to see whrong call to abort due to tail > merging. So it may be acceptable to lose info in a situation where user > does sily thing and only annotates caller. > > Since we auto-detect noreturn, we may need to be extra careful about noreturn > comdats. Here auto-detection of prevailing def may have different > outcome than auto-detection of prevailed defs. So we may want to disable > the optimization for auto-detected comdats. >
There are 2 kinds of noreturns. One is abort which may require backtrace. The other is a normal exit from the previous frame. The latter case doesn't require backtrace and can be performance critical. Which one is more important for users? -- H.J.