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; }
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)); }