本文整理汇总了C++中tr::Node::getSecondChild方法的典型用法代码示例。如果您正苦于以下问题:C++ Node::getSecondChild方法的具体用法?C++ Node::getSecondChild怎么用?C++ Node::getSecondChild使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类tr::Node
的用法示例。
在下文中一共展示了Node::getSecondChild方法的10个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: if
int32_t
TR::RegDepCopyRemoval::perform()
{
if (!cg()->supportsPassThroughCopyToNewVirtualRegister())
return 0;
discardAllNodeChoices();
TR::TreeTop *tt;
for (tt = comp()->getStartTree(); tt != NULL; tt = tt->getNextTreeTop())
{
TR::Node *node = tt->getNode();
switch (node->getOpCodeValue())
{
case TR::BBStart:
if (!node->getBlock()->isExtensionOfPreviousBlock())
{
if (trace())
traceMsg(comp(), "clearing remembered node choices at start of extended block at block_%d\n", node->getBlock()->getNumber());
discardAllNodeChoices();
}
if (node->getNumChildren() > 0)
processRegDeps(node->getFirstChild(), tt);
break;
case TR::BBEnd:
if (node->getNumChildren() > 0)
processRegDeps(node->getFirstChild(), tt);
break;
default:
if (node->getOpCode().isSwitch())
{
TR::Node *defaultDest = node->getSecondChild();
if (defaultDest->getNumChildren() > 0)
processRegDeps(defaultDest->getFirstChild(), tt);
}
else if (node->getOpCode().isBranch())
{
int nChildren = node->getNumChildren();
// only the last child may be GlRegDeps
for (int i = 0; i < nChildren - 1; i++)
TR_ASSERT(node->getChild(i)->getOpCodeValue() != TR::GlRegDeps, "GlRegDeps for branch is not the last child\n");
if (nChildren > 0)
{
TR::Node *lastChild = node->getChild(nChildren - 1);
if (lastChild->getOpCodeValue() == TR::GlRegDeps)
processRegDeps(lastChild, tt);
}
}
break;
}
}
return 1; // a bit arbitrary...
}
示例2:
TR::TreeTop *searchForStringAppend(TR::ValuePropagation *vp,const char *sig, TR::TreeTop *tt, TR::TreeTop *exitTree,
TR::ILOpCodes opCode, TR::Node *newBuffer, vcount_t visitCount, TR::Node **string)
{
int len = 0;
bool isGlobal = false;
for (;tt != exitTree; tt = tt->getNextRealTreeTop())
{
TR::Node *node = tt->getNode();
if (node->getNumChildren() == 1 &&
node->getFirstChild()->getOpCodeValue() == opCode)
{
if (checkMethodSignature(vp,node->getFirstChild()->getSymbolReference(), sig))
{
TR::Node *call = node->getFirstChild();
if (call->getFirstChild() == newBuffer)
{
if (vp->getConstraint(call->getSecondChild(),isGlobal))
{
if (vp->getConstraint(call->getSecondChild(),isGlobal)->getClassType())
{
const char *sigAppend = vp->getConstraint(call->getSecondChild(),isGlobal)->getClassType()->getClassSignature(len);
if (call->getSecondChild()->getOpCodeValue() == TR::aload && (!strncmp(sigAppend,"Ljava/lang/String;",18)))
{
*string = call->getSecondChild();
}
}
}
}
return tt;
}
else
return tt;
}
//if (countNodeOccurrencesInSubTree(node, newBuffer, visitCount) > 0) return tt;
}
return tt;
}
示例3: if
TR::Node *
OMR::TransformUtil::scalarizeArrayCopy(
TR::Compilation *comp,
TR::Node *node,
TR::TreeTop *tt,
bool useElementType,
bool &didTransformArrayCopyNode,
TR::SymbolReference *sourceRef,
TR::SymbolReference *targetRef,
bool castToIntegral)
{
TR::CodeGenerator *cg = comp->cg();
didTransformArrayCopyNode = false;
if ((comp->getOptLevel() == noOpt) ||
!comp->getOption(TR_ScalarizeSSOps) ||
node->getOpCodeValue() != TR::arraycopy ||
node->getNumChildren() != 3 ||
comp->requiresSpineChecks() ||
!node->getChild(2)->getOpCode().isLoadConst() ||
cg->getOptimizationPhaseIsComplete())
return node;
int64_t byteLen = node->getChild(2)->get64bitIntegralValue();
if (byteLen == 0)
{
if (tt)
{
// Anchor the first two children
if (!node->getFirstChild()->safeToDoRecursiveDecrement())
TR::TreeTop::create(comp, tt->getPrevTreeTop(),
TR::Node::create(TR::treetop, 1, node->getFirstChild()));
if (!node->getSecondChild()->safeToDoRecursiveDecrement())
TR::TreeTop::create(comp, tt->getPrevTreeTop(),
TR::Node::create(TR::treetop, 1, node->getSecondChild()));
tt->getPrevTreeTop()->join(tt->getNextTreeTop());
tt->getNode()->recursivelyDecReferenceCount();
didTransformArrayCopyNode = true;
}
return node;
}
else if (byteLen < 0)
{
return node;
}
else if (byteLen > TR_MAX_OTYPE_SIZE)
{
return node;
}
TR::DataType dataType = TR::Aggregate;
// Get the element datatype from the (hidden) 4th child
TR::DataType elementType = node->getArrayCopyElementType();
int32_t elementSize = TR::Symbol::convertTypeToSize(elementType);
if (byteLen == elementSize)
{
dataType = elementType;
}
else if (!useElementType)
{
switch (byteLen)
{
case 1: dataType = TR::Int8; break;
case 2: dataType = TR::Int16; break;
case 4: dataType = TR::Int32; break;
case 8: dataType = TR::Int64; break;
}
}
else
{
return node;
}
// load/store double on 64-bit PPC requires offset to be word aligned
// abort if this requirement is not met.
// TODO: also need to check if the first two children are aload nodes
bool cannot_use_load_store_long = false;
if (TR::Compiler->target.cpu.isPower())
if (dataType == TR::Int64 && TR::Compiler->target.is64Bit())
{
TR::Node * firstChild = node->getFirstChild();
if (firstChild->getNumChildren() == 2)
{
TR::Node *offsetChild = firstChild->getSecondChild();
TR_ASSERT(offsetChild->getOpCodeValue() != TR::iconst, "iconst shouldn't be used for 64-bit array indexing");
if (offsetChild->getOpCodeValue() == TR::lconst)
{
if ((offsetChild->getLongInt() & 0x3) != 0)
cannot_use_load_store_long = true;
}
}
TR::Node *secondChild = node->getSecondChild();
if (secondChild->getNumChildren() == 2)
{
TR::Node *offsetChild = secondChild->getSecondChild();
TR_ASSERT(offsetChild->getOpCodeValue() != TR::iconst, "iconst shouldn't be used for 64-bit array indexing");
if (offsetChild->getOpCodeValue() == TR::lconst)
{
//.........这里部分代码省略.........
示例4: if
bool
OMR::Simplifier::isBoundDefinitelyGELength(TR::Node *boundChild, TR::Node *lengthChild)
{
TR::ILOpCodes boundOp = boundChild->getOpCodeValue();
if (boundOp == TR::iadd)
{
TR::Node *first = boundChild->getFirstChild();
TR::Node *second = boundChild->getSecondChild();
if (first == lengthChild)
{
TR::ILOpCodes secondOp = second->getOpCodeValue();
if (second->getOpCode().isArrayLength() ||
secondOp == TR::bu2i ||
secondOp == TR::su2i ||
(secondOp == TR::iconst &&
second->getInt() >= 0) ||
(secondOp == TR::iand &&
second->getSecondChild()->getOpCodeValue() == TR::iconst &&
(second->getSecondChild()->getInt() & 80000000) == 0) ||
(secondOp == TR::iushr &&
second->getSecondChild()->getOpCodeValue() == TR::iconst &&
(second->getSecondChild()->getInt() & 0x1f) > 0))
{
return true;
}
}
else if (second == lengthChild)
{
TR::ILOpCodes firstOp = first->getOpCodeValue();
if (first->getOpCode().isArrayLength() ||
firstOp == TR::bu2i ||
firstOp == TR::su2i ||
(firstOp == TR::iand &&
first->getSecondChild()->getOpCodeValue() == TR::iconst &&
(first->getSecondChild()->getInt() & 80000000) == 0) ||
(firstOp == TR::iushr &&
first->getSecondChild()->getOpCodeValue() == TR::iconst &&
(first->getSecondChild()->getInt() & 0x1f) > 0))
{
return true;
}
}
}
else if (boundOp == TR::isub)
{
TR::Node *first = boundChild->getFirstChild();
TR::Node *second = boundChild->getSecondChild();
if (first == lengthChild)
{
TR::ILOpCodes secondOp = second->getOpCodeValue();
if ((secondOp == TR::iconst &&
second->getInt() < 0) ||
(secondOp == TR::ior &&
second->getSecondChild()->getOpCodeValue() == TR::iconst &&
(second->getSecondChild()->getInt() & 0x80000000) != 0))
{
return true;
}
}
}
return false;
}
示例5: traceMsg
TR::Node *
OMR::Simplifier::unaryCancelOutWithChild(TR::Node * node, TR::Node * firstChild, TR::TreeTop *anchorTree, TR::ILOpCodes opcode, bool anchorChildren)
{
if (!isLegalToUnaryCancel(node, firstChild, opcode))
return NULL;
if (firstChild->getOpCodeValue() == opcode &&
(node->getType().isAggregate() || firstChild->getType().isAggregate()) &&
(node->getSize() > firstChild->getSize() || node->getSize() != firstChild->getFirstChild()->getSize()))
{
// ensure a truncation side-effect of a conversion is not lost
// o2a size=3
// a2o size=3 // conversion truncates in addition to type cast so cannot be removed
// loadaddr size=4
// This restriction could be loosened to only disallow intermediate truncations (see BCD case above) but then would require a node
// op that would just correct for size (e.g. addrSizeMod size=3 to replace the o2a/a2o pair)
//
// Do allow cases when all three sizes are the same and when the middle node widens but the top and bottom node have the same size, e.g.
//
// i2o size=3
// o2i size=4
// oload size=3
//
// Also allow the special case where the grandchild is not really truncated as the 'truncated' bytes are known to be zero
// (i.e. there really isn't an intermediate truncation of 4->3 even though it appears that way from looking at the sizes alone)
// o2i
// i2o size=3
// iushr
// x
// iconst 8
bool disallow = true;
TR::Node *grandChild = firstChild->getFirstChild();
size_t nodeSize = node->getSize();
if (node->getType().isIntegral() &&
nodeSize == grandChild->getSize() &&
nodeSize > firstChild->getSize())
{
size_t truncatedBits = (nodeSize - firstChild->getSize()) * 8;
if (grandChild->getOpCode().isRightShift() && grandChild->getOpCode().isShiftLogical() &&
grandChild->getSecondChild()->getOpCode().isLoadConst() &&
(grandChild->getSecondChild()->get64bitIntegralValue() == truncatedBits))
{
disallow = false;
if (trace())
traceMsg(comp(),"do allow unaryCancel of node %s (%p) and firstChild %s (%p) as grandChild %s (%p) zeros the %d truncated bytes\n",
node->getOpCode().getName(),node,firstChild->getOpCode().getName(),firstChild,
grandChild->getOpCode().getName(),grandChild,truncatedBits/8);
}
}
if (disallow)
{
if (trace())
traceMsg(comp(),"disallow unaryCancel of node %s (%p) and firstChild %s (%p) due to unequal sizes (nodeSize %d, firstChildSize %d, firstChild->childSize %d)\n",
node->getOpCode().getName(),node,firstChild->getOpCode().getName(),firstChild,
node->getSize(),firstChild->getSize(),firstChild->getFirstChild()->getSize());
return NULL;
}
}
if (firstChild->getOpCodeValue() == opcode &&
performTransformation(comp(), "%sRemoving node [" POINTER_PRINTF_FORMAT "] %s and its child [" POINTER_PRINTF_FORMAT "] %s\n",
optDetailString(), node, node->getOpCode().getName(), firstChild, firstChild->getOpCode().getName()))
{
TR::Node *grandChild = firstChild->getFirstChild();
grandChild->incReferenceCount();
bool anchorChildrenNeeded = anchorChildren &&
(node->getNumChildren() > 1 ||
firstChild->getNumChildren() > 1 ||
node->getOpCode().hasSymbolReference() ||
firstChild->getOpCode().hasSymbolReference());
prepareToStopUsingNode(node, anchorTree, anchorChildrenNeeded);
node->recursivelyDecReferenceCount();
node->setVisitCount(0);
return grandChild;
}
return NULL;
}
示例6: if
TR_ExpressionsSimplification::LoopInfo*
TR_ExpressionsSimplification::findLoopInfo(TR_RegionStructure* region)
{
ListIterator<TR::CFGEdge> exitEdges(®ion->getExitEdges());
if (region->getExitEdges().getSize() != 1)
{
if (trace())
traceMsg(comp(), "Region with more than 1 exit edges can't be handled\n");
return 0;
}
TR_StructureSubGraphNode* exitNode = toStructureSubGraphNode(exitEdges.getFirst()->getFrom());
if (!exitNode->getStructure()->asBlock())
{
if (trace())
traceMsg(comp(), "The exit block can't be found\n");
return 0;
}
TR::Block *exitBlock = exitNode->getStructure()->asBlock()->getBlock();
TR::Node *lastTreeInExitBlock = exitBlock->getLastRealTreeTop()->getNode();
if (trace())
{
traceMsg(comp(), "The exit block is %d\n", exitBlock->getNumber());
traceMsg(comp(), "The branch node is %p\n", lastTreeInExitBlock);
}
if (!lastTreeInExitBlock->getOpCode().isBranch())
{
if (trace())
traceMsg(comp(), "The branch node couldn't be found\n");
return 0;
}
if (lastTreeInExitBlock->getNumChildren() < 2)
{
if (trace())
traceMsg(comp(), "The branch node has less than 2 children\n");
return 0;
}
TR::Node *firstChildOfLastTree = lastTreeInExitBlock->getFirstChild();
TR::Node *secondChildOfLastTree = lastTreeInExitBlock->getSecondChild();
if (!firstChildOfLastTree->getOpCode().hasSymbolReference())
{
if (trace())
traceMsg(comp(), "The branch node's first child node %p - its opcode does not have a symbol reference\n", firstChildOfLastTree);
return 0;
}
TR::SymbolReference *firstChildSymRef = firstChildOfLastTree->getSymbolReference();
if (trace())
traceMsg(comp(), "Symbol Reference: %p Symbol: %p\n", firstChildSymRef, firstChildSymRef->getSymbol());
// Locate the induction variable that matches with the exit node symbol
//
TR_InductionVariable *indVar = region->findMatchingIV(firstChildSymRef);
if (!indVar) return 0;
if (!indVar->getIncr()->asIntConst())
{
if (trace())
traceMsg(comp(), "Increment is not a constant\n");
return 0;
}
int32_t increment = indVar->getIncr()->getLowInt();
_visitCount = comp()->incVisitCount();
bool indVarWrittenAndUsedUnexpectedly = false;
if (firstChildOfLastTree->getReferenceCount() > 1)
{
TR::TreeTop *cursorTreeTopInExitBlock = exitBlock->getEntry();
TR::TreeTop *exitTreeTopInExitBlock = exitBlock->getExit();
bool loadSeen = false;
while (cursorTreeTopInExitBlock != exitTreeTopInExitBlock)
{
TR::Node *cursorNode = cursorTreeTopInExitBlock->getNode();
if (checkForLoad(cursorNode, firstChildOfLastTree))
loadSeen = true;
if (!cursorNode->getOpCode().isStore() &&
(cursorNode->getNumChildren() > 0))
cursorNode = cursorNode->getFirstChild();
if (cursorNode->getOpCode().isStore() &&
(cursorNode->getSymbolReference() == firstChildSymRef))
{
indVarWrittenAndUsedUnexpectedly = true;
if ((cursorNode->getFirstChild() == firstChildOfLastTree) ||
!loadSeen)
indVarWrittenAndUsedUnexpectedly = false;
else
//.........这里部分代码省略.........
示例7: tranformSummationReductionCandidate
bool TR_ExpressionsSimplification::tranformSummationReductionCandidate(TR::TreeTop *treeTop, LoopInfo *loopInfo, bool *isPreheaderBlockInvalid)
{
TR::Node *node = treeTop->getNode();
TR::Node *opNode = node->getFirstChild();
TR::Node *expNode = NULL;
int32_t expChildNumber = 0;
bool removeOnly = false;
bool replaceWithNewNode = false;
if (opNode->getOpCodeValue() == TR::iadd || opNode->getOpCodeValue() == TR::isub)
{
if (opNode->getSecondChild()->getOpCode().hasSymbolReference() &&
node->getSymbolReference() == opNode->getSecondChild()->getSymbolReference())
{
expChildNumber = 0;
expNode = opNode->getFirstChild();
}
else
{
expChildNumber = 1;
expNode = opNode->getSecondChild();
}
expNode = iaddisubSimplifier(expNode, loopInfo);
replaceWithNewNode = true;
}
else if (opNode->getOpCodeValue() == TR::ixor || opNode->getOpCodeValue() == TR::ineg)
{
expNode = ixorinegSimplifier(opNode, loopInfo, &removeOnly);
}
if (expNode)
{
if (trace())
comp()->getDebug()->print(comp()->getOutFile(), expNode, 0, true);
TR::Block *entryBlock = _currentRegion->getEntryBlock();
TR::Block *preheaderBlock = findPredecessorBlock(entryBlock);
if (!preheaderBlock)
{
if (trace())
traceMsg(comp(), "Fail to find a place to put the hoist code in\n");
*isPreheaderBlockInvalid = true;
return true;
}
if (loopInfo->getNumIterations() > 0 || // make sure that the loop is going to be executed at least once
_currentRegion->isCanonicalizedLoop()) // or that the loop is canonicalized, in which case the preheader is
{ // executed in its first iteration and is protected.
if (performTransformation(comp(), "%sMove out loop-invariant node [%p] to block_%d\n", OPT_DETAILS, node, preheaderBlock->getNumber()))
{
if (!(removeOnly))
{
TR::Node *newNode = node->duplicateTree();
if (replaceWithNewNode)
newNode->getFirstChild()->setAndIncChild(expChildNumber, expNode);
transformNode(newNode, preheaderBlock);
}
TR::TransformUtil::removeTree(comp(), treeTop);
}
}
}
return (expNode != NULL);
}
示例8: setSummationReductionCandidates
void TR_ExpressionsSimplification::setSummationReductionCandidates(TR::Node *node, TR::TreeTop *tt)
{
// Must be a store node
//
if (node->getOpCodeValue() != TR::istore
/* || node->getOpCodeValue() != TR::astore */)
{
if (trace())
traceMsg(comp(), "Node %p: The opcode is not istore so not a summation reduction candidate\n",node);
return;
}
TR::Node *opNode = node->getFirstChild();
if (opNode->getOpCodeValue() == TR::iadd ||
opNode->getOpCodeValue() == TR::isub)
{
TR::Node *firstNode = opNode->getFirstChild();
TR::Node *secondNode = opNode->getSecondChild();
if (firstNode->getOpCode().hasSymbolReference() &&
node->getSymbolReference() == firstNode->getSymbolReference() &&
opNode->getReferenceCount() == 1 && firstNode->getReferenceCount() == 1)
{
// The second node must be loop invariant
//
if (!_currentRegion->isExprInvariant(secondNode))
{
if (trace())
{
traceMsg(comp(), "The node %p is not loop invariant\n",secondNode);
// This can be the arithmetic series case
// only when the node is an induction variable
if (secondNode->getNumChildren() == 1 && secondNode->getOpCode().hasSymbolReference())
{
TR_InductionVariable *indVar = _currentRegion->findMatchingIV(secondNode->getSymbolReference());
if (indVar)
{
//printf("Found Candidate of arithmetic series\n" );
}
}
}
return;
}
_candidateTTs->add(tt);
}
else if (secondNode->getOpCode().hasSymbolReference() &&
node->getSymbolReference() == secondNode->getSymbolReference() &&
opNode->getReferenceCount() == 1 && secondNode->getReferenceCount() == 1 &&
_currentRegion->isExprInvariant(firstNode))
{
_candidateTTs->add(tt);
}
}
else if (opNode->getOpCodeValue() == TR::ixor ||
opNode->getOpCodeValue() == TR::ineg)
{
if (opNode->getFirstChild()->getOpCode().hasSymbolReference() &&
node->getSymbolReference() == opNode->getFirstChild()->getSymbolReference() &&
opNode->getReferenceCount() == 1 && opNode->getFirstChild()->getReferenceCount() == 1 &&
(opNode->getOpCodeValue() == TR::ineg || _currentRegion->isExprInvariant(opNode->getSecondChild())))
_candidateTTs->add(tt);
else if (opNode->getOpCodeValue() == TR::ixor && opNode->getSecondChild()->getOpCode().hasSymbolReference() &&
node->getSymbolReference() == opNode->getSecondChild()->getSymbolReference() &&
opNode->getReferenceCount() == 1 && opNode->getSecondChild()->getReferenceCount() == 1 &&
_currentRegion->isExprInvariant(opNode->getFirstChild()))
_candidateTTs->add(tt);
}
}
示例9: if
//.........这里部分代码省略.........
_nullCheckNodesAsArray = NULL;
else
{
_nullCheckNodesAsArray = (TR::Node**)trMemory()->allocateStackMemory(_numNullChecks*sizeof(TR::Node*));
memset(_nullCheckNodesAsArray, 0, _numNullChecks*sizeof(TR::Node*));
}
currentTree = comp()->getStartTree();
int32_t symRefCount = comp()->getSymRefCount();
_checkSymbolReferences = new (trStackMemory()) TR_BitVector(symRefCount, trMemory(), stackAlloc);
_numNodes = 1;
_numNullChecks = 0;
// This loop counts all the nodes that are going to take part in PRE.
// This is a computation intensive loop as we check if the node that
// is syntactically equivalent to a given node has been seen before
// and if so we use the local index of the original node (that
// is syntactically equivalent to the given node). Could be improved
// in complexity with value numbering at some stage.
//
_visitCount = comp()->incVisitCount();
while (currentTree)
{
TR::Node *firstNodeInTree = currentTree->getNode();
TR::ILOpCode *opCode = &firstNodeInTree->getOpCode();
if (((firstNodeInTree->getOpCodeValue() == TR::treetop) ||
(comp()->useAnchors() && firstNodeInTree->getOpCode().isAnchor())) &&
(firstNodeInTree->getFirstChild()->getOpCode().isStore()))
{
firstNodeInTree->setLocalIndex(-1);
if (comp()->useAnchors() && firstNodeInTree->getOpCode().isAnchor())
firstNodeInTree->getSecondChild()->setLocalIndex(-1);
firstNodeInTree = firstNodeInTree->getFirstChild();
opCode = &firstNodeInTree->getOpCode();
}
// This call finds nodes with opcodes that are supported by PRE
// in this subtree; this accounts for all opcodes other than stores/checks
// which are handled later on below
//
bool firstNodeInTreeHasCallsInStoreLhs = false;
countSupportedNodes(firstNodeInTree, NULL, firstNodeInTreeHasCallsInStoreLhs);
if ((opCode->isStore() && !firstNodeInTree->getSymbolReference()->getSymbol()->isAutoOrParm()) ||
opCode->isCheck())
{
int32_t oldExpressionOnRhs = hasOldExpressionOnRhs(firstNodeInTree);
//
// Return value 0 denotes that the node contains some sub-expression
// that cannot participate in PRE; e.g. a call or a new
//
// Return value -1 denotes that the node can participate in PRE
// but did not match with any existing expression seen so far
//
// Any other return value (should be positive always) denotes that
// the node can participate in PRE and has been matched with a seen
// expression having local index == return value
//
if (oldExpressionOnRhs == -1)
{
if (trace())
{
示例10: stackRegion
//.........这里部分代码省略.........
requestOpt(OMR::treeSimplification, true, block);
if (nextTree->getNode()->getOpCodeValue() == TR::Goto
&& prevTree->getNode()->getOpCodeValue() == TR::BBStart
&& !prevTree->getNode()->getBlock()->isExtensionOfPreviousBlock())
{
requestOpt(
OMR::redundantGotoElimination,
prevTree->getNode()->getBlock());
}
}
}
else
{
if (performTransformation(comp(), "%sMove tree : [" POINTER_PRINTF_FORMAT "]([" POINTER_PRINTF_FORMAT "] = %s) to end of block\n", optDetailString(), node, node->getFirstChild(), node->getFirstChild()->getOpCode().getName()))
{
prevTree->join(nextTree);
node->setVisitCount(visitCount);
TR::TreeTop *lastTree = findLastTreetop(block, prevTree);
TR::TreeTop *prevLastTree = lastTree->getPrevTreeTop();
TR::TreeTop *cursorTreeTop = nextTree;
while (cursorTreeTop != lastTree)
{
if (cursorTreeTop->getNode()->getOpCode().isStoreReg() &&
(cursorTreeTop->getNode()->getGlobalRegisterNumber() == iter.currentTree()->getNode()->getGlobalRegisterNumber()))
{
lastTree = cursorTreeTop;
prevLastTree = lastTree->getPrevTreeTop();
break;
}
cursorTreeTop = cursorTreeTop->getNextTreeTop();
}
if (lastTree->getNode()->getOpCodeValue() == TR::BBStart)
{
prevLastTree = lastTree;
lastTree = block->getExit();
}
TR::Node *lastNode = lastTree->getNode();
TR::Node *prevLastNode = prevLastTree->getNode();
if (lastNode->getOpCode().isIf() && !lastNode->getOpCode().isCompBranchOnly() &&
prevLastNode->getOpCode().isStoreReg() &&
((prevLastNode->getFirstChild() == lastNode->getFirstChild()) ||
(prevLastNode->getFirstChild() == lastNode->getSecondChild())))
{
lastTree = prevLastTree;
prevLastTree = lastTree->getPrevTreeTop();
}
prevLastTree->join(iter.currentTree());
iter.currentTree()->join(lastTree);
iter.jumpTo(prevTree);
requestOpt(OMR::treeSimplification, true, block);
}
}
}
}
for (auto it = anchors.begin(); it != anchors.end(); ++it)
{
TR::Node *anchor = it->tree->getNode();
TR::Node *load = anchor->getChild(0);
if (load->getReferenceCount() > 1)
continue;
// We can eliminate the indirect load immediately, but for the moment the
// subtree providing the base object has to be anchored.
TR::Node *heapBase = anchor->getChild(1);
TR::Node::recreate(anchor, TR::treetop);
anchor->setAndIncChild(0, load->getChild(0));
anchor->setChild(1, NULL);
anchor->setNumChildren(1);
if (!heapBase->getOpCode().isLoadConst())
{
it->tree->insertAfter(
TR::TreeTop::create(
comp(),
TR::Node::create(heapBase, TR::treetop, 1, heapBase)));
}
load->recursivelyDecReferenceCount();
heapBase->recursivelyDecReferenceCount();
// A later pass of dead trees can likely move (or even remove) the base
// object expression.
requestOpt(OMR::deadTreesElimination, true, it->block);
}
return 1; // actual cost
}