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

Off Heap Changes and lowering trees bug #7296

Merged
merged 5 commits into from
May 17, 2024
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
2 changes: 1 addition & 1 deletion compiler/compile/OMRSymbolReferenceTable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ OMR::SymbolReferenceTable::findOrCreateContiguousArrayDataAddrFieldShadowSymRef(
{
if (!element(contiguousArrayDataAddrFieldSymbol))
{
TR::Symbol * sym = TR::Symbol::createShadow(trHeapMemory(), TR::Address);
TR::Symbol * sym = TR::Symbol::createShadow(trHeapMemory(), TR::Int64);
sym->setContiguousArrayDataAddrFieldSymbol();
element(contiguousArrayDataAddrFieldSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), contiguousArrayDataAddrFieldSymbol, sym);
element(contiguousArrayDataAddrFieldSymbol)->setOffset(TR::Compiler->om.offsetOfContiguousDataAddrField());
Expand Down
9 changes: 9 additions & 0 deletions compiler/control/OMROptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2605,6 +2605,15 @@ OMR::Options::jitPreProcess()
_disabledOptimizations[IVTypeTransformation] = true;
_disabledOptimizations[basicBlockHoisting] = true;

#ifdef OMR_GC_SPARSE_HEAP_ALLOCATION
if (TR::Compiler->om.isOffHeapAllocationEnabled())
{
// Disable opts known to be broken for off heap
_disabledOptimizations[escapeAnalysis] = true;
_disabledOptimizations[idiomRecognition] = true;
}
#endif

self()->setOption(TR_DisableTreePatternMatching);
self()->setOption(TR_DisableHalfSlotSpills);

Expand Down
93 changes: 93 additions & 0 deletions compiler/optimizer/OMRTransformUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -436,3 +436,96 @@ OMR::TransformUtil::createConditionalAlternatePath(TR::Compilation* comp,
cfg->addEdge(TR::CFGEdge::createEdge(ifBlock, thenBlock, comp->trMemory()));
cfg->copyExceptionSuccessors(elseBlock, thenBlock);
}

#if defined(OMR_GC_SPARSE_HEAP_ALLOCATION)
TR::Node *
OMR::TransformUtil::generateDataAddrLoadTrees(TR::Compilation *comp, TR::Node *arrayObject)
{
TR_ASSERT_FATAL_WITH_NODE(arrayObject,
TR::Compiler->om.isOffHeapAllocationEnabled(),
"This helper shouldn't be called if off heap allocation is disabled.\n");

TR::SymbolReference *dataAddrFieldOffset = comp->getSymRefTab()->findOrCreateContiguousArrayDataAddrFieldShadowSymRef();
TR::Node *dataAddrField = TR::Node::createWithSymRef(TR::aloadi, 1, arrayObject, 0, dataAddrFieldOffset);
dataAddrField->setIsInternalPointer(true);

return dataAddrField;
}
#endif /* OMR_GC_SPARSE_HEAP_ALLOCATION */

TR::Node *
OMR::TransformUtil::generateArrayElementAddressTrees(TR::Compilation *comp, TR::Node *arrayNode, TR::Node *offsetNode)
{
TR::Node *arrayAddressNode = NULL;
TR::Node *totalOffsetNode = NULL;

TR_ASSERT_FATAL_WITH_NODE(arrayNode,
!TR::Compiler->om.canGenerateArraylets(),
"This helper shouldn't be called if arraylets are enabled.\n");

#if defined(OMR_GC_SPARSE_HEAP_ALLOCATION)
if (TR::Compiler->om.isOffHeapAllocationEnabled())
{
arrayAddressNode = generateDataAddrLoadTrees(comp, arrayNode);
if (offsetNode)
arrayAddressNode = TR::Node::create(TR::aladd, 2, arrayAddressNode, offsetNode);
}
else if (comp->target().is64Bit())
#else
if (comp->target().is64Bit())
#endif /* OMR_GC_SPARSE_HEAP_ALLOCATION */
{
totalOffsetNode = TR::Node::lconst(TR::Compiler->om.contiguousArrayHeaderSizeInBytes());
if (offsetNode)
totalOffsetNode = TR::Node::create(TR::ladd, 2, offsetNode, totalOffsetNode);
arrayAddressNode = TR::Node::create(TR::aladd, 2, arrayNode, totalOffsetNode);
}
else
{
totalOffsetNode = TR::Node::iconst(static_cast<int32_t>(TR::Compiler->om.contiguousArrayHeaderSizeInBytes()));
if (offsetNode)
totalOffsetNode = TR::Node::create(TR::iadd, 2, offsetNode, totalOffsetNode);
arrayAddressNode = TR::Node::create(TR::aiadd, 2, arrayNode, totalOffsetNode);
}

return arrayAddressNode;
}

TR::Node *
OMR::TransformUtil::generateFirstArrayElementAddressTrees(TR::Compilation *comp, TR::Node *arrayObject)
{
TR::Node *firstArrayElementNode = generateArrayElementAddressTrees(comp, arrayObject);
return firstArrayElementNode;
}

TR::Node *
OMR::TransformUtil::generateConvertArrayElementIndexToOffsetTrees(TR::Compilation *comp, TR::Node *indexNode, TR::Node *elementSizeNode, int32_t elementSize, bool useShiftOpCode)
{
TR::Node *offsetNode = indexNode->createLongIfNeeded();
TR::Node *strideNode = elementSizeNode;
if (strideNode)
strideNode = strideNode->createLongIfNeeded();

if (strideNode != NULL || elementSize > 1)
{
TR::ILOpCodes offsetOpCode = TR::BadILOp;
if (comp->target().is64Bit())
{
if (strideNode == NULL && elementSize > 1)
strideNode = TR::Node::lconst(indexNode, elementSize);

offsetOpCode = useShiftOpCode ? TR::lshl : TR::lmul;
}
else
{
if (strideNode == NULL && elementSize > 1)
strideNode = TR::Node::iconst(indexNode, elementSize);

offsetOpCode = useShiftOpCode ? TR::ishl : TR::imul;
}

offsetNode = TR::Node::create(offsetOpCode, 2, offsetNode, strideNode);
}

return offsetNode;
}
85 changes: 85 additions & 0 deletions compiler/optimizer/OMRTransformUtil.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,91 @@ class OMR_EXTENSIBLE TransformUtil
TR::Block* mergeBlock,
TR::CFG *cfg,
bool markCold = true);

#if defined(OMR_GC_SPARSE_HEAP_ALLOCATION)
/**
* \brief
* Generate IL to load dataAddr pointer from the array header
*
* \param comp
* The compilation object
*
* \param arrayObject
* The array object node
*
* \return
* IL for loading dataAddr pointer
*/
static TR::Node *generateDataAddrLoadTrees(TR::Compilation *comp, TR::Node *arrayObject);
#endif /* OMR_GC_SPARSE_HEAP_ALLOCATION */

/**
* \brief
* Generate array element access IL for on and off heap contiguous arrays
*
* \param comp
* The compilation object
*
* \param arrayNode
* The array object node
*
* \param offsetNode
* The offset node (in bytes)
*
* \return
* IL to access array element at offset provided by offsetNode or
* first array element if no offset node is provided
*/
static TR::Node *generateArrayElementAddressTrees(
TR::Compilation *comp,
TR::Node *arrayNode,
TR::Node *offsetNode = NULL);

/**
* \brief
* Generate IL to access first array element
*
* \param comp
* The compilation object
*
* \param arrayObject
* The array object node
*
* \return
* IL for accessing first array element
*/
static TR::Node *generateFirstArrayElementAddressTrees(TR::Compilation *comp, TR::Node *arrayObject);

/**
* \brief
* Generates IL to convert element index to offset in bytes using element
* size (node or integer)
*
* \param comp
* The compilation object
*
* \param indexNode
* Array element index node
*
* \param elementSizeNode
* Array element size tree (ex: const node containing element size)
*
* \param elementSize
* Array element size
*
* \param useShiftOpCode
* Use left shift instead of multiplication
*
* \return
* IL to convert array element index to offset in bytes
*/
static TR::Node *generateConvertArrayElementIndexToOffsetTrees(
TR::Compilation *comp,
TR::Node *indexNode,
TR::Node *elementSizeNode = NULL,
int32_t elementSize = 0,
bool useShiftOpCode = false);

private:

static uint32_t _widthToShift[];
Expand Down
102 changes: 78 additions & 24 deletions compiler/optimizer/ValuePropagationCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -846,6 +846,11 @@ TR::Node* generateLenForArrayCopy(TR::Compilation *comp, int32_t elementSize, TR
stride = TR::TransformUtil::generateArrayElementShiftAmountTrees(comp, srcObjNode);
#endif

#if defined(OMR_GC_SPARSE_HEAP_ALLOCATION)
if (TR::Compiler->om.isOffHeapAllocationEnabled())
len = TR::TransformUtil::generateConvertArrayElementIndexToOffsetTrees(comp, copyLenNode, stride, elementSize, true);
else
#endif /* OMR_GC_SPARSE_HEAP_ALLOCATION */
if (is64BitTarget)
{
if (stride->getType().isInt32())
Expand All @@ -864,6 +869,11 @@ TR::Node* generateLenForArrayCopy(TR::Compilation *comp, int32_t elementSize, TR
}
else
{
#if defined(OMR_GC_SPARSE_HEAP_ALLOCATION)
if (TR::Compiler->om.isOffHeapAllocationEnabled())
len = TR::TransformUtil::generateConvertArrayElementIndexToOffsetTrees(comp, copyLenNode, stride, elementSize, false);
else
#endif /* OMR_GC_SPARSE_HEAP_ALLOCATION */
if (is64BitTarget)
{
if (!stride)
Expand Down Expand Up @@ -2114,6 +2124,30 @@ TR::Node *generateArrayAddressTree(

TR::Node *array;

#if defined(OMR_GC_SPARSE_HEAP_ALLOCATION)
if (TR::Compiler->om.isOffHeapAllocationEnabled())
{
if (offHigh > 0)
{
if (elementSize == 1)
array = offNode->createLongIfNeeded();
else if (elementSize == 0)
{
if (!stride)
stride = TR::TransformUtil::generateArrayElementShiftAmountTrees(comp, objNode);
array = TR::TransformUtil::generateConvertArrayElementIndexToOffsetTrees(comp, offNode, stride, elementSize, true);
}
else
{
array = TR::TransformUtil::generateConvertArrayElementIndexToOffsetTrees(comp, offNode, stride, elementSize, false);
}
}
array = TR::TransformUtil::generateArrayElementAddressTrees(comp, objNode, array);
array->setIsInternalPointer(true);
return array;
}
#endif /* OMR_GC_SPARSE_HEAP_ALLOCATION */

if (offHigh > 0)
{
if (elementSize == 1)
Expand Down Expand Up @@ -2429,25 +2463,47 @@ void OMR::ValuePropagation::generateArrayTranslateNode(TR::TreeTop *callTree,TR:
(rm == TR::sun_nio_cs_UTF_8_Encoder_encodeUTF_8))
encode = true;

if (encode)
#if defined(OMR_GC_SPARSE_HEAP_ALLOCATION)
if (TR::Compiler->om.isOffHeapAllocationEnabled())
{
node = TR::Node::create(is64BitTarget ? TR::lmul : TR::imul, 2, srcOff, strideNode);
node = TR::Node::create(is64BitTarget ? TR::ladd : TR::iadd, 2, node, hdrSize);
src = TR::Node::create(is64BitTarget? TR::aladd : TR::aiadd, 2, srcObj, node);
node = TR::Node::create(is64BitTarget ? TR::ladd : TR::iadd, 2, dstOff, hdrSize);
dst = TR::Node::create(is64BitTarget? TR::aladd : TR::aiadd, 2, dstObj, node);
arrayTranslateNode->setSourceIsByteArrayTranslate(false);
arrayTranslateNode->setTargetIsByteArrayTranslate(true);
if (encode)
{
srcOff = TR::TransformUtil::generateConvertArrayElementIndexToOffsetTrees(comp(), srcOff, strideNode, 0, false);
arrayTranslateNode->setSourceIsByteArrayTranslate(false);
arrayTranslateNode->setTargetIsByteArrayTranslate(true);
}
else
{
dstOff = TR::TransformUtil::generateConvertArrayElementIndexToOffsetTrees(comp(), dstOff, strideNode, 0, false);
arrayTranslateNode->setSourceIsByteArrayTranslate(true);
arrayTranslateNode->setTargetIsByteArrayTranslate(false);
}
src = TR::TransformUtil::generateArrayElementAddressTrees(comp(), srcObj, srcOff);
dst = TR::TransformUtil::generateArrayElementAddressTrees(comp(), dstObj, dstOff);
}
else
#endif /* OMR_GC_SPARSE_HEAP_ALLOCATION */
{
node = TR::Node::create(is64BitTarget ? TR::ladd : TR::iadd, 2, srcOff, hdrSize);
src = TR::Node::create(is64BitTarget? TR::aladd : TR::aiadd, 2, srcObj, node);
node = TR::Node::create(is64BitTarget ? TR::lmul : TR::imul, 2, dstOff, strideNode);
node = TR::Node::create(is64BitTarget ? TR::ladd : TR::iadd, 2, node, hdrSize);
dst = TR::Node::create(is64BitTarget? TR::aladd : TR::aiadd, 2, dstObj, node);
arrayTranslateNode->setSourceIsByteArrayTranslate(true);
arrayTranslateNode->setTargetIsByteArrayTranslate(false);
if (encode)
{
node = TR::Node::create(is64BitTarget ? TR::lmul : TR::imul, 2, srcOff, strideNode);
node = TR::Node::create(is64BitTarget ? TR::ladd : TR::iadd, 2, node, hdrSize);
src = TR::Node::create(is64BitTarget? TR::aladd : TR::aiadd, 2, srcObj, node);
node = TR::Node::create(is64BitTarget ? TR::ladd : TR::iadd, 2, dstOff, hdrSize);
dst = TR::Node::create(is64BitTarget? TR::aladd : TR::aiadd, 2, dstObj, node);
arrayTranslateNode->setSourceIsByteArrayTranslate(false);
arrayTranslateNode->setTargetIsByteArrayTranslate(true);
}
else
{
node = TR::Node::create(is64BitTarget ? TR::ladd : TR::iadd, 2, srcOff, hdrSize);
src = TR::Node::create(is64BitTarget? TR::aladd : TR::aiadd, 2, srcObj, node);
node = TR::Node::create(is64BitTarget ? TR::lmul : TR::imul, 2, dstOff, strideNode);
node = TR::Node::create(is64BitTarget ? TR::ladd : TR::iadd, 2, node, hdrSize);
dst = TR::Node::create(is64BitTarget? TR::aladd : TR::aiadd, 2, dstObj, node);
arrayTranslateNode->setSourceIsByteArrayTranslate(true);
arrayTranslateNode->setTargetIsByteArrayTranslate(false);
}
rmnattas marked this conversation as resolved.
Show resolved Hide resolved
}

if (encode && !isSBCSEncoder)
Expand Down Expand Up @@ -4090,17 +4146,15 @@ void OMR::ValuePropagation::transformArrayCloneCall(TR::TreeTop *callTree, OMR::
newArray->setIsNonNull(true);

int32_t elementSize = TR::Compiler->om.getSizeOfArrayElement(newArray);
TR::Node *lengthInBytes = comp()->target().is64Bit() ?
TR::Node::create(callNode, TR::lmul, 2, TR::Node::create(callNode, TR::i2l, 1, lenNode), TR::Node::lconst(lenNode, elementSize)) :
TR::Node::create(callNode, TR::imul, 2, lenNode, TR::Node::iconst(lenNode, elementSize));

TR::Node *lengthInBytes;
TR::Node *srcStart;
TR::Node *destStart;

lengthInBytes = TR::TransformUtil::generateConvertArrayElementIndexToOffsetTrees(comp(), lenNode, NULL, elementSize, false);
srcStart = TR::TransformUtil::generateFirstArrayElementAddressTrees(comp(), objNode);
destStart = TR::TransformUtil::generateFirstArrayElementAddressTrees(comp(), newArray);

TR::Node *srcStart = comp()->target().is64Bit() ?
TR::Node::create(callNode, TR::aladd, 2, objNode, TR::Node::lconst(objNode, TR::Compiler->om.contiguousArrayHeaderSizeInBytes())) :
TR::Node::create(callNode, TR::aiadd, 2, objNode, TR::Node::iconst(objNode, TR::Compiler->om.contiguousArrayHeaderSizeInBytes()));
TR::Node *destStart = comp()->target().is64Bit() ?
TR::Node::create(callNode, TR::aladd, 2, newArray, TR::Node::lconst(newArray, TR::Compiler->om.contiguousArrayHeaderSizeInBytes())) :
TR::Node::create(callNode, TR::aiadd, 2, newArray, TR::Node::iconst(newArray, TR::Compiler->om.contiguousArrayHeaderSizeInBytes()));
TR::Node *arraycopy = NULL;
if (isPrimitiveClass)
arraycopy = TR::Node::createArraycopy(srcStart, destStart, lengthInBytes);
Expand Down
Loading
Loading