Пример #1
0
// Volatile memory operands are not allowed in long subtractions
// if we are compiling for an SMP machine, as the carry flag can
// get clobbered by the memory barrier immediately preceding the
// SBB4RegMem instruction.
//
static bool isVolatileMemoryOperand(TR::Node *node)
   {
   if (TR::Compiler->target.isSMP() && node->getOpCode().isMemoryReference())
      {
      TR_ASSERT(node->getSymbolReference(), "expecting a symbol reference\n");
      TR::Symbol *sym = node->getSymbolReference()->getSymbol();
      return (sym && sym->isVolatile());
      }
   return false;
   }
Пример #2
0
bool
OMR::SymbolReference::storeCanBeRemoved()
   {
   TR::Compilation *comp = TR::comp();
   TR::Symbol * s = self()->getSymbol();

   return !s->isVolatile() &&
     (((s->getDataType() != TR::Double) && (s->getDataType() != TR::Float)) ||
           comp->cg()->getSupportsJavaFloatSemantics() ||
           (self()->isTemporary(comp) && !s->behaveLikeNonTemp()));
   }
Пример #3
0
bool checkMethodSignature(TR::ValuePropagation *vp, TR::SymbolReference *symRef, const char *sig)
   {
   TR::Symbol *symbol = symRef->getSymbol();
   if (!symbol->isResolvedMethod())
      return false;

   TR::ResolvedMethodSymbol *method = symbol->castToResolvedMethodSymbol();
   if (!method) return false;

    if (strncmp(method->getResolvedMethod()->signature(vp->trMemory()), sig, strlen(sig)) == 0)
      return true;
   return false;
   }
Пример #4
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());
      }
   }
Пример #5
0
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;
   }
Пример #6
0
static int cacheStringAppend(TR::ValuePropagation *vp,TR::Node *node)
   {
   return 0;

   if (!vp->lastTimeThrough())
     return 0;

   TR::TreeTop *tt = vp->_curTree;
   TR::TreeTop *newTree   = tt;
   TR::TreeTop *startTree = 0;
   TR::TreeTop *exitTree  =  vp->_curBlock->getExit();
   TR::Node    *newBuffer;

   if(node->getNumChildren() >= 1)
      newBuffer = node->getFirstChild();
      else
         return 0;

   enum {MAX_STRINGS = 2};
   int        initWithString = 0;
   bool       initWithInteger = false;
   TR::TreeTop *appendTree[MAX_STRINGS+1];
   TR::Node    *appendedString[MAX_STRINGS+1];
   char       pattern[MAX_STRINGS+1];
   int        stringCount = 0;
   bool useStringBuffer=false;
   TR::SymbolReference *valueOfSymRef[MAX_STRINGS+1];
   bool success = false;
   char *sigBuffer="java/lang/StringBuffer.<init>(";
   char *sigBuilder = "java/lang/StringBuilder.<init>(";
   char *sigInit = "java/lang/String.<init>(";


  ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   if (checkMethodSignature(vp,node->getSymbolReference(), sigInit))
    {
	  TR::Symbol *symbol =node->getSymbolReference()->getSymbol();
      TR_ResolvedMethod *m = symbol->castToResolvedMethodSymbol()->getResolvedMethod();
      if (strncmp(m->signatureChars(), "(Ljava/lang/String;Ljava/lang/String;)V", m->signatureLength())==0)
        {
	      vp->_cachedStringPeepHolesVcalls.add(new (vp->comp()->trStackMemory()) TR::ValuePropagation::VPTreeTopPair(tt,tt->getPrevRealTreeTop()));
		}
    }
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

   if (checkMethodSignature(vp,node->getSymbolReference(), sigBuffer))
      {
         useStringBuffer=true;
         success = true;
      }
   else if (checkMethodSignature(vp,node->getSymbolReference(), sigBuilder))
      {
         success = true;
	     useStringBuffer=false;
      }
	  else
	  {
	     return 0;
	  }


	if (success)
      {
      TR::Symbol *symbol =node->getSymbolReference()->getSymbol();
      TR_ResolvedMethod *m = symbol->castToResolvedMethodSymbol()->getResolvedMethod();
      if (strncmp(m->signatureChars(), "()V", m->signatureLength())==0)
        {
             // Diagnostics
		}else
        {
      	  return 0;
        }
      }
      else // <init> not found (could be unresolved)
      {
         return 0;
      }


   // now search for StringBuffer.append calls that are chained to one another
   TR::TreeTop *lastAppendTree = 0; // updated when we find an append
   TR::Node    *child = newBuffer;

   while (1)
      {
      startTree = tt->getNextRealTreeTop();
	  appendedString[stringCount] = 0;
      int visitCount = 0;
      if (useStringBuffer)
         tt = searchForStringAppend(vp,"java/lang/StringBuffer.append(",
                                    startTree, exitTree, TR::acall, child, visitCount,
                                    appendedString + stringCount);
      else
         tt = searchForStringAppend(vp,"java/lang/StringBuilder.append(",
                                    startTree, exitTree, TR::acall, child, visitCount,
                                    appendedString + stringCount);

	  if (appendedString[stringCount]) // we found it
         {
         appendTree[stringCount] = tt;

         // we could exit here if too many appends are chained
         if (stringCount >= MAX_STRINGS)
            return 0;

         // see which type of append we have
         TR::Symbol *symbol = tt->getNode()->getFirstChild()->getSymbolReference()->getSymbol();
         TR_ASSERT(symbol->isResolvedMethod(), "assertion failure");
         TR::ResolvedMethodSymbol *method = symbol->castToResolvedMethodSymbol();
         TR_ASSERT(method, "assertion failure");
         TR_ResolvedMethod *m = method->getResolvedMethod();
         if (strncmp(m->signatureChars(), "(Ljava/lang/String;)", 20)==0)
            {
            pattern[stringCount] = 'S';
            valueOfSymRef[stringCount] = 0; // don't need conversion to string
            }
         else // appending something that needs conversion using valueOf
            {
            TR::SymbolReference *symRefForValueOf = 0;
            // In the following we can vp->compare only (C) because we know that
            // StringBuffer.append returns a StringBuffer.
            //s
            char *sigBuffer = m->signatureChars();
            TR_ASSERT(m->signatureLength() >= 3, "The minimum signature length should be 3 for ()V");
            }
         stringCount++;
         }
      else // the chain of appends is broken
         {
         appendTree[stringCount] = 0;
         pattern[stringCount] = 0; // string terminator
         break;
         }
      lastAppendTree = tt;
      child = tt->getNode()->getFirstChild(); // the first node is a NULLCHK and its child is the call
      } // end while

   if (stringCount < 2)
      return 0; // cannot apply StringPeepholes
   if (stringCount > MAX_STRINGS)
      return 0;
   if (stringCount == 3)
      return 0; // same as above

   TR_ASSERT(lastAppendTree, "If stringCount <=2 then we must have found an append");

   // now look for the toString call
     TR::TreeTop *toStringTree = 0;
   //visitCount = vp->comp()->incVisitCount();

   int visitCount=0;
   tt = searchForToStringCall(vp,lastAppendTree->getNextRealTreeTop(), exitTree,
                              lastAppendTree->getNode()->getFirstChild(),
                              visitCount, &toStringTree, useStringBuffer);
   if (!toStringTree)
      return 0;

   vp->_cachedStringBufferVcalls.add(new (vp->comp()->trStackMemory()) TR::ValuePropagation::VPStringCached(appendTree[0],appendTree[1],appendedString[0],appendedString[1],newTree,toStringTree));
}