bounds checking and optimization
Bruce Carneal
bcarneal at gmail.com
Wed Jun 30 15:51:58 UTC 2021
On Wednesday, 30 June 2021 at 11:43:08 UTC, Johan wrote:
> On Wednesday, 30 June 2021 at 01:18:53 UTC, Bruce Carneal wrote:
>>
>> A related question: is there anything preventing the compiler
>> from lifting range checks out of loops and throwing early?
>> For example, on something like:
>>
>> foreach(i, ref dst; c[])
>> dst = a[i] + b[i];
>>
>> could c.length be extracted and asserted as being leq a.length
>> and b.length before we drop in to the loop?
>
> That would be observable behavior change, so not possible.
> Unless the behavior upon out-of-bounds access is defined as UB.
>
So a compiler that could pull bounds checking out of a loop would
need to generate code that would run a potentially shortened loop
and then throw if OOB. Something like:
const __bound = min(a.length, b.length, c.length);
const __throwAtEnd = a.length < __bound || b.length < __bound;
foreach(i, ref dst; c[0..__bound])
dst = a[i] + b[i];
if (__throwAtEnd) { /* throw */ }
The above is ugly enough that I imagine it puts enabling speedy
@safe loops of this type pretty far down on the TODO list.
I now suspect that there may be an easier path to safe data
parallel code: we improve code gen for sequences of operations on
slices (single bounds check at the top of the basic block and
operation fusing to reduce the memory touches).
Thanks for the info.
More information about the digitalmars-d-ldc
mailing list