Kenneth Zadeck <zad...@naturalbridge.com> writes:
> On 11/02/2013 10:47 AM, Richard Sandiford wrote:
>> Kenneth Zadeck <zad...@naturalbridge.com> writes:
>>> On 11/02/2013 07:06 AM, Richard Sandiford wrote:
>>>> The first part of this is a simple type mismatch -- get_max_loop_iterations
>>>> returns a widest_int aka max_wide_int -- and I'd have installed it as
>>>> obvious.  The second part isn't as obvious though.  The old code stored
>>>> the maximum iterations as:
>>>>
>>>>     if (!get_max_loop_iterations (loop, &iter)
>>>>         || !iter.fits_shwi ())
>>>>       iterations_max = const0_rtx;
>>>>     else
>>>>       iterations_max = GEN_INT (iter.to_shwi ());
>>>>
>>>> and the new code uses:
>>>>
>>>>     if (!get_max_loop_iterations (loop, &iter)
>>>>         || !wi::fits_shwi_p (iter))
>>>>       iterations_max = const0_rtx;
>>>>     else
>>>>       iterations_max = immed_wide_int_const (iter, mode);
>>>>
>>>> which includes an extra canonicalisation.  I agree it would be good to do
>>>> that in principle, but I'm not sure it copes correctly with the case where
>>>> the loop iterates 1 << GET_MODE_PRECISION (mode) times.  Plus I think the
>>>> real fix would be to avoid the host dependence altogether, i.e. get rid
>>>> of the fits_shwi_p too.
>>>>
>>>> As it stands, this breaks bfin-elf's pattern, which has:
>>>>
>>>>     /* Due to limitations in the hardware (an initial loop count of 0
>>>>        does not loop 2^32 times) we must avoid to generate a hardware
>>>>        loops when we cannot rule out this case.  */
>>>>     if (!flag_unsafe_loop_optimizations
>>>>         && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 0xFFFFFFFF)
>>>>       FAIL;
>>>>
>>>> With the sign-extending conversion, this now triggers more often than
>>>> it was supposed to.
>>>>
>>>> Since the old "GEN_INT (iter.to_shwi ());" works verbatim in wide-int too,
>>>> and since we still use that form in the doloop_begin code, I think we 
>>>> should
>>>> just back the immed_wide_int_const out.
>>>>
>>>> Tested on powerpc64-linux-gnu and x86_64-linux-gnu.  It fixes some
>>>> unwanted testsuite changes in bfin-elf.  OK to install?
>>> I dislike this a lot.     I think that this is a badly written pattern
>>> in the bfin port if it depends on the host size.   As machines get
>>> bigger, (they may not be getting faster but they are still getting
>>> bigger) having traps like this at the portable level will bite us.
>> But this isn't at the portable level, it's backend-specific code.
>> It knows that it's dealing with a 32-bit counter.
> yes, but the patch is dumbing down the portable part of the compiler.
>>
>>> in truth this code should really be iterations_max =
>>> immed_wide_int_const (iter, mode) with no tests at all.
>> But like I say, that won't cope with loops that iterate
>> 1 << GET_MODE_PRECISION (mode) times, even if that fits
>> in a signed HWI.  (That case could happen if the hardware
>> supports it and if the counter starts out as 0.)
>>
>> The mainline code is self-consistent in that the number of
>> iterations is passed as a positive signed HWI, using 0 if the
>> value isn't known or is greater than HOST_WIDE_INT_MAX.
>> In the current interface, the CONST_INT doesn't really have a mode.
>> It's just used as a convenient way of passing a HWI to an expander.
>>
>> I'm not saying that it's the ideal interface.  But if we want to change it,
>> let's do that separately, and test it on targets that have doloops.
>> Until then, the wide-int branch can provide the current interface
>> just as easily as mainline.
> we do not have a predicate at the rtl level like we do at the tree level 
> where we can ask if the value can be represented in a mode without 
> loosing any information.   But the proper thing to do here is to check 
> to see if iter fits in the mode, if it does, then generate the 
> immed_wide_int_const and if not generate the 0.   In this way it does 
> the right thing for loops that iterate 1<<GET_MODE_PRECISION (mode), 
> i.e. it will produce a 0.   And that will be correct even if the mode is 
> SI or TI.

Well, like I say, I don't see the current rtx has having a mode,
even conceptually.  The CONST_INT is just a convenient way of passing
an iteration count to a function that only accepts rtxes as arguments.
If we could, we'd be passing the widest_int directly as a pointer or
reference.

But since I'm just repeating what I said above, I should probably bow
out of this one.

Note that the current wide-int code doesn't allow any more cases than
the current mainline code, it just changes their values (and so breaks
the ports that relied on the old values).  So I think we both agree that
the current wide-int code needs to change in some way.  And I'd prefer
to change it to follow the existing interface, rather than (a) combining
a subtle interface change with a big patch and (b) potentially putting
the merge back unnecessarily.

If you and Mike want to change the interface on wide-int first,
and if the maintainers agree that's OK, then I won't object.
But you'll need to test it on ports that have doloops.

Thanks,
Richard



Reply via email to