Skip to content

Commit

Permalink
Merge pull request #7368 from rmnattas/off-heap-merge3
Browse files Browse the repository at this point in the history
Commoning and InductionVariable changes for OffHeap
  • Loading branch information
vijaysun-omr authored Jun 25, 2024
2 parents df33ce1 + 8fabd3a commit 2074489
Show file tree
Hide file tree
Showing 6 changed files with 176 additions and 36 deletions.
22 changes: 18 additions & 4 deletions compiler/il/OMRNode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2333,7 +2333,7 @@ OMR::Node::isNotCollected()
bool
OMR::Node::computeIsInternalPointer()
{
TR_ASSERT(self()->getOpCode().hasPinningArrayPointer(), "Opcode %s is not supported, node is " POINTER_PRINTF_FORMAT, self()->getOpCode().getName(), self());
TR_ASSERT(self()->hasPinningArrayPointer(), "Opcode %s is not supported, node is " POINTER_PRINTF_FORMAT, self()->getOpCode().getName(), self());
return self()->computeIsCollectedReference();
}

Expand Down Expand Up @@ -3785,6 +3785,20 @@ OMR::Node::createStoresForVar(TR::SymbolReference * &nodeRef, TR::TreeTop *inser
TR::SymbolReference *newArrayRef = NULL;
TR::TreeTop *newStoreTree = NULL;

if (self()->isDataAddrPointer())
{
TR::Node *firstChild = self()->getFirstChild();
TR::Node *arrayLoadNode = NULL;
TR::SymbolReference *newArrayRef = comp->getSymRefTab()->createTemporary(comp->getMethodSymbol(), TR::Address);
TR::Node *newStore = TR::Node::createStore(newArrayRef, firstChild);
TR::TreeTop *newStoreTree = TR::TreeTop::create(comp, newStore);
insertBefore = origInsertBefore->insertBefore(newStoreTree);
arrayLoadNode = TR::Node::createLoad(firstChild, newArrayRef);
self()->setAndIncChild(0, arrayLoadNode);
firstChild->recursivelyDecReferenceCount();
return insertBefore;
}

bool isInternalPointer = false;
if ((self()->hasPinningArrayPointer() &&
self()->computeIsInternalPointer()) ||
Expand Down Expand Up @@ -3877,7 +3891,7 @@ OMR::Node::createStoresForVar(TR::SymbolReference * &nodeRef, TR::TreeTop *inser
if (self()->getOpCode().isArrayRef())
{
child = self()->getFirstChild();
if (child->isInternalPointer())
if (child->isInternalPointer() && !child->isDataAddrPointer())
pinningArray = child->getPinningArrayPointer();
else
{
Expand Down Expand Up @@ -5903,14 +5917,14 @@ OMR::Node::chkCompressionSequence()
bool
OMR::Node::isInternalPointer()
{
return _flags.testAny(internalPointer) && (self()->getOpCode().hasPinningArrayPointer() || self()->getOpCode().isArrayRef());
return _flags.testAny(internalPointer) && (self()->hasPinningArrayPointer() || self()->getOpCode().isArrayRef());
}

void
OMR::Node::setIsInternalPointer(bool v)
{
TR::Compilation *c = TR::comp();
TR_ASSERT(self()->getOpCode().hasPinningArrayPointer() || self()->getOpCode().isArrayRef(),
TR_ASSERT(self()->hasPinningArrayPointer() || self()->getOpCode().isArrayRef(),
"Opcode must be one that can have a pinningArrayPointer or must be an array reference");
if (performNodeTransformation2(c, "O^O NODE FLAGS: Setting internalPointer flag on node %p to %d\n", self(), v))
_flags.set(internalPointer, v);
Expand Down
177 changes: 150 additions & 27 deletions compiler/optimizer/InductionVariable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1913,6 +1913,7 @@ bool TR_LoopStrider::examineTreeForInductionVariableUse(TR::Block *loopInvariant
TR::Node *originalNode = NULL;
if (cg()->supportsInternalPointers() &&
(node->isInternalPointer()) &&
!node->isDataAddrPointer() &&
node->getFirstChild()->getOpCode().isLoadVar() &&
node->getFirstChild()->getSymbolReference()->getSymbol()->isAutoOrParm() &&
//node->getFirstChild()->getSymbolReference()->getSymbol()->isAuto() &&
Expand Down Expand Up @@ -3000,6 +3001,7 @@ bool TR_LoopStrider::identifyExpressionLinearInInductionVariable(TR::Node *node,
node->setVisitCount(visitCount);
if (cg()->supportsInternalPointers() &&
node->isInternalPointer() &&
!node->isDataAddrPointer() &&
node->getFirstChild()->getOpCode().isLoadVar() &&
node->getFirstChild()->getSymbolReference()->getSymbol()->isAutoOrParm() &&
//node->getFirstChild()->getSymbolReference()->getSymbol()->isAuto() &&
Expand Down Expand Up @@ -3394,35 +3396,41 @@ bool TR_LoopStrider::reassociateAndHoistComputations(TR::Block *loopInvariantBlo
TR::AutomaticSymbol *pinningArrayPointer = NULL;
int32_t originalInternalPointerSymbol = 0;
TR::Node *originalNode = NULL;
if (cg()->supportsInternalPointers() &&
(reassociateAndHoistNonPacked() && node->isInternalPointer()) &&
node->getFirstChild()->getOpCode().isLoadVar() &&
node->getFirstChild()->getSymbolReference()->getSymbol()->isAutoOrParm() &&
//node->getFirstChild()->getSymbolReference()->getSymbol()->isAuto() &&
_neverWritten->get(node->getFirstChild()->getSymbolReference()->getReferenceNumber()))
TR::Node *pinningArrayNode = NULL;
if (cg()->supportsInternalPointers() && reassociateAndHoistNonPacked() &&
node->isInternalPointer() && !node->isDataAddrPointer())
{
//printf("Creating internal ptr in %s\n", comp()->signature());
isInternalPointer = true;
internalPointerSymbol = node->getFirstChild()->getSymbolReference()->getReferenceNumber();
originalInternalPointerSymbol = internalPointerSymbol;
if (node->getFirstChild()->getSymbolReference()->getSymbol()->isAuto())
pinningArrayPointer = node->getFirstChild()->getSymbolReference()->getSymbol()->castToAutoSymbol();
if (node->getFirstChild()->isDataAddrPointer())
pinningArrayNode = node->getFirstChild()->getFirstChild();
else
pinningArrayNode = node->getFirstChild();

if (pinningArrayNode->getOpCode().isLoadVar() &&
pinningArrayNode->getSymbolReference()->getSymbol()->isAutoOrParm() &&
_neverWritten->get(pinningArrayNode->getSymbolReference()->getReferenceNumber()))
{
SymRefPair *pair = _parmAutoPairs;
while (pair)
isInternalPointer = true;
internalPointerSymbol = pinningArrayNode->getSymbolReference()->getReferenceNumber();
originalInternalPointerSymbol = internalPointerSymbol;
if (pinningArrayNode->getSymbolReference()->getSymbol()->isAuto())
pinningArrayPointer = pinningArrayNode->getSymbolReference()->getSymbol()->castToAutoSymbol();
else
{
if (pair->_indexSymRef == node->getFirstChild()->getSymbolReference())
SymRefPair *pair = _parmAutoPairs;
while (pair)
{
pinningArrayPointer = pair->_derivedSymRef->getSymbol()->castToAutoSymbol();
internalPointerSymbol = pair->_derivedSymRef->getReferenceNumber();
break;
if (pair->_indexSymRef == pinningArrayNode->getSymbolReference())
{
pinningArrayPointer = pair->_derivedSymRef->getSymbol()->castToAutoSymbol();
internalPointerSymbol = pair->_derivedSymRef->getReferenceNumber();
break;
}
pair = pair->_next;
}
pair = pair->_next;
}
originalNode = node;
node = node->getSecondChild();
}
originalNode = node;
node = node->getSecondChild();
}

if (isInternalPointer &&
Expand Down Expand Up @@ -3643,6 +3651,81 @@ bool TR_LoopStrider::reassociateAndHoistComputations(TR::Block *loopInvariantBlo
}
}

#ifdef J9_PROJECT_SPECIFIC
// For OffHeap runs, the array access trees don't include headerSize addition
// Offset tree opcode is lmul/lshl to calculate offset from the index node.
if (TR::Compiler->om.isOffHeapAllocationEnabled() &&
(node->getOpCodeValue() == TR::lmul || node->getOpCodeValue() == TR::lshl))
{
if ((isInternalPointer &&
(comp()->getSymRefTab()->getNumInternalPointers() < maxInternalPointers())) &&
(!_registersScarce || (node->getReferenceCount() > 1) || _reassociatedNodes.find(node)) &&
(!comp()->cg()->canBeAffectedByStoreTagStalls() ||
_numInternalPointerOrPinningArrayTempsInitialized < MAX_INTERNAL_POINTER_AUTOS_INITIALIZED) &&
performTransformation(comp(), "%s Replacing reassociated internal pointer based on symRef #%d\n", OPT_DETAILS, internalPointerSymbol))
{
if (_reassociatedAutos->find(originalInternalPointerSymbol) == _reassociatedAutos->end())
{
TR::SymbolReference *newSymbolReference = comp()->getSymRefTab()->createTemporary(comp()->getMethodSymbol(), TR::Address, isInternalPointer);
if (isInternalPointer && !pinningArrayPointer)
{
TR::SymbolReference *newPinningArray = comp()->getSymRefTab()->createTemporary(comp()->getMethodSymbol(), TR::Address, false);
pinningArrayPointer = newPinningArray->getSymbol()->castToAutoSymbol();
createParmAutoPair(comp()->getSymRefTab()->getSymRef(internalPointerSymbol), newPinningArray);

TR::Node *newAload = TR::Node::createLoad(node, comp()->getSymRefTab()->getSymRef(internalPointerSymbol));
newAload->setLocalIndex(~0);
TR::Node *newStore = TR::Node::createWithSymRef(TR::astore, 1, 1, newAload, newPinningArray);
internalPointerSymbol = newPinningArray->getReferenceNumber();
TR::TreeTop *placeHolderTree = loopInvariantBlock->getEntry();
TR::TreeTop *nextTree = placeHolderTree->getNextTreeTop();
newStore->setLocalIndex(~0);
TR::TreeTop *newStoreTreeTop = TR::TreeTop::create(comp(), newStore);
placeHolderTree->join(newStoreTreeTop);
newStoreTreeTop->join(nextTree);
dumpOptDetails(comp(), "\nO^O INDUCTION VARIABLE ANALYSIS: Induction variable analysis inserted initialization tree : %p for new symRef #%d\n", newStoreTreeTop->getNode(), newPinningArray->getReferenceNumber());
_numInternalPointerOrPinningArrayTempsInitialized++;
}

_newTempsCreated = true;
if (isInternalPointer)
_numInternalPointers++;
else
_newNonAddressTempsCreated = true;

TR::Symbol *symbol = newSymbolReference->getSymbol();

if (!pinningArrayPointer->isInternalPointer())
{
symbol->castToInternalPointerAutoSymbol()->setPinningArrayPointer(pinningArrayPointer);
pinningArrayPointer->setPinningArrayPointer();
}
else
symbol->castToInternalPointerAutoSymbol()->setPinningArrayPointer(pinningArrayPointer->castToInternalPointerAutoSymbol()->getPinningArrayPointer());

(*_reassociatedAutos)[originalInternalPointerSymbol] = newSymbolReference;
dumpOptDetails(comp(), "reass num %d newsymref %d\n", internalPointerSymbol, newSymbolReference->getReferenceNumber());
}

TR::SymbolReference *internalPointerSymRef = (*_reassociatedAutos)[originalInternalPointerSymbol];
originalNode->getFirstChild()->recursivelyDecReferenceCount();
node->decReferenceCount();
_reassociatedNodes.add(node);

if (node->getReferenceCount() == 0)
{
node->getFirstChild()->decReferenceCount();
node->getSecondChild()->decReferenceCount();
}

TR::Node *newLoad = TR::Node::createWithSymRef(node, TR::aload, 0, internalPointerSymRef);
newLoad->setLocalIndex(~0);
originalNode->setAndIncChild(0, newLoad);
originalNode->setAndIncChild(1, node->getFirstChild());
reassociatedComputation = true;
}
}
#endif /* J9_PROJECT_SPECIFIC */

if (examineChildren)
{
Expand Down Expand Up @@ -4573,6 +4656,7 @@ bool TR_LoopStrider::morphExpressionLinearInInductionVariable(TR::Node *parent,
node->setVisitCount(visitCount);
if (cg()->supportsInternalPointers() &&
node->isInternalPointer() &&
!node->isDataAddrPointer() &&
node->getFirstChild()->getOpCode().isLoadVar() &&
node->getFirstChild()->getSymbolReference()->getSymbol()->isAuto() &&
//node->getFirstChild()->getSymbolReference()->getSymbol()->isAutoOrParm() &&
Expand All @@ -4582,12 +4666,14 @@ bool TR_LoopStrider::morphExpressionLinearInInductionVariable(TR::Node *parent,
}

// pattern match trees
// ladd <-- node
// lmul <-- firstChild
// i2l
// <index> ; where <index>==> iload; iadd ; isub
// lconst iload iload
// lconst iconst iconst
// aladd (internalPtr)
// aload
// ladd <-- node
// lmul <-- firstChild
// i2l
// <index> ; where <index>==> iload; iadd ; isub
// lconst iload iload
// lconst iconst iconst

if (node->getOpCodeValue() == TR::ladd || node->getOpCodeValue() == TR::lsub)
{
Expand Down Expand Up @@ -4622,6 +4708,43 @@ bool TR_LoopStrider::morphExpressionLinearInInductionVariable(TR::Node *parent,
}
}
}
// pattern match trees for indexable object structure that includes a pointer to the data address field (off-heap)
// aladd (internalPtr)
// aloadi (internalPtr dataAddrPointer)
// aload
// lmul <-- node
// i2l
// <index> ; where <index> ==> iload; iadd ; isub
// lconst
#ifdef J9_PROJECT_SPECIFIC
else if (TR::Compiler->om.isOffHeapAllocationEnabled() &&
(node->getOpCodeValue() == TR::lmul || node->getOpCodeValue() == TR::lshl))
{
bool isLinearInInductionVariable;
TR::Node *indVarTree = NULL;
if (node->getFirstChild()->getOpCodeValue() == TR::i2l)
{
indVarTree = node->getFirstChild()->getFirstChild();
isLinearInInductionVariable = checkExpressionForInductionVariable(indVarTree);
if (isLinearInInductionVariable &&
node->getSecondChild()->getOpCodeValue() == TR::lconst)
{
examineChildren = false;

// Request a sign-extension only when there is no arithmetic
// here, or the arithmetic is known not to overflow.
//
// If we're looking at possibly overflowing arithmetic,
// another expression still might request a sign-extension,
// in which case indVarTree will continue to do 32-bit
// arithmetic consuming l2i of the new 64-bit variable.
TR::Node *ivLoad = getInductionVariableNode(indVarTree);
if (ivLoad != NULL && (ivLoad == indVarTree || indVarTree->cannotOverflow()))
_isInductionVariableMorphed = true;
}
}
}
#endif /* J9_PROJECT_SPECIFIC */
// collect uses of ind var
// parent
// iload <-- node
Expand Down
4 changes: 2 additions & 2 deletions compiler/optimizer/Inliner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3362,11 +3362,11 @@ TR::TreeTop * OMR_InlinerUtil::storeValueInATemp(
if (value->getOpCode().hasSymbolReference() && value->getSymbolReference()->getSymbol()->isNotCollected())
valueRef->getSymbol()->setNotCollected();

else if (value->getOpCode().isArrayRef())
else if (value->getOpCode().isArrayRef() || value->isDataAddrPointer())
value->setIsInternalPointer(true);

TR::AutomaticSymbol *pinningArray = NULL;
if (value->getOpCode().isArrayRef())
if (value->getOpCode().isArrayRef() || value->isDataAddrPointer())
{
TR::Node *valueChild = value->getFirstChild();
if (valueChild->isInternalPointer() &&
Expand Down
3 changes: 3 additions & 0 deletions compiler/optimizer/LocalAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,9 @@ bool TR_LocalAnalysis::isSupportedNodeForFunctionality(TR::Node *node, TR::Compi
node->getSymbolReference()->isUnresolved()))
return false;

if (node->isDataAddrPointer())
return false;

if (isSupportedOpCode(node->getOpCode(), comp) || isSupportedStoreNode || node->getOpCode().isLoadConst())
{
if (node->getDataType() == TR::Address)
Expand Down
2 changes: 1 addition & 1 deletion compiler/optimizer/OMRLocalCSE.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ bool OMR::LocalCSE::shouldCopyPropagateNode(TR::Node *parent, TR::Node *node, in

bool OMR::LocalCSE::shouldCommonNode(TR::Node *parent, TR::Node *node)
{
return isTreetopSafeToCommon();
return !node->isDataAddrPointer() && isTreetopSafeToCommon();
}

TR::Node * getRHSOfStoreDefNode(TR::Node * storeNode)
Expand Down
4 changes: 2 additions & 2 deletions compiler/optimizer/OMROptimizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2573,8 +2573,8 @@ bool OMR::Optimizer::areNodesEquivalent(TR::Node *node1, TR::Node *node2, TR::C
// for some reason this tests hasPinningArrayPointer only when the node also is true on _flags.testAny(internalPointer)
bool haveIPs = node1->isInternalPointer() && node2->isInternalPointer();
bool haveNoIPs = !node1->isInternalPointer() && !node2->isInternalPointer();
TR::AutomaticSymbol * pinning1 = node1->getOpCode().hasPinningArrayPointer() ? node1->getPinningArrayPointer() : NULL;
TR::AutomaticSymbol * pinning2 = node2->getOpCode().hasPinningArrayPointer() ? node2->getPinningArrayPointer() : NULL;
TR::AutomaticSymbol * pinning1 = node1->hasPinningArrayPointer() ? node1->getPinningArrayPointer() : NULL;
TR::AutomaticSymbol * pinning2 = node2->hasPinningArrayPointer() ? node2->getPinningArrayPointer() : NULL;
if ((haveIPs && (pinning1 == pinning2)) || haveNoIPs)
return true;
else
Expand Down

0 comments on commit 2074489

Please sign in to comment.