Skip to content

Commit

Permalink
For Unsafe.get()/put(), reorder blocks to optimize fallthrough path
Browse files Browse the repository at this point in the history
There are three possible cases regarding the type of the object being
operated on for Unsafe.get()/put():
1.) array object
2.) java/lang/Class object
3.) none of the above

Since case (3) is the most likely, we want the block corresponding to
this case (directAccessBlock) to be on the fallthrough path.

Signed-off-by: midronij <[email protected]>
  • Loading branch information
midronij committed Nov 21, 2023
1 parent 0aabde1 commit a2c8471
Showing 1 changed file with 38 additions and 1 deletion.
39 changes: 38 additions & 1 deletion runtime/compiler/optimizer/InlinerTempForJ9.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -999,9 +999,46 @@ TR_J9InlinerPolicy::genCodeForUnsafeGetPut(TR::Node* unsafeAddress,
traceMsg(comp(),"\t\t Generating an isArray test as j9class of java/lang/Class is NULL");
directAccessBlock->getEntry()->insertTreeTopsBeforeMe(lowTagCmpBlock->getEntry(), lowTagCmpBlock->getExit());
lowTagCmpTree->getNode()->setBranchDestination(indirectAccessBlock->getEntry());
}
}

lowTagCmpBlock->getEntry()->insertTreeTopsBeforeMe(isArrayBlock->getEntry(),
isArrayBlock->getExit());

//reorder directAccess, arrayDirectAccess, and indirectAccess blocks to optimize fallthrough paths
// (want directAccess (i.e.: non array and non class object) case on fallthrough path)
if (arrayBlockNeeded)
{
//switch indirectAccessBlock and directAccessBlock
TR::Block *indirectPrevBlock = indirectAccessBlock->getEntry()->getPrevTreeTop()->getEnclosingBlock();
TR::Block *indirectNextBlock = indirectAccessBlock->getExit()->getNextTreeTop()->getEnclosingBlock();
TR::Block *directPrevBlock = directAccessBlock->getEntry()->getPrevTreeTop()->getEnclosingBlock();
TR::Block *directNextBlock = directAccessBlock->getExit()->getNextTreeTop()->getEnclosingBlock();

indirectAccessBlock->getEntry()->setPrevTreeTop(directPrevBlock->getExit());
directPrevBlock->getExit()->setNextTreeTop(indirectAccessBlock->getEntry());
indirectAccessBlock->getExit()->setNextTreeTop(directNextBlock->getEntry());
directNextBlock->getEntry()->setPrevTreeTop(indirectAccessBlock->getExit());

directAccessBlock->getEntry()->setPrevTreeTop(indirectPrevBlock->getExit());
indirectPrevBlock->getExit()->setNextTreeTop(directAccessBlock->getEntry());
directAccessBlock->getExit()->setNextTreeTop(indirectNextBlock->getEntry());
indirectNextBlock->getEntry()->setPrevTreeTop(directAccessBlock->getExit());

if (indirectPrevBlock == lowTagCmpTree->getEnclosingBlock())
{
//add goto to the end of indirectAccessBlock, since it's no longer on the fallthrough path
indirectAccessBlock->append(TR::TreeTop::create(comp(), TR::Node::create(indirectAccessBlock->getEntry()->getNode(), TR::Goto, 0, directAccessBlock->getExit()->getNextTreeTop())));

//since the directAccessBlock is now accessible via fallthrough, we need change the condition/destination
//of the conditional branch in the lowTagCmp block so that it can reach the indirectAccessBlock
TR::ILOpCodes lowTagCmpOpCode = lowTagCmpTree->getNode()->getOpCodeValue();
TR::ILOpCodes newOpCode = lowTagCmpOpCode == TR::ificmpne ? TR::ificmpeq : TR::iflcmpeq;

lowTagCmpTree->getNode()->getOpCode().setOpCodeValue(newOpCode);
lowTagCmpTree->getNode()->setBranchDestination(indirectAccessBlock->getEntry());
}
}

cfg->addEdge(TR::CFGEdge::createEdge(isArrayBlock, lowTagCmpBlock, trMemory()));
cfg->addEdge(TR::CFGEdge::createEdge(lowTagCmpBlock, indirectAccessBlock, trMemory()));
cfg->addEdge(TR::CFGEdge::createEdge(isArrayBlock, arrayBlockNeeded ? arrayDirectAccessBlock : directAccessBlock, trMemory()));
Expand Down

0 comments on commit a2c8471

Please sign in to comment.