void TR_ReachingDefinitions::initializeGenAndKillSetInfoForNode(TR::Node *node, TR_UseDefInfo::BitVector &defsKilled, bool seenException, int32_t blockNum, TR::Node *parent) { // Update gen and kill info for nodes in this subtree // int32_t i; if (node->getVisitCount() == comp()->getVisitCount()) return; node->setVisitCount(comp()->getVisitCount()); // Process the children first // for (i = node->getNumChildren()-1; i >= 0; --i) { initializeGenAndKillSetInfoForNode(node->getChild(i), defsKilled, seenException, blockNum, node); } bool irrelevantStore = false; scount_t nodeIndex = node->getLocalIndex(); if (nodeIndex <= 0) { if (node->getOpCode().isStore() && node->getSymbol()->isAutoOrParm() && node->storedValueIsIrrelevant()) { irrelevantStore = true; } else return; } bool foundDefsToKill = false; int32_t numDefNodes = 0; defsKilled.Clear(); TR::ILOpCode &opCode = node->getOpCode(); TR::SymbolReference *symRef; TR::Symbol *sym; uint16_t symIndex; uint32_t num_aliases; if (_useDefInfo->_useDefForRegs && (opCode.isLoadReg() || opCode.isStoreReg())) { sym = NULL; symRef = NULL; symIndex = _useDefInfo->getNumSymbols() + node->getGlobalRegisterNumber(); num_aliases = 1; } else { symRef = node->getSymbolReference(); sym = symRef->getSymbol(); symIndex = symRef->getSymbol()->getLocalIndex(); num_aliases = _useDefInfo->getNumAliases(symRef, _aux); } if (symIndex == NULL_USEDEF_SYMBOL_INDEX || node->getOpCode().isCall() || node->getOpCode().isFence() || (parent && parent->getOpCode().isResolveCheck() && num_aliases > 1)) { // A call or unresolved reference is a definition of all // symbols it is aliased with // numDefNodes = num_aliases; //for all symbols that are a mustdef of a call, kill defs of those symbols if (node->getOpCode().isCall()) foundDefsToKill = false; } else if (irrelevantStore || _useDefInfo->isExpandedDefIndex(nodeIndex)) { // DefOnly node defines all symbols it is aliased with // UseDef node(load) defines only the symbol itself // if (!irrelevantStore) { numDefNodes = num_aliases; numDefNodes = _useDefInfo->isExpandedUseDefIndex(nodeIndex) ? 1 : numDefNodes; if (!_useDefInfo->getDefsForSymbolIsZero(symIndex, _aux) && (!sym || (!sym->isShadow() && !sym->isMethod()))) { foundDefsToKill = true; // defsKilled ORed with defsForSymbol(symIndex); _useDefInfo->getDefsForSymbol(defsKilled, symIndex, _aux); } if (node->getOpCode().isStoreIndirect()) { int32_t memSymIndex = _useDefInfo->getMemorySymbolIndex(node); if (memSymIndex != -1 && !_useDefInfo->getDefsForSymbolIsZero(memSymIndex, _aux)) { foundDefsToKill = true; // defsKilled ORed with defsForSymbol(symIndex); _useDefInfo->getDefsForSymbol(defsKilled, memSymIndex, _aux); } } } else if (!_useDefInfo->getDefsForSymbolIsZero(symIndex, _aux)) { numDefNodes = 1; foundDefsToKill = true; // defsKilled ORed with defsForSymbol(symIndex); _useDefInfo->getDefsForSymbol(defsKilled, symIndex, _aux); } } else { numDefNodes = 0; } if (foundDefsToKill) { if (_regularKillSetInfo[blockNum] == NULL) allocateContainer(&_regularKillSetInfo[blockNum]); *_regularKillSetInfo[blockNum] |= defsKilled; if (!seenException) { if (_exceptionKillSetInfo[blockNum] == NULL) allocateContainer(&_exceptionKillSetInfo[blockNum]); *_exceptionKillSetInfo[blockNum] |= defsKilled; } } if (_regularGenSetInfo[blockNum] == NULL) allocateContainer(&_regularGenSetInfo[blockNum]); else if (foundDefsToKill) *_regularGenSetInfo[blockNum] -= defsKilled; if (_exceptionGenSetInfo[blockNum] == NULL) allocateContainer(&_exceptionGenSetInfo[blockNum]); else if (foundDefsToKill && !seenException) *_exceptionGenSetInfo[blockNum] -= defsKilled; if (!irrelevantStore) { for (i = 0; i < numDefNodes; ++i) { _regularGenSetInfo[blockNum]->set(nodeIndex+i); _exceptionGenSetInfo[blockNum]->set(nodeIndex+i); } } else // fake up the method entry def as the def index to "gen" to avoid a use without a def completely { _regularGenSetInfo[blockNum]->set(sym->getLocalIndex()); _exceptionGenSetInfo[blockNum]->set(sym->getLocalIndex()); } }
TR_BitVector * addVeryRefinedCallAliasSets(TR::ResolvedMethodSymbol * methodSymbol, TR_BitVector * aliases, List<void> * methodsPeeked) { TR::Compilation *comp = TR::comp(); void * methodId = methodSymbol->getResolvedMethod()->getPersistentIdentifier(); if (methodsPeeked->find(methodId)) { // This can't be allocated into the alias region as it must be accessed across optimizations TR_BitVector *heapAliases = new (comp->trHeapMemory()) TR_BitVector(comp->getSymRefCount(), comp->trMemory(), heapAlloc, growable); *heapAliases |= *aliases; return heapAliases; } // stop if the peek is getting very deep // if (methodsPeeked->getSize() >= PEEK_THRESHOLD) return 0; methodsPeeked->add(methodId); dumpOptDetails(comp, "O^O REFINING ALIASES: Peeking into the IL to refine aliases \n"); if (!methodSymbol->getResolvedMethod()->genMethodILForPeeking(methodSymbol, comp, true)) return 0; TR::SymbolReferenceTable * symRefTab = comp->getSymRefTab(); for (TR::TreeTop * tt = methodSymbol->getFirstTreeTop(); tt; tt = tt->getNextTreeTop()) { TR::Node *node = tt->getNode(); if (node->getOpCode().isResolveCheck()) return 0; if ((node->getOpCodeValue() == TR::treetop) || (node->getOpCodeValue() == TR::compressedRefs) || node->getOpCode().isCheck()) node = node->getFirstChild(); if (node->getOpCode().isStore()) { TR::SymbolReference * symRefInCallee = node->getSymbolReference(), * symRefInCaller; TR::Symbol * symInCallee = symRefInCallee->getSymbol(); TR::DataType type = symInCallee->getDataType(); if (symInCallee->isShadow()) { if (symInCallee->isArrayShadowSymbol()) symRefInCaller = symRefTab->getSymRef(symRefTab->getArrayShadowIndex(type)); else if (symInCallee->isArrayletShadowSymbol()) symRefInCaller = symRefTab->getSymRef(symRefTab->getArrayletShadowIndex(type)); else symRefInCaller = symRefTab->findShadowSymbol(symRefInCallee->getOwningMethod(comp), symRefInCallee->getCPIndex(), type); if (symRefInCaller) { if (symRefInCaller->reallySharesSymbol(comp)) symRefInCaller->setSharedShadowAliases(aliases, symRefTab); aliases->set(symRefInCaller->getReferenceNumber()); } } else if (symInCallee->isStatic()) { symRefInCaller = symRefTab->findStaticSymbol(symRefInCallee->getOwningMethod(comp), symRefInCallee->getCPIndex(), type); if (symRefInCaller) { if (symRefInCaller->reallySharesSymbol(comp)) symRefInCaller->setSharedStaticAliases(aliases, symRefTab); else aliases->set(symRefInCaller->getReferenceNumber()); } } } else if (node->getOpCode().isCall()) { if (node->getOpCode().isCallIndirect()) return 0; TR::ResolvedMethodSymbol * calleeSymbol = node->getSymbol()->getResolvedMethodSymbol(); if (!calleeSymbol) return 0; TR_ResolvedMethod * calleeMethod = calleeSymbol->getResolvedMethod(); if (!calleeMethod->isCompilable(comp->trMemory()) || calleeMethod->isJNINative()) return 0; if (!addVeryRefinedCallAliasSets(calleeSymbol, aliases, methodsPeeked)) return 0; } else if (node->getOpCodeValue() == TR::monent) return 0; } // This can't be allocated into the alias region as it must be accessed across optimizations TR_BitVector *heapAliases = new (comp->trHeapMemory()) TR_BitVector(comp->getSymRefCount(), comp->trMemory(), heapAlloc, growable); *heapAliases |= *aliases; return heapAliases; }