From d74a758f19fdb16cbb52a23127522083f7840988 Mon Sep 17 00:00:00 2001 From: Spencer Comin Date: Thu, 13 Apr 2023 16:11:54 -0400 Subject: [PATCH] Use arraycmplen opcode Changes uses of opcode arraycmp with ArrayCmplen flag set to use the opcode arraycmplen. Signed-off-by: Spencer Comin --- .../compiler/optimizer/IdiomRecognition.cpp | 12 ++++--- .../optimizer/IdiomTransformations.cpp | 34 ++++++++++++------- 2 files changed, 29 insertions(+), 17 deletions(-) diff --git a/runtime/compiler/optimizer/IdiomRecognition.cpp b/runtime/compiler/optimizer/IdiomRecognition.cpp index ca2ab1eb46f..c763a47dba9 100644 --- a/runtime/compiler/optimizer/IdiomRecognition.cpp +++ b/runtime/compiler/optimizer/IdiomRecognition.cpp @@ -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 @@ -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) { diff --git a/runtime/compiler/optimizer/IdiomTransformations.cpp b/runtime/compiler/optimizer/IdiomTransformations.cpp index b8c7b3979ca..20f9f12b391 100644 --- a/runtime/compiler/optimizer/IdiomTransformations.cpp +++ b/runtime/compiler/optimizer/IdiomTransformations.cpp @@ -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); @@ -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 @@ -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); @@ -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);