本文整理汇总了C++中tr::Node::getReferenceCount方法的典型用法代码示例。如果您正苦于以下问题:C++ Node::getReferenceCount方法的具体用法?C++ Node::getReferenceCount怎么用?C++ Node::getReferenceCount使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类tr::Node
的用法示例。
在下文中一共展示了Node::getReferenceCount方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: validityRule
void TR::ILValidator::updateNodeState(Location &newLocation)
{
TR::Node *node = newLocation.currentNode();
NodeState &state = _nodeStates[node];
if (node->getReferenceCount() == state._futureReferenceCount)
{
// First occurrence -- do some bookkeeping
//
if (node->getReferenceCount() == 0)
{
validityRule(newLocation, node->getOpCode().isTreeTop(), "Only nodes with isTreeTop opcodes can have refcount == 0");
}
else
{
_liveNodes.add(node);
}
}
if (_liveNodes.contains(node))
{
validityRule(newLocation, state._futureReferenceCount >= 1, "Node already has reference count 0");
if (--state._futureReferenceCount == 0)
{
_liveNodes.remove(node);
}
}
else
{
validityRule(newLocation, node->getOpCode().isTreeTop(), "Node has already gone dead");
}
if (isLoggingEnabled())
{
static const char *traceLiveNodesDuringValidation = feGetEnv("TR_traceLiveNodesDuringValidation");
if (traceLiveNodesDuringValidation && !_liveNodes.isEmpty())
{
traceMsg(comp(), " -- Live nodes: {");
char *separator = "";
for (LiveNodeWindow::Iterator lnwi(_liveNodes); lnwi.currentNode(); ++lnwi)
{
traceMsg(comp(), "%sn%dn", separator, lnwi.currentNode()->getGlobalIndex());
separator = ", ";
}
traceMsg(comp(), "}\n");
}
}
}
示例2: 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();
}
示例3: generateRegMemInstruction
static TR::Register *l2fd(TR::Node *node, TR::RealRegister *target, TR_X86OpCodes opRegMem8, TR_X86OpCodes opRegReg8, TR::CodeGenerator *cg)
{
TR::Node *child = node->getFirstChild();
TR::MemoryReference *tempMR;
TR_ASSERT(cg->useSSEForSinglePrecision(), "assertion failure");
if (child->getRegister() == NULL &&
child->getReferenceCount() == 1 &&
child->getOpCode().isLoadVar())
{
tempMR = generateX86MemoryReference(child, cg);
generateRegMemInstruction(opRegMem8, node, target, tempMR, cg);
tempMR->decNodeReferenceCounts(cg);
}
else
{
TR::Register *intReg = cg->evaluate(child);
generateRegRegInstruction(opRegReg8, node, target, intReg, cg);
cg->decReferenceCount(child);
}
node->setRegister(target);
return target;
}
示例4:
void TR::ValidateNodeRefCountWithinBlock::validate(TR::TreeTop *firstTreeTop,
TR::TreeTop *exitTreeTop)
{
_nodeChecklist.empty();
for (TR::TreeTop *tt = firstTreeTop; tt != exitTreeTop->getNextTreeTop();
tt = tt->getNextTreeTop())
{
TR::Node *node = tt->getNode();
node->setLocalIndex(node->getReferenceCount());
validateRefCountPass1(node);
}
/**
* We start again from the start of the block, and check the localIndex to
* make sure it is 0.
*
* NOTE: Walking the tree backwards causes huge stack usage in validateRefCountPass2.
*/
_nodeChecklist.empty();
for (TR::TreeTop *tt = firstTreeTop; tt != exitTreeTop->getNextTreeTop();
tt = tt->getNextTreeTop())
{
validateRefCountPass2(tt->getNode());
}
}
示例5: collectSymbolReferencesInNode
bool collectSymbolReferencesInNode(TR::Node *node,
TR::SparseBitVector &symbolReferencesInNode,
int32_t *numDeadSubNodes, vcount_t visitCount, TR::Compilation *comp,
bool *seenInternalPointer, bool *seenArraylet,
bool *cantMoveUnderBranch)
{
// The visit count in the node must be maintained by this method.
//
vcount_t oldVisitCount = node->getVisitCount();
if (oldVisitCount == visitCount || oldVisitCount == comp->getVisitCount())
return true;
node->setVisitCount(comp->getVisitCount());
//diagnostic("Walking node %p, height=%d, oldVisitCount=%d, visitCount=%d, compVisitCount=%d\n", node, *height, oldVisitCount, visitCount,comp->getVisitCount());
// For all other subtrees collect all symbols that could be killed between
// here and the next reference.
//
for (int32_t i = node->getNumChildren()-1; i >= 0; i--)
{
TR::Node *child = node->getChild(i);
if (child->getFutureUseCount() == 1 &&
child->getReferenceCount() > 1 &&
!child->getOpCode().isLoadConst())
*numDeadSubNodes = (*numDeadSubNodes) + 1;
collectSymbolReferencesInNode(child, symbolReferencesInNode, numDeadSubNodes, visitCount, comp,
seenInternalPointer, seenArraylet, cantMoveUnderBranch);
}
// detect if this is a direct load that shouldn't be moved under a branch (because an update was moved past
// this load by treeSimplification)
if (cantMoveUnderBranch &&
(node->getOpCode().isLoadVarDirect() || node->getOpCode().isLoadReg()) &&
node->isDontMoveUnderBranch())
*cantMoveUnderBranch = true;
if (seenInternalPointer && node->isInternalPointer() && node->getReferenceCount() > 1)
*seenInternalPointer = true;
if (seenArraylet)
{
if (node->getOpCode().hasSymbolReference() &&
node->getSymbolReference()->getSymbol()->isArrayletShadowSymbol() &&
node->getReferenceCount() > 1)
{
*seenArraylet = true;
}
}
// Add this node's symbol reference to the set
if (node->getOpCode().hasSymbolReference())
{
symbolReferencesInNode[node->getSymbolReference()->getReferenceNumber()]=true;
}
return true;
}
示例6: containsCallOrCheck
//returns true if there is first reference of a call or check
bool TR_LocalLiveRangeReduction::containsCallOrCheck(TR_TreeRefInfo *treeRefInfo, TR::Node *node)
{
if ((node->getOpCode().isCall() &&
(node->getReferenceCount()==1 || treeRefInfo->getFirstRefNodesList()->find(node))) ||
node->getOpCode().isCheck())
{
return true;
}
for (int32_t i = 0; i < node->getNumChildren(); i++)
{
TR::Node *child = node->getChild(i);
if (child->getReferenceCount()==1 || treeRefInfo->getFirstRefNodesList()->find(child))
return containsCallOrCheck(treeRefInfo, child);
}
return false;
}
示例7: self
void
OMR::CodeGenerator::evaluateChildrenWithMultipleRefCount(TR::Node * node)
{
for (int i=0; i < node->getNumChildren(); i++)
{
TR::Node *child = node->getChild(i);
if (child->getRegister() == NULL) // not already evaluated
{
// Note: we assume things without a symbol reference don't
// necessarily need to be evaluated here, and can wait
// until they are actually needed.
//
// vft pointers are speical - we need to evaluate the object in all cases
// but for nopable virtual guards we can wait to load and mask the pointer
// until we actually need to use it
//
if (child->getReferenceCount() > 1 &&
(child->getOpCode().hasSymbolReference() ||
(child->getOpCodeValue() == TR::l2a && child->getChild(0)->containsCompressionSequence())))
{
TR::SymbolReference *vftPointerSymRef = TR::comp()->getSymRefTab()->element(TR::SymbolReferenceTable::vftSymbol);
if (node->isNopableInlineGuard()
&& self()->getSupportsVirtualGuardNOPing()
&& child->getOpCodeValue() == TR::aloadi
&& child->getChild(0)->getOpCode().hasSymbolReference()
&& child->getChild(0)->getSymbolReference() == vftPointerSymRef
&& child->getChild(0)->getOpCodeValue() == TR::aloadi)
{
if (!child->getChild(0)->getChild(0)->getRegister() &&
child->getChild(0)->getChild(0)->getReferenceCount() > 1)
self()->evaluate(child->getChild(0)->getChild(0));
else
self()->evaluateChildrenWithMultipleRefCount(child->getChild(0)->getChild(0));
}
else
{
self()->evaluate(child);
}
}
else
{
self()->evaluateChildrenWithMultipleRefCount(child);
}
}
}
}
示例8:
// TODO:AMD64: Could this be combined with istoreEvaluator without too much ugliness?
TR::Register *OMR::X86::AMD64::TreeEvaluator::lstoreEvaluator(TR::Node *node, TR::CodeGenerator *cg)
{
TR::Node *valueChild;
TR::Compilation* comp = cg->comp();
if (node->getOpCode().isIndirect())
valueChild = node->getSecondChild();
else
valueChild = node->getFirstChild();
// Handle special cases
//
if (valueChild->getRegister() == NULL &&
valueChild->getReferenceCount() == 1)
{
// Special case storing a double value into long variable
//
if (valueChild->getOpCodeValue() == TR::dbits2l &&
!valueChild->normalizeNanValues())
{
if (node->getOpCode().isIndirect())
{
node->setChild(1, valueChild->getFirstChild());
TR::Node::recreate(node, TR::dstorei);
TR::TreeEvaluator::floatingPointStoreEvaluator(node, cg);
node->setChild(1, valueChild);
TR::Node::recreate(node, TR::lstorei);
}
else
{
node->setChild(0, valueChild->getFirstChild());
TR::Node::recreate(node, TR::dstore);
TR::TreeEvaluator::floatingPointStoreEvaluator(node, cg);
node->setChild(0, valueChild);
TR::Node::recreate(node, TR::lstore);
}
cg->decReferenceCount(valueChild);
return NULL;
}
}
return TR::TreeEvaluator::integerStoreEvaluator(node, cg);
}
示例9: generateRegRegInstruction
TR::Register *OMR::X86::AMD64::TreeEvaluator::l2iEvaluator(TR::Node *node, TR::CodeGenerator *cg)
{
TR::Node *child = node->getFirstChild();
TR::Register *reg = cg->evaluate(child);
if (child->getReferenceCount() > 1)
{
// This catches two scenarios:
//
// 1) A longClobberEvaluate (or any other register-clobbering logic) on
// the l2i node could see a refcount of 1, and hence won't make a copy.
// If child's refcount is more than 1, we do in fact need a copy, so we'd
// better do it here.
//
// 2) If the child is commoned, and the l2i node is also commoned, then
// we may end up with a situation where the last evaluation of the child
// is a clobberEvaluate. By that time, the child's refcount would be 1,
// so no copy is made, and the register would be clobbered. Therefore,
// the l2i node can't return that same register, or else the other uses
// of the node will end up getting the clobbered value.
//
// Note that case 2 is conservative, in that it presumes that the child's
// register will be clobbered by another node. If this does not occur,
// then the copy we're about to make is unnecessary.
//
TR::Register *childReg = reg;
reg = cg->allocateRegister();
// to support signExtension in GRA, need to preserve upper word
// in this move
generateRegRegInstruction(MOV8RegReg, node, reg, childReg, cg);
}
node->setRegister(reg);
cg->decReferenceCount(child);
if (cg->enableRegisterInterferences() && node->getOpCode().getSize() == 1)
cg->getLiveRegisters(TR_GPR)->setByteRegisterAssociation(node->getRegister());
return reg;
}
示例10: if
//.........这里部分代码省略.........
}
}
else
{
if (getEvalChild1())
{
firstRegister = _cg->evaluate(firstChild);
}
if (getEvalChild2())
{
secondRegister = _cg->evaluate(secondChild);
}
}
}
// Adjust the FP precision of feeding operands.
//
if (firstRegister &&
(firstRegister->needsPrecisionAdjustment() ||
comp->getOption(TR_StrictFPCompares) ||
(firstRegister->mayNeedPrecisionAdjustment() && secondChild->getOpCode().isLoadConst()) ||
(firstRegister->mayNeedPrecisionAdjustment() && !secondRegister)))
{
TR::TreeEvaluator::insertPrecisionAdjustment(firstRegister, root, _cg);
}
if (secondRegister &&
(secondRegister->needsPrecisionAdjustment() ||
comp->getOption(TR_StrictFPCompares) ||
(secondRegister->mayNeedPrecisionAdjustment() && firstChild->getOpCode().isLoadConst()) ||
(secondRegister->mayNeedPrecisionAdjustment() && !firstRegister)))
{
TR::TreeEvaluator::insertPrecisionAdjustment(secondRegister, root, _cg);
}
// Generate the compare instruction.
//
if (targetRegisterForFTST)
{
generateFPRegInstruction(FTSTReg, root, targetRegisterForFTST, _cg);
}
else if (!useFCOMIInstructions && (getCmpReg1Mem2() || reverseMemOp))
{
TR::MemoryReference *tempMR = generateX86MemoryReference(secondChild, _cg);
generateFPRegMemInstruction(cmpRegMemOpCode, root, firstRegister, tempMR, _cg);
tempMR->decNodeReferenceCounts(_cg);
}
else if (!useFCOMIInstructions && getCmpReg2Mem1())
{
TR::MemoryReference *tempMR = generateX86MemoryReference(firstChild, _cg);
generateFPRegMemInstruction(cmpRegMemOpCode, root, secondRegister, tempMR, _cg);
notReversedOperands();
tempMR->decNodeReferenceCounts(_cg);
}
else if (getCmpReg1Reg2() || reverseCmpOp)
{
generateFPCompareRegRegInstruction(cmpInstr, root, firstRegister, secondRegister, _cg);
}
else if (getCmpReg2Reg1())
{
generateFPCompareRegRegInstruction(cmpInstr, root, secondRegister, firstRegister, _cg);
notReversedOperands();
}
_cg->decReferenceCount(firstChild);
_cg->decReferenceCount(secondChild);
// Evaluate the comparison.
//
if (getReversedOperands())
{
cmpOp = TR::ILOpCode(cmpOp).getOpCodeForSwapChildren();
TR::Node::recreate(root, cmpOp);
}
if (useFCOMIInstructions && !targetRegisterForFTST)
{
return NULL;
}
// We must manually move the FP condition flags to the EFLAGS register if we don't
// use the FCOMI instructions.
//
TR::Register *accRegister = _cg->allocateRegister();
TR::RegisterDependencyConditions *dependencies = generateRegisterDependencyConditions((uint8_t)1, 1, _cg);
dependencies->addPreCondition(accRegister, TR::RealRegister::eax, _cg);
dependencies->addPostCondition(accRegister, TR::RealRegister::eax, _cg);
generateRegInstruction(STSWAcc, root, accRegister, dependencies, _cg);
// Pop the FTST target register if it is not used any more.
//
if (targetRegisterForFTST &&
targetChildForFTST && targetChildForFTST->getReferenceCount() == 0)
{
generateFPSTiST0RegRegInstruction(FSTRegReg, root, targetRegisterForFTST, targetRegisterForFTST, _cg);
}
return accRegister;
}
示例11: self
int32_t
OMR::X86::I386::CodeGenerator::getMaximumNumberOfGPRsAllowedAcrossEdge(TR::Node *node)
{
// TODO: Currently, lookupEvaluator doesn't deal properly with different
// glRegDeps on different cases of a lookupswitch.
//
static const char *enableLookupswitch = feGetEnv("TR_enableGRAAcrossLookupSwitch");
if (!enableLookupswitch && node->getOpCode().getOpCodeValue()==TR::lookup)
return 1;
if (node->getOpCode().getOpCodeValue()==TR::table)
{
// 1 for jump table base reg, which is not apparent in the trees
// 1 for ebp when it is needed for the VMThread
//
return self()->getNumberOfGlobalGPRs() - 2;
}
if (node->getOpCode().isIf())
{
// we run out of all but one/two registers in these cases
//
if (node->getFirstChild()->getType().isInt64())
{
if (node->getOpCode().isBranch())
{
TR::Node *firstChild = node->getFirstChild();
TR::Node *secondChild = node->getSecondChild();
int extraRegsAvailable = 0;
if(firstChild->getOpCodeValue() == TR::d2l ||
secondChild->getOpCodeValue() == TR::d2l)
{
return 1;
}
if ((firstChild->getReferenceCount() == 1 &&
firstChild->getOpCode().isLoadVarDirect()) ||
(secondChild->getReferenceCount() == 1 &&
firstChild->getOpCode().isLoadVarDirect()))
extraRegsAvailable += 0; // TODO: put it back to 2 when looking at GRA, GRA pushes allocation of 8 registers
return 2 + extraRegsAvailable;
}
else
{
// TR_lcmpXX opcodes take up 5 regs
//
return 1;
}
}
// we run out of all but one register in these cases....last time I tried....
//
if (node->getFirstChild()->getOpCodeValue() == TR::instanceof)
{
if (!TR::TreeEvaluator::instanceOfOrCheckCastNeedSuperTest(node->getFirstChild(), self()) &&
TR::TreeEvaluator::instanceOfOrCheckCastNeedEqualityTest(node->getFirstChild(), self()))
return self()->getNumberOfGlobalGPRs() - 4; // ebp plus three other regs if vft masking is enabled
else
return 0;
}
// All other conditional branches, we usually need one reg for the compare and possibly one for the vmthread
//return getNumberOfGlobalGPRs() - 1 - (node->isVMThreadRequired()? 1 : 0);
// vmThread required might be set on a node after GRA has ran
return self()->getNumberOfGlobalGPRs() - 2;
}
return INT_MAX;
}
示例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: stackRegion
int32_t TR::DeadTreesElimination::process(TR::TreeTop *startTree, TR::TreeTop *endTree)
{
TR::StackMemoryRegion stackRegion(*comp()->trMemory());
LongestPathMap longestPaths(std::less<TR::Node*>(), stackRegion);
typedef TR::typed_allocator<CRAnchor, TR::Region&> CRAnchorAlloc;
typedef TR::forward_list<CRAnchor, CRAnchorAlloc> CRAnchorList;
CRAnchorList anchors(stackRegion);
vcount_t visitCount = comp()->incOrResetVisitCount();
TR::TreeTop *treeTop;
for (treeTop = startTree; (treeTop != endTree); treeTop = treeTop->getNextTreeTop())
treeTop->getNode()->initializeFutureUseCounts(visitCount);
TR::Block *block = NULL;
bool delayedRegStoresBeforeThisPass = _delayedRegStores;
// Update visitCount as they are used in this optimization and need to be
visitCount = comp()->incOrResetVisitCount();
for (TR::TreeTopIterator iter(startTree, comp()); iter != endTree; ++iter)
{
TR::Node *node = iter.currentTree()->getNode();
if (node->getOpCodeValue() == TR::BBStart)
{
block = node->getBlock();
if (!block->isExtensionOfPreviousBlock())
longestPaths.clear();
}
int vcountLimit = MAX_VCOUNT - 3;
if (comp()->getVisitCount() > vcountLimit)
{
dumpOptDetails(comp(),
"%sVisit count %d exceeds limit %d; stopping\n",
optDetailString(), comp()->getVisitCount(), vcountLimit);
return 0;
}
// correct at all intermediate stages
//
if ((node->getOpCodeValue() != TR::treetop) &&
(!node->getOpCode().isAnchor() || (node->getFirstChild()->getReferenceCount() != 1)) &&
(!node->getOpCode().isStoreReg() || (node->getFirstChild()->getReferenceCount() != 1)) &&
(delayedRegStoresBeforeThisPass ||
(iter.currentTree() == block->getLastRealTreeTop()) ||
!node->getOpCode().isStoreReg() ||
(node->getVisitCount() == visitCount)))
{
if (node->getOpCode().isAnchor() && node->getFirstChild()->getOpCode().isLoadIndirect())
anchors.push_front(CRAnchor(iter.currentTree(), block));
TR::TransformUtil::recursivelySetNodeVisitCount(node, visitCount);
continue;
}
if (node->getOpCode().isStoreReg())
_delayedRegStores = true;
TR::Node *child = node->getFirstChild();
if (child->getOpCodeValue() == TR::PassThrough)
{
TR::Node *newChild = child->getFirstChild();
node->setAndIncChild(0, newChild);
newChild->incFutureUseCount();
if (child->getReferenceCount() <= 1)
optimizer()->prepareForNodeRemoval(child);
child->recursivelyDecReferenceCount();
recursivelyDecFutureUseCount(child);
child = newChild;
}
bool treeTopCanBeEliminated = false;
// If the treetop child has been seen before then it must be anchored
// somewhere above already; so we don't need the treetop to be anchoring
// this node (as the computation is already done at the first reference to
// the node).
//
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() ||
//.........这里部分代码省略.........
示例14: isAnySymInDefinedOrUsedBy
//.........这里部分代码省略.........
// Don't move object header store past a GC point
//
if ((currentNode->getOpCode().isWrtBar() || currentNode->canCauseGC()) && mayBeObjectHeaderStore(movingNode, fe()))
{
if (trace())
traceMsg(comp(),"cannot move possible object header store %s past GC point %s\n", getDebug()->getName(movingNode), getDebug()->getName(currentNode));
return true;
}
if (TR::Compiler->target.cpu.isPower() && opCode.getOpCodeValue() == TR::allocationFence)
{
// Can't move allocations past flushes
if (movingNode->getOpCodeValue() == TR::treetop &&
movingNode->getFirstChild()->getOpCode().isNew() &&
(currentNode->getAllocation() == NULL ||
currentNode->getAllocation() == movingNode->getFirstChild()))
{
if (trace())
{
traceMsg(comp(),"cannot move %p beyond flush %p - ", movingNode, currentNode);
if (currentNode->getAllocation() == NULL)
traceMsg(comp(),"(flush with null allocation)\n");
else
traceMsg(comp(),"(flush for allocation %p)\n", currentNode->getAllocation());
}
return true;
}
// Can't move certain stores past flushes
// Exclude all indirect stores, they may be for stack allocs, in which case the flush is needed at least as a scheduling barrier
// Direct stores to autos and parms are the only safe candidates
if (movingNode->getOpCode().isStoreIndirect() ||
(movingNode->getOpCode().isStoreDirect() && !movingNode->getSymbol()->isParm() && !movingNode->getSymbol()->isAuto()))
{
if (trace())
traceMsg(comp(),"cannot move %p beyond flush %p - (flush for possible stack alloc)", movingNode, currentNode);
return true;
}
}
for (int32_t i = 0; i < currentNode->getNumChildren(); i++)
{
TR::Node *child = currentNode->getChild(i);
//Any node that has side effects (like call and newarrya) cannot be evaluated in the middle of the tree.
if (movingTreeRefInfo->getFirstRefNodesList()->find(child))
{
//for calls and unresolve symbol that are not under check
if (child->exceptionsRaised() ||
(child->getOpCode().hasSymbolReference() && child->getSymbolReference()->isUnresolved()))
{
if (trace())
traceMsg(comp(),"cannot move %p beyond %p - cannot change evaluation point of %p\n ",movingNode,currentTreeRefInfo->getTreeTop()->getNode(),child);
return true;
}
else if(movingNode->getOpCode().isStore())
{
TR::SymbolReference *stSymRef = movingNode->getSymbolReference();
int32_t stSymRefNum = stSymRef->getReferenceNumber();
//TR::SymbolReference *stSymRef = movingNode->getSymbolReference();
int32_t numHelperSymbols = comp()->getSymRefTab()->getNumHelperSymbols();
if ((comp()->getSymRefTab()->isNonHelper(stSymRefNum, TR::SymbolReferenceTable::vftSymbol))||
(comp()->getSymRefTab()->isNonHelper(stSymRefNum, TR::SymbolReferenceTable::contiguousArraySizeSymbol))||
(comp()->getSymRefTab()->isNonHelper(stSymRefNum, TR::SymbolReferenceTable::discontiguousArraySizeSymbol))||
(stSymRef == comp()->getSymRefTab()->findHeaderFlagsSymbolRef())||
(stSymRef->getSymbol() == comp()->getSymRefTab()->findGenericIntShadowSymbol()))
return true;
}
else if (movingNode->getOpCode().isResolveOrNullCheck())
{
if (trace())
traceMsg(comp(),"cannot move %p beyond %p - node %p under ResolveOrNullCheck",movingNode,currentTreeRefInfo->getTreeTop()->getNode(),currentNode);
return true;
}
else if (TR::Compiler->target.is64Bit() &&
movingNode->getOpCode().isBndCheck() &&
((opCode.getOpCodeValue() == TR::i2l) || (opCode.getOpCodeValue() == TR::iu2l)) &&
!child->isNonNegative())
{
if (trace())
traceMsg(comp(),"cannot move %p beyond %p - changing the eval point of %p will casue extra cg instruction ",movingNode,currentTreeRefInfo->getTreeTop()->getNode(),currentNode);
return true;
}
}
//don't recurse over nodes each are not the first reference
if (child->getReferenceCount()==1 || currentTreeRefInfo->getFirstRefNodesList()->find(child))
{
if (isAnySymInDefinedOrUsedBy(currentTreeRefInfo, child, movingTreeRefInfo ))
return true;
}
}
return false;
}
示例15: populatePotentialDeps
void TR_LocalLiveRangeReduction::populatePotentialDeps(TR_TreeRefInfo *treeRefInfo,TR::Node *node)
{
TR::ILOpCode &opCode = node->getOpCode();
if (node->getOpCode().hasSymbolReference())
{
TR::SymbolReference *symRef = node->getSymbolReference();
int32_t symRefNum = symRef->getReferenceNumber();
//set defSym - all symbols that might be written
if (opCode.isCall() || opCode.isResolveCheck()|| opCode.isStore() || node->mightHaveVolatileSymbolReference())
{
bool isCallDirect = false;
if (node->getOpCode().isCallDirect())
isCallDirect = true;
if (!symRef->getUseDefAliases(isCallDirect).isZero(comp()))
{
TR::SparseBitVector useDefAliases(comp()->allocator());
symRef->getUseDefAliases(isCallDirect).getAliases(useDefAliases);
TR::SparseBitVector::Cursor aliasCursor(useDefAliases);
for (aliasCursor.SetToFirstOne(); aliasCursor.Valid(); aliasCursor.SetToNextOne())
{
int32_t nextAlias = aliasCursor;
treeRefInfo->getDefSym()->set(nextAlias);
}
}
if (opCode.isStore())
treeRefInfo->getDefSym()->set(symRefNum);
}
//set useSym - all symbols that are used
if (opCode.canRaiseException())
{
TR::SparseBitVector useAliases(comp()->allocator());
symRef->getUseonlyAliases().getAliases(useAliases);
{
TR::SparseBitVector::Cursor aliasesCursor(useAliases);
for (aliasesCursor.SetToFirstOne(); aliasesCursor.Valid(); aliasesCursor.SetToNextOne())
{
int32_t nextAlias = aliasesCursor;
treeRefInfo->getUseSym()->set(nextAlias);
}
}
}
if (opCode.isLoadVar() || (opCode.getOpCodeValue() == TR::loadaddr))
{
treeRefInfo->getUseSym()->set(symRefNum);
}
}
for (int32_t i = 0; i < node->getNumChildren(); i++)
{
TR::Node *child = node->getChild(i);
//don't recurse over references (nodes which are not the first reference)
//
if (child->getReferenceCount()==1 || treeRefInfo->getFirstRefNodesList()->find(child))
populatePotentialDeps(treeRefInfo,child );
}
return;
}