Skip to content

Commit

Permalink
Merge pull request #7296 from rmnattas/off-heap-merge1
Browse files Browse the repository at this point in the history
Off Heap Changes and lowering trees bug
  • Loading branch information
0xdaryl committed May 17, 2024
2 parents 76296e1 + a6e711a commit dd4c5d5
Show file tree
Hide file tree
Showing 6 changed files with 301 additions and 25 deletions.
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 @@ -2607,6 +2607,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);
}
}

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

0 comments on commit dd4c5d5

Please sign in to comment.