Skip to content

Commit

Permalink
Merge pull request #17331 from VermaSh/inlineStringHashCode_cleanup
Browse files Browse the repository at this point in the history
Hoist getSupportsInlineStringHashCode check for better readability
  • Loading branch information
0xdaryl committed May 5, 2023
2 parents 74c5450 + ba8a0fa commit eb7a704
Showing 1 changed file with 102 additions and 103 deletions.
205 changes: 102 additions & 103 deletions runtime/compiler/x/codegen/J9TreeEvaluator.cpp
Expand Up @@ -9237,112 +9237,105 @@ inlineNanoTime(
// end_label
static TR::Register* inlineStringHashCode(TR::Node* node, bool isCompressed, TR::CodeGenerator* cg)
{
if (!cg->getSupportsInlineStringHashCode())
{
return NULL;
}
else
{
TR_ASSERT(node->getChild(1)->getOpCodeValue() == TR::iconst && node->getChild(1)->getInt() == 0, "String hashcode offset can only be const zero.");
TR_ASSERT(node->getChild(1)->getOpCodeValue() == TR::iconst && node->getChild(1)->getInt() == 0, "String hashcode offset can only be const zero.");

const int size = 4;
auto shift = isCompressed ? 0 : 1;
const int size = 4;
auto shift = isCompressed ? 0 : 1;

auto address = cg->evaluate(node->getChild(0));
auto length = cg->evaluate(node->getChild(2));
auto index = cg->allocateRegister();
auto hash = cg->allocateRegister();
auto tmp = cg->allocateRegister();
auto hashXMM = cg->allocateRegister(TR_VRF);
auto tmpXMM = cg->allocateRegister(TR_VRF);
auto multiplierXMM = cg->allocateRegister(TR_VRF);
auto address = cg->evaluate(node->getChild(0));
auto length = cg->evaluate(node->getChild(2));
auto index = cg->allocateRegister();
auto hash = cg->allocateRegister();
auto tmp = cg->allocateRegister();
auto hashXMM = cg->allocateRegister(TR_VRF);
auto tmpXMM = cg->allocateRegister(TR_VRF);
auto multiplierXMM = cg->allocateRegister(TR_VRF);

auto begLabel = generateLabelSymbol(cg);
auto endLabel = generateLabelSymbol(cg);
auto loopLabel = generateLabelSymbol(cg);
begLabel->setStartInternalControlFlow();
endLabel->setEndInternalControlFlow();
auto deps = generateRegisterDependencyConditions((uint8_t)6, (uint8_t)6, cg);
deps->addPreCondition(address, TR::RealRegister::NoReg, cg);
deps->addPreCondition(index, TR::RealRegister::NoReg, cg);
deps->addPreCondition(length, TR::RealRegister::NoReg, cg);
deps->addPreCondition(multiplierXMM, TR::RealRegister::NoReg, cg);
deps->addPreCondition(tmpXMM, TR::RealRegister::NoReg, cg);
deps->addPreCondition(hashXMM, TR::RealRegister::NoReg, cg);
deps->addPostCondition(address, TR::RealRegister::NoReg, cg);
deps->addPostCondition(index, TR::RealRegister::NoReg, cg);
deps->addPostCondition(length, TR::RealRegister::NoReg, cg);
deps->addPostCondition(multiplierXMM, TR::RealRegister::NoReg, cg);
deps->addPostCondition(tmpXMM, TR::RealRegister::NoReg, cg);
deps->addPostCondition(hashXMM, TR::RealRegister::NoReg, cg);

generateRegRegInstruction(TR::InstOpCode::MOV4RegReg, node, index, length, cg);
generateRegImmInstruction(TR::InstOpCode::AND4RegImms, node, index, size-1, cg); // mod size
generateRegMemInstruction(TR::InstOpCode::CMOVE4RegMem, node, index, generateX86MemoryReference(cg->findOrCreate4ByteConstant(node, size), cg), cg);

// Prepend zeros
{
TR::Compilation *comp = cg->comp();

static uint64_t MASKDECOMPRESSED[] = { 0x0000000000000000ULL, 0xffffffffffffffffULL };
static uint64_t MASKCOMPRESSED[] = { 0xffffffff00000000ULL, 0x0000000000000000ULL };
generateRegMemInstruction(isCompressed ? TR::InstOpCode::MOVDRegMem : TR::InstOpCode::MOVQRegMem, node, hashXMM, generateX86MemoryReference(address, index, shift, -(size << shift) + TR::Compiler->om.contiguousArrayHeaderSizeInBytes(), cg), cg);
generateRegMemInstruction(TR::InstOpCode::LEARegMem(), node, tmp, generateX86MemoryReference(cg->findOrCreate16ByteConstant(node, isCompressed ? MASKCOMPRESSED : MASKDECOMPRESSED), cg), cg);

auto mr = generateX86MemoryReference(tmp, index, shift, 0, cg);
if (comp->target().cpu.supportsAVX())
{
generateRegMemInstruction(TR::InstOpCode::PANDRegMem, node, hashXMM, mr, cg);
}
else
{
generateRegMemInstruction(TR::InstOpCode::MOVDQURegMem, node, tmpXMM, mr, cg);
generateRegRegInstruction(TR::InstOpCode::PANDRegReg, node, hashXMM, tmpXMM, cg);
}
generateRegRegInstruction(isCompressed ? TR::InstOpCode::PMOVZXBDRegReg : TR::InstOpCode::PMOVZXWDRegReg, node, hashXMM, hashXMM, cg);
}
auto begLabel = generateLabelSymbol(cg);
auto endLabel = generateLabelSymbol(cg);
auto loopLabel = generateLabelSymbol(cg);
begLabel->setStartInternalControlFlow();
endLabel->setEndInternalControlFlow();
auto deps = generateRegisterDependencyConditions((uint8_t)6, (uint8_t)6, cg);
deps->addPreCondition(address, TR::RealRegister::NoReg, cg);
deps->addPreCondition(index, TR::RealRegister::NoReg, cg);
deps->addPreCondition(length, TR::RealRegister::NoReg, cg);
deps->addPreCondition(multiplierXMM, TR::RealRegister::NoReg, cg);
deps->addPreCondition(tmpXMM, TR::RealRegister::NoReg, cg);
deps->addPreCondition(hashXMM, TR::RealRegister::NoReg, cg);
deps->addPostCondition(address, TR::RealRegister::NoReg, cg);
deps->addPostCondition(index, TR::RealRegister::NoReg, cg);
deps->addPostCondition(length, TR::RealRegister::NoReg, cg);
deps->addPostCondition(multiplierXMM, TR::RealRegister::NoReg, cg);
deps->addPostCondition(tmpXMM, TR::RealRegister::NoReg, cg);
deps->addPostCondition(hashXMM, TR::RealRegister::NoReg, cg);

// Reduction Loop
generateRegRegInstruction(TR::InstOpCode::MOV4RegReg, node, index, length, cg);
generateRegImmInstruction(TR::InstOpCode::AND4RegImms, node, index, size-1, cg); // mod size
generateRegMemInstruction(TR::InstOpCode::CMOVE4RegMem, node, index, generateX86MemoryReference(cg->findOrCreate4ByteConstant(node, size), cg), cg);

// Prepend zeros
{
TR::Compilation *comp = cg->comp();

static uint64_t MASKDECOMPRESSED[] = { 0x0000000000000000ULL, 0xffffffffffffffffULL };
static uint64_t MASKCOMPRESSED[] = { 0xffffffff00000000ULL, 0x0000000000000000ULL };
generateRegMemInstruction(isCompressed ? TR::InstOpCode::MOVDRegMem : TR::InstOpCode::MOVQRegMem, node, hashXMM, generateX86MemoryReference(address, index, shift, -(size << shift) + TR::Compiler->om.contiguousArrayHeaderSizeInBytes(), cg), cg);
generateRegMemInstruction(TR::InstOpCode::LEARegMem(), node, tmp, generateX86MemoryReference(cg->findOrCreate16ByteConstant(node, isCompressed ? MASKCOMPRESSED : MASKDECOMPRESSED), cg), cg);

auto mr = generateX86MemoryReference(tmp, index, shift, 0, cg);
if (comp->target().cpu.supportsAVX())
{
static uint32_t multiplier[] = { 31*31*31*31, 31*31*31*31, 31*31*31*31, 31*31*31*31 };
generateLabelInstruction(TR::InstOpCode::label, node, begLabel, cg);
generateRegRegInstruction(TR::InstOpCode::CMP4RegReg, node, index, length, cg);
generateLabelInstruction(TR::InstOpCode::JGE4, node, endLabel, cg);
generateRegMemInstruction(TR::InstOpCode::MOVDQURegMem, node, multiplierXMM, generateX86MemoryReference(cg->findOrCreate16ByteConstant(node, multiplier), cg), cg);
generateLabelInstruction(TR::InstOpCode::label, node, loopLabel, cg);
generateRegRegInstruction(TR::InstOpCode::PMULLDRegReg, node, hashXMM, multiplierXMM, cg);
generateRegMemInstruction(isCompressed ? TR::InstOpCode::PMOVZXBDRegMem : TR::InstOpCode::PMOVZXWDRegMem, node, tmpXMM, generateX86MemoryReference(address, index, shift, TR::Compiler->om.contiguousArrayHeaderSizeInBytes(), cg), cg);
generateRegImmInstruction(TR::InstOpCode::ADD4RegImms, node, index, 4, cg);
generateRegRegInstruction(TR::InstOpCode::PADDDRegReg, node, hashXMM, tmpXMM, cg);
generateRegRegInstruction(TR::InstOpCode::CMP4RegReg, node, index, length, cg);
generateLabelInstruction(TR::InstOpCode::JL4, node, loopLabel, cg);
generateLabelInstruction(TR::InstOpCode::label, node, endLabel, deps, cg);
generateRegMemInstruction(TR::InstOpCode::PANDRegMem, node, hashXMM, mr, cg);
}

// Finalization
else
{
static uint32_t multiplier[] = { 31*31*31, 31*31, 31, 1 };
generateRegMemInstruction(TR::InstOpCode::PMULLDRegMem, node, hashXMM, generateX86MemoryReference(cg->findOrCreate16ByteConstant(node, multiplier), cg), cg);
generateRegRegImmInstruction(TR::InstOpCode::PSHUFDRegRegImm1, node, tmpXMM, hashXMM, 0x0e, cg);
generateRegRegInstruction(TR::InstOpCode::PADDDRegReg, node, hashXMM, tmpXMM, cg);
generateRegRegImmInstruction(TR::InstOpCode::PSHUFDRegRegImm1, node, tmpXMM, hashXMM, 0x01, cg);
generateRegRegInstruction(TR::InstOpCode::PADDDRegReg, node, hashXMM, tmpXMM, cg);
generateRegMemInstruction(TR::InstOpCode::MOVDQURegMem, node, tmpXMM, mr, cg);
generateRegRegInstruction(TR::InstOpCode::PANDRegReg, node, hashXMM, tmpXMM, cg);
}
generateRegRegInstruction(isCompressed ? TR::InstOpCode::PMOVZXBDRegReg : TR::InstOpCode::PMOVZXWDRegReg, node, hashXMM, hashXMM, cg);
}

generateRegRegInstruction(TR::InstOpCode::MOVDReg4Reg, node, hash, hashXMM, cg);
// Reduction Loop
{
static uint32_t multiplier[] = { 31*31*31*31, 31*31*31*31, 31*31*31*31, 31*31*31*31 };
generateLabelInstruction(TR::InstOpCode::label, node, begLabel, cg);
generateRegRegInstruction(TR::InstOpCode::CMP4RegReg, node, index, length, cg);
generateLabelInstruction(TR::InstOpCode::JGE4, node, endLabel, cg);
generateRegMemInstruction(TR::InstOpCode::MOVDQURegMem, node, multiplierXMM, generateX86MemoryReference(cg->findOrCreate16ByteConstant(node, multiplier), cg), cg);
generateLabelInstruction(TR::InstOpCode::label, node, loopLabel, cg);
generateRegRegInstruction(TR::InstOpCode::PMULLDRegReg, node, hashXMM, multiplierXMM, cg);
generateRegMemInstruction(isCompressed ? TR::InstOpCode::PMOVZXBDRegMem : TR::InstOpCode::PMOVZXWDRegMem, node, tmpXMM, generateX86MemoryReference(address, index, shift, TR::Compiler->om.contiguousArrayHeaderSizeInBytes(), cg), cg);
generateRegImmInstruction(TR::InstOpCode::ADD4RegImms, node, index, 4, cg);
generateRegRegInstruction(TR::InstOpCode::PADDDRegReg, node, hashXMM, tmpXMM, cg);
generateRegRegInstruction(TR::InstOpCode::CMP4RegReg, node, index, length, cg);
generateLabelInstruction(TR::InstOpCode::JL4, node, loopLabel, cg);
generateLabelInstruction(TR::InstOpCode::label, node, endLabel, deps, cg);
}

cg->stopUsingRegister(index);
cg->stopUsingRegister(tmp);
cg->stopUsingRegister(hashXMM);
cg->stopUsingRegister(tmpXMM);
cg->stopUsingRegister(multiplierXMM);
// Finalization
{
static uint32_t multiplier[] = { 31*31*31, 31*31, 31, 1 };
generateRegMemInstruction(TR::InstOpCode::PMULLDRegMem, node, hashXMM, generateX86MemoryReference(cg->findOrCreate16ByteConstant(node, multiplier), cg), cg);
generateRegRegImmInstruction(TR::InstOpCode::PSHUFDRegRegImm1, node, tmpXMM, hashXMM, 0x0e, cg);
generateRegRegInstruction(TR::InstOpCode::PADDDRegReg, node, hashXMM, tmpXMM, cg);
generateRegRegImmInstruction(TR::InstOpCode::PSHUFDRegRegImm1, node, tmpXMM, hashXMM, 0x01, cg);
generateRegRegInstruction(TR::InstOpCode::PADDDRegReg, node, hashXMM, tmpXMM, cg);
}

node->setRegister(hash);
cg->decReferenceCount(node->getChild(0));
cg->recursivelyDecReferenceCount(node->getChild(1));
cg->decReferenceCount(node->getChild(2));
return hash;
}
generateRegRegInstruction(TR::InstOpCode::MOVDReg4Reg, node, hash, hashXMM, cg);

cg->stopUsingRegister(index);
cg->stopUsingRegister(tmp);
cg->stopUsingRegister(hashXMM);
cg->stopUsingRegister(tmpXMM);
cg->stopUsingRegister(multiplierXMM);

node->setRegister(hash);
cg->decReferenceCount(node->getChild(0));
cg->recursivelyDecReferenceCount(node->getChild(1));
cg->decReferenceCount(node->getChild(2));
return hash;
}

static bool
Expand Down Expand Up @@ -11606,27 +11599,33 @@ J9::X86::TreeEvaluator::directCallEvaluator(TR::Node *node, TR::CodeGenerator *c
switch (symbol->getMandatoryRecognizedMethod())
{
case TR::com_ibm_jit_JITHelpers_intrinsicIndexOfLatin1:
if (!cg->getSupportsInlineStringIndexOf())
break;
else
if (cg->getSupportsInlineStringIndexOf())
return inlineIntrinsicIndexOf(node, cg, true);
break;

case TR::com_ibm_jit_JITHelpers_intrinsicIndexOfUTF16:
if (!cg->getSupportsInlineStringIndexOf())
break;
else
if (cg->getSupportsInlineStringIndexOf())
return inlineIntrinsicIndexOf(node, cg, false);
break;

case TR::com_ibm_jit_JITHelpers_transformedEncodeUTF16Big:
case TR::com_ibm_jit_JITHelpers_transformedEncodeUTF16Little:
return TR::TreeEvaluator::encodeUTF16Evaluator(node, cg);

case TR::java_lang_String_hashCodeImplDecompressed:
returnRegister = inlineStringHashCode(node, false, cg);
if (cg->getSupportsInlineStringHashCode())
returnRegister = inlineStringHashCode(node, false, cg);

callInlined = (returnRegister != NULL);
break;

case TR::java_lang_String_hashCodeImplCompressed:
returnRegister = inlineStringHashCode(node, true, cg);
if (cg->getSupportsInlineStringHashCode())
returnRegister = inlineStringHashCode(node, true, cg);

callInlined = (returnRegister != NULL);
break;

default:
break;
}
Expand Down

0 comments on commit eb7a704

Please sign in to comment.