Skip to content

Commit f8fecbe

Browse files
authored
Merge pull request eclipse-omr#6983 from Spencer-Comin/split-arraycmp
Create arraycmplen opcode to replace arraycmp + arrayCmpLen flag
2 parents 612cde0 + 848971a commit f8fecbe

35 files changed

+537
-303
lines changed

compiler/aarch64/codegen/OMRCodeGenerator.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,11 @@ OMR::ARM64::CodeGenerator::initialize()
184184
{
185185
cg->setSupportsArrayCmp();
186186
}
187+
static const bool disableArrayCmpLen = feGetEnv("TR_aarch64DisableArrayCmpLen") != NULL;
188+
if (!disableArrayCmpLen)
189+
{
190+
cg->setSupportsArrayCmpLen();
191+
}
187192
}
188193
if (!comp->getOption(TR_DisableArraySetOpts))
189194
{

compiler/aarch64/codegen/OMRTreeEvaluator.cpp

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6796,8 +6796,8 @@ OMR::ARM64::TreeEvaluator::arraysetEvaluator(TR::Node *node, TR::CodeGenerator *
67966796
return NULL;
67976797
}
67986798

6799-
TR::Register *
6800-
OMR::ARM64::TreeEvaluator::arraycmpEvaluator(TR::Node *node, TR::CodeGenerator *cg)
6799+
static TR::Register *
6800+
arraycmpEvaluatorHelper(TR::Node *node, TR::CodeGenerator *cg, bool isArrayCmpLen)
68016801
{
68026802
/*
68036803
* Generating following instruction sequence
@@ -6903,7 +6903,6 @@ OMR::ARM64::TreeEvaluator::arraycmpEvaluator(TR::Node *node, TR::CodeGenerator *
69036903
TR::Node *src2Node = node->getSecondChild();
69046904
TR::Node *lengthNode = node->getThirdChild();
69056905
bool isLengthGreaterThan15 = lengthNode->getOpCode().isLoadConst() && lengthNode->getConstValue() > 15;
6906-
const bool isArrayCmpLen = node->isArrayCmpLen();
69076906
TR_ARM64ScratchRegisterManager *srm = cg->generateScratchRegisterManager(12);
69086907

69096908
TR::Register *savedSrc1Reg = cg->evaluate(src1Node);
@@ -6930,7 +6929,7 @@ OMR::ARM64::TreeEvaluator::arraycmpEvaluator(TR::Node *node, TR::CodeGenerator *
69306929
generateLabelInstruction(cg, TR::InstOpCode::label, node, startLabel);
69316930
if (isArrayCmpLen)
69326931
{
6933-
generateMovInstruction(cg, node, resultReg, lengthReg, false);
6932+
generateMovInstruction(cg, node, resultReg, lengthReg, true);
69346933
}
69356934
else
69366935
{
@@ -6939,7 +6938,7 @@ OMR::ARM64::TreeEvaluator::arraycmpEvaluator(TR::Node *node, TR::CodeGenerator *
69396938
generateCompareInstruction(cg, node, src1Reg, src2Reg, true);
69406939
if (!isLengthGreaterThan15)
69416940
{
6942-
auto ccmpLengthInstr = generateConditionalCompareImmInstruction(cg, node, lengthReg, 0, 4, TR::CC_NE); /* 4 for Z flag */
6941+
auto ccmpLengthInstr = generateConditionalCompareImmInstruction(cg, node, lengthReg, 0, 4, TR::CC_NE, /* is64bit */ isArrayCmpLen); /* 4 for Z flag */
69436942
if (debugObj)
69446943
{
69456944
debugObj->addInstructionComment(ccmpLengthInstr, "Compares lengthReg with 0 if src1 and src2 are not the same array. Otherwise, sets EQ flag.");
@@ -6961,14 +6960,14 @@ OMR::ARM64::TreeEvaluator::arraycmpEvaluator(TR::Node *node, TR::CodeGenerator *
69616960
TR::Register *data4Reg = srm->findOrCreateScratchRegister();
69626961
if (!isLengthGreaterThan15)
69636962
{
6964-
generateCompareImmInstruction(cg, node, lengthReg, 16);
6963+
generateCompareImmInstruction(cg, node, lengthReg, 16, /* is64bit */ isArrayCmpLen);
69656964
auto branchToLessThan16LabelInstr = generateConditionalBranchInstruction(cg, TR::InstOpCode::b_cond, node, lessThan16Label, TR::CC_CC);
69666965
if (debugObj)
69676966
{
69686967
debugObj->addInstructionComment(branchToLessThan16LabelInstr, "Jumps to lessThan16Label if length < 16.");
69696968
}
69706969
}
6971-
generateTrg1Src1ImmInstruction(cg, TR::InstOpCode::subimmw, node, lengthReg, lengthReg, 16);
6970+
generateTrg1Src1ImmInstruction(cg, isArrayCmpLen ? TR::InstOpCode::subimmx : TR::InstOpCode::subimmw, node, lengthReg, lengthReg, 16);
69726971

69736972
TR::LabelSymbol *loop16Label = generateLabelSymbol(cg);
69746973
{
@@ -6985,7 +6984,7 @@ OMR::ARM64::TreeEvaluator::arraycmpEvaluator(TR::Node *node, TR::CodeGenerator *
69856984
}
69866985
generateConditionalCompareInstruction(cg, node, data3Reg, data4Reg, 0, TR::CC_EQ, true);
69876986
auto branchToNotEqual16LabelInstr2 = generateConditionalBranchInstruction(cg, TR::InstOpCode::b_cond, node, notEqual16Label, TR::CC_NE);
6988-
auto subtractLengthInstr = generateTrg1Src1ImmInstruction(cg, isLengthGreaterThan15 ? TR::InstOpCode::subsimmx : TR::InstOpCode::subsimmw, node, lengthReg, lengthReg, 16);
6987+
auto subtractLengthInstr = generateTrg1Src1ImmInstruction(cg, (isLengthGreaterThan15 || isArrayCmpLen) ? TR::InstOpCode::subsimmx : TR::InstOpCode::subsimmw, node, lengthReg, lengthReg, 16);
69896988
auto branchBacktoLoop16LabelInstr = generateConditionalBranchInstruction(cg, TR::InstOpCode::b_cond, node, loop16Label, TR::CC_CS);
69906989
if (debugObj)
69916990
{
@@ -7004,7 +7003,10 @@ OMR::ARM64::TreeEvaluator::arraycmpEvaluator(TR::Node *node, TR::CodeGenerator *
70047003
auto branchToDoneLabelInstr3 = generateConditionalBranchInstruction(cg, TR::InstOpCode::b_cond, node, isArrayCmpLen ? done0Label : doneLabel, TR::CC_EQ);
70057004
auto adjustSrc1RegInstr = generateTrg1Src2Instruction(cg, TR::InstOpCode::addx, node, src1Reg, src1Reg, lengthReg);
70067005
generateTrg1Src2Instruction(cg, TR::InstOpCode::addx, node, src2Reg, src2Reg, lengthReg);
7007-
loadConstant32(cg, node, 0, lengthReg);
7006+
if (isArrayCmpLen)
7007+
loadConstant64(cg, node, 0, lengthReg);
7008+
else
7009+
loadConstant32(cg, node, 0, lengthReg);
70087010
auto branchBacktoLoop16LabelInstr = generateLabelInstruction(cg, TR::InstOpCode::b, node, loop16Label);
70097011
if (debugObj)
70107012
{
@@ -7022,8 +7024,18 @@ OMR::ARM64::TreeEvaluator::arraycmpEvaluator(TR::Node *node, TR::CodeGenerator *
70227024
}
70237025
else
70247026
{
7025-
generateTrg1Src1ImmInstruction(cg, TR::InstOpCode::addimmw, node, lengthReg, lengthReg, 16);
7026-
auto branchToDoneLabelInstr3 = generateCompareBranchInstruction(cg, TR::InstOpCode::cbzw, node, lengthReg, isArrayCmpLen ? done0Label : doneLabel);
7027+
TR::Instruction *branchToDoneLabelInstr3;
7028+
if (isArrayCmpLen)
7029+
{
7030+
generateTrg1Src1ImmInstruction(cg, TR::InstOpCode::addimmx, node, lengthReg, lengthReg, 16);
7031+
branchToDoneLabelInstr3 = generateCompareBranchInstruction(cg, TR::InstOpCode::cbzx, node, lengthReg, done0Label);
7032+
}
7033+
else
7034+
{
7035+
generateTrg1Src1ImmInstruction(cg, TR::InstOpCode::addimmw, node, lengthReg, lengthReg, 16);
7036+
branchToDoneLabelInstr3 = generateCompareBranchInstruction(cg, TR::InstOpCode::cbzw, node, lengthReg, doneLabel);
7037+
}
7038+
70277039
auto branchToLessThan16Label2 = generateLabelInstruction(cg, TR::InstOpCode::b, node, lessThan16Label);
70287040

70297041
if (debugObj)
@@ -7080,7 +7092,7 @@ OMR::ARM64::TreeEvaluator::arraycmpEvaluator(TR::Node *node, TR::CodeGenerator *
70807092
auto branchToDone0LabelInstr = generateLabelInstruction(cg, TR::InstOpCode::b, node, done0Label);
70817093

70827094
auto lessThan16LabelInstr = generateLabelInstruction(cg, TR::InstOpCode::label, node, lessThan16Label);
7083-
generateTrg1Src1ImmInstruction(cg, TR::InstOpCode::subsimmw, node, lengthReg, lengthReg, 1);
7095+
generateTrg1Src1ImmInstruction(cg, isArrayCmpLen ? TR::InstOpCode::subsimmx : TR::InstOpCode::subsimmw, node, lengthReg, lengthReg, 1);
70847096
generateTrg1MemInstruction(cg, TR::InstOpCode::ldrbpost, node, data1Reg, TR::MemoryReference::createWithDisplacement(cg, src1Reg, 1));
70857097
generateTrg1MemInstruction(cg, TR::InstOpCode::ldrbpost, node, data2Reg, TR::MemoryReference::createWithDisplacement(cg, src2Reg, 1));
70867098
generateConditionalCompareInstruction(cg, node, data1Reg, data2Reg, 0, TR::CC_HI);
@@ -7151,6 +7163,18 @@ OMR::ARM64::TreeEvaluator::arraycmpEvaluator(TR::Node *node, TR::CodeGenerator *
71517163
return resultReg;
71527164
}
71537165

7166+
TR::Register *
7167+
OMR::ARM64::TreeEvaluator::arraycmpEvaluator(TR::Node *node, TR::CodeGenerator *cg)
7168+
{
7169+
return arraycmpEvaluatorHelper(node, cg, false);
7170+
}
7171+
7172+
TR::Register *
7173+
OMR::ARM64::TreeEvaluator::arraycmplenEvaluator(TR::Node *node, TR::CodeGenerator *cg)
7174+
{
7175+
return arraycmpEvaluatorHelper(node, cg, true);
7176+
}
7177+
71547178
static void
71557179
inlineConstantLengthForwardArrayCopy(TR::Node *node, int64_t byteLen, TR::Register *srcReg, TR::Register *dstReg, TR::CodeGenerator *cg)
71567180
{

compiler/aarch64/codegen/OMRTreeEvaluator.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -833,6 +833,7 @@ class OMR_EXTENSIBLE TreeEvaluator: public OMR::TreeEvaluator
833833
static TR::Register *arraytranslateEvaluator(TR::Node *node, TR::CodeGenerator *cg);
834834
static TR::Register *arraytranslateAndTestEvaluator(TR::Node *node, TR::CodeGenerator *cg);
835835
static TR::Register *arraycmpEvaluator(TR::Node *node, TR::CodeGenerator *cg);
836+
static TR::Register *arraycmplenEvaluator(TR::Node *node, TR::CodeGenerator *cg);
836837
static TR::Register *computeCCEvaluator(TR::Node *node, TR::CodeGenerator *cg);
837838
static TR::Register *butestEvaluator(TR::Node *node, TR::CodeGenerator *cg);
838839
static TR::Register *sutestEvaluator(TR::Node *node, TR::CodeGenerator *cg);

compiler/arm/codegen/OMRTreeEvaluator.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3626,6 +3626,12 @@ TR::Register *OMR::ARM::TreeEvaluator::arraycmpEvaluator(TR::Node *node, TR::Cod
36263626
return NULL;
36273627
}
36283628

3629+
TR::Register *OMR::ARM::TreeEvaluator::arraycmplenEvaluator(TR::Node *node, TR::CodeGenerator *cg)
3630+
{
3631+
TR_UNIMPLEMENTED();
3632+
return NULL;
3633+
}
3634+
36293635
bool OMR::ARM::TreeEvaluator::stopUsingCopyReg(
36303636
TR::Node* node,
36313637
TR::Register*& reg,

compiler/arm/codegen/OMRTreeEvaluator.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -762,6 +762,7 @@ class OMR_EXTENSIBLE TreeEvaluator: public OMR::TreeEvaluator
762762
static TR::Register *arraytranslateAndTestEvaluator(TR::Node *node, TR::CodeGenerator *cg);
763763
static TR::Register *arraytranslateEvaluator(TR::Node *node, TR::CodeGenerator *cg);
764764
static TR::Register *arraycmpEvaluator(TR::Node *node, TR::CodeGenerator *cg);
765+
static TR::Register *arraycmplenEvaluator(TR::Node *node, TR::CodeGenerator *cg);
765766
static TR::Register *BBStartEvaluator(TR::Node *node, TR::CodeGenerator *cg);
766767
static TR::Register *BBEndEvaluator(TR::Node *node, TR::CodeGenerator *cg);
767768
static TR::Register *commonLoadEvaluator(TR::Node *node, TR::InstOpCode::Mnemonic memoryToRegisterOp, int32_t memSize, TR::CodeGenerator *cg);

compiler/codegen/OMRCodeGenerator.hpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1631,6 +1631,9 @@ class OMR_EXTENSIBLE CodeGenerator
16311631
bool getSupportsArrayCmp() {return _flags1.testAny(SupportsArrayCmp);}
16321632
void setSupportsArrayCmp() {_flags1.set(SupportsArrayCmp);}
16331633

1634+
bool getSupportsArrayCmpLen() {return _flags1.testAny(SupportsArrayCmpLen);}
1635+
void setSupportsArrayCmpLen() {_flags1.set(SupportsArrayCmpLen);}
1636+
16341637
bool getSupportsArrayCmpSign() {return _flags3.testAny(SupportsArrayCmpSign);}
16351638
void setSupportsArrayCmpSign() {_flags3.set(SupportsArrayCmpSign);}
16361639

@@ -1832,7 +1835,7 @@ class OMR_EXTENSIBLE CodeGenerator
18321835
// AVAILABLE = 0x02000000,
18331836
UsesRegisterPairsForLongs = 0x04000000,
18341837
SupportsArraySet = 0x08000000,
1835-
// AVAILABLE = 0x10000000,
1838+
SupportsArrayCmpLen = 0x10000000,
18361839
SupportsArrayCmp = 0x20000000,
18371840
DisableLongGRA = 0x40000000,
18381841
DummyLastEnum1

compiler/compile/OMRNonHelperSymbols.enum

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
arraySetSymbol,
2828
arrayCopySymbol,
2929
arrayCmpSymbol,
30+
arrayCmpLenSymbol,
3031
prefetchSymbol,
3132

3233
killsAllMethodSymbol, // A dummy method whose alias set includes all

compiler/compile/OMRSymbolReferenceTable.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -663,6 +663,19 @@ OMR::SymbolReferenceTable::findOrCreateArrayCmpSymbol()
663663
return element(arrayCmpSymbol);
664664
}
665665

666+
TR::SymbolReference *
667+
OMR::SymbolReferenceTable::findOrCreateArrayCmpLenSymbol()
668+
{
669+
if (!element(arrayCmpLenSymbol))
670+
{
671+
TR::MethodSymbol * sym = TR::MethodSymbol::create(trHeapMemory(),TR_Helper);
672+
sym->setHelper();
673+
674+
element(arrayCmpLenSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), arrayCmpLenSymbol, sym);
675+
}
676+
return element(arrayCmpLenSymbol);
677+
}
678+
666679
TR::SymbolReference *
667680
OMR::SymbolReferenceTable::findOrCreateCurrentTimeMaxPrecisionSymbol()
668681
{

compiler/compile/OMRSymbolReferenceTable.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ class SymbolReferenceTable
8888
arraySetSymbol,
8989
arrayCopySymbol,
9090
arrayCmpSymbol,
91+
arrayCmpLenSymbol,
9192
prefetchSymbol,
9293

9394
killsAllMethodSymbol, // A dummy method whose alias set includes all
@@ -844,6 +845,7 @@ class SymbolReferenceTable
844845
TR::SymbolReference * findOrCreateArrayCopySymbol();
845846
TR::SymbolReference * findOrCreateArraySetSymbol();
846847
TR::SymbolReference * findOrCreateArrayCmpSymbol();
848+
TR::SymbolReference * findOrCreateArrayCmpLenSymbol();
847849

848850
TR::SymbolReference * findOrCreateClassSymbol(TR::ResolvedMethodSymbol * owningMethodSymbol, int32_t cpIndex, void * classObject, bool cpIndexOfStatic = false);
849851
TR::SymbolReference * findOrCreateArrayShadowSymbolRef(TR::DataType type, TR::Node * baseArrayAddress, int32_t size, TR_FrontEnd * fe);

compiler/il/Aliases.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,8 @@ OMR::SymbolReference::getUseDefAliasesBV(bool isDirectCall, bool includeGCSafePo
351351
return &symRefTab->aliasBuilder.defaultMethodDefAliases();
352352
}
353353

354-
if (symRefTab->isNonHelper(self(), TR::SymbolReferenceTable::arrayCmpSymbol))
354+
if (symRefTab->isNonHelper(self(), TR::SymbolReferenceTable::arrayCmpSymbol) ||
355+
symRefTab->isNonHelper(self(), TR::SymbolReferenceTable::arrayCmpLenSymbol))
355356
return 0;
356357

357358
switch (self()->getReferenceNumber())

0 commit comments

Comments
 (0)