PR63633: May middle-end come up width hard regs for insn expanders?
Georg-Johann Lay
avr@gjlay.de
Fri Apr 17 13:14:00 GMT 2015
I allowed me to CC Vladimir; maybe he can propose how the backend can describe
an efficient, constraint-based solution. The problem is about expanders
producing insns with non-fixed hard-regs as in/out operands or clobbers. This
includes move insn from non-generic address spaces which require dedicated hard
regs. Issue is about correctness and efficiency of generated code.
Am 10/24/2014 um 08:29 PM schrieb Jakub Jelinek:
> On Fri, Oct 24, 2014 at 08:19:57PM +0200, Georg-Johann Lay wrote:
>> Yes, that's the straight forward approach which works so far. Bit tedious,
>> but well...
>>
>> In one case expmed generated different code, though: divmodhi instead of
>> mulhi_highpart for HI division by const_int. Cheating with costs did not
>> help. However for now I am mostly after correct, ICE-less code.
>>
>> What I am concerned about is:
>>
>> 1) May it happen that a value lives in a hard-reg across the expander? The
>> expander has no means to detect that situation and interfere, e.g.
>>
>> hard-reg = source_value // middle-end
>> expand-code // back-end
>> sink_value = hard-reg // middle-end
>>
>> where "expand-code" is one defind_expand / define_insn that clobbers /
>> changes (parts of) hard-reg but does *not* get hard-reg as operand. This is
>> wrong code obviously.
>
> It can happen, but if it happens, that would mean user code bug, like using
> register asm with an register that is unsuitable for use as global or local
> register var on the target, or it could be backend bug (expansion of some
> pattern clobbering register that has other fixed uses).
> You shouldn't ICE on it, but what happens is undefined.
>
> Before RA, the use of hard regs should be limited (pretty much just fixed
> regs where really necessary, global and local register variables (user needs
> to use with care), function arguments and return values (short lived around
> the call patterns).
>
> Jakub
FYI, the problem with using hard regs returned, now as PR65657 with move insns
which use hard regs.
There is one simple and obvious solution : Don't use hard regs, but instead
introduce respective constraints and let the register allocator do the job of
allocating the hard regs.
I tried that and it works in principle (for non-moves), but the code generated
by the register allocator is *bloated* beyond all recognition.
The use of hard regs in the avr BE is motivated by avoiding standard ABI calls
for support functions. Many of these libgcc functions are written in assembly
and have a much smaller footprint than ordinary ABI functions. The move insns
mentioned above perform loading from a non-standard address-sppace which is too
complicated to be expanded inline -- and even if expanded inline, the code will
need specific hard registers in specific operands because the instruction set
is dictating that.
Bottom line is: Using that simple and obvious hard-regs-by-constraint approach
would lead to code that is not acceptable w.r.t its performance.
One only solution that might work without bloating the code as mad might be to
perform the register selection by hand in a dedicated, pre-reload,
target-specific pass as outlined in
https://gcc.gnu.org/ml/gcc-patches/2015-04/msg00823.html
Johann
-------------- next part --------------
A non-text attachment was scrubbed...
Name: fixregs.diff
Type: text/x-patch
Size: 6979 bytes
Desc: not available
URL: <https://gcc.gnu.org/pipermail/gcc/attachments/20150417/6fff72c7/attachment.bin>
More information about the Gcc
mailing list