Skip to content

Commit

Permalink
Merge pull request #7313 from Spencer-Comin/arraycmp-64
Browse files Browse the repository at this point in the history
Change arraycmp length child to 64 bits
  • Loading branch information
hzongaro committed Jun 12, 2024
2 parents 8735090 + 9589a57 commit 2acfd24
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 69 deletions.
33 changes: 9 additions & 24 deletions compiler/aarch64/codegen/OMRTreeEvaluator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6938,7 +6938,7 @@ arraycmpEvaluatorHelper(TR::Node *node, TR::CodeGenerator *cg, bool isArrayCmpLe
generateCompareInstruction(cg, node, src1Reg, src2Reg, true);
if (!isLengthGreaterThan15)
{
auto ccmpLengthInstr = generateConditionalCompareImmInstruction(cg, node, lengthReg, 0, 4, TR::CC_NE, /* is64bit */ isArrayCmpLen); /* 4 for Z flag */
auto ccmpLengthInstr = generateConditionalCompareImmInstruction(cg, node, lengthReg, 0, 4, TR::CC_NE, /* is64bit */ true); /* 4 for Z flag */
if (debugObj)
{
debugObj->addInstructionComment(ccmpLengthInstr, "Compares lengthReg with 0 if src1 and src2 are not the same array. Otherwise, sets EQ flag.");
Expand All @@ -6960,14 +6960,14 @@ arraycmpEvaluatorHelper(TR::Node *node, TR::CodeGenerator *cg, bool isArrayCmpLe
TR::Register *data4Reg = srm->findOrCreateScratchRegister();
if (!isLengthGreaterThan15)
{
generateCompareImmInstruction(cg, node, lengthReg, 16, /* is64bit */ isArrayCmpLen);
generateCompareImmInstruction(cg, node, lengthReg, 16, /* is64bit */ true);
auto branchToLessThan16LabelInstr = generateConditionalBranchInstruction(cg, TR::InstOpCode::b_cond, node, lessThan16Label, TR::CC_CC);
if (debugObj)
{
debugObj->addInstructionComment(branchToLessThan16LabelInstr, "Jumps to lessThan16Label if length < 16.");
}
}
generateTrg1Src1ImmInstruction(cg, isArrayCmpLen ? TR::InstOpCode::subimmx : TR::InstOpCode::subimmw, node, lengthReg, lengthReg, 16);
generateTrg1Src1ImmInstruction(cg, TR::InstOpCode::subimmx, node, lengthReg, lengthReg, 16);

TR::LabelSymbol *loop16Label = generateLabelSymbol(cg);
{
Expand All @@ -6984,29 +6984,22 @@ arraycmpEvaluatorHelper(TR::Node *node, TR::CodeGenerator *cg, bool isArrayCmpLe
}
generateConditionalCompareInstruction(cg, node, data3Reg, data4Reg, 0, TR::CC_EQ, true);
auto branchToNotEqual16LabelInstr2 = generateConditionalBranchInstruction(cg, TR::InstOpCode::b_cond, node, notEqual16Label, TR::CC_NE);
auto subtractLengthInstr = generateTrg1Src1ImmInstruction(cg, (isLengthGreaterThan15 || isArrayCmpLen) ? TR::InstOpCode::subsimmx : TR::InstOpCode::subsimmw, node, lengthReg, lengthReg, 16);
auto subtractLengthInstr = generateTrg1Src1ImmInstruction(cg, TR::InstOpCode::subsimmx, node, lengthReg, lengthReg, 16);
auto branchBacktoLoop16LabelInstr = generateConditionalBranchInstruction(cg, TR::InstOpCode::b_cond, node, loop16Label, TR::CC_CS);
if (debugObj)
{
debugObj->addInstructionComment(loop16LabelInstr, "loop16Label");
debugObj->addInstructionComment(branchToNotEqual16LabelInstr2, "Jumps to notEqual16Label if mismatch is found in the 16-byte data");
debugObj->addInstructionComment(branchBacktoLoop16LabelInstr, "Jumps to loop16Label if the remaining length >= 16 and no mismatch is found so far.");
if (isLengthGreaterThan15)
{
debugObj->addInstructionComment(subtractLengthInstr, "Treats length reg as a 64-bit reg as it is used as the 2nd source reg for 64-bit add later.");
}
}
}
if (isLengthGreaterThan15)
{
generateCompareImmInstruction(cg, node, lengthReg, -16, true);
auto branchToDoneLabelInstr3 = generateConditionalBranchInstruction(cg, TR::InstOpCode::b_cond, node, isArrayCmpLen ? done0Label : doneLabel, TR::CC_EQ);
auto branchToDoneLabelInstr3 = generateConditionalBranchInstruction(cg, TR::InstOpCode::b_cond, node, done0Label, TR::CC_EQ);
auto adjustSrc1RegInstr = generateTrg1Src2Instruction(cg, TR::InstOpCode::addx, node, src1Reg, src1Reg, lengthReg);
generateTrg1Src2Instruction(cg, TR::InstOpCode::addx, node, src2Reg, src2Reg, lengthReg);
if (isArrayCmpLen)
loadConstant64(cg, node, 0, lengthReg);
else
loadConstant32(cg, node, 0, lengthReg);
loadConstant64(cg, node, 0, lengthReg);
auto branchBacktoLoop16LabelInstr = generateLabelInstruction(cg, TR::InstOpCode::b, node, loop16Label);
if (debugObj)
{
Expand All @@ -7025,16 +7018,8 @@ arraycmpEvaluatorHelper(TR::Node *node, TR::CodeGenerator *cg, bool isArrayCmpLe
else
{
TR::Instruction *branchToDoneLabelInstr3;
if (isArrayCmpLen)
{
generateTrg1Src1ImmInstruction(cg, TR::InstOpCode::addimmx, node, lengthReg, lengthReg, 16);
branchToDoneLabelInstr3 = generateCompareBranchInstruction(cg, TR::InstOpCode::cbzx, node, lengthReg, done0Label);
}
else
{
generateTrg1Src1ImmInstruction(cg, TR::InstOpCode::addimmw, node, lengthReg, lengthReg, 16);
branchToDoneLabelInstr3 = generateCompareBranchInstruction(cg, TR::InstOpCode::cbzw, node, lengthReg, doneLabel);
}
generateTrg1Src1ImmInstruction(cg, TR::InstOpCode::addimmx, node, lengthReg, lengthReg, 16);
branchToDoneLabelInstr3 = generateCompareBranchInstruction(cg, TR::InstOpCode::cbzx, node, lengthReg, isArrayCmpLen? done0Label : doneLabel);

auto branchToLessThan16Label2 = generateLabelInstruction(cg, TR::InstOpCode::b, node, lessThan16Label);

Expand Down Expand Up @@ -7092,7 +7077,7 @@ arraycmpEvaluatorHelper(TR::Node *node, TR::CodeGenerator *cg, bool isArrayCmpLe
auto branchToDone0LabelInstr = generateLabelInstruction(cg, TR::InstOpCode::b, node, done0Label);

auto lessThan16LabelInstr = generateLabelInstruction(cg, TR::InstOpCode::label, node, lessThan16Label);
generateTrg1Src1ImmInstruction(cg, isArrayCmpLen ? TR::InstOpCode::subsimmx : TR::InstOpCode::subsimmw, node, lengthReg, lengthReg, 1);
generateTrg1Src1ImmInstruction(cg, TR::InstOpCode::subsimmx, node, lengthReg, lengthReg, 1);
generateTrg1MemInstruction(cg, TR::InstOpCode::ldrbpost, node, data1Reg, TR::MemoryReference::createWithDisplacement(cg, src1Reg, 1));
generateTrg1MemInstruction(cg, TR::InstOpCode::ldrbpost, node, data2Reg, TR::MemoryReference::createWithDisplacement(cg, src2Reg, 1));
generateConditionalCompareInstruction(cg, node, data1Reg, data2Reg, 0, TR::CC_HI);
Expand Down
2 changes: 1 addition & 1 deletion compiler/il/OMROpcodes.enum
Original file line number Diff line number Diff line change
Expand Up @@ -7196,7 +7196,7 @@ OPCODE_MACRO(\
/* .properties4 = */ 0, \
/* .dataType = */ TR::Int32, \
/* .typeProperties = */ ILTypeProp::Size_4 | ILTypeProp::Integer, \
/* .childProperties = */ THREE_CHILD(TR::Address, TR::Address, TR::Int32), \
/* .childProperties = */ THREE_CHILD(TR::Address, TR::Address, TR::Int64), \
/* .swapChildrenOpCode = */ TR::BadILOp, \
/* .reverseBranchOpCode = */ TR::BadILOp, \
/* .booleanCompareOpCode = */ TR::BadILOp, \
Expand Down
11 changes: 9 additions & 2 deletions compiler/optimizer/LoopReducer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2143,7 +2143,14 @@ TR_LoopReducer::generateArraycmp(TR_RegionStructure * whileLoop, TR_InductionVar
//
arraycmpLoop.getFirstAddress()->updateAiaddSubTree(arraycmpLoop.getFirstIndVarNode(), &arraycmpLoop);
arraycmpLoop.getSecondAddress()->updateAiaddSubTree(arraycmpLoop.getSecondIndVarNode(), &arraycmpLoop);
TR::Node * imul = arraycmpLoop.updateIndVarStore(arraycmpLoop.getFirstIndVarNode(), indVarStoreNode, arraycmpLoop.getFirstAddress());
TR::Node * mul = arraycmpLoop.updateIndVarStore(arraycmpLoop.getFirstIndVarNode(), indVarStoreNode, arraycmpLoop.getFirstAddress());
if (!comp()->target().is64Bit())
{
// updateIndVarStore returns an imul on 32 bit, extend as arraycmp takes 64 bit length
mul = TR::Node::create(TR::i2l, 1, mul);
// extending the imul is technically unneccessary since the length of an array on 32 bit cannot exceed 32 bit range
mul->setUnneededConversion(true);
}

arraycmpLoop.getFirstAddress()->updateMultiply(arraycmpLoop.getFirstMultiplyNode());
arraycmpLoop.getFirstAddress()->updateMultiply(arraycmpLoop.getSecondMultiplyNode());
Expand All @@ -2159,7 +2166,7 @@ TR_LoopReducer::generateArraycmp(TR_RegionStructure * whileLoop, TR_InductionVar
TR_ASSERT(arraycmpLoop.getSecondLoad()->getOpCode().isLoadVar(),"secondLoad %s (%p) is not a loadVar for arraycmp reduction\n",
arraycmpLoop.getSecondLoad()->getOpCode().getName(),arraycmpLoop.getSecondLoad());

TR::Node * arraycmp = TR::Node::create(TR::arraycmp, 3, firstBase, secondBase, imul);
TR::Node * arraycmp = TR::Node::create(TR::arraycmp, 3, firstBase, secondBase, mul);

TR::SymbolReference *arraycmpSymRef = comp()->getSymRefTab()->findOrCreateArrayCmpSymbol();
arraycmp->setSymbolReference(arraycmpSymRef);
Expand Down
20 changes: 10 additions & 10 deletions compiler/p/codegen/OMRTreeEvaluator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5472,7 +5472,7 @@ static TR::Register *inlineArrayCmpP10(TR::Node *node, TR::CodeGenerator *cg, bo

bool is64bit = cg->comp()->target().is64Bit();

if (isArrayCmpLen && !is64bit)
if (!is64bit)
{
pairReg = tempReg;
tempReg = tempReg->getLowOrder();
Expand All @@ -5482,13 +5482,13 @@ static TR::Register *inlineArrayCmpP10(TR::Node *node, TR::CodeGenerator *cg, bo
startLabel->setStartInternalControlFlow();

generateTrg1ImmInstruction(cg, TR::InstOpCode::li, node, indexReg, 0);
generateTrg1Src1ImmInstruction(cg, (is64bit && isArrayCmpLen) ? TR::InstOpCode::cmpi8 : TR::InstOpCode::cmpli4, node, condReg, tempReg, 16);
generateTrg1Src1ImmInstruction(cg, is64bit ? TR::InstOpCode::cmpi8 : TR::InstOpCode::cmpli4, node, condReg, tempReg, 16);

// We don't need length anymore as we can calculate the appropriate index by using indexReg and the remainder
generateTrg1Src1Imm2Instruction(cg, TR::InstOpCode::rlwinm, node, returnReg, tempReg, 0, 0xF);
generateConditionalBranchInstruction(cg, TR::InstOpCode::blt, node, residueStartLabel, condReg);

if (is64bit && isArrayCmpLen)
if (is64bit)
{
generateShiftRightLogicalImmediateLong(cg, node, tempReg, tempReg, 4);
}
Expand Down Expand Up @@ -5641,7 +5641,7 @@ static TR::Register *inlineArrayCmp(TR::Node *node, TR::CodeGenerator *cg, bool
}

byteLenRegister = cg->evaluate(lengthNode);
if (isArrayCmpLen && !is64bit)
if (!is64bit)
{
byteLenRegister = byteLenRegister->getLowOrder();
}
Expand All @@ -5660,13 +5660,13 @@ static TR::Register *inlineArrayCmp(TR::Node *node, TR::CodeGenerator *cg, bool
condReg2 = cg->allocateRegister(TR_CCR);

mid2Label = generateLabelSymbol(cg);
generateTrg1Src1ImmInstruction(cg, (is64bit && isArrayCmpLen) ? TR::InstOpCode::cmpi8 : TR::InstOpCode::cmpli4, node, condReg2, byteLenRemainingRegister, byteLen);
generateTrg1Src1ImmInstruction(cg, is64bit ? TR::InstOpCode::cmpi8 : TR::InstOpCode::cmpli4, node, condReg2, byteLenRemainingRegister, byteLen);
generateConditionalBranchInstruction(cg, TR::InstOpCode::blt, node, mid2Label, condReg2);

generateTrg1Src1ImmInstruction(cg, TR::InstOpCode::addi2, node, src1AddrReg, src1AddrReg, -1*byteLen);
generateTrg1Src1ImmInstruction(cg, TR::InstOpCode::addi2, node, src2AddrReg, src2AddrReg, -1*byteLen);

if (is64bit && isArrayCmpLen)
if (is64bit)
{
generateShiftRightLogicalImmediateLong(cg, node, tempReg, byteLenRemainingRegister, (byteLen == 8) ? 3 : 2);
}
Expand Down Expand Up @@ -5728,17 +5728,17 @@ static TR::Register *inlineArrayCmp(TR::Node *node, TR::CodeGenerator *cg, bool

generateTrg1Instruction(cg, TR::InstOpCode::mfctr, node, byteLenRemainingRegister);

generateTrg1Src1ImmInstruction(cg, (is64bit && isArrayCmpLen) ? TR::InstOpCode::cmpi8 : TR::InstOpCode::cmpli4, node, condReg2, byteLenRemainingRegister, 0);
generateTrg1Src1ImmInstruction(cg, is64bit ? TR::InstOpCode::cmpi8 : TR::InstOpCode::cmpli4, node, condReg2, byteLenRemainingRegister, 0);
generateTrg1Src2Instruction(cg, TR::InstOpCode::subf, node, byteLenRemainingRegister, byteLenRemainingRegister, tempReg);

if (is64bit && isArrayCmpLen)
if (is64bit)
generateShiftLeftImmediateLong(cg, node, byteLenRemainingRegister, byteLenRemainingRegister, (byteLen == 8) ? 3 : 2);
else
generateShiftLeftImmediate(cg, node, byteLenRemainingRegister, byteLenRemainingRegister, (byteLen == 8) ? 3 : 2);

generateConditionalBranchInstruction(cg, TR::InstOpCode::bne, node, midLabel, condReg2);

generateTrg1Src2Instruction(cg, (is64bit && isArrayCmpLen) ? TR::InstOpCode::cmp8 : TR::InstOpCode::cmpl4, node, condReg2, byteLenRemainingRegister, byteLenRegister);
generateTrg1Src2Instruction(cg, is64bit ? TR::InstOpCode::cmp8 : TR::InstOpCode::cmpl4, node, condReg2, byteLenRemainingRegister, byteLenRegister);
generateLabelInstruction(cg, TR::InstOpCode::label, node, midLabel);
generateTrg1Src2Instruction(cg, TR::InstOpCode::subf, node, byteLenRemainingRegister, byteLenRemainingRegister, byteLenRegister);
generateLabelInstruction(cg, TR::InstOpCode::label, node, mid2Label);
Expand Down Expand Up @@ -5778,7 +5778,7 @@ static TR::Register *inlineArrayCmp(TR::Node *node, TR::CodeGenerator *cg, bool
}
else
{
generateTrg1Src1ImmInstruction(cg, TR::InstOpCode::cmpli4, node, condReg2, byteLenRemainingRegister, 0);
generateTrg1Src1ImmInstruction(cg, is64bit ? TR::InstOpCode::cmpli8 : TR::InstOpCode::cmpli4, node, condReg2, byteLenRemainingRegister, 0);
generateConditionalBranchInstruction(cg, TR::InstOpCode::bne, node, result2Label, condReg2);
generateTrg1ImmInstruction(cg, TR::InstOpCode::li, node, ccReg, 0);
generateLabelInstruction(cg, TR::InstOpCode::b, node, residueEndLabel);
Expand Down
10 changes: 9 additions & 1 deletion compiler/x/codegen/OMRTreeEvaluator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1151,7 +1151,15 @@ TR::Register *OMR::X86::TreeEvaluator::SSE2ArraycmpEvaluator(TR::Node *node, TR:

TR::Register *s1Reg = cg->gprClobberEvaluate(s1AddrNode, TR::InstOpCode::MOVRegReg());
TR::Register *s2Reg = cg->gprClobberEvaluate(s2AddrNode, TR::InstOpCode::MOVRegReg());
TR::Register *strLenReg = cg->gprClobberEvaluate(lengthNode, TR::InstOpCode::MOVRegReg());
TR::Register *strLenReg = cg->longClobberEvaluate(lengthNode);

if (cg->comp()->target().is32Bit() && strLenReg->getRegisterPair())
{
// On 32-bit, the length is guaranteed to fit into the bottom 32 bits
cg->stopUsingRegister(strLenReg->getHighOrder());
strLenReg = strLenReg->getLowOrder();
}

TR::Register *deltaReg = cg->allocateRegister(TR_GPR);
TR::Register *equalTestReg = cg->allocateRegister(TR_GPR);
TR::Register *s2ByteVer1Reg = cg->allocateRegister(TR_GPR);
Expand Down
13 changes: 3 additions & 10 deletions compiler/z/codegen/OMRTreeEvaluator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10759,7 +10759,9 @@ OMR::Z::TreeEvaluator::arraycmpHelper(TR::Node *node,

bool lengthCanBeZero = true;
bool lenMinusOne = false;
bool needs64BitOpCode = false;

// Length is specified to be 64 bits, however on 32 bit target the length is guaranteed to fit in 32 bits
bool needs64BitOpCode = cg->comp()->target().is64Bit();

TR::LabelSymbol *cFlowRegionStart = generateLabelSymbol(cg);
TR::LabelSymbol *cFlowRegionEnd = generateLabelSymbol(cg);
Expand All @@ -10770,15 +10772,6 @@ OMR::Z::TreeEvaluator::arraycmpHelper(TR::Node *node,
TR::RegisterPair *source1Pair = NULL;
TR::RegisterPair *source2Pair = NULL;

if (lengthNode)
{
needs64BitOpCode = lengthNode->getSize() > 4;
}
else
{
needs64BitOpCode = cg->comp()->target().is64Bit();
}

if (maxLenIn256)
{
source1Reg = cg->evaluate(source1Node);
Expand Down
Loading

0 comments on commit 2acfd24

Please sign in to comment.