RFR(L): 8203197: C2: consider all paths in loop body for loop predication

Vladimir Kozlov vladimir.kozlov at oracle.com
Mon Jun 11 21:05:10 UTC 2018


On 6/11/18 6:03 AM, Roland Westrelin wrote:
> 
> Hi Vladimir,
> 
>>> With this:
>>>
>>> while() {
>>>     if (!null_check1) unc(null_check);
>>>     if (!range_check1) unc(range_check);
>>>     ...
>>>     if (some_condition) { // both branches profiled taken
>>>       if (!null_check2) unc(null_check);
>>>       if (!range_check2) unc(range_check);
>>>       ...
>>>     }
>>>     if (!null_check3) unc(null_check);
>>>     if (!range_check3) unc(range_check);
>>> }
>>
>> In this example what will happen if *_check1 and *_check3 are moved from
>> loop first (they are regular predicates). And then you found that
>> "profiling" *_check2 can be moved. How you enforce order in such case?
> 
> Predicates *_check1 and *_check3 are executed first because they are
> part of the regular predicates block. Then only *_check2 are executed
> because they're part of the profiling predicates block which is
> after. My understanding is that it doesn't matter whether predicates are
> executed in the same order they would be in the loop body because they
> have no side effect anyway.

Got it.

> 
> Order of predicates matter in cases like:
> 
> while() {
>    if (object == null) unc(null_check);
>    value = object.field;
>    if (value == null) unc(null_check);
>    result += value.field;
> }
> 
> Once they are out of loop, if (object == null) .. must be before if
> (value == null) .. because the first check causes the object.field load
> to be becomes loop independent and the second check depends on the
> object.field load. So order matters, because there's a data dependence
> between the 2 checks.

So if there is dependency like this, the second check will stay in loop 
because it depends on values in loop. Okay.

> 
>> No I was asking about this case when you have "profiling" case:
>>
>> while() {
>>     if (some_condition) { // both branches profiled taken
>>       if (!null_check) unc(null_check);
>>       if (!range_check) unc(range_check);
>>       break;
>>     }
>>     ...
>> }
>>
>> Should you take special care in such case because such checks only
>> executed on exit?
> 
> Both checks are not in the loop. If we walk through the loop body from
> the tail to the head we shouldn't encounter them, right?

Right. I forgot that you scan checks from loop exit up.

Thanks you for answering all my questions. Reviewed.

Vladimir

> 
> Roland.
> 


More information about the hotspot-compiler-dev mailing list