Skip to content

Commit

Permalink
Merge pull request #2462 from dhong44/indexOf
Browse files Browse the repository at this point in the history
Implement vectorized String.indexOf() on Z
  • Loading branch information
fjeremic authored Jul 26, 2018
2 parents f1fd1aa + 6a8cc98 commit f1fb1ff
Show file tree
Hide file tree
Showing 11 changed files with 224 additions and 30 deletions.
4 changes: 2 additions & 2 deletions jcl/src/java.base/share/classes/com/ibm/jit/JITHelpers.java
Original file line number Diff line number Diff line change
Expand Up @@ -568,7 +568,7 @@ public char getCharFromArrayByIndex(Object obj, int index) {
}
}

public int findElementFromArray(Object array, byte ch, int offset, int length) {
public int intrinsicIndexOfLatin1(Object array, byte ch, int offset, int length) {
for (int i = offset; i < length; i++) {
if(getByteFromArrayByIndex(array, i) == ch) {
return i;
Expand All @@ -577,7 +577,7 @@ public int findElementFromArray(Object array, byte ch, int offset, int length) {
return -1;
}

public int findElementFromArray(Object array, char ch, int offset, int length) {
public int intrinsicIndexOfUTF16(Object array, char ch, int offset, int length) {
for (int i = offset; i < length; i++) {
if(getCharFromArrayByIndex(array, i) == ch) {
return i;
Expand Down
8 changes: 4 additions & 4 deletions jcl/src/java.base/share/classes/java/lang/String.java
Original file line number Diff line number Diff line change
Expand Up @@ -1956,10 +1956,10 @@ public int indexOf(int c, int start) {
// Check if the String is compressed
if (enableCompression && (null == compressionFlag || coder == LATIN1)) {
if (c <= 255) {
return helpers.findElementFromArray(array, (byte)c, start, len);
return helpers.intrinsicIndexOfLatin1(array, (byte)c, start, len);
}
} else {
return helpers.findElementFromArray(array, (char)c, start, len);
return helpers.intrinsicIndexOfUTF16(array, (char)c, start, len);
}
} else if (c <= Character.MAX_CODE_POINT) {
for (int i = start; i < len; ++i) {
Expand Down Expand Up @@ -5958,10 +5958,10 @@ public int indexOf(int c, int start) {
// Check if the String is compressed
if (enableCompression && (null == compressionFlag || count >= 0)) {
if (c <= 255) {
return helpers.findElementFromArray(array, (byte)c, start, len);
return helpers.intrinsicIndexOfLatin1(array, (byte)c, start, len);
}
} else {
return helpers.findElementFromArray(array, (char)c, start, len);
return helpers.intrinsicIndexOfUTF16(array, (char)c, start, len);
}
} else if (c <= Character.MAX_CODE_POINT) {
for (int i = start; i < len; ++i) {
Expand Down
13 changes: 12 additions & 1 deletion runtime/compiler/codegen/J9CodeGenerator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,16 @@ class OMR_EXTENSIBLE CodeGenerator : public OMR::CodeGeneratorConnector
*/
void setSupportsInlineStringCaseConversion() { return _j9Flags.set(SupportsInlineStringCaseConversion);}

/** \brief
* Determines whether the code generator supports inlining of java/lang/String.indexOf()
*/
bool getSupportsInlineStringIndexOf() { return _j9Flags.testAny(SupportsInlineStringIndexOf);}

/** \brief
* The code generator supports inlining of java/lang/String.indexOf()
*/
void setSupportsInlineStringIndexOf() { return _j9Flags.set(SupportsInlineStringIndexOf);}

/**
* \brief
* The number of nodes between a monext and the next monent before
Expand All @@ -390,7 +400,8 @@ class OMR_EXTENSIBLE CodeGenerator : public OMR::CodeGeneratorConnector
{
HasFixedFrameC_CallingConvention = 0x00000001,
SupportsMaxPrecisionMilliTime = 0x00000002,
SupportsInlineStringCaseConversion = 0x00000004 /*! codegen inlining of Java string case conversion */
SupportsInlineStringCaseConversion = 0x00000004, /*! codegen inlining of Java string case conversion */
SupportsInlineStringIndexOf = 0x00000008 /*! codegen inlining of Java string index of */
};

flags32_t _j9Flags;
Expand Down
3 changes: 2 additions & 1 deletion runtime/compiler/codegen/J9RecognizedMethodsEnum.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -664,7 +664,8 @@

com_ibm_jit_JITHelpers_is32Bit,
com_ibm_jit_JITHelpers_isArray,
com_ibm_jit_JITHelpers_findElementFromArray,
com_ibm_jit_JITHelpers_intrinsicIndexOfLatin1,
com_ibm_jit_JITHelpers_intrinsicIndexOfUTF16,
com_ibm_jit_JITHelpers_getJ9ClassFromObject32,
com_ibm_jit_JITHelpers_getJ9ClassFromObject64,
com_ibm_jit_JITHelpers_getNumBitsInReferenceField,
Expand Down
11 changes: 9 additions & 2 deletions runtime/compiler/env/VMJ9.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3092,15 +3092,22 @@ bool TR_J9VMBase::supressInliningRecognizedInitialCallee(TR_CallSite* callsite,
if(comp->cg()->getSupportsInlineStringCaseConversion())
{
dontInlineRecognizedMethod = true;
break;
}
break;
case TR::com_ibm_jit_JITHelpers_intrinsicIndexOfLatin1:
case TR::com_ibm_jit_JITHelpers_intrinsicIndexOfUTF16:
if (comp->cg()->getSupportsInlineStringIndexOf())
{
dontInlineRecognizedMethod = true;
}
break;
case TR::java_lang_Math_max_D:
case TR::java_lang_Math_min_D:
if(comp->cg()->getSupportsVectorRegisters() && !comp->getOption(TR_DisableSIMDDoubleMaxMin))
{
dontInlineRecognizedMethod = true;
break;
}
break;
case TR::java_lang_String_hashCodeImplDecompressed:
case TR::java_lang_String_hashCodeImplCompressed:
if (!TR::Compiler->om.canGenerateArraylets()){
Expand Down
3 changes: 2 additions & 1 deletion runtime/compiler/env/j9method.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3231,7 +3231,8 @@ TR_ResolvedJ9Method::TR_ResolvedJ9Method(TR_OpaqueMethodBlock * aMethod, TR_Fron
{
{x(TR::com_ibm_jit_JITHelpers_is32Bit, "is32Bit", "()Z")},
{x(TR::com_ibm_jit_JITHelpers_isArray, "isArray", "(Ljava/lang/Object;)Z")},
{ TR::com_ibm_jit_JITHelpers_findElementFromArray, 20, "findElementFromArray", (int16_t)-1, "*" },
{x(TR::com_ibm_jit_JITHelpers_intrinsicIndexOfLatin1, "intrinsicIndexOfLatin1", "(Ljava/lang/Object;BII)I")},
{x(TR::com_ibm_jit_JITHelpers_intrinsicIndexOfUTF16, "intrinsicIndexOfUTF16", "(Ljava/lang/Object;CII)I")},
#ifdef TR_TARGET_32BIT
{x(TR::com_ibm_jit_JITHelpers_getJ9ClassFromObject32, "getJ9ClassFromObject32", "(Ljava/lang/Object;)I")},
{x(TR::com_ibm_jit_JITHelpers_getJ9ClassFromClass32, "getJ9ClassFromClass32", "(Ljava/lang/Class;)I")},
Expand Down
3 changes: 2 additions & 1 deletion runtime/compiler/optimizer/InlinerTempForJ9.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,8 @@ TR_J9InlinerPolicy::alwaysWorthInlining(TR_ResolvedMethod * calleeMethod, TR::No
case TR::com_ibm_jit_JITHelpers_compareAndSwapLongInArray:
case TR::com_ibm_jit_JITHelpers_compareAndSwapObjectInArray:
case TR::com_ibm_jit_JITHelpers_jitHelpers:
case TR::com_ibm_jit_JITHelpers_findElementFromArray:
case TR::com_ibm_jit_JITHelpers_intrinsicIndexOfLatin1:
case TR::com_ibm_jit_JITHelpers_intrinsicIndexOfUTF16:
case TR::java_lang_String_charAtInternal_I:
case TR::java_lang_String_charAtInternal_IB:
case TR::java_lang_String_length:
Expand Down
8 changes: 7 additions & 1 deletion runtime/compiler/x/codegen/J9CodeGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,13 @@ J9::X86::CodeGenerator::CodeGenerator() :
!TR::Compiler->om.canGenerateArraylets())
cg->setSupportsInlineStringCaseConversion();

if (cg->getX86ProcessorInfo().supportsSSSE3() &&
!comp->getOption(TR_DisableFastStringIndexOf) &&
!TR::Compiler->om.canGenerateArraylets())
{
cg->setSupportsInlineStringIndexOf();
}

if (comp->generateArraylets() && !comp->getOptions()->realTimeGC())
{
cg->setSupportsStackAllocationOfArraylets();
Expand Down Expand Up @@ -383,7 +390,6 @@ J9::X86::CodeGenerator::suppressInliningOfRecognizedMethod(TR::RecognizedMethod
switch (method)
{
case TR::java_lang_Object_clone:
case TR::com_ibm_jit_JITHelpers_findElementFromArray:
return true;
default:
return false;
Expand Down
36 changes: 19 additions & 17 deletions runtime/compiler/x/codegen/J9TreeEvaluator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11347,7 +11347,7 @@ TR::Register *intOrLongClobberEvaluate(
}
}

static TR::Register* inlineFindElementFromArray(TR::Node* node, TR::CodeGenerator* cg)
static TR::Register* intrinsicIndexOf(TR::Node* node, TR::CodeGenerator* cg, bool isCompressed)
{
static uint8_t MASKOFSIZEONE[] =
{
Expand All @@ -11368,20 +11368,17 @@ static TR::Register* inlineFindElementFromArray(TR::Node* node, TR::CodeGenerato
uint8_t shift = 0;
uint8_t* shuffleMask = NULL;
auto compareOp = BADIA32Op;
switch(node->getSymbol()->castToMethodSymbol()->getMethod()->parmType(1))
if(isCompressed)
{
case TR::Int8:
shuffleMask = MASKOFSIZEONE;
compareOp = PCMPEQBRegReg;
shift = 0;
break;
case TR::Int16:
shuffleMask = MASKOFSIZETWO;
compareOp = PCMPEQWRegReg;
shift = 1;
break;
default:
TR_ASSERT(0, "Incorrect value parameter type!");
shuffleMask = MASKOFSIZEONE;
compareOp = PCMPEQBRegReg;
shift = 0;
}
else
{
shuffleMask = MASKOFSIZETWO;
compareOp = PCMPEQWRegReg;
shift = 1;
}

auto address = cg->evaluate(node->getChild(1));
Expand Down Expand Up @@ -13626,11 +13623,16 @@ J9::X86::TreeEvaluator::directCallEvaluator(TR::Node *node, TR::CodeGenerator *c

switch (symbol->getMandatoryRecognizedMethod())
{
case TR::com_ibm_jit_JITHelpers_findElementFromArray:
if (TR::Compiler->om.canGenerateArraylets() || !cg->getX86ProcessorInfo().supportsSSSE3())
case TR::com_ibm_jit_JITHelpers_intrinsicIndexOfLatin1:
if (!cg->getSupportsInlineStringIndexOf())
break;
else
return intrinsicIndexOf(node, cg, true);
case TR::com_ibm_jit_JITHelpers_intrinsicIndexOfUTF16:
if (!cg->getSupportsInlineStringIndexOf())
break;
else
return inlineFindElementFromArray(node, cg);
return intrinsicIndexOf(node, cg, false);
case TR::com_ibm_jit_JITHelpers_transformedEncodeUTF16Big:
case TR::com_ibm_jit_JITHelpers_transformedEncodeUTF16Little:
return TR::TreeEvaluator::encodeUTF16Evaluator(node, cg);
Expand Down
23 changes: 23 additions & 0 deletions runtime/compiler/z/codegen/J9CodeGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,12 @@ J9::Z::CodeGenerator::CodeGenerator() :
if (cg->getSupportsVectorRegisters() && !comp->getOption(TR_DisableSIMDStringCaseConv))
cg->setSupportsInlineStringCaseConversion();

if (cg->getSupportsVectorRegisters() && !comp->getOption(TR_DisableFastStringIndexOf) &&
!TR::Compiler->om.canGenerateArraylets())
{
cg->setSupportsInlineStringIndexOf();
}

// Let's turn this on. There is more work needed in the opt
// to catch the case where the BNDSCHK is inserted after
//
Expand Down Expand Up @@ -3938,6 +3944,8 @@ extern TR::Register *inlineBigDecimalToPackedConverter(TR::Node * node, TR::Code
extern TR::Register *toUpperIntrinsic(TR::Node * node, TR::CodeGenerator * cg, bool isCompressedString);
extern TR::Register *toLowerIntrinsic(TR::Node * node, TR::CodeGenerator * cg, bool isCompressedString);

extern TR::Register *intrinsicIndexOf(TR::Node * node, TR::CodeGenerator * cg, bool isCompressed);

extern TR::Register *inlineDoubleMax(TR::Node *node, TR::CodeGenerator *cg);
extern TR::Register *inlineDoubleMin(TR::Node *node, TR::CodeGenerator *cg);

Expand Down Expand Up @@ -4221,6 +4229,21 @@ J9::Z::CodeGenerator::inlineDirectCall(
}
}

if (cg->getSupportsInlineStringIndexOf())
{
switch (methodSymbol->getRecognizedMethod())
{
case TR::com_ibm_jit_JITHelpers_intrinsicIndexOfLatin1:
resultReg = intrinsicIndexOf(node, cg, true);
return true;
case TR::com_ibm_jit_JITHelpers_intrinsicIndexOfUTF16:
resultReg = intrinsicIndexOf(node, cg, false);
return true;
default:
break;
}
}

if (!comp->getOption(TR_DisableSIMDDoubleMaxMin) && cg->getSupportsVectorRegisters())
{
switch (methodSymbol->getRecognizedMethod())
Expand Down
Loading

0 comments on commit f1fb1ff

Please sign in to comment.