本文整理汇总了C++中tr::Node::getNumChildren方法的典型用法代码示例。如果您正苦于以下问题:C++ Node::getNumChildren方法的具体用法?C++ Node::getNumChildren怎么用?C++ Node::getNumChildren使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类tr::Node
的用法示例。
在下文中一共展示了Node::getNumChildren方法的13个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: removeGlRegDep
static void removeGlRegDep(TR::Node * parent, TR_GlobalRegisterNumber registerNum, TR::Block *containingBlock, TR::Optimization *opt)
{
if (parent->getNumChildren() == 0)
return;
TR_ASSERT(parent->getNumChildren() > 0, "expected TR::GlRegDeps %p", parent);
TR::Node * predGlRegDeps = parent->getLastChild();
if (predGlRegDeps->getOpCodeValue() != TR::GlRegDeps) // could be already removed
return;
TR_ASSERT(predGlRegDeps->getOpCodeValue() == TR::GlRegDeps, "expected TR::GlRegDeps");
for (int32_t i = predGlRegDeps->getNumChildren() - 1; i >= 0; --i)
if (predGlRegDeps->getChild(i)->getGlobalRegisterNumber() == registerNum)
{
dumpOptDetails(opt->comp(), "%sRemove GlRegDep : %p\n", opt->optDetailString(), predGlRegDeps->getChild(i));
TR::Node *removedChild = predGlRegDeps->removeChild(i);
if (removedChild->getReferenceCount() <= 1)
{
// The only remaining parent is the RegStore. Another pass of
// deadTrees may be able to eliminate that.
//
opt->requestOpt(OMR::deadTreesElimination, true, containingBlock);
}
break;
}
if (predGlRegDeps->getNumChildren() == 0)
parent->removeLastChild();
}
示例2: 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...
}
示例3:
TR::TreeTop *searchForToStringCall(TR::ValuePropagation *vp,TR::TreeTop *tt, TR::TreeTop *exitTree,
TR::Node *newBuffer, vcount_t visitCount,
TR::TreeTop **toStringTree, bool useStringBuffer)
{
for (;tt != exitTree; tt = tt->getNextRealTreeTop())
{
TR::Node *node = tt->getNode();
if (node->getNumChildren() == 1 &&
node->getFirstChild()->getOpCodeValue() == TR::acall)
{
if (checkMethodSignature(vp,node->getFirstChild()->getSymbolReference(),
(useStringBuffer ?
"java/lang/StringBuffer.toString()Ljava/lang/String;" :
"java/lang/StringBuilder.toString()Ljava/lang/String;")))
{
TR::Node *call = node->getFirstChild();
if (call->getFirstChild() == newBuffer)
*toStringTree = tt;
return tt;
}
}
}
return tt;
}
示例4: comp
// Simplify a sub-tree.
// Returns the replaced root of the sub-tree, which may be null if the sub-tree
// has been removed.
//
TR::Node *
OMR::Simplifier::simplify(TR::Node * node, TR::Block * block)
{
// Set the visit count for this node to prevent recursion into it
//
vcount_t visitCount = comp()->getVisitCount();
node->setVisitCount(visitCount);
if (node->nodeRequiresConditionCodes())
{
// On Java, nodes that require condition codes must not be simplified.
dftSimplifier(node, block, (TR::Simplifier *) this);
return node;
}
// Simplify this node.
// Note that the processing routine for the node is responsible for
// simplifying its children.
//
TR::Node * newNode = simplifierOpts[node->getOpCodeValue()](node, block, (TR::Simplifier *) this);
if ((node != newNode) ||
(newNode &&
((newNode->getOpCodeValue() != node->getOpCodeValue()) ||
(newNode->getNumChildren() != node->getNumChildren()))))
requestOpt(OMR::localCSE, true, block);
return newNode;
}
示例5: if
bool TR::ILValidator::treesAreValid(TR::TreeTop *start, TR::TreeTop *stop)
{
checkSoundness(start, stop);
for (PostorderNodeOccurrenceIterator iter(start, _comp, "VALIDATOR"); iter != stop; ++iter)
{
updateNodeState(iter);
// General node validation
//
validateNode(iter);
//
// Additional specific kinds of validation
//
TR::Node *node = iter.currentNode();
if (node->getOpCodeValue() == TR::BBEnd)
{
// Determine whether this is the end of an extended block
//
bool isEndOfExtendedBlock = false;
TR::TreeTop *nextTree = iter.currentTree()->getNextTreeTop();
if (nextTree)
{
validityRule(iter, nextTree->getNode()->getOpCodeValue() == TR::BBStart, "Expected BBStart after BBEnd");
isEndOfExtendedBlock = ! nextTree->getNode()->getBlock()->isExtensionOfPreviousBlock();
}
else
{
isEndOfExtendedBlock = true;
}
if (isEndOfExtendedBlock)
validateEndOfExtendedBlock(iter);
}
auto opcode = node->getOpCode();
if (opcode.expectedChildCount() != ILChildProp::UnspecifiedChildCount)
{
// Validate child expectations
//
const auto expChildCount = opcode.expectedChildCount();
const auto actChildCount = node->getNumChildren();
// validate child count
if (!opcode.canHaveGlRegDeps())
{
// in the common case, no GlRegDeps child is expect nor present
validityRule(iter, actChildCount == expChildCount,
"Child count %d does not match expected value of %d", actChildCount, expChildCount);
}
else if (actChildCount == (expChildCount + 1))
{
// adjust expected child number to account for a possible extra GlRegDeps
// child and make sure the last child is actually a GlRegDeps
validityRule(iter, node->getChild(actChildCount - 1)->getOpCodeValue() == TR::GlRegDeps,
"Child count %d does not match expected value of %d (%d without GlRegDeps) and last child is not a GlRegDeps",
actChildCount, expChildCount + 1, expChildCount);
}
else
{
// if expected and actual child counts don't match, then the child
// count is just wrong, even with an expected GlRegDeps
validityRule(iter, actChildCount == expChildCount,
"Child count %d matches neither expected values of %d (without GlRegDeps) nor %d (with GlRegDeps)",
actChildCount, expChildCount, expChildCount + 1);
}
// validate child types
for (auto i = 0; i < actChildCount; ++i)
{
auto childOpcode = node->getChild(i)->getOpCode();
if (childOpcode.getOpCodeValue() != TR::GlRegDeps)
{
const auto expChildType = opcode.expectedChildType(i);
const auto actChildType = childOpcode.getDataType().getDataType();
const auto expChildTypeName = expChildType == ILChildProp::UnspecifiedChildType ? "UnspecifiedChildType" : TR::DataType::getName(expChildType);
const auto actChildTypeName = TR::DataType::getName(actChildType);
validityRule(iter, expChildType == ILChildProp::UnspecifiedChildType || actChildType == expChildType,
"Child %d has unexpected type %s (expected %s)" , i, actChildTypeName, expChildTypeName);
}
else
{
// make sure the node is allowed to have a GlRegDeps child
// and make sure that it is the last child
validityRule(iter, opcode.canHaveGlRegDeps() && (i == actChildCount - 1), "Unexpected GlRegDeps child %d", i);
}
}
}
}
return _isValidSoFar;
}
示例6: 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)
{
//.........这里部分代码省略.........
示例7: tailSplitBlock
// This function splits a single succeesor block following an guard and is used to
// do the following transform
// block - cold1 block - cold1
// \ / => | |
// nextBlock nextBlock nextBlock' (called tailSplitBlock below)
// | \ /
// ... ...
void TR_VirtualGuardHeadMerger::tailSplitBlock(TR::Block * block, TR::Block * cold1)
{
TR::CFG *cfg = comp()->getFlowGraph();
cfg->setStructure(NULL);
TR_BlockCloner cloner(cfg);
TR::Block *tailSplitBlock = cloner.cloneBlocks(block->getNextBlock(), block->getNextBlock());
tailSplitBlock->setFrequency(cold1->getFrequency());
if (cold1->isCold())
tailSplitBlock->setIsCold();
// physically put the block after cold1 since we want cold1 to fall through
tailSplitBlock->getExit()->join(cold1->getExit()->getNextTreeTop());
cold1->getExit()->join(tailSplitBlock->getEntry());
// remove cold1's goto
TR::TransformUtil::removeTree(comp(), cold1->getExit()->getPrevRealTreeTop());
// copy the exception edges
for (auto e = block->getNextBlock()->getExceptionSuccessors().begin(); e != block->getNextBlock()->getExceptionSuccessors().end(); ++e)
cfg->addExceptionEdge(tailSplitBlock, (*e)->getTo());
cfg->addEdge(cold1, tailSplitBlock);
// lastly fix up the exit of tailSplitBlock
TR::Node *tailSplitEnd = tailSplitBlock->getExit()->getPrevRealTreeTop()->getNode();
if (tailSplitEnd->getOpCode().isGoto())
{
tailSplitEnd->setBranchDestination(block->getNextBlock()->getLastRealTreeTop()->getNode()->getBranchDestination());
cfg->addEdge(tailSplitBlock, block->getNextBlock()->getSuccessors().front()->getTo());
}
else if (tailSplitEnd->getOpCode().isBranch())
{
TR::Block *gotoBlock = TR::Block::createEmptyBlock(tailSplitEnd, comp(), cold1->getFrequency());
if (cold1->isCold())
gotoBlock->setIsCold(true);
gotoBlock->getExit()->join(tailSplitBlock->getExit()->getNextTreeTop());
tailSplitBlock->getExit()->join(gotoBlock->getEntry());
cfg->addNode(gotoBlock);
gotoBlock->append(TR::TreeTop::create(comp(), TR::Node::create(tailSplitEnd, TR::Goto, 0, block->getNextBlock()->getExit()->getNextTreeTop())));
cfg->addEdge(tailSplitBlock, gotoBlock);
cfg->addEdge(tailSplitBlock, tailSplitBlock->getLastRealTreeTop()->getNode()->getBranchDestination()->getEnclosingBlock());
cfg->addEdge(gotoBlock, block->getNextBlock()->getNextBlock());
}
else if (
!tailSplitEnd->getOpCode().isReturn() &&
!tailSplitEnd->getOpCode().isJumpWithMultipleTargets() &&
tailSplitEnd->getOpCodeValue() != TR::athrow &&
!(tailSplitEnd->getNumChildren() >= 1 && tailSplitEnd->getFirstChild()->getOpCodeValue() == TR::athrow)
)
{
tailSplitBlock->append(TR::TreeTop::create(comp(), TR::Node::create(tailSplitEnd, TR::Goto, 0, block->getNextBlock()->getExit()->getNextTreeTop())));
cfg->addEdge(tailSplitBlock, block->getNextBlock()->getNextBlock());
}
else
{
for (auto e = block->getNextBlock()->getSuccessors().begin(); e != block->getNextBlock()->getSuccessors().end(); ++e)
cfg->addEdge(tailSplitBlock, (*e)->getTo());
}
cfg->removeEdge(cold1, block->getNextBlock());
optimizer()->setUseDefInfo(NULL);
optimizer()->setValueNumberInfo(NULL);
}
示例8: 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
//.........这里部分代码省略.........
示例9: 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);
}
}
示例10: hasOldExpressionOnRhs
// Checks for syntactic equivalence and returns the side-table index
// of the syntactically equivalent node if it found one; else it returns
// -1 signifying that this is the first time any node similar syntactically
// to this node has been seen. Adds the node to the hash table if seen for the
// first time.
//
//
int TR_LocalAnalysisInfo::hasOldExpressionOnRhs(TR::Node *node, bool recalcContainsCall, bool storeLhsContainsCall)
{
//
// Get the relevant portion of the subtree
// for this node; this is different for a null check
// as its null check reference is the only
// sub-expression that matters
//
TR::Node *relevantSubtree = NULL;
if (node->getOpCodeValue() == TR::NULLCHK)
relevantSubtree = node->getNullCheckReference();
else
relevantSubtree = node;
// containsCall checks whether the relevant node has some
// sub-expression that cannot be commoned, e.g. call or a new
//
bool nodeContainsCall;
if (!recalcContainsCall && (relevantSubtree == node))
{
// can use pre-calculated value of containsCall and storeLhsContainsCall, to avoid visitCount overflow
nodeContainsCall = node->containsCall();
}
else
{
storeLhsContainsCall = false;
nodeContainsCall = containsCall(relevantSubtree, storeLhsContainsCall);
}
if (nodeContainsCall)
{
//
// If the node is not a store, a call-like sub-expression is inadmissable;
// if the node is a store, a call-like sub-expression is allowed on the RHS
// of the store as this does not inhibit privatization in any way as
// the private temp store's RHS simply points at original RHS. But if a call-like
// sub-expression is present in the LHS of the store, that is inadmissable
//
if (!node->getOpCode().isStore() ||
storeLhsContainsCall)
return 0;
}
bool seenIndirectStore = false;
#ifdef J9_PROJECT_SPECIFIC
bool seenIndirectBCDStore = false;
#endif
bool seenWriteBarrier = false;
int32_t storeNumChildren = node->getNumChildren();
// If node is a null check, compare the
// null check reference only to establish syntactic equivalence
//
if (node->getOpCodeValue() == TR::NULLCHK)
/////if (node->getOpCode().isNullCheck())
{
int32_t k;
for (k=0;k<_numNullChecks;k++)
{
if (!(_nullCheckNodesAsArray[k] == NULL))
{
if (areSyntacticallyEquivalent(_nullCheckNodesAsArray[k]->getNullCheckReference(), node->getNullCheckReference()))
return _nullCheckNodesAsArray[k]->getLocalIndex();
}
}
_nullCheckNodesAsArray[_numNullChecks++] = node;
}
else
{
//
// If this node is a global store, then equivalence check is different.
// We try to give a store to field (or static) o.f the same index as
// a load of o.f. This is so that privatization happens for fields/statics.
// So the store's opcode value is changed temporarily to be a load before
// syntactic equivalence is checked; this enables matching stores/loads to
// same global symbol.
//
if (node->getOpCode().isStore() &&
!node->getSymbolReference()->getSymbol()->isAutoOrParm())
{
if (node->getOpCode().isWrtBar())
seenWriteBarrier = true;
#ifdef J9_PROJECT_SPECIFIC
seenIndirectBCDStore = node->getType().isBCD();
#endif
if (node->getOpCode().isStoreIndirect())
{
if (seenWriteBarrier)
{
TR::Node::recreate(node, _compilation->il.opCodeForIndirectArrayLoad(node->getDataType()));
}
//.........这里部分代码省略.........
示例11: stackRegion
//.........这里部分代码省略.........
//
if (visitCount == child->getVisitCount())
{
treeTopCanBeEliminated = true;
}
else
{
TR::ILOpCode &childOpCode = child->getOpCode();
TR::ILOpCodes opCodeValue = childOpCode.getOpCodeValue();
bool seenConditionalBranch = false;
bool callWithNoSideEffects = child->getOpCode().isCall() &&
child->getSymbolReference()->getSymbol()->isResolvedMethod() &&
child->getSymbolReference()->getSymbol()->castToResolvedMethodSymbol()->isSideEffectFree();
if (callWithNoSideEffects)
{
treeTopCanBeEliminated = true;
}
else if (!((childOpCode.isCall() && !callWithNoSideEffects) ||
childOpCode.isStore() ||
((opCodeValue == TR::New ||
opCodeValue == TR::anewarray ||
opCodeValue == TR::newarray) &&
child->getReferenceCount() > 1) ||
opCodeValue == TR::multianewarray ||
opCodeValue == TR::MergeNew ||
opCodeValue == TR::checkcast ||
opCodeValue == TR::Prefetch ||
opCodeValue == TR::iu2l ||
((childOpCode.isDiv() ||
childOpCode.isRem()) &&
child->getNumChildren() == 3)))
{
// Perform the rather complex check to see whether its safe
// to disconnect the child node from the treetop
//
bool safeToReplaceNode = false;
if (child->getReferenceCount() == 1)
{
safeToReplaceNode = true;
#ifdef J9_PROJECT_SPECIFIC
if (child->getOpCode().isPackedExponentiation())
{
// pdexp has a possible message side effect in truncating or no significant digits left cases
safeToReplaceNode = false;
}
#endif
if (opCodeValue == TR::loadaddr)
treeTopCanBeEliminated = true;
}
else if (!_cannotBeEliminated)
{
safeToReplaceNode = isSafeToReplaceNode(
child,
iter.currentTree(),
&seenConditionalBranch,
visitCount,
comp(),
&_targetTrees,
_cannotBeEliminated,
longestPaths);
}
if (safeToReplaceNode)
示例12: if
void TR::DeadTreesElimination::prePerformOnBlocks()
{
_cannotBeEliminated = false;
_delayedRegStores = false;
_targetTrees.deleteAll();
// Walk through all the blocks to remove trivial dead trees of the form
// treetop
// => node
// The problem with these trees is in the scenario where the earlier use
// of 'node' is also dead. However, our analysis won't find that because
// the reference count is > 1.
vcount_t visitCount = comp()->incOrResetVisitCount();
for (TR::TreeTop *tt = comp()->getStartTree();
tt != 0;
tt = tt->getNextTreeTop())
{
bool removed = false;
TR::Node *node = tt->getNode();
if (node->getOpCodeValue() == TR::treetop &&
node->getFirstChild()->getVisitCount() == visitCount &&
performTransformation(comp(), "%sRemove trivial dead tree: %p\n", optDetailString(), node))
{
TR::TransformUtil::removeTree(comp(), tt);
removed = true;
}
else
{
if (node->getOpCode().isCheck() &&
node->getFirstChild()->getOpCode().isCall() &&
node->getFirstChild()->getReferenceCount() == 1 &&
node->getFirstChild()->getSymbolReference()->getSymbol()->isResolvedMethod() &&
node->getFirstChild()->getSymbolReference()->getSymbol()->castToResolvedMethodSymbol()->isSideEffectFree() &&
performTransformation(comp(), "%sRemove dead check of side-effect free call: %p\n", optDetailString(), node))
{
TR::TransformUtil::removeTree(comp(), tt);
removed = true;
}
}
if (removed
&& tt->getNextTreeTop()->getNode()->getOpCodeValue() == TR::Goto
&& tt->getPrevTreeTop()->getNode()->getOpCodeValue() == TR::BBStart
&& !tt->getPrevTreeTop()->getNode()->getBlock()->isExtensionOfPreviousBlock())
{
requestOpt(OMR::redundantGotoElimination, tt->getEnclosingBlock());
}
if (node->getVisitCount() >= visitCount)
continue;
TR::TransformUtil::recursivelySetNodeVisitCount(tt->getNode(), visitCount);
}
// If the last use of an iRegLoad has been removed, then remove the node from
// the BBStart and remove the corresponding dependency node from each of the block's
// predecessors.
//
while (1)
{
bool glRegDepRemoved = false;
for (TR::Block * b = comp()->getStartBlock(); b; b = b->getNextBlock())
{
TR::TreeTop * startTT = b->getEntry();
TR::Node * startNode = startTT->getNode();
if (startNode->getNumChildren() > 0 && !debug("disableEliminationOfGlRegDeps"))
{
TR::Node * glRegDeps = startNode->getFirstChild();
TR_ASSERT(glRegDeps->getOpCodeValue() == TR::GlRegDeps, "expected TR::GlRegDeps");
for (int32_t i = glRegDeps->getNumChildren() - 1; i >= 0; --i)
{
TR::Node * dep = glRegDeps->getChild(i);
if (dep->getReferenceCount() == 1 &&
(!dep->getOpCode().isFloatingPoint() ||
cg()->getSupportsJavaFloatSemantics()) &&
performTransformation(comp(), "%sRemove GlRegDep : %p\n", optDetailString(), glRegDeps->getChild(i)))
{
glRegDeps->removeChild(i);
glRegDepRemoved = true;
TR_GlobalRegisterNumber registerNum = dep->getGlobalRegisterNumber();
for (auto e = b->getPredecessors().begin(); e != b->getPredecessors().end(); ++e)
{
TR::Block * pred = toBlock((*e)->getFrom());
if (pred == comp()->getFlowGraph()->getStart())
continue;
TR::Node * parent = pred->getLastRealTreeTop()->getNode();
if ( parent->getOpCode().isJumpWithMultipleTargets() && parent->getOpCode().hasBranchChildren())
{
for (int32_t j = parent->getCaseIndexUpperBound() - 1; j > 0; --j)
{
TR::Node * caseNode = parent->getChild(j);
TR_ASSERT(caseNode->getOpCode().isCase() || caseNode->getOpCodeValue() == TR::branch,
"having problems navigating a switch");
if (caseNode->getBranchDestination() == startTT &&
caseNode->getNumChildren() > 0 &&
0) // can't do this now that all glRegDeps are hung off the default branch
removeGlRegDep(caseNode, registerNum, pred, this);
//.........这里部分代码省略.........
示例13: if
void
OMR::CodeGenPhase::performSetupForInstructionSelectionPhase(TR::CodeGenerator * cg, TR::CodeGenPhase * phase)
{
TR::Compilation *comp = cg->comp();
if (TR::Compiler->target.cpu.isZ() && TR::Compiler->om.shouldGenerateReadBarriersForFieldLoads())
{
// TODO (GuardedStorage): We need to come up with a better solution than anchoring aloadi's
// to enforce certain evaluation order
traceMsg(comp, "GuardedStorage: in performSetupForInstructionSelectionPhase\n");
auto mapAllocator = getTypedAllocator<std::pair<TR::TreeTop*, TR::TreeTop*> >(comp->allocator());
std::map<TR::TreeTop*, TR::TreeTop*, std::less<TR::TreeTop*>, TR::typed_allocator<std::pair<TR::TreeTop* const, TR::TreeTop*>, TR::Allocator> >
currentTreeTopToappendTreeTop(std::less<TR::TreeTop*> (), mapAllocator);
TR_BitVector *unAnchorableAloadiNodes = comp->getBitVectorPool().get();
for (TR::PreorderNodeIterator iter(comp->getStartTree(), comp); iter != NULL; ++iter)
{
TR::Node *node = iter.currentNode();
traceMsg(comp, "GuardedStorage: Examining node = %p\n", node);
// isNullCheck handles both TR::NULLCHK and TR::ResolveAndNULLCHK
// both of which do not operate on their child but their
// grandchild (or greatgrandchild).
if (node->getOpCode().isNullCheck())
{
// An aloadi cannot be anchored if there is a Null Check on
// its child. There are two situations where this occurs.
// The first is when doing an aloadi off some node that is
// being NULLCHK'd (see Ex1). The second is when doing an
// icalli in which case the aloadi loads the VFT of an
// object that must be NULLCHK'd (see Ex2).
//
// Ex1:
// n1n NULLCHK on n3n
// n2n aloadi f <-- First Child And Parent of Null Chk'd Node
// n3n aload O
//
// Ex2:
// n1n NULLCHK on n4n
// n2n icall foo <-- First Child
// n3n aloadi <vft> <-- Parent of Null Chk'd Node
// n4n aload O
// n4n ==> aload O
TR::Node *nodeBeingNullChkd = node->getNullCheckReference();
if (nodeBeingNullChkd)
{
TR::Node *firstChild = node->getFirstChild();
TR::Node *parentOfNullChkdNode = NULL;
if (firstChild->getOpCode().isCall() &&
firstChild->getOpCode().isIndirect())
{
parentOfNullChkdNode = firstChild->getFirstChild();
}
else
{
parentOfNullChkdNode = firstChild;
}
if (parentOfNullChkdNode &&
parentOfNullChkdNode->getOpCodeValue() == TR::aloadi &&
parentOfNullChkdNode->getNumChildren() > 0 &&
parentOfNullChkdNode->getFirstChild() == nodeBeingNullChkd)
{
unAnchorableAloadiNodes->set(parentOfNullChkdNode->getGlobalIndex());
traceMsg(comp, "GuardedStorage: Cannot anchor %p\n", firstChild);
}
}
}
else
{
bool shouldAnchorNode = false;
if (node->getOpCodeValue() == TR::aloadi &&
!unAnchorableAloadiNodes->isSet(node->getGlobalIndex()))
{
shouldAnchorNode = true;
}
else if (node->getOpCodeValue() == TR::aload &&
node->getSymbol()->isStatic() &&
node->getSymbol()->isCollectedReference())
{
shouldAnchorNode = true;
}
if (shouldAnchorNode)
{
TR::TreeTop* anchorTreeTop = TR::TreeTop::create(comp, TR::Node::create(TR::treetop, 1, node));
TR::TreeTop* appendTreeTop = iter.currentTree();
if (currentTreeTopToappendTreeTop.count(appendTreeTop) > 0)
{
appendTreeTop = currentTreeTopToappendTreeTop[appendTreeTop];
}
//.........这里部分代码省略.........