Skip to content
Draft
Show file tree
Hide file tree
Changes from 17 commits
Commits
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
1 change: 0 additions & 1 deletion src/hotspot/share/c1/c1_Canonicalizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -842,7 +842,6 @@ void Canonicalizer::do_OsrEntry (OsrEntry* x) {}
void Canonicalizer::do_ExceptionObject(ExceptionObject* x) {}
void Canonicalizer::do_UnsafeGet (UnsafeGet* x) {}
void Canonicalizer::do_UnsafePut (UnsafePut* x) {}
void Canonicalizer::do_UnsafeGetAndSet(UnsafeGetAndSet* x) {}
void Canonicalizer::do_ProfileCall (ProfileCall* x) {}
void Canonicalizer::do_ProfileReturnType(ProfileReturnType* x) {}
void Canonicalizer::do_ProfileInvoke (ProfileInvoke* x) {}
Expand Down
1 change: 0 additions & 1 deletion src/hotspot/share/c1/c1_Canonicalizer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,6 @@ class Canonicalizer: InstructionVisitor {
virtual void do_ExceptionObject(ExceptionObject* x);
virtual void do_UnsafeGet (UnsafeGet* x);
virtual void do_UnsafePut (UnsafePut* x);
virtual void do_UnsafeGetAndSet(UnsafeGetAndSet* x);
virtual void do_ProfileCall (ProfileCall* x);
virtual void do_ProfileReturnType (ProfileReturnType* x);
virtual void do_ProfileInvoke (ProfileInvoke* x);
Expand Down
134 changes: 63 additions & 71 deletions src/hotspot/share/c1/c1_Compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,34 +96,26 @@ BufferBlob* Compiler::init_buffer_blob() {
return buffer_blob;
}

bool Compiler::is_intrinsic_supported(const methodHandle& method) {
vmIntrinsics::ID id = method->intrinsic_id();
assert(id != vmIntrinsics::_none, "must be a VM intrinsic");

if (method->is_synchronized()) {
// C1 does not support intrinsification of synchronized methods.
return false;
}
return Compiler::is_intrinsic_supported(id);
}

bool Compiler::is_intrinsic_supported(vmIntrinsics::ID id) {
bool Compiler::is_intrinsic_supported_nv(vmIntrinsics::ID id) {
switch (id) {
case vmIntrinsics::_compareAndSetLong:
break;
case vmIntrinsics::_getAndAddInt:
if (!VM_Version::supports_atomic_getadd4()) return false;
break;
case vmIntrinsics::_getAndAddLong:
if (!VM_Version::supports_atomic_getadd8()) return false;
break;
case vmIntrinsics::_getAndSetInt:
if (!VM_Version::supports_atomic_getset4()) return false;
case vmIntrinsics::_compareAndExchangeReferenceMO:
case vmIntrinsics::_compareAndExchangePrimitiveBitsMO:
// FIXME: Most platforms support full cmpxchg in all sizes.
return false;
case vmIntrinsics::_compareAndSetPrimitiveBitsMO:
case vmIntrinsics::_compareAndSetReferenceMO:
// all platforms must support at least T_OBJECT, T_INT, T_LONG
break;
case vmIntrinsics::_getAndSetLong:
if (!VM_Version::supports_atomic_getset8()) return false;
case vmIntrinsics::_getAndOperatePrimitiveBitsMO:
if (!(VM_Version::supports_atomic_getadd4() ||
VM_Version::supports_atomic_getadd8() ||
VM_Version::supports_atomic_getset4() ||
VM_Version::supports_atomic_getset8())) {
// if any of the hardware ops are present, try the expansion
return false;
}
break;
case vmIntrinsics::_getAndSetReference:
case vmIntrinsics::_getAndSetReferenceMO:
#ifdef _LP64
if (!UseCompressedOops && !VM_Version::supports_atomic_getset8()) return false;
if (UseCompressedOops && !VM_Version::supports_atomic_getset4()) return false;
Expand Down Expand Up @@ -176,50 +168,10 @@ bool Compiler::is_intrinsic_supported(vmIntrinsics::ID id) {
case vmIntrinsics::_dpow:
case vmIntrinsics::_fmaD:
case vmIntrinsics::_fmaF:
case vmIntrinsics::_getReference:
case vmIntrinsics::_getBoolean:
case vmIntrinsics::_getByte:
case vmIntrinsics::_getShort:
case vmIntrinsics::_getChar:
case vmIntrinsics::_getInt:
case vmIntrinsics::_getLong:
case vmIntrinsics::_getFloat:
case vmIntrinsics::_getDouble:
case vmIntrinsics::_putReference:
case vmIntrinsics::_putBoolean:
case vmIntrinsics::_putByte:
case vmIntrinsics::_putShort:
case vmIntrinsics::_putChar:
case vmIntrinsics::_putInt:
case vmIntrinsics::_putLong:
case vmIntrinsics::_putFloat:
case vmIntrinsics::_putDouble:
case vmIntrinsics::_getReferenceVolatile:
case vmIntrinsics::_getBooleanVolatile:
case vmIntrinsics::_getByteVolatile:
case vmIntrinsics::_getShortVolatile:
case vmIntrinsics::_getCharVolatile:
case vmIntrinsics::_getIntVolatile:
case vmIntrinsics::_getLongVolatile:
case vmIntrinsics::_getFloatVolatile:
case vmIntrinsics::_getDoubleVolatile:
case vmIntrinsics::_putReferenceVolatile:
case vmIntrinsics::_putBooleanVolatile:
case vmIntrinsics::_putByteVolatile:
case vmIntrinsics::_putShortVolatile:
case vmIntrinsics::_putCharVolatile:
case vmIntrinsics::_putIntVolatile:
case vmIntrinsics::_putLongVolatile:
case vmIntrinsics::_putFloatVolatile:
case vmIntrinsics::_putDoubleVolatile:
case vmIntrinsics::_getShortUnaligned:
case vmIntrinsics::_getCharUnaligned:
case vmIntrinsics::_getIntUnaligned:
case vmIntrinsics::_getLongUnaligned:
case vmIntrinsics::_putShortUnaligned:
case vmIntrinsics::_putCharUnaligned:
case vmIntrinsics::_putIntUnaligned:
case vmIntrinsics::_putLongUnaligned:
case vmIntrinsics::_getPrimitiveBitsMO:
case vmIntrinsics::_putPrimitiveBitsMO:
case vmIntrinsics::_getReferenceMO:
case vmIntrinsics::_putReferenceMO:
case vmIntrinsics::_Preconditions_checkIndex:
case vmIntrinsics::_Preconditions_checkLongIndex:
case vmIntrinsics::_updateCRC32:
Expand All @@ -230,8 +182,6 @@ bool Compiler::is_intrinsic_supported(vmIntrinsics::ID id) {
case vmIntrinsics::_updateDirectByteBufferCRC32C:
#endif
case vmIntrinsics::_vectorizedMismatch:
case vmIntrinsics::_compareAndSetInt:
case vmIntrinsics::_compareAndSetReference:
case vmIntrinsics::_getCharStringU:
case vmIntrinsics::_putCharStringU:
#ifdef JFR_HAVE_INTRINSICS
Expand All @@ -250,6 +200,48 @@ bool Compiler::is_intrinsic_supported(vmIntrinsics::ID id) {

return true;
}
bool Compiler::is_intrinsic_supported_nv(vmIntrinsics::ID id,
vmIntrinsics::MemoryOrder mo,
BasicType bt,
vmIntrinsics::BitsOperation op) {
assert(vmIntrinsics::polymorphic_prefix(id) != vmIntrinsics::PP_NONE, "");
if (!is_intrinsic_supported_nv(id)) return false;
switch (id) {
case vmIntrinsics::_compareAndSetReferenceMO:
assert(bt == T_OBJECT, ""); // and fall through
case vmIntrinsics::_compareAndSetPrimitiveBitsMO:
if (bt == T_INT || bt == T_LONG || bt == T_OBJECT) {
return true;
}
// FIXME: detect other combinations supported by platform
return false;

case vmIntrinsics::_getAndSetReferenceMO:
assert(bt == T_OBJECT, "");
assert(op == vmIntrinsics::OP_NONE, "");
op = vmIntrinsics::OP_SWAP;
// and fall through
case vmIntrinsics::_getAndOperatePrimitiveBitsMO:
switch (op) {
case vmIntrinsics::OP_ADD:
if (bt == T_INT && !VM_Version::supports_atomic_getadd4()) return false;
if (bt == T_LONG && !VM_Version::supports_atomic_getadd8()) return false;
break;
case vmIntrinsics::OP_SWAP:
if (bt == T_INT && !VM_Version::supports_atomic_getset4()) return false;
if (bt == T_LONG && !VM_Version::supports_atomic_getset8()) return false;
break;
default:
return false;
}
// FIXME: Most platforms (including arm64 and x64) support byte
// and short as well, and with all the bitwise combination ops.
return (bt == T_INT || bt == T_LONG || bt == T_OBJECT);
default:
break;
}
return true;
}

void Compiler::compile_method(ciEnv* env, ciMethod* method, int entry_bci, bool install_code, DirectiveSet* directive) {
BufferBlob* buffer_blob = CompilerThread::current()->get_buffer_blob();
Expand Down
22 changes: 18 additions & 4 deletions src/hotspot/share/c1/c1_Compiler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,25 @@ class Compiler: public AbstractCompiler {
// Print compilation timers and statistics
virtual void print_timers();

// Check if the C1 compiler supports an intrinsic for 'method'.
virtual bool is_intrinsic_supported(const methodHandle& method);
// Check if the C1 compiler supports an intrinsic.
// Return true if the intrinsic `id` is supported.
virtual bool is_intrinsic_supported(vmIntrinsics::ID id) {
return is_intrinsic_supported_nv(id);
}
// Fine-grained query about polymorphic intrinsics,
// applicable only to an intrinsic with a polymorphic prefix.
virtual bool is_intrinsic_supported(vmIntrinsics::ID id,
vmIntrinsics::MemoryOrder mo,
BasicType bt = T_OBJECT,
vmIntrinsics::BitsOperation op = vmIntrinsics::OP_NONE) {
return is_intrinsic_supported_nv(id, mo, bt, op);
}

// Return true if the intrinsic `id` is supported by C1
static bool is_intrinsic_supported(vmIntrinsics::ID id);
static bool is_intrinsic_supported_nv(vmIntrinsics::ID id);
static bool is_intrinsic_supported_nv(vmIntrinsics::ID id,
vmIntrinsics::MemoryOrder mo,
BasicType bt,
vmIntrinsics::BitsOperation op);

// Size of the code buffer
static uint code_buffer_size();
Expand Down
Loading