This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [Patch/rtl-expand] Take tree range info into account to improve LSHIFT_EXP expanding
- From: Jiong Wang <jiong dot wang at arm dot com>
- To: Jeff Law <law at redhat dot com>
- Cc: "gcc-patches\ at gcc dot gnu dot org" <gcc-patches at gcc dot gnu dot org>
- Date: Fri, 14 Aug 2015 21:44:06 +0100
- Subject: Re: [Patch/rtl-expand] Take tree range info into account to improve LSHIFT_EXP expanding
- Authentication-results: sourceware.org; auth=none
- References: <n99sic0uyf2 dot fsf at arm dot com> <5539A922 dot 7060708 at redhat dot com> <n99pp6pwaob dot fsf at arm dot com> <554054E9 dot 4030400 at redhat dot com> <n99vbgebnrr dot fsf at arm dot com> <55415C2E dot 9010001 at redhat dot com> <n99oai9epez dot fsf at arm dot com> <55CE4E7A dot 8000603 at redhat dot com>
Jeff Law writes:
> On 08/14/2015 11:40 AM, Jiong Wang wrote:
>>
>> * Figuring out whether the shift source is coming from sign extension
>> by checking SSA_NAME_DEF_STMT instead of deducing from tree range
>> info. I fell checking the gimple statement is more reliable and
>> straigtforward.
> I suspect it'll also apply more often if you're looking for the
> nop-conversion rather than looking at range information.
>
> I keep thinking there ought to be a generalization here so that we're
> not so restrictive on the modes, but it's probably not worth doing.
>
> In a perfect world we'd also integrate the other strategies for
> double-word shifts that exist in the various ports as special cases in
> expansion and remove the double-word shift patterns for ports that don't
> actually have them in hardware. But that's probably a bit much to ask
> -- however, it probably couldn't hurt to see if there are any that are
> easily handled.
Agree.
Doing these in early tree/rtl expand stage is more clean & safe, and
expose more details to later RTL optimization passes as I think if you
handle double-word by defining insn pattern, then you will try to split
it in RTL split pass which happens later after some important
optimizations.
>
>> +
>> + If mode == GET_MODE_WIDER_MODE (word_mode), then normally there isn't
>> + native instruction to support this wide mode left shift. Given below
>> + example:
>> +
>> + Type A = (Type) B << C
>> +
>> + |< T >|
>> + | high | low |
>> +
>> + |<- size ->|
>> +
>> + By checking tree shape, if operand B is coming from signed extension,
>> + then the left shift operand can be simplified into:
>> +
>> + 1. high = low >> (size - C);
>> + 2. low = low << C;
> You'll want to reorder those to match the code you generate.
>
> Doesn't this require that C be less than the bitsize of a word?
Yes.
Above transformation is to handle double word left shift which shift the
original source across the word boundary.
Part of the contents shifted into the high half of destination, and the
other remain in the low half.
So if C is bigger than bitsize of a word, the the whole source will be
shifted into high half, thus should generate what you have listed below
and that's what gcc is generating, looks like the existed double word
shift logic can recognize this special cases.
So, I should check the value of C,if it's bigger than bitsize of a word,
then just fall through to default expand logic.
> If C is larger than the bitsize of a word, then you need some
> adjustments, something like:
>
>
> 1. high = low << (C - size)
> 2. low = 0
>
> Does this transformation require that the wider mode be exactly 2X the
> narrower mode? If so, that needs to be verified.
I think so, the wider mode should be exactly 2X the word_mode, will
add the check.
>
>> + if (GET_MODE_SIZE (rmode) < GET_MODE_SIZE (mode)
> So we're assured we have a widening conversion.
>
>> + && ((TREE_INT_CST_LOW (treeop1) + GET_MODE_BITSIZE (rmode))
>> + >= GET_MODE_BITSIZE (word_mode)))
> This test seems wrong. I'm not sure what you're really trying to test
> here. It seems you want to look at the shift count relative to the
> bitsize of word_mode. If it's less, then generate the code you
> mentioned above in the comment. If it's more, then generate the
> sequence I referenced? Right?
As explained above, I am trying to check whether the left shift is
causing the original source across word boundary while I should make sure
TREE_INT_CST_LOW (treeop1) < GET_MODE_BITSIZE (word_mode) at the same
time, otherwise fall through to default expand logic.
>
> I do think you need to be verifying that rmode == wordmode here. If I
> understand everything correctly, the final value is "mode" which must be
> 2X the size size of rmode/wordmode here, right?
I think rmode don't need to equal wordmode. For example the
transformation is OK for the following, where rmode = SImode, and final
mode = TImode.
int b;
__128_int a = (__128_int) b;
the expand_expr (treeop0... in the start of those code will generate
necessary instruction sequences to extend whatever mode b is into TImode
register (op0 in the patch);
>
>
>
> The other question is are we endianness-safe in these transformations?
I think it is. As this transformation is done with register involved
only. I think endianness issue will only happen if there is operation on
memory object.
>> + temp = expand_variable_shift (code, word_mode, low, treeop1,
>> + tlow, unsignedp);
> Why use "code" here right than just using LSHIFT_EXPR? As noted
> earlier,
Yes, better to use the constant LSHIFT_EXPR.
Thanks.
--
Regards,
Jiong