Skip to content

8353786: Migrate Vector API math library support to FFM API #24462

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 29 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
50210bd
Remove vector math intrinsics
iwanowww Nov 19, 2024
57487c8
Vector math library
iwanowww Nov 20, 2024
a92a2a8
VM intrinsics
iwanowww Nov 21, 2024
714e4d0
VectorMathLib: Migrate to lambdas
iwanowww Nov 21, 2024
02802d0
cleanup
iwanowww Nov 21, 2024
0734e25
SLEEF improvements
iwanowww Nov 21, 2024
def3434
fixes
iwanowww Nov 21, 2024
2efdac9
Update templates
iwanowww Nov 21, 2024
c74739e
SVML fixes
iwanowww Nov 21, 2024
2a7006b
TODO list
iwanowww Nov 22, 2024
70cdd15
Cleanup
iwanowww Mar 31, 2025
0a1bba8
CPU features support
iwanowww Apr 1, 2025
fc27aee
Misc fixes and cleanups
iwanowww Apr 2, 2025
368b943
Reviews and Float64Vector-related fix
iwanowww Apr 7, 2025
9a8f620
features_string -> cpu_info_string
iwanowww Apr 7, 2025
bb1a11d
Fix windows-aarch64 build failure
iwanowww Apr 7, 2025
5e8a499
Merge branch 'master' into vector.math.01.java
iwanowww Apr 10, 2025
22754c8
RVV and SVE adjustments
iwanowww Apr 11, 2025
0ffed12
Merge branch 'master' into vector.math.01.java
iwanowww Apr 11, 2025
84d02cb
Fix debugName handling
iwanowww Apr 16, 2025
a288cbb
Merge branch 'master' into vector.math.01.java
iwanowww Apr 16, 2025
1ade1ff
fix broken merge
iwanowww Apr 17, 2025
e2b762e
RVV and SVE adjustments
iwanowww Apr 17, 2025
88eacc4
Merge remote-tracking branch 'origin/master' into vector.math.01.java
iwanowww Apr 17, 2025
3d1adff
riscv fix
iwanowww Apr 22, 2025
42ed9ba
Avoid thread state transition in VectorSupport_GetCPUFeatures
iwanowww Apr 23, 2025
585312a
CPUFeatures: RISC-V support
iwanowww Apr 23, 2025
541c4d7
Improve comments
iwanowww Apr 24, 2025
f4373e4
Remove UseVectorStubs usage in riscv.ad
iwanowww Apr 25, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/hotspot/cpu/aarch64/aarch64.ad
Original file line number Diff line number Diff line change
Expand Up @@ -2306,11 +2306,11 @@ const RegMask* Matcher::predicate_reg_mask(void) {
}

bool Matcher::supports_vector_calling_convention(void) {
return EnableVectorSupport && UseVectorStubs;
return EnableVectorSupport;
}

OptoRegPair Matcher::vector_return_value(uint ideal_reg) {
assert(EnableVectorSupport && UseVectorStubs, "sanity");
assert(EnableVectorSupport, "sanity");
int lo = V0_num;
int hi = V0_H_num;
if (ideal_reg == Op_VecX || ideal_reg == Op_VecA) {
Expand Down
75 changes: 0 additions & 75 deletions src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11172,79 +11172,6 @@ class StubGenerator: public StubCodeGenerator {
// }
};

void generate_vector_math_stubs() {
// Get native vector math stub routine addresses
void* libsleef = nullptr;
char ebuf[1024];
char dll_name[JVM_MAXPATHLEN];
if (os::dll_locate_lib(dll_name, sizeof(dll_name), Arguments::get_dll_dir(), "sleef")) {
libsleef = os::dll_load(dll_name, ebuf, sizeof ebuf);
}
if (libsleef == nullptr) {
log_info(library)("Failed to load native vector math library, %s!", ebuf);
return;
}
// Method naming convention
// All the methods are named as <OP><T><N>_<U><suffix>
// Where:
// <OP> is the operation name, e.g. sin
// <T> is optional to indicate float/double
// "f/d" for vector float/double operation
// <N> is the number of elements in the vector
// "2/4" for neon, and "x" for sve
// <U> is the precision level
// "u10/u05" represents 1.0/0.5 ULP error bounds
// We use "u10" for all operations by default
// But for those functions do not have u10 support, we use "u05" instead
// <suffix> indicates neon/sve
// "sve/advsimd" for sve/neon implementations
// e.g. sinfx_u10sve is the method for computing vector float sin using SVE instructions
// cosd2_u10advsimd is the method for computing 2 elements vector double cos using NEON instructions
//
log_info(library)("Loaded library %s, handle " INTPTR_FORMAT, JNI_LIB_PREFIX "sleef" JNI_LIB_SUFFIX, p2i(libsleef));

// Math vector stubs implemented with SVE for scalable vector size.
if (UseSVE > 0) {
for (int op = 0; op < VectorSupport::NUM_VECTOR_OP_MATH; op++) {
int vop = VectorSupport::VECTOR_OP_MATH_START + op;
// Skip "tanh" because there is performance regression
if (vop == VectorSupport::VECTOR_OP_TANH) {
continue;
}

// The native library does not support u10 level of "hypot".
const char* ulf = (vop == VectorSupport::VECTOR_OP_HYPOT) ? "u05" : "u10";

snprintf(ebuf, sizeof(ebuf), "%sfx_%ssve", VectorSupport::mathname[op], ulf);
StubRoutines::_vector_f_math[VectorSupport::VEC_SIZE_SCALABLE][op] = (address)os::dll_lookup(libsleef, ebuf);

snprintf(ebuf, sizeof(ebuf), "%sdx_%ssve", VectorSupport::mathname[op], ulf);
StubRoutines::_vector_d_math[VectorSupport::VEC_SIZE_SCALABLE][op] = (address)os::dll_lookup(libsleef, ebuf);
}
}

// Math vector stubs implemented with NEON for 64/128 bits vector size.
for (int op = 0; op < VectorSupport::NUM_VECTOR_OP_MATH; op++) {
int vop = VectorSupport::VECTOR_OP_MATH_START + op;
// Skip "tanh" because there is performance regression
if (vop == VectorSupport::VECTOR_OP_TANH) {
continue;
}

// The native library does not support u10 level of "hypot".
const char* ulf = (vop == VectorSupport::VECTOR_OP_HYPOT) ? "u05" : "u10";

snprintf(ebuf, sizeof(ebuf), "%sf4_%sadvsimd", VectorSupport::mathname[op], ulf);
StubRoutines::_vector_f_math[VectorSupport::VEC_SIZE_64][op] = (address)os::dll_lookup(libsleef, ebuf);

snprintf(ebuf, sizeof(ebuf), "%sf4_%sadvsimd", VectorSupport::mathname[op], ulf);
StubRoutines::_vector_f_math[VectorSupport::VEC_SIZE_128][op] = (address)os::dll_lookup(libsleef, ebuf);

snprintf(ebuf, sizeof(ebuf), "%sd2_%sadvsimd", VectorSupport::mathname[op], ulf);
StubRoutines::_vector_d_math[VectorSupport::VEC_SIZE_128][op] = (address)os::dll_lookup(libsleef, ebuf);
}
}

// Initialization
void generate_initial_stubs() {
// Generate initial stubs and initializes the entry points
Expand Down Expand Up @@ -11398,8 +11325,6 @@ class StubGenerator: public StubCodeGenerator {
StubRoutines::_montgomerySquare = g.generate_multiply();
}

generate_vector_math_stubs();

#endif // COMPILER2

if (UseChaCha20Intrinsics) {
Expand Down
9 changes: 7 additions & 2 deletions src/hotspot/cpu/aarch64/vm_version_aarch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -639,14 +639,19 @@ void VM_Version::initialize() {
if (_model2) {
os::snprintf_checked(buf + buf_used_len, sizeof(buf) - buf_used_len, "(0x%03x)", _model2);
}
size_t features_offset = strnlen(buf, sizeof(buf));
#define ADD_FEATURE_IF_SUPPORTED(id, name, bit) \
do { \
if (VM_Version::supports_##name()) strcat(buf, ", " #name); \
} while(0);
CPU_FEATURE_FLAGS(ADD_FEATURE_IF_SUPPORTED)
#undef ADD_FEATURE_IF_SUPPORTED

_features_string = os::strdup(buf);
_cpu_info_string = os::strdup(buf);

_features_string = extract_features_string(_cpu_info_string,
strnlen(_cpu_info_string, sizeof(buf)),
features_offset);
}

#if defined(LINUX)
Expand Down Expand Up @@ -713,7 +718,7 @@ void VM_Version::initialize_cpu_information(void) {
int desc_len = snprintf(_cpu_desc, CPU_DETAILED_DESC_BUF_SIZE, "AArch64 ");
get_compatible_board(_cpu_desc + desc_len, CPU_DETAILED_DESC_BUF_SIZE - desc_len);
desc_len = (int)strlen(_cpu_desc);
snprintf(_cpu_desc + desc_len, CPU_DETAILED_DESC_BUF_SIZE - desc_len, " %s", _features_string);
snprintf(_cpu_desc + desc_len, CPU_DETAILED_DESC_BUF_SIZE - desc_len, " %s", _cpu_info_string);

_initialized = true;
}
4 changes: 2 additions & 2 deletions src/hotspot/cpu/arm/vm_version_arm_32.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ void VM_Version::initialize() {
(has_multiprocessing_extensions() ? ", mp_ext" : ""));

// buf is started with ", " or is empty
_features_string = os::strdup(buf);
_cpu_info_string = os::strdup(buf);

if (has_simd()) {
if (FLAG_IS_DEFAULT(UsePopCountInstruction)) {
Expand Down Expand Up @@ -363,6 +363,6 @@ void VM_Version::initialize_cpu_information(void) {
_no_of_threads = _no_of_cores;
_no_of_sockets = _no_of_cores;
snprintf(_cpu_name, CPU_TYPE_DESC_BUF_SIZE - 1, "ARM%d", _arm_arch);
snprintf(_cpu_desc, CPU_DETAILED_DESC_BUF_SIZE, "%s", _features_string);
snprintf(_cpu_desc, CPU_DETAILED_DESC_BUF_SIZE, "%s", _cpu_info_string);
_initialized = true;
}
6 changes: 3 additions & 3 deletions src/hotspot/cpu/ppc/vm_version_ppc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ void VM_Version::initialize() {
(has_brw() ? " brw" : "")
// Make sure number of %s matches num_features!
);
_features_string = os::strdup(buf);
_cpu_info_string = os::strdup(buf);
if (Verbose) {
print_features();
}
Expand Down Expand Up @@ -519,7 +519,7 @@ void VM_Version::print_platform_virtualization_info(outputStream* st) {
}

void VM_Version::print_features() {
tty->print_cr("Version: %s L1_data_cache_line_size=%d", features_string(), L1_data_cache_line_size());
tty->print_cr("Version: %s L1_data_cache_line_size=%d", cpu_info_string(), L1_data_cache_line_size());

if (Verbose) {
if (ContendedPaddingWidth > 0) {
Expand Down Expand Up @@ -726,6 +726,6 @@ void VM_Version::initialize_cpu_information(void) {
_no_of_threads = _no_of_cores;
_no_of_sockets = _no_of_cores;
snprintf(_cpu_name, CPU_TYPE_DESC_BUF_SIZE, "PowerPC POWER%lu", PowerArchitecturePPC64);
snprintf(_cpu_desc, CPU_DETAILED_DESC_BUF_SIZE, "PPC %s", features_string());
snprintf(_cpu_desc, CPU_DETAILED_DESC_BUF_SIZE, "PPC %s", cpu_info_string());
_initialized = true;
}
4 changes: 2 additions & 2 deletions src/hotspot/cpu/riscv/riscv.ad
Original file line number Diff line number Diff line change
Expand Up @@ -1944,11 +1944,11 @@ const RegMask* Matcher::predicate_reg_mask(void) {

// Vector calling convention not yet implemented.
bool Matcher::supports_vector_calling_convention(void) {
return EnableVectorSupport && UseVectorStubs;
return EnableVectorSupport;
}

OptoRegPair Matcher::vector_return_value(uint ideal_reg) {
assert(EnableVectorSupport && UseVectorStubs, "sanity");
assert(EnableVectorSupport, "sanity");
assert(ideal_reg == Op_VecA, "sanity");
// check more info at https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-cc.adoc
int lo = V8_num;
Expand Down
54 changes: 0 additions & 54 deletions src/hotspot/cpu/riscv/stubGenerator_riscv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6458,58 +6458,6 @@ static const int64_t right_3_bits = right_n_bits(3);
return start;
}

void generate_vector_math_stubs() {
if (!UseRVV) {
log_info(library)("vector is not supported, skip loading vector math (sleef) library!");
return;
}

// Get native vector math stub routine addresses
void* libsleef = nullptr;
char ebuf[1024];
char dll_name[JVM_MAXPATHLEN];
if (os::dll_locate_lib(dll_name, sizeof(dll_name), Arguments::get_dll_dir(), "sleef")) {
libsleef = os::dll_load(dll_name, ebuf, sizeof ebuf);
}
if (libsleef == nullptr) {
log_info(library)("Failed to load native vector math (sleef) library, %s!", ebuf);
return;
}

// Method naming convention
// All the methods are named as <OP><T>_<U><suffix>
//
// Where:
// <OP> is the operation name, e.g. sin, cos
// <T> is to indicate float/double
// "fx/dx" for vector float/double operation
// <U> is the precision level
// "u10/u05" represents 1.0/0.5 ULP error bounds
// We use "u10" for all operations by default
// But for those functions do not have u10 support, we use "u05" instead
// <suffix> rvv, indicates riscv vector extension
//
// e.g. sinfx_u10rvv is the method for computing vector float sin using rvv instructions
//
log_info(library)("Loaded library %s, handle " INTPTR_FORMAT, JNI_LIB_PREFIX "sleef" JNI_LIB_SUFFIX, p2i(libsleef));

for (int op = 0; op < VectorSupport::NUM_VECTOR_OP_MATH; op++) {
int vop = VectorSupport::VECTOR_OP_MATH_START + op;
if (vop == VectorSupport::VECTOR_OP_TANH) { // skip tanh because of performance regression
continue;
}

// The native library does not support u10 level of "hypot".
const char* ulf = (vop == VectorSupport::VECTOR_OP_HYPOT) ? "u05" : "u10";

snprintf(ebuf, sizeof(ebuf), "%sfx_%srvv", VectorSupport::mathname[op], ulf);
StubRoutines::_vector_f_math[VectorSupport::VEC_SIZE_SCALABLE][op] = (address)os::dll_lookup(libsleef, ebuf);

snprintf(ebuf, sizeof(ebuf), "%sdx_%srvv", VectorSupport::mathname[op], ulf);
StubRoutines::_vector_d_math[VectorSupport::VEC_SIZE_SCALABLE][op] = (address)os::dll_lookup(libsleef, ebuf);
}
}

#endif // COMPILER2

/**
Expand Down Expand Up @@ -6741,8 +6689,6 @@ static const int64_t right_3_bits = right_n_bits(3);

generate_string_indexof_stubs();

generate_vector_math_stubs();

#endif // COMPILER2
}

Expand Down
2 changes: 1 addition & 1 deletion src/hotspot/cpu/riscv/vm_version_riscv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,7 @@ void VM_Version::initialize_cpu_information(void) {
_no_of_threads = _no_of_cores;
_no_of_sockets = _no_of_cores;
snprintf(_cpu_name, CPU_TYPE_DESC_BUF_SIZE - 1, "RISCV64");
snprintf(_cpu_desc, CPU_DETAILED_DESC_BUF_SIZE, "RISCV64 %s", features_string());
snprintf(_cpu_desc, CPU_DETAILED_DESC_BUF_SIZE, "RISCV64 %s", cpu_info_string());
_initialized = true;
}

Expand Down
32 changes: 16 additions & 16 deletions src/hotspot/cpu/s390/vm_version_s390.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ static const char* z_features[] = {" ",

void VM_Version::initialize() {
determine_features(); // Get processor capabilities.
set_features_string(); // Set a descriptive feature indication.
set_cpu_info_string(); // Set a descriptive feature indication.

if (Verbose || PrintAssembly || PrintStubCode) {
print_features_internal("CPU Version as detected internally:", PrintAssembly || PrintStubCode);
Expand Down Expand Up @@ -388,9 +388,9 @@ int VM_Version::get_model_index() {
}


void VM_Version::set_features_string() {
// A note on the _features_string format:
// There are jtreg tests checking the _features_string for various properties.
void VM_Version::set_cpu_info_string() {
// A note on the _cpu_info_string format:
// There are jtreg tests checking the _cpu_info_string for various properties.
// For some strange reason, these tests require the string to contain
// only _lowercase_ characters. Keep that in mind when being surprised
// about the unusual notation of features - and when adding new ones.
Expand All @@ -412,29 +412,29 @@ void VM_Version::set_features_string() {
_model_string = "unknown model";
strcpy(buf, "z/Architecture (ambiguous detection)");
}
_features_string = os::strdup(buf);
_cpu_info_string = os::strdup(buf);

if (has_Crypto_AES()) {
assert(strlen(_features_string) + 3*8 < sizeof(buf), "increase buffer size");
assert(strlen(_cpu_info_string) + 3*8 < sizeof(buf), "increase buffer size");
jio_snprintf(buf, sizeof(buf), "%s%s%s%s",
_features_string,
_cpu_info_string,
has_Crypto_AES128() ? ", aes128" : "",
has_Crypto_AES192() ? ", aes192" : "",
has_Crypto_AES256() ? ", aes256" : "");
os::free((void *)_features_string);
_features_string = os::strdup(buf);
os::free((void *)_cpu_info_string);
_cpu_info_string = os::strdup(buf);
}

if (has_Crypto_SHA()) {
assert(strlen(_features_string) + 6 + 2*8 + 7 < sizeof(buf), "increase buffer size");
assert(strlen(_cpu_info_string) + 6 + 2*8 + 7 < sizeof(buf), "increase buffer size");
jio_snprintf(buf, sizeof(buf), "%s%s%s%s%s",
_features_string,
_cpu_info_string,
has_Crypto_SHA1() ? ", sha1" : "",
has_Crypto_SHA256() ? ", sha256" : "",
has_Crypto_SHA512() ? ", sha512" : "",
has_Crypto_GHASH() ? ", ghash" : "");
os::free((void *)_features_string);
_features_string = os::strdup(buf);
os::free((void *)_cpu_info_string);
_cpu_info_string = os::strdup(buf);
}
}

Expand Down Expand Up @@ -464,7 +464,7 @@ bool VM_Version::test_feature_bit(unsigned long* featureBuffer, int featureNum,
}

void VM_Version::print_features_internal(const char* text, bool print_anyway) {
tty->print_cr("%s %s", text, features_string());
tty->print_cr("%s %s", text, cpu_info_string());
tty->cr();

if (Verbose || print_anyway) {
Expand Down Expand Up @@ -906,7 +906,7 @@ void VM_Version::set_features_from(const char* march) {
err = true;
}
if (!err) {
set_features_string();
set_cpu_info_string();
if (prt || PrintAssembly) {
print_features_internal("CPU Version as set by cmdline option:", prt);
}
Expand Down Expand Up @@ -1542,6 +1542,6 @@ void VM_Version::initialize_cpu_information(void) {
_no_of_threads = _no_of_cores;
_no_of_sockets = _no_of_cores;
snprintf(_cpu_name, CPU_TYPE_DESC_BUF_SIZE, "s390 %s", VM_Version::get_model_string());
snprintf(_cpu_desc, CPU_DETAILED_DESC_BUF_SIZE, "s390 %s", features_string());
snprintf(_cpu_desc, CPU_DETAILED_DESC_BUF_SIZE, "s390 %s", cpu_info_string());
_initialized = true;
}
2 changes: 1 addition & 1 deletion src/hotspot/cpu/s390/vm_version_s390.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ class VM_Version: public Abstract_VM_Version {

static bool test_feature_bit(unsigned long* featureBuffer, int featureNum, unsigned int bufLen);
static int get_model_index();
static void set_features_string();
static void set_cpu_info_string();
static void print_features_internal(const char* text, bool print_anyway=false);
static void determine_features();
static long call_getFeatures(unsigned long* buffer, int buflen, int functionCode);
Expand Down
Loading