Skip to content

Commit c5723c0

Browse files
rwestrelRealCLanger
authored andcommitted
8314307: Improve loop handling
Reviewed-by: mbalao, fferrari Backport-of: ed1269b7410759e8fa0d97d85328f20d11ae8d9a
1 parent a0b9d41 commit c5723c0

File tree

3 files changed

+330
-82
lines changed

3 files changed

+330
-82
lines changed

src/hotspot/share/opto/ifnode.cpp

Lines changed: 52 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1864,6 +1864,46 @@ Node* RangeCheckNode::Ideal(PhaseGVN *phase, bool can_reshape) {
18641864
// then we are guaranteed to fail, so just start interpreting there.
18651865
// We 'expand' the top 3 range checks to include all post-dominating
18661866
// checks.
1867+
//
1868+
// Example:
1869+
// a[i+x] // (1) 1 < x < 6
1870+
// a[i+3] // (2)
1871+
// a[i+4] // (3)
1872+
// a[i+6] // max = max of all constants
1873+
// a[i+2]
1874+
// a[i+1] // min = min of all constants
1875+
//
1876+
// If x < 3:
1877+
// (1) a[i+x]: Leave unchanged
1878+
// (2) a[i+3]: Replace with a[i+max] = a[i+6]: i+x < i+3 <= i+6 -> (2) is covered
1879+
// (3) a[i+4]: Replace with a[i+min] = a[i+1]: i+1 < i+4 <= i+6 -> (3) and all following checks are covered
1880+
// Remove all other a[i+c] checks
1881+
//
1882+
// If x >= 3:
1883+
// (1) a[i+x]: Leave unchanged
1884+
// (2) a[i+3]: Replace with a[i+min] = a[i+1]: i+1 < i+3 <= i+x -> (2) is covered
1885+
// (3) a[i+4]: Replace with a[i+max] = a[i+6]: i+1 < i+4 <= i+6 -> (3) and all following checks are covered
1886+
// Remove all other a[i+c] checks
1887+
//
1888+
// We only need the top 2 range checks if x is the min or max of all constants.
1889+
//
1890+
// This, however, only works if the interval [i+min,i+max] is not larger than max_int (i.e. abs(max - min) < max_int):
1891+
// The theoretical max size of an array is max_int with:
1892+
// - Valid index space: [0,max_int-1]
1893+
// - Invalid index space: [max_int,-1] // max_int, min_int, min_int - 1 ..., -1
1894+
//
1895+
// The size of the consecutive valid index space is smaller than the size of the consecutive invalid index space.
1896+
// If we choose min and max in such a way that:
1897+
// - abs(max - min) < max_int
1898+
// - i+max and i+min are inside the valid index space
1899+
// then all indices [i+min,i+max] must be in the valid index space. Otherwise, the invalid index space must be
1900+
// smaller than the valid index space which is never the case for any array size.
1901+
//
1902+
// Choosing a smaller array size only makes the valid index space smaller and the invalid index space larger and
1903+
// the argument above still holds.
1904+
//
1905+
// Note that the same optimization with the same maximal accepted interval size can also be found in C1.
1906+
const jlong maximum_number_of_min_max_interval_indices = (jlong)max_jint;
18671907

18681908
// The top 3 range checks seen
18691909
const int NRC = 3;
@@ -1898,13 +1938,18 @@ Node* RangeCheckNode::Ideal(PhaseGVN *phase, bool can_reshape) {
18981938
found_immediate_dominator = true;
18991939
break;
19001940
}
1901-
// Gather expanded bounds
1902-
off_lo = MIN2(off_lo,offset2);
1903-
off_hi = MAX2(off_hi,offset2);
1904-
// Record top NRC range checks
1905-
prev_checks[nb_checks%NRC].ctl = prev_dom;
1906-
prev_checks[nb_checks%NRC].off = offset2;
1907-
nb_checks++;
1941+
1942+
// "x - y" -> must add one to the difference for number of elements in [x,y]
1943+
const jlong diff = (jlong)MIN2(offset2, off_lo) - (jlong)MAX2(offset2, off_hi);
1944+
if (ABS(diff) < maximum_number_of_min_max_interval_indices) {
1945+
// Gather expanded bounds
1946+
off_lo = MIN2(off_lo, offset2);
1947+
off_hi = MAX2(off_hi, offset2);
1948+
// Record top NRC range checks
1949+
prev_checks[nb_checks % NRC].ctl = prev_dom;
1950+
prev_checks[nb_checks % NRC].off = offset2;
1951+
nb_checks++;
1952+
}
19081953
}
19091954
}
19101955
prev_dom = dom;

0 commit comments

Comments
 (0)