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; }
// Collects nodes that involved in PRE that are not stores or checks. // These nodes require temps. // bool TR_LocalAnalysisInfo::collectSupportedNodes(TR::Node *node, TR::Node *parent) { if (node->getVisitCount() == _visitCount) return false; node->setVisitCount(_visitCount); bool flag = false; bool childRelevant = false; TR::ILOpCode &opCode = node->getOpCode(); int32_t i; for (i = 0; i < node->getNumChildren(); i++) { TR::Node *child = node->getChild(i); if (collectSupportedNodes(child, node)) flag = true; if (_checkExpressions->get(child->getLocalIndex())) childRelevant = true; } if (TR_LocalAnalysis::isSupportedNode(node, _compilation, parent)) { _supportedNodesAsArray[node->getLocalIndex()] = node; bool indirectionSafe = true; if (opCode.isIndirect() && (opCode.isLoadVar() || opCode.isStore())) { indirectionSafe = false; if (node->getFirstChild()->isThisPointer() && node->getFirstChild()->isNonNull()) { indirectionSafe = true; TR::Node *firstChild = node->getFirstChild(); TR::SymbolReference *symRef = firstChild->getSymbolReference(); int32_t len; const char *sig = symRef->getTypeSignature(len); TR::SymbolReference *otherSymRef = node->getSymbolReference(); TR_OpaqueClassBlock *cl = NULL; if (sig && (len > 0)) cl = _compilation->fe()->getClassFromSignature(sig, len, symRef->getOwningMethod(_compilation)); TR_OpaqueClassBlock *otherClassObject = NULL; int32_t otherLen; const char *otherSig = otherSymRef->getOwningMethod(_compilation)->classNameOfFieldOrStatic(otherSymRef->getCPIndex(), otherLen); if (otherSig) { otherSig = classNameToSignature(otherSig, otherLen, _compilation); otherClassObject = _compilation->fe()->getClassFromSignature(otherSig, otherLen, otherSymRef->getOwningMethod(_compilation)); } if (!cl || !otherClassObject || (cl != otherClassObject)) indirectionSafe = false; } } if (childRelevant || (!indirectionSafe || (opCode.isArrayLength())) || (node->getOpCode().isArrayRef()) || (opCode.hasSymbolReference() && (node->getSymbolReference()->isUnresolved() || node->getSymbol()->isArrayShadowSymbol())) || (opCode.isDiv() || opCode.isRem())) _checkExpressions->set(node->getLocalIndex()); } return flag; }