Skip to content
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

Add zNext support #20507

Merged
merged 6 commits into from
Jan 30, 2025
Merged
Show file tree
Hide file tree
Changes from all 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: 1 addition & 0 deletions runtime/cmake/caches/common.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -216,3 +216,4 @@ set(J9VM_THR_LOCK_RESERVATION ON CACHE BOOL "")
set(J9VM_THR_PREEMPTIVE ON CACHE BOOL "")
set(J9VM_THR_SMART_DEFLATION ON CACHE BOOL "")
set(J9VM_OPT_OPENJDK_FFI ON CACHE BOOL "")
set(J9VM_JIT_EMULATE_ZNEXT OFF CACHE BOOL "Enable ZNext emulation")
10 changes: 10 additions & 0 deletions runtime/compiler/codegen/J9RecognizedMethodsEnum.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,8 @@
java_lang_Integer_reverseBytes,
java_lang_Integer_rotateLeft,
java_lang_Integer_rotateRight,
java_lang_Integer_compress,
java_lang_Integer_expand,
java_lang_Integer_valueOf,
java_lang_Integer_toUnsignedLong,
java_lang_Integer_stringSize,
Expand All @@ -544,6 +546,8 @@
java_lang_Long_reverseBytes,
java_lang_Long_rotateLeft,
java_lang_Long_rotateRight,
java_lang_Long_compress,
java_lang_Long_expand,
java_lang_Short_reverseBytes,
java_lang_Long_stringSize,
java_lang_Long_toString,
Expand Down Expand Up @@ -720,6 +724,12 @@
com_ibm_dataaccess_PackedDecimal_movePackedDecimal_,
com_ibm_dataaccess_PackedDecimal_checkPackedDecimal_,

// wrapper methods
com_ibm_dataaccess_ExternalDecimal_checkExternalDecimal,

//inline methods
com_ibm_dataaccess_ExternalDecimal_checkExternalDecimal_,

com_ibm_Compiler_Internal__TR_Prefetch,

com_ibm_Compiler_Internal_Quad_enableQuadOptimization,
Expand Down
6 changes: 6 additions & 0 deletions runtime/compiler/codegen/J9TreeEvaluator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@
#include "runtime/J9ValueProfiler.hpp"
#include "util_api.h"

TR::Register*
J9::TreeEvaluator::zdchkEvaluator(TR::Node *node, TR::CodeGenerator *cg)
{
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
}

TR::Register*
J9::TreeEvaluator::zdloadEvaluator(TR::Node *node, TR::CodeGenerator *cg)
{
Expand Down
1 change: 1 addition & 0 deletions runtime/compiler/codegen/J9TreeEvaluator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ class OMR_EXTENSIBLE TreeEvaluator: public OMR::TreeEvaluatorConnector
float frequency;
};

static TR::Register *zdchkEvaluator(TR::Node *node, TR::CodeGenerator *cg);
static TR::Register *zdloadEvaluator(TR::Node *node, TR::CodeGenerator *cg);
static TR::Register *zdloadiEvaluator(TR::Node *node, TR::CodeGenerator *cg);
static TR::Register *zdstoreEvaluator(TR::Node *node, TR::CodeGenerator *cg);
Expand Down
31 changes: 29 additions & 2 deletions runtime/compiler/env/j9method.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2617,6 +2617,14 @@ void TR_ResolvedJ9Method::construct()
{TR::unknownMethod}
};

static X DataAccessExternalDecimalMethods[] =
{
{x(TR::com_ibm_dataaccess_ExternalDecimal_checkExternalDecimal , "checkExternalDecimal" , "([BIIII)I")},
{x(TR::com_ibm_dataaccess_ExternalDecimal_checkExternalDecimal_, "checkExternalDecimal_", "([BIIII)I")},

{TR::unknownMethod}
};


static X BigDecimalMethods[] =
{
Expand Down Expand Up @@ -3314,6 +3322,8 @@ void TR_ResolvedJ9Method::construct()
{x(TR::java_lang_Integer_reverseBytes, "reverseBytes", "(I)I")},
{x(TR::java_lang_Integer_rotateLeft, "rotateLeft", "(II)I")},
{x(TR::java_lang_Integer_rotateRight, "rotateRight", "(II)I")},
{x(TR::java_lang_Integer_compress, "compress", "(II)I")},
{x(TR::java_lang_Integer_expand, "expand", "(II)I")},
{x(TR::java_lang_Integer_valueOf, "valueOf", "(I)Ljava/lang/Integer;")},
{ TR::java_lang_Integer_init, 6, "<init>", (int16_t)-1, "*"},
{x(TR::java_lang_Integer_toUnsignedLong, "toUnsignedLong", "(I)J")},
Expand All @@ -3335,6 +3345,8 @@ void TR_ResolvedJ9Method::construct()
{x(TR::java_lang_Long_reverseBytes, "reverseBytes", "(J)J")},
{x(TR::java_lang_Long_rotateLeft, "rotateLeft", "(JI)J")},
{x(TR::java_lang_Long_rotateRight, "rotateRight", "(JI)J")},
{x(TR::java_lang_Long_compress, "compress", "(JJ)J")},
{x(TR::java_lang_Long_expand, "expand", "(JJ)J")},
{ TR::java_lang_Long_init, 6, "<init>", (int16_t)-1, "*"},
{x(TR::java_lang_Long_stringSize, "stringSize", "(J)I") },
{x(TR::java_lang_Long_toString, "toString", "(J)Ljava/lang/String;") },
Expand Down Expand Up @@ -4287,6 +4299,7 @@ void TR_ResolvedJ9Method::construct()
{ "java/util/Hashtable$HashEnumerator", HashtableHashEnumeratorMethods },
{ "com/ibm/Compiler/Internal/Prefetch", PrefetchMethods },
{ "java/lang/invoke/VarHandleInternal", VarHandleMethods },
{ "com/ibm/dataaccess/ExternalDecimal", DataAccessExternalDecimalMethods },
{ 0 }
};

Expand Down Expand Up @@ -9822,10 +9835,17 @@ TR_ResolvedJ9Method::isFieldFlattened(TR::Compilation *comp, int32_t cpIndex, bo
return vmThread->javaVM->internalVMFunctions->isFlattenableFieldFlattened(reinterpret_cast<J9Class *>(containingClass), fieldShape);
}

bool
TR_ResolvedJ9Method::isDAAExternalDecimalWrapperMethod()
{
// DAA External Decimal check method
return (this->TR_ResolvedMethod::getRecognizedMethod() == TR::com_ibm_dataaccess_ExternalDecimal_checkExternalDecimal);
}

bool
TR_ResolvedJ9Method::isDAAWrapperMethod()
{
return isDAAMarshallingWrapperMethod() || isDAAPackedDecimalWrapperMethod();
return isDAAMarshallingWrapperMethod() || isDAAPackedDecimalWrapperMethod() || isDAAExternalDecimalWrapperMethod();
}

bool
Expand Down Expand Up @@ -9966,10 +9986,17 @@ TR_ResolvedJ9Method::isDAAPackedDecimalWrapperMethod()
return false;
}

bool
TR_ResolvedJ9Method::isDAAExternalDecimalIntrinsicMethod()
{
// DAA External Decimal check method
return (this->TR_ResolvedMethod::getRecognizedMethod() == TR::com_ibm_dataaccess_ExternalDecimal_checkExternalDecimal_);
}

bool
TR_ResolvedJ9Method::isDAAIntrinsicMethod()
{
return isDAAMarshallingIntrinsicMethod() || isDAAPackedDecimalIntrinsicMethod();
return isDAAMarshallingIntrinsicMethod() || isDAAPackedDecimalIntrinsicMethod() || isDAAExternalDecimalIntrinsicMethod();
}

bool
Expand Down
2 changes: 2 additions & 0 deletions runtime/compiler/env/j9method.h
Original file line number Diff line number Diff line change
Expand Up @@ -471,9 +471,11 @@ class TR_ResolvedJ9Method : public TR_J9Method, public TR_ResolvedJ9MethodBase
bool isDAAWrapperMethod();
bool isDAAMarshallingWrapperMethod();
bool isDAAPackedDecimalWrapperMethod();
bool isDAAExternalDecimalWrapperMethod();
bool isDAAIntrinsicMethod();
bool isDAAMarshallingIntrinsicMethod();
bool isDAAPackedDecimalIntrinsicMethod();
bool isDAAExternalDecimalIntrinsicMethod();

protected:
TR_ResolvedMethod * aotMaskResolvedPossiblyPrivateVirtualMethod(TR::Compilation *comp, TR_ResolvedMethod *method);
Expand Down
2 changes: 1 addition & 1 deletion runtime/compiler/il/ILOpCodesEnum.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
#include "compiler/il/OMRILOpCodesEnum.hpp"

FirstJ9Op = LastScalarOMROp + 1,
LastJ9Op = BCDCHK,
LastJ9Op = zdchk,
FirstTROp = FirstOMROp,
LastTROp = LastJ9Op,

Expand Down
16 changes: 16 additions & 0 deletions runtime/compiler/il/Opcodes.enum
Original file line number Diff line number Diff line change
Expand Up @@ -1542,3 +1542,19 @@ OPCODE_MACRO(\
/* .ifCompareOpCode = */ TR::BadILOp, \
/* .description = */ \
)
OPCODE_MACRO(\
/* .opcode = */ zdchk, \
/* .name = */ "zdchk", \
/* .properties1 = */ 0, \
/* .properties2 = */ ILProp2::ValueNumberShare | ILProp2::SupportedForPRE, \
/* .properties3 = */ 0, \
/* .properties4 = */ ILProp4::BinaryCodedDecimalOp, \
/* .dataType = */ TR::Int32, \
/* .typeProperties = */ ILTypeProp::Size_4 | ILTypeProp::Integer, \
/* .childProperties = */ TWO_CHILD(TR::ZonedDecimal, TR::Int8), \
/* .swapChildrenOpCode = */ TR::BadILOp, \
/* .reverseBranchOpCode = */ TR::BadILOp, \
/* .booleanCompareOpCode = */ TR::BadILOp, \
/* .ifCompareOpCode = */ TR::BadILOp, \
/* .description = zoned decimal validity checking */ \
)
2 changes: 2 additions & 0 deletions runtime/compiler/ilgen/Walker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4190,6 +4190,8 @@ break
DAA_PRINT(TR::com_ibm_dataaccess_PackedDecimal_shiftRightPackedDecimal);
DAA_PRINT(TR::com_ibm_dataaccess_PackedDecimal_movePackedDecimal);

DAA_PRINT(TR::com_ibm_dataaccess_ExternalDecimal_checkExternalDecimal);

default:
break;
}
Expand Down
101 changes: 101 additions & 0 deletions runtime/compiler/optimizer/DataAccessAccelerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,14 @@ int32_t TR_DataAccessAccelerator::performOnBlock(TR::Block* block, TreeTopContai
++result;
}
break;
// DAA External Decimal Check
case TR::com_ibm_dataaccess_ExternalDecimal_checkExternalDecimal_:
if (comp()->target().cpu.supportsFeature(OMR_FEATURE_S390_VECTOR_PACKED_DECIMAL_ENHANCEMENT_FACILITY_3)
&& inlineCheckExternalDecimal(treeTop, callNode))
{
++result;
}
break;

default:
matched = false;
Expand Down Expand Up @@ -846,6 +854,99 @@ bool TR_DataAccessAccelerator::inlineCheckPackedDecimal(TR::TreeTop *callTreeTop
return false;
}

bool TR_DataAccessAccelerator::inlineCheckExternalDecimal(TR::TreeTop *callTreeTop, TR::Node *callNode)
{
TR::Node *byteArrayNode = callNode->getChild(0);
TR::Node *offsetNode = callNode->getChild(1);
TR::Node *precisionNode = callNode->getChild(2);
TR::Node *typeNode = callNode->getChild(3);
TR::Node *bytesWithSpacesNode = callNode->getChild(4);

int32_t precision = precisionNode->getInt();
int32_t bytesWithSpaces = bytesWithSpacesNode->getInt();
int32_t type = typeNode->getInt();
const char *failMsg = NULL;

/* Hardware expects both, precision and bytesWithSpaces to be
* 5 bit unsigned binary integer. However, 0 is valid only for
* bytesWithSpaces. This is why precision must be within [1-31]
* range and bytesWithSpaces must be within [0-31] range.
*/
// TODO: Add support for non-constant arguments
if (!isChildConst(callNode, 2))
failMsg = "Precision is not constant";
else if (precision < 1 || precision > 31)
failMsg = "Precision value is not in valid range [1-31]";
else if (!isChildConst(callNode, 3))
failMsg = "Decimal type node is not constant";
else if (type < 1 || type > 4)
failMsg = "Invalid decimal type. Supported types are (1|2|3|4)";
else if (!isChildConst(callNode, 4))
failMsg = "bytesWithSpaces node is not constant";
else if (bytesWithSpaces < 0 || bytesWithSpaces > 31)
failMsg = "bytesWithSpaces value not in valid range [0-31]";

if (failMsg)
{
TR::DebugCounter::incStaticDebugCounter(comp(),
TR::DebugCounter::debugCounterName(comp(),
"DAA/rejected/chkZonedDecimal"));

return printInliningStatus (false, callNode, failMsg);
}

if (performTransformation(comp(), "O^O TR_DataAccessAccelerator: inlineCheckZonedDecimal on callNode %p\n", callNode))
{
TR::DebugCounter::incStaticDebugCounter(comp(),
TR::DebugCounter::debugCounterName(comp(),
"DAA/inlined/chkZonedDecimal"));

insertByteArrayNULLCHK(callTreeTop, callNode, byteArrayNode);

TR::DataType decimalType = TR::DataTypes::NoType;
TR::ILOpCodes loadOpCode = TR::BadILOp;
if (type == 1)
{
decimalType = TR::ZonedDecimal;
loadOpCode = TR::zdloadi;
}
else if (type == 2)
{
decimalType = TR::ZonedDecimalSignLeadingEmbedded;
loadOpCode = TR::zdsleLoadi;
}
else if (type == 3)
{
decimalType = TR::ZonedDecimalSignTrailingSeparate;
loadOpCode = TR::zdstsLoadi;
}
else if (type == 4)
{
decimalType = TR::ZonedDecimalSignLeadingSeparate;
loadOpCode = TR::zdslsLoadi;
}
int32_t precisionSizeInNumberOfBytes = TR::DataType::getSizeFromBCDPrecision(decimalType, precision);

insertByteArrayBNDCHK(callTreeTop, callNode, byteArrayNode, offsetNode, 0);
insertByteArrayBNDCHK(callTreeTop, callNode, byteArrayNode, offsetNode, precisionSizeInNumberOfBytes - 1);

TR::SymbolReference* zonedDecimalSymbolReference = comp()->getSymRefTab()->findOrCreateArrayShadowSymbolRef(decimalType, NULL, precisionSizeInNumberOfBytes, fe());
TR::Node* zdchkChild0Node = TR::Node::createWithSymRef(loadOpCode, 1, 1, constructAddressNode(callNode, byteArrayNode, offsetNode), zonedDecimalSymbolReference);
zdchkChild0Node->setDecimalPrecision(precision);

byteArrayNode->decReferenceCount();
offsetNode->decReferenceCount();
precisionNode->decReferenceCount();
typeNode->decReferenceCount();

TR::Node* bytesWithSpacesConstNode = TR::Node::bconst(static_cast<uint8_t>(bytesWithSpaces));
TR::Node::recreateWithoutProperties(callNode, TR::zdchk, 2, zdchkChild0Node, bytesWithSpacesConstNode);
return true;
}

return false;
}

TR::Node* TR_DataAccessAccelerator::insertIntegerGetIntrinsic(TR::TreeTop* callTreeTop, TR::Node* callNode, int32_t sourceNumBytes, int32_t targetNumBytes)
{
if (targetNumBytes != 1 && targetNumBytes != 2 && targetNumBytes != 4 && targetNumBytes != 8)
Expand Down
1 change: 1 addition & 0 deletions runtime/compiler/optimizer/DataAccessAccelerator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ class TR_DataAccessAccelerator : public TR::Optimization
TR::Node* insertDecimalSetIntrinsic(TR::TreeTop* callTreeTop, TR::Node* callNode, int32_t sourceNumBytes, int32_t targetNumBytes);

bool inlineCheckPackedDecimal(TR::TreeTop* callTreeTop, TR::Node* callNode);
bool inlineCheckExternalDecimal(TR::TreeTop* callTreeTop, TR::Node* callNode);

private:

Expand Down
3 changes: 3 additions & 0 deletions runtime/compiler/optimizer/InlinerTempForJ9.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5411,6 +5411,9 @@ TR_J9InlinerPolicy::supressInliningRecognizedInitialCallee(TR_CallSite* callsite
// DAA Packed Decimal check method
case TR::com_ibm_dataaccess_PackedDecimal_checkPackedDecimal_:

// DAA External Decimal check method
case TR::com_ibm_dataaccess_ExternalDecimal_checkExternalDecimal_:

// DAA Packed Decimal <-> Integer
case TR::com_ibm_dataaccess_DecimalData_convertPackedDecimalToInteger_:
case TR::com_ibm_dataaccess_DecimalData_convertPackedDecimalToInteger_ByteBuffer_:
Expand Down
1 change: 1 addition & 0 deletions runtime/compiler/optimizer/J9LocalCSE.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ J9::LocalCSE::shouldCommonNode(TR::Node *parent, TR::Node *node)
case TR::com_ibm_dataaccess_PackedDecimal_equalsPackedDecimal_:
case TR::com_ibm_dataaccess_PackedDecimal_notEqualsPackedDecimal_:
case TR::com_ibm_dataaccess_PackedDecimal_checkPackedDecimal_:
case TR::com_ibm_dataaccess_ExternalDecimal_checkExternalDecimal_:
case TR::com_ibm_dataaccess_DecimalData_convertExternalDecimalToPackedDecimal_:
case TR::com_ibm_dataaccess_DecimalData_convertPackedDecimalToExternalDecimal_:
case TR::com_ibm_dataaccess_DecimalData_convertPackedDecimalToUnicodeDecimal_:
Expand Down
1 change: 1 addition & 0 deletions runtime/compiler/optimizer/J9SimplifierTable.enum
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@
#define pdModifyPrecisionSimplifierHandler pdshlSimplifier
#define countDigitsSimplifierHandler dftSimplifier
#define BCDCHKSimplifierHandler dftSimplifier
#define zdchkSimplifierHandler dftSimplifier

#include "optimizer/OMRSimplifierTable.enum"

Expand Down
19 changes: 15 additions & 4 deletions runtime/compiler/runtime/SignalHandler.c
Original file line number Diff line number Diff line change
Expand Up @@ -564,11 +564,11 @@ UDATA jitPPCHandler(J9VMThread* vmThread, U_32 sigType, void* sigInfo)
*iarPtr = (UDATA) ((void *) &jitHandleInternalErrorTrap);
#endif
return J9PORT_SIG_EXCEPTION_CONTINUE_EXECUTION;

}
else if (J9PORT_SIG_FLAG_SIGTRAP == sigType) {
IDATA trapType = jitPPCIdentifyCodeCacheTrapType((U_8 *) *iarPtr);

switch (trapType) {

case TRAP_TYPE_NULL_CHECK:
Expand Down Expand Up @@ -937,8 +937,19 @@ UDATA restoreSystemStackPointerState(J9VMThread* vmThread, U_32 sigType, void* s
return J9PORT_SIG_EXCEPTION_CONTINUE_EXECUTION;
}

#ifdef EMULATE_ZNEXT
extern int jitS390Emulation(J9VMThread* vmThread, void* sigInfo);
#endif

UDATA jit390Handler(J9VMThread* vmThread, U_32 sigType, void* sigInfo)
{
#ifdef EMULATE_ZNEXT
if (J9PORT_SIG_FLAG_SIGILL == sigType && jitS390Emulation(vmThread, sigInfo) == 0)
{
return J9PORT_SIG_EXCEPTION_CONTINUE_EXECUTION;
}
#endif

PORT_ACCESS_FROM_VMC(vmThread);

J9JITConfig *jitConfig = vmThread->javaVM->jitConfig;
Expand Down Expand Up @@ -1251,13 +1262,13 @@ UDATA jit390Handler(J9VMThread* vmThread, U_32 sigType, void* sigInfo)
/* add one to *controlPC for symmetry with IA32, handler check subs one */
jit390SetTrapHandler(controlPC, entryPointRegister, (void *) &jitHandleNullPointerExceptionTrap);
return restoreSystemStackPointerState(vmThread, sigType, sigInfo);

case TRAP_TYPE_INTERNAL_ERROR:
vmThread->jitException = (J9Object *) (controlPCValue + 1);
/* add one to *controlPC for symmetry with IA32, handler check subs one */
jit390SetTrapHandler(controlPC, entryPointRegister, (void *) &jitHandleInternalErrorTrap);
return restoreSystemStackPointerState(vmThread, sigType, sigInfo);

case TRAP_TYPE_ARRAY_BOUNDS:
vmThread->jitException = (J9Object *) (controlPCValue + 1);
/* add one to *controlPC for symmetry with IA32, handler check subs one */
Expand Down
Loading