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