Skip to content

Commit e976b99

Browse files
martinuygnu-andrew
authored andcommitted
8335713: Enhance vectorization analysis
Reviewed-by: roland, andrew Backport-of: 3c05ad2290936ec9abc3f271cb6bf89e18c3eea7
1 parent c5508ab commit e976b99

File tree

2 files changed

+62
-11
lines changed

2 files changed

+62
-11
lines changed

hotspot/src/share/vm/opto/superword.cpp

Lines changed: 61 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2735,10 +2735,30 @@ bool SWPointer::scaled_iv_plus_offset(Node* n) {
27352735
}
27362736
} else if (opc == Op_SubI) {
27372737
if (scaled_iv(n->in(1)) && offset_plus_k(n->in(2), true)) {
2738+
// (scale * iv) - (offset1 + invar1)
2739+
// Subtraction handled via "negate" flag of "offset_plus_k".
27382740
return true;
27392741
}
2740-
if (scaled_iv(n->in(2)) && offset_plus_k(n->in(1))) {
2741-
_scale *= -1;
2742+
SWPointer tmp(this);
2743+
if (tmp.scaled_iv(n->in(2)) && offset_plus_k(n->in(1))) {
2744+
// (offset1 + invar1) - (scale * iv)
2745+
// Subtraction handled explicitly below.
2746+
assert(_scale == 0, "shouldn't be set yet");
2747+
// _scale = -tmp._scale
2748+
if (!try_MulI_no_overflow(-1, tmp._scale, _scale)) {
2749+
return false; // mul overflow.
2750+
}
2751+
// _offset -= tmp._offset
2752+
if (!try_SubI_no_overflow(_offset, tmp._offset, _offset)) {
2753+
return false; // sub overflow.
2754+
}
2755+
2756+
// SWPointer tmp does not have an integer part to be forwarded
2757+
// (tmp._has_int_index_after_convI2L is false) because n is a SubI, all
2758+
// nodes above must also be of integer type (ConvL2I is not handled
2759+
// to allow a long) and ConvI2L (the only node that can add an integer
2760+
// part) won't be present.
2761+
27422762
return true;
27432763
}
27442764
}
@@ -2766,7 +2786,9 @@ bool SWPointer::scaled_iv(Node* n) {
27662786
}
27672787
} else if (opc == Op_LShiftI) {
27682788
if (n->in(1) == iv() && n->in(2)->is_Con()) {
2769-
_scale = 1 << n->in(2)->get_int();
2789+
if (!try_LShiftI_no_overflow(1, n->in(2)->get_int(), _scale)) {
2790+
return false; // shift overflow.
2791+
}
27702792
return true;
27712793
}
27722794
} else if (opc == Op_ConvI2L && !has_iv()) {
@@ -2792,15 +2814,28 @@ bool SWPointer::scaled_iv(Node* n) {
27922814
if (tmp.scaled_iv_plus_offset(n->in(1)) && tmp.has_iv()) {
27932815
// We successfully matched an integer index, of the form:
27942816
// int_index = int_offset + int_invar + int_scale * iv
2817+
// Forward scale.
2818+
assert(_scale == 0 && tmp._scale != 0, "iv only found just now");
2819+
_scale = tmp._scale;
2820+
// Accumulate offset.
2821+
if (!try_AddI_no_overflow(_offset, tmp._offset, _offset)) {
2822+
return false; // add overflow.
2823+
}
2824+
// Forward invariant if not already found.
2825+
if (tmp._invar != NULL) {
2826+
if (_invar != NULL) {
2827+
return false;
2828+
}
2829+
_invar = tmp._invar;
2830+
_negate_invar = tmp._negate_invar;
2831+
}
2832+
// Set info about the int_index:
2833+
assert(!_has_int_index_after_convI2L, "no previous int_index discovered");
27952834
_has_int_index_after_convI2L = true;
27962835
_int_index_after_convI2L_offset = tmp._offset;
27972836
_int_index_after_convI2L_invar = tmp._invar;
27982837
_int_index_after_convI2L_scale = tmp._scale;
2799-
}
28002838

2801-
// Now parse it again for the real SWPointer. This makes sure that the int_offset, int_invar,
2802-
// and int_scale are properly added to the final SWPointer's offset, invar, and scale.
2803-
if (scaled_iv_plus_offset(n->in(1))) {
28042839
return true;
28052840
}
28062841
} else if (opc == Op_LShiftL) {
@@ -2811,20 +2846,22 @@ bool SWPointer::scaled_iv(Node* n) {
28112846
SWPointer tmp(this);
28122847
if (tmp.scaled_iv_plus_offset(n->in(1))) {
28132848
if (tmp._invar == NULL) {
2814-
int scale = (int)(n->in(2)->get_int());
2815-
int mult = 1 << scale;
2849+
int shift = (int)(n->in(2)->get_int());
28162850
// Accumulate scale.
2817-
_scale = tmp._scale * ((jint)mult);
2851+
if (!try_LShiftI_no_overflow(tmp._scale, shift, _scale)) {
2852+
return false; // shift overflow.
2853+
}
28182854
// Accumulate offset.
28192855
jint shifted_offset = 0;
2820-
if (!try_LShiftI_no_overflow(tmp._offset, scale, shifted_offset)) {
2856+
if (!try_LShiftI_no_overflow(tmp._offset, shift, shifted_offset)) {
28212857
return false; // shift overflow.
28222858
}
28232859
if (!try_AddI_no_overflow(_offset, shifted_offset, _offset)) {
28242860
return false; // add overflow.
28252861
}
28262862

28272863
// Forward info about the int_index:
2864+
assert(!_has_int_index_after_convI2L, "no previous int_index discovered");
28282865
_has_int_index_after_convI2L = tmp._has_int_index_after_convI2L;
28292866
_int_index_after_convI2L_offset = tmp._int_index_after_convI2L_offset;
28302867
_int_index_after_convI2L_invar = tmp._int_index_after_convI2L_invar;
@@ -2933,6 +2970,9 @@ bool SWPointer::try_AddSubI_no_overflow(jint offset1, jint offset2, bool is_sub,
29332970
}
29342971

29352972
bool SWPointer::try_LShiftI_no_overflow(jint offset, int shift, jint& result) {
2973+
if (shift < 0 || shift > 31) {
2974+
return false;
2975+
}
29362976
jlong long_offset = java_shift_left((jlong)(offset), (julong)((jlong)(shift)));
29372977
jint int_offset = java_shift_left( offset, (juint)((jint)(shift)));
29382978
if (long_offset != int_offset) {
@@ -2942,6 +2982,16 @@ bool SWPointer::try_LShiftI_no_overflow(jint offset, int shift, jint& result) {
29422982
return true;
29432983
}
29442984

2985+
bool SWPointer::try_MulI_no_overflow(jint offset1, jint offset2, jint& result) {
2986+
jlong long_offset = java_multiply((jlong)(offset1), (jlong)(offset2));
2987+
jint int_offset = java_multiply( offset1, offset2);
2988+
if (long_offset != int_offset) {
2989+
return false;
2990+
}
2991+
result = int_offset;
2992+
return true;
2993+
}
2994+
29452995
//----------------------------print------------------------
29462996
void SWPointer::print() {
29472997
#ifndef PRODUCT

hotspot/src/share/vm/opto/superword.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -614,6 +614,7 @@ class SWPointer VALUE_OBJ_CLASS_SPEC {
614614
static bool try_SubI_no_overflow(jint offset1, jint offset2, jint& result);
615615
static bool try_AddSubI_no_overflow(jint offset1, jint offset2, bool is_sub, jint& result);
616616
static bool try_LShiftI_no_overflow(jint offset1, int offset2, jint& result);
617+
static bool try_MulI_no_overflow(jint offset1, jint offset2, jint& result);
617618

618619
};
619620

0 commit comments

Comments
 (0)