Skip to content

Commit

Permalink
Use arraycmplen opcode
Browse files Browse the repository at this point in the history
Changes uses of opcode arraycmp with ArrayCmplen flag set to use the opcode arraycmplen.

Signed-off-by: Spencer Comin <spencer.comin@ibm.com>
  • Loading branch information
Spencer-Comin committed Jun 19, 2023
1 parent 575cae3 commit d74a758
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 17 deletions.
12 changes: 8 additions & 4 deletions runtime/compiler/optimizer/IdiomRecognition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1064,6 +1064,7 @@ TR_CISCGraph::initializeGraphs(TR::Compilation *c)
bool genMemcpy = c->cg()->getSupportsReferenceArrayCopy() || c->cg()->getSupportsPrimitiveArrayCopy();
bool genMemset = c->cg()->getSupportsArraySet();
bool genMemcmp = c->cg()->getSupportsArrayCmp();
bool genMemcmpidx = c->cg()->getSupportsArrayCmpLen();
bool genIDiv2Mul = c->cg()->getSupportsLoweringConstIDiv();
bool genLDiv2Mul = c->cg()->getSupportsLoweringConstLDiv();
// FIXME: We need getSupportsCountDecimalDigit() like interface
Expand All @@ -1087,10 +1088,13 @@ TR_CISCGraph::initializeGraphs(TR::Compilation *c)
{
preparedCISCGraphs[num] = makeMemCmpGraph(c, ctrl);
setEssentialNodes(preparedCISCGraphs[num++]);
preparedCISCGraphs[num] = makeMemCmpIndexOfGraph(c, ctrl);
setEssentialNodes(preparedCISCGraphs[num++]);
preparedCISCGraphs[num] = makeMemCmpSpecialGraph(c, ctrl);
setEssentialNodes(preparedCISCGraphs[num++]);
if (genMemcmpidx)
{
preparedCISCGraphs[num] = makeMemCmpIndexOfGraph(c, ctrl);
setEssentialNodes(preparedCISCGraphs[num++]);
preparedCISCGraphs[num] = makeMemCmpSpecialGraph(c, ctrl);
setEssentialNodes(preparedCISCGraphs[num++]);
}
}
if (genTRT)
{
Expand Down
34 changes: 21 additions & 13 deletions runtime/compiler/optimizer/IdiomTransformations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8989,23 +8989,23 @@ CISCTransform2ArrayCmp2Ifs(TR_CISCTransformer *trans)
TR::TreeTop * newLastTreeTop[2];

// Using the CLCL instruction
lengthNode = createI2LIfNecessary(comp, trans->isGenerateI2L(), lengthNode);
TR::Node * arraycmplen = TR::Node::create(TR::arraycmp, 3, input1Node, input2Node, lengthNode);
arraycmplen->setArrayCmpLen(true);
arraycmplen->setSymbolReference(comp->getSymRefTab()->findOrCreateArrayCmpSymbol());
lengthNode = TR::Node::create(TR::iu2l, 1, lengthNode);
TR::Node * arraycmplen = TR::Node::create(TR::arraycmplen, 3, input1Node, input2Node, lengthNode);
arraycmplen->setSymbolReference(comp->getSymRefTab()->findOrCreateArrayCmpLenSymbol());

TR::SymbolReference * resultSymRef = comp->getSymRefTab()->
createTemporary(comp->getMethodSymbol(), TR::Int32);
createTemporary(comp->getMethodSymbol(), TR::Int64);
topArraycmp = TR::Node::createStore(resultSymRef, arraycmplen);

TR::Node * resultLoad = TR::Node::createLoad(topArraycmp, resultSymRef);
TR::Node * equalLen = resultLoad;
if (shrCount != 0)
{
equalLen = TR::Node::create(TR::ishr, 2,
equalLen = TR::Node::create(TR::lshr, 2,
equalLen,
TR::Node::create(equalLen, TR::iconst, 0, shrCount));
}
equalLen = TR::Node::create(TR::l2i, 1, equalLen);

TR::Node *tmpNode = createStoreOP2(comp, src1IdxSymRef, TR::iadd, src1IdxSymRef, equalLen, trNode);
newFirstTreeTop[0] = TR::TreeTop::create(comp, tmpNode);
Expand Down Expand Up @@ -9351,6 +9351,14 @@ CISCTransform2ArrayCmp(TR_CISCTransformer *trans)
generateArraycmplen = true;
}
}
if (generateArraycmplen)
{
if (!comp->cg()->getSupportsArrayCmpLen())
{
dumpOptDetails(comp, "Bailing CISCTransform2ArrayCmp. Arraycmplen length is needed to continue this transformation, but codgen does not support arraycmplen.\n");
return false;
}
}

// check the indices used in the array loads and
// the store nodes
Expand Down Expand Up @@ -9552,21 +9560,21 @@ CISCTransform2ArrayCmp(TR_CISCTransformer *trans)
{
// Using the CLCL instruction

TR::Node * arraycmplen = TR::Node::create(TR::arraycmp, 3, input1Node, input2Node, createI2LIfNecessary(comp, trans->isGenerateI2L(), lengthNode));
arraycmplen->setArrayCmpLen(true);
arraycmplen->setSymbolReference(comp->getSymRefTab()->findOrCreateArrayCmpSymbol());
TR::Node * arraycmplen = TR::Node::create(TR::arraycmplen, 3, input1Node, input2Node, TR::Node::create(TR::iu2l, 1, lengthNode));
arraycmplen->setSymbolReference(comp->getSymRefTab()->findOrCreateArrayCmpLenSymbol());

TR::SymbolReference * resultSymRef = comp->getSymRefTab()->createTemporary(comp->getMethodSymbol(), TR::Int32);
TR::SymbolReference * resultSymRef = comp->getSymRefTab()->createTemporary(comp->getMethodSymbol(), TR::Int64);
topArraycmp = TR::Node::createStore(resultSymRef, arraycmplen);

TR::Node * resultLoad = TR::Node::createLoad(topArraycmp, resultSymRef);
TR::Node * equalLen = resultLoad;
if (shrCount != 0)
{
equalLen = TR::Node::create(TR::ishr, 2,
equalLen = TR::Node::create(TR::lshr, 2,
equalLen,
TR::Node::create(equalLen, TR::iconst, 0, shrCount));
}
equalLen = TR::Node::create(TR::l2i, 1, equalLen);

TR::Node *tmpNode = createStoreOP2(comp, src1IdxSymRef, TR::iadd, src1IdxSymRef, equalLen, trNode);
newFirstTreeTop = TR::TreeTop::create(comp, tmpNode);
Expand All @@ -9581,8 +9589,8 @@ CISCTransform2ArrayCmp(TR_CISCTransformer *trans)
newLastTreeTop = tmpTreeTop;
}

tmpNode = TR::Node::createif(TR::ificmpeq,
lengthNode,
tmpNode = TR::Node::createif(TR::iflcmpeq,
TR::Node::create(TR::iu2l, 1, lengthNode),
resultLoad,
okDest);
tmpTreeTop = TR::TreeTop::create(comp, tmpNode);
Expand Down

0 comments on commit d74a758

Please sign in to comment.