bool TR_LocalLiveRangeReduction::moveTreeBefore(TR_TreeRefInfo *treeToMove,TR_TreeRefInfo *anchor,int32_t passNumber)
   {
   TR::TreeTop *treeToMoveTT = treeToMove->getTreeTop();
   TR::TreeTop *anchorTT = anchor->getTreeTop();
   if (treeToMoveTT->getNextRealTreeTop() == anchorTT)
      {
      addDepPair(treeToMove, anchor);
      return false;
      }

   if (!performTransformation(comp(), "%sPass %d: moving tree [%p] before Tree %p\n", OPT_DETAILS, passNumber, treeToMoveTT->getNode(),anchorTT->getNode()))
      return false;

   //   printf("Moving [%p] before Tree %p\n",  treeToMoveTT->getNode(),anchorTT->getNode());


   //changing location in block
   TR::TreeTop *origPrevTree = treeToMoveTT->getPrevTreeTop();
   TR::TreeTop *origNextTree = treeToMoveTT->getNextTreeTop();
   origPrevTree->setNextTreeTop(origNextTree);
   origNextTree->setPrevTreeTop(origPrevTree);
   TR::TreeTop *prevTree = anchorTT->getPrevTreeTop();
   anchorTT->setPrevTreeTop(treeToMoveTT);
   treeToMoveTT->setNextTreeTop(anchorTT);
   treeToMoveTT->setPrevTreeTop(prevTree);
   prevTree->setNextTreeTop(treeToMoveTT);

   //UPDATE REFINFO
   //find locations of treeTops in TreeTopsRefInfo array
   //startIndex points to the currentTree that has moved
   //endIndex points to the treeTop after which we moved the tree (nextTree)

   int32_t startIndex = getIndexInArray(treeToMove);
   int32_t endIndex = getIndexInArray(anchor)-1;
   int32_t i=0;
   for ( i = startIndex+1; i<= endIndex ; i++)
      {
      TR_TreeRefInfo *currentTreeRefInfo = _treesRefInfoArray[i];
      List<TR::Node> *firstList = currentTreeRefInfo->getFirstRefNodesList();
      List<TR::Node> *midList = currentTreeRefInfo->getMidRefNodesList();
      List<TR::Node> *lastList = currentTreeRefInfo->getLastRefNodesList();
      List<TR::Node> *M_firstList = treeToMove->getFirstRefNodesList();
      List<TR::Node> *M_midList = treeToMove->getMidRefNodesList();
      List<TR::Node> *M_lastList = treeToMove->getLastRefNodesList();

      if (trace())
    	 {
    	 traceMsg(comp(),"Before move:\n");
    	 printRefInfo(treeToMove);
    	 printRefInfo(currentTreeRefInfo);
    	 }

      updateRefInfo(treeToMove->getTreeTop()->getNode(), currentTreeRefInfo, treeToMove , false);
      treeToMove->resetSyms();
      currentTreeRefInfo->resetSyms();
      populatePotentialDeps(currentTreeRefInfo,currentTreeRefInfo->getTreeTop()->getNode());
      populatePotentialDeps(treeToMove,treeToMove->getTreeTop()->getNode());

      if (trace())
    	 {
    	 traceMsg(comp(),"After move:\n");
    	 printRefInfo(treeToMove);
    	 printRefInfo(currentTreeRefInfo);
    	 traceMsg(comp(),"------------------------\n");
    	 }
      }

   TR_TreeRefInfo *temp = _treesRefInfoArray[startIndex];
   for (i = startIndex; i< endIndex ; i++)
      {
      _treesRefInfoArray[i] = _treesRefInfoArray[i+1];
      }

   _treesRefInfoArray[endIndex]=temp;

#if defined(DEBUG) || defined(PROD_WITH_ASSUMES)
   if (!(comp()->getOption(TR_EnableParanoidOptCheck) || debug("paranoidOptCheck")))
      return true;

   //verifier
   {
   TR::StackMemoryRegion stackMemoryRegion(*trMemory());

   vcount_t visitCount = comp()->getVisitCount();
   int32_t maxRefCount = 0;
   TR::TreeTop *tt;
   TR_TreeRefInfo **treesRefInfoArrayTemp = (TR_TreeRefInfo**)trMemory()->allocateStackMemory(_numTreeTops*sizeof(TR_TreeRefInfo*));
   memset(treesRefInfoArrayTemp, 0, _numTreeTops*sizeof(TR_TreeRefInfo*));
   TR_TreeRefInfo *treeRefInfoTemp;


   //collect info
   for ( int32_t i  = 0; i<_numTreeTops-1; i++)
      {
      tt =_treesRefInfoArray[i]->getTreeTop();
      treeRefInfoTemp = new (trStackMemory()) TR_TreeRefInfo(tt, trMemory());
      collectRefInfo(treeRefInfoTemp, tt->getNode(),visitCount,&maxRefCount);
      treesRefInfoArrayTemp[i] = treeRefInfoTemp;
      }

   comp()->setVisitCount(visitCount+maxRefCount);

   for ( int32_t i  = 0; i<_numTreeTops-1; i++)
      {
      if (!verifyRefInfo(treesRefInfoArrayTemp[i]->getFirstRefNodesList(),_treesRefInfoArray[i]->getFirstRefNodesList()))
    	 {
    	 printOnVerifyError(_treesRefInfoArray[i],treesRefInfoArrayTemp[i]);
    	 TR_ASSERT(0,"fail to verify firstRefNodesList for %p\n",_treesRefInfoArray[i]->getTreeTop()->getNode());
    	 }

      if (!verifyRefInfo(treesRefInfoArrayTemp[i]->getMidRefNodesList(),_treesRefInfoArray[i]->getMidRefNodesList()))
    	 {
    	 printOnVerifyError(_treesRefInfoArray[i],treesRefInfoArrayTemp[i]);
    	 TR_ASSERT(0,"fail to verify midRefNodesList for %p\n",_treesRefInfoArray[i]->getTreeTop()->getNode());
    	 }

      if (!verifyRefInfo(treesRefInfoArrayTemp[i]->getLastRefNodesList(),_treesRefInfoArray[i]->getLastRefNodesList()))
    	 {
    	 printOnVerifyError(_treesRefInfoArray[i],treesRefInfoArrayTemp[i]);
    	 TR_ASSERT(0,"fail to verify lastRefNodesList for %p\n",_treesRefInfoArray[i]->getTreeTop()->getNode());
    	 }


       }
   } // scope of the stack memory region

#endif
   return true;
   }
Beispiel #2
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));
}