On Fri, Sep 09, 2016 at 12:58:11PM +0200, Bernd Schmidt wrote:
> Hmm? The problem is that you can't generally emit a save/restore 
> independent of placement, because you may not know which offset to use 
> from whichever base register. But these offsets aren't necessarily 
> constant throughout the function. Segher explained that the algorithm 
> deals with this by giving up in many cases, which of course limits the 
> usefulness. It probably makes it unusable entirely on targets that want 
> to use pushes for function args.

It's not the generic algorithm that gives up; it's the target hook.
Specifically, at least for the PowerPC one I wrote, the
TARGET_SHRINK_WRAP_GET_SEPARATE_COMPONENTS hook gives up on register
components that need an offset from the base reg (stack or frame pointer)
that cannot be used in a single instruction (i.e. won't fit in 16 bits).

The generic code only does

+  /* We don't handle "strange" functions.  */
+  if (cfun->calls_alloca
+      || cfun->calls_setjmp
+      || cfun->can_throw_non_call_exceptions
+      || crtl->calls_eh_return
+      || crtl->has_nonlocal_goto
+      || crtl->saves_all_registers)
+    return;

so that does not give up in "many" cases.

Targets that push function args can handle things fine as far as I see?
Targets that normally use push insns in the prologue will just have to
not do that for the components that are separately wrapped.  Or they can
still use pushes to reserve that space, if that works better.


Segher

Reply via email to