Example #1
0
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;
      }
   }
Example #2
0
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());
      }
   }