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; }