On Wed, Aug 24, 2011 at 9:46 AM, Bernd Schmidt <ber...@codesourcery.com> wrote: > On 08/03/11 17:38, Richard Sandiford wrote: >> Bernd Schmidt <ber...@codesourcery.com> writes: >>> +@findex simple_return >>> +@item (simple_return) >>> +Like @code{(return)}, but truly represents only a function return, while >>> +@code{(return)} may represent an insn that also performs other functions >>> +of the function epilogue. Like @code{(return)}, this may also occur in >>> +conditional jumps. >> >> Sorry, I've forgotton the outcome of the discussion about what happens >> on targets whose return expands to the same code as their simple_return. >> Do the targets still need both "return" and "simple_return" rtxes? > > It's important to distinguish between these names as rtxes that can > occur in instruction patterns, and a use as a standard pattern name. > When a "return" pattern is generated, it should either fail or expand to > something that performs both the epilogue and the return. A > "simple_return" expands to something that performs only the return. > > Most targets allow "return" patterns only if the epilogue is empty. In > that case, "return" and "simple_return" can expand to the same insn; it > does not matter if that insn uses "simple_return" or "return", as they > are equivalent in the absence of an epilogue. It would be slightly nicer > to use "simple_return" in the patterns everywhere except ARM, but ports > don't need to be changed. > >> Do they need both md patterns (but potentially using the same rtx >> underneath)? > > The "return" standard pattern is needed for the existing optimizations > (inserting returns in-line rather than jumping to the end of the > function). Typically, it always fails if the function needs an epilogue, > except in the ARM case. > For shrink-wrapping to work, a port needs a "simple_return" pattern, > which the compiler can use even if parts of the function need an > epilogue. So yes, they have different purposes. > >> I ask because the rtl.def comment implies that those targets still >> need both expanders and both rtxes. If that's so, I think it needs >> to be mentioned here too. E.g. something like: >> >> Like @code{(return)}, but truly represents only a function return, while >> @code{(return)} may represent an insn that also performs other functions >> of the function epilogue. @code{(return)} only occurs on paths that >> pass through the function prologue, while @code{(simple_return)} >> only occurs on paths that do not pass through the prologue. > > This is not accurate for the rtx code. It is mostly accurate for the > standard pattern name. A simple_return rtx may occur just after an > epilogue, i.e. on a path that has passed through the prologue. > > Even for the simple_return pattern, I'm not sure reorg.c couldn't > introduce new expansions in a location after both prologue and epilogue. > >> Like @code{(return)}, @code{(simple_return)} may also occur in >> conditional jumps. >> >> You need to document the simple_return pattern in md.texi too. > > I was trying to update the documentation to only the current state after > the patch. The thinking was that without shrink-wrapping, nothing > generates this pattern, so documenting it would be misleading. > However, with the mips changes in this version of the patch, reorg.c > does make use of this pattern, so I've added documentation > >>> @@ -3498,6 +3506,8 @@ relax_delay_slots (rtx first) >>> continue; >>> >>> target_label = JUMP_LABEL (delay_insn); >>> + if (target_label && ANY_RETURN_P (target_label)) >>> + continue; >>> >>> if (!ANY_RETURN_P (target_label)) >>> { >> >> This doesn't look like a pure "handle return as well as simple return" >> change. Is the idea that every following test only makes sense for >> labels, and that things like: >> >> && prev_active_insn (target_label) == insn >> >> (to pick just one example) are actively dangerous for returns? > > That probably was the idea. Looking at it again, there's one case at the > bottom of the loop which may be safe, but given that there were no code > generation differences with the patch on three targets with > define_delay, I've done: > >> If so, I think you should remove the immediately-following. >> "if (!ANY_RETURN_P (target_label))" condition and reindent the body. > > this. > >> Given what you said about JUMP_LABEL sometimes being null, >> I think we need either (a) to check whether each *_return_label >> is null before comparing it with JUMP_LABEL, or (b) to ensure that >> we're dealing with a jump to a label. (b) seems neater IMO >> (as a call to jump_to_label_p). > > Done. > >> >>> +#if defined HAVE_return || defined HAVE_simple_return >>> + if ( >>> #ifdef HAVE_return >>> - if (HAVE_return && end_of_function_label != 0) >>> + (HAVE_return && function_return_label != 0) >>> +#else >>> + 0 >>> +#endif >>> +#ifdef HAVE_simple_return >>> + || (HAVE_simple_return && function_simple_return_label != 0) >>> +#endif >>> + ) >>> make_return_insns (first); >>> #endif >> >> Eww. > > Restructured. > >> (define_code_iterator any_return [return simple_return]) >> >> and just change the appropriate returns to any_returns. > > I've done this a bit differently - to show that it can be done, I've > changed mips to always emit simple_return rtxs, even for "return" > patterns (no code generation changes observed again). > > This version regression tested on mips64-elf, c/c++/objc. > > > Bernd >
This caused: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50215 -- H.J.