On Thu, Jan 28, 2016 at 5:37 AM, Richard Biener <rguent...@suse.de> wrote:
>> To workaround this, I defined a new hook expand_divmod_libfunc, which
>> targets must override for expanding call to target-specific dimovd.
>> The "default" hook default_expand_divmod_libfunc() expands call to
>> libgcc2.c:__udivmoddi4() since that's the only "generic" divmod
>> available.
>> Is this a reasonable approach ?
>
> Hum.  How do they get to expand/generate it today?  That said, I'm
> no expert in this area.

Currently, the only place where a divmod libfunc can be called is in
expand_divmod in expmed.c, which can return either the div or mod
result, but not both.  If this is called for the mod result, and there
is no div insn, and no mod insn, and no mod libfunc, then it will call
the divmod libfunc to generate the mod result.  This is exactly the
case where the ARM port needs it, as this code was written for the
arm.

There are 3 targets that define a divmod libfunc: arm, c6x, and spu.
The arm port is OK, because expand_divmod does the right thing for
arm, using the arm divmod calling convention.  The c6x port is OK
because it defines mod insns and libfuncs, and hence the divmod
libfunc will never be called and is redundant.  The spu port is also
OK, because it defines mod libcalls, and hence the divmod libfunc will
never be called, and is likewise redundant.  Both the c6x and spu
ports have their own divmod library functions in
libgcc/config/$target.  The divmod library functions are called by the
div and mod library functions, so they are necessary, they are just
never directly called.  Both the c6x and spu port uses the current
libgcc __udivmoddi4 calling convention with a pointer to the mod
result, which is different and incompatible to the ARM convention of
returning a double size result that contains div and mod.

WIth Prathamesh's patch to add support to the tree optimizers to
create divmod operations, the c6x and spu ports break.  The divmod
libfuncs are no longer redundant, and will be called, except with the
wrong ABI, so we need to extend the divmod support to handle multiple
ABIs.  This is why Prathamesh added the target hook for the divmod
libcall, so the target can specify the ABI used by its divmod
libcalls.  Prathamesh has correct support for ARM (current code), and
apparently correct code for c6x and spu (libgcc udivmodsi4).

> A simpler solution may be to not do the transform if there is no
> instruction for divmod.

This prevents the optimization from happening on ARM, which has divmod
libfuncs but no divmod insn.  We want the optimization to happen
there, as if we need both div and mod results, then calling the divmod
libfunc is faster than calling both the div and mod libfuncs.

Jim

Reply via email to