void TR_ReachingDefinitions::initializeGenAndKillSetInfo() { // For each block in the CFG build the gen and kill set for this analysis. // Go in treetop order, which guarantees that we see the correct (i.e. first) // evaluation point for each node. // TR::Block *block; int32_t blockNum = 0; bool seenException = false; TR_BitVector defsKilled(getNumberOfBits(), trMemory()->currentStackRegion()); comp()->incVisitCount(); for (TR::TreeTop *treeTop = comp()->getStartTree(); treeTop; treeTop = treeTop->getNextTreeTop()) { TR::Node *node = treeTop->getNode(); if (node->getOpCodeValue() == TR::BBStart) { block = node->getBlock(); blockNum = block->getNumber(); seenException = false; if (traceRD()) traceMsg(comp(), "\nNow generating gen and kill information for block_%d\n", blockNum); continue; } #if DEBUG if (node->getOpCodeValue() == TR::BBEnd && traceRD()) { traceMsg(comp(), " Block %d:\n", blockNum); traceMsg(comp(), " Gen set "); if (_regularGenSetInfo[blockNum]) _regularGenSetInfo[blockNum]->print(comp()); else traceMsg(comp(), "{}"); traceMsg(comp(), "\n Kill set "); if (_regularKillSetInfo[blockNum]) _regularKillSetInfo[blockNum]->print(comp()); else traceMsg(comp(), "{}"); traceMsg(comp(), "\n Exception Gen set "); if (_exceptionGenSetInfo[blockNum]) _exceptionGenSetInfo[blockNum]->print(comp()); else traceMsg(comp(), "{}"); traceMsg(comp(), "\n Exception Kill set "); if (_exceptionKillSetInfo[blockNum]) _exceptionKillSetInfo[blockNum]->print(comp()); else traceMsg(comp(), "{}"); continue; } #endif initializeGenAndKillSetInfoForNode(node, defsKilled, seenException, blockNum, NULL); if (!seenException && treeHasChecks(treeTop)) seenException = true; } }
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()); } }