From a2c847154d246def4e9cc5d5e24ea170656267ce Mon Sep 17 00:00:00 2001 From: midronij Date: Mon, 28 Aug 2023 10:09:24 -0400 Subject: [PATCH] For Unsafe.get()/put(), reorder blocks to optimize fallthrough path 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 --- .../compiler/optimizer/InlinerTempForJ9.cpp | 39 ++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/runtime/compiler/optimizer/InlinerTempForJ9.cpp b/runtime/compiler/optimizer/InlinerTempForJ9.cpp index 722351e907c..9eb12a4f9af 100644 --- a/runtime/compiler/optimizer/InlinerTempForJ9.cpp +++ b/runtime/compiler/optimizer/InlinerTempForJ9.cpp @@ -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()));