// deleteValue method - This method is used to remove a pointer value from the // AliasSetTracker entirely. It should be used when an instruction is deleted // from the program to update the AST. If you don't use this, you would have // dangling pointers to deleted instructions. // void AliasSetTracker::deleteValue(Value *PtrVal) { // Notify the alias analysis implementation that this value is gone. AA.deleteValue(PtrVal); // If this is a call instruction, remove the callsite from the appropriate // AliasSet. CallSite CS = CallSite::get(PtrVal); if (CS.getInstruction()) { Function *F = CS.getCalledFunction(); if (!F || !AA.doesNotAccessMemory(F)) { if (AliasSet *AS = findAliasSetForCallSite(CS)) AS->removeCallSite(CS); } } // First, look up the PointerRec for this pointer. hash_map<Value*, AliasSet::PointerRec>::iterator I = PointerMap.find(PtrVal); if (I == PointerMap.end()) return; // Noop // If we found one, remove the pointer from the alias set it is in. AliasSet::HashNodePair &PtrValEnt = *I; AliasSet *AS = PtrValEnt.second.getAliasSet(*this); // Unlink from the list of values... PtrValEnt.second.removeFromList(); // Stop using the alias set AS->dropRef(*this); PointerMap.erase(I); }
// deleteValue method - This method is used to remove a pointer value from the // AliasSetTracker entirely. It should be used when an instruction is deleted // from the program to update the AST. If you don't use this, you would have // dangling pointers to deleted instructions. // void AliasSetTracker::deleteValue(Value *PtrVal) { // Notify the alias analysis implementation that this value is gone. AA.deleteValue(PtrVal); // If this is a call instruction, remove the callsite from the appropriate // AliasSet (if present). if (Instruction *Inst = dyn_cast<Instruction>(PtrVal)) { if (Inst->mayReadOrWriteMemory()) { // Scan all the alias sets to see if this call site is contained. for (iterator I = begin(), E = end(); I != E;) { iterator Cur = I++; if (!Cur->Forward) Cur->removeUnknownInst(*this, Inst); } } } // First, look up the PointerRec for this pointer. PointerMapType::iterator I = PointerMap.find_as(PtrVal); if (I == PointerMap.end()) return; // Noop // If we found one, remove the pointer from the alias set it is in. AliasSet::PointerRec *PtrValEnt = I->second; AliasSet *AS = PtrValEnt->getAliasSet(*this); // Unlink and delete from the list of values. PtrValEnt->eraseFromList(); // Stop using the alias set. AS->dropRef(*this); PointerMap.erase(I); }
/// remove - Remove the specified (potentially non-empty) alias set from the /// tracker. void AliasSetTracker::remove(AliasSet &AS) { // Drop all call sites. if (!AS.UnknownInsts.empty()) AS.dropRef(*this); AS.UnknownInsts.clear(); // Clear the alias set. unsigned NumRefs = 0; while (!AS.empty()) { AliasSet::PointerRec *P = AS.PtrList; Value *ValToRemove = P->getValue(); // Unlink and delete entry from the list of values. P->eraseFromList(); // Remember how many references need to be dropped. ++NumRefs; // Finally, remove the entry. PointerMap.erase(ValToRemove); } // Stop using the alias set, removing it. AS.RefCount -= NumRefs; if (AS.RefCount == 0) AS.removeFromTracker(*this); }
// deleteValue method - This method is used to remove a pointer value from the // AliasSetTracker entirely. It should be used when an instruction is deleted // from the program to update the AST. If you don't use this, you would have // dangling pointers to deleted instructions. // void AliasSetTracker::deleteValue(Value *PtrVal) { // Notify the alias analysis implementation that this value is gone. AA.deleteValue(PtrVal); // If this is a call instruction, remove the callsite from the appropriate // AliasSet (if present). if (CallSite CS = PtrVal) { if (!AA.doesNotAccessMemory(CS)) { // Scan all the alias sets to see if this call site is contained. for (iterator I = begin(), E = end(); I != E; ++I) { if (I->Forward) continue; I->removeCallSite(CS); } } } // First, look up the PointerRec for this pointer. PointerMapType::iterator I = PointerMap.find(PtrVal); if (I == PointerMap.end()) return; // Noop // If we found one, remove the pointer from the alias set it is in. AliasSet::PointerRec *PtrValEnt = I->second; AliasSet *AS = PtrValEnt->getAliasSet(*this); // Unlink and delete from the list of values. PtrValEnt->eraseFromList(); // Stop using the alias set. AS->dropRef(*this); PointerMap.erase(I); }
// deleteValue method - This method is used to remove a pointer value from the // AliasSetTracker entirely. It should be used when an instruction is deleted // from the program to update the AST. If you don't use this, you would have // dangling pointers to deleted instructions. // void AliasSetTracker::deleteValue(Value *PtrVal) { // Notify the alias analysis implementation that this value is gone. AA.deleteValue(PtrVal); // If this is a call instruction, remove the callsite from the appropriate // AliasSet. CallSite CS = CallSite::get(PtrVal); if (CS.getInstruction()) if (!AA.doesNotAccessMemory(CS)) if (AliasSet *AS = findAliasSetForCallSite(CS)) AS->removeCallSite(CS); // First, look up the PointerRec for this pointer. PointerMapType::iterator I = PointerMap.find(PtrVal); if (I == PointerMap.end()) return; // Noop // If we found one, remove the pointer from the alias set it is in. AliasSet::PointerRec *PtrValEnt = I->second; AliasSet *AS = PtrValEnt->getAliasSet(*this); // Unlink and delete from the list of values. PtrValEnt->eraseFromList(); // Stop using the alias set. AS->dropRef(*this); PointerMap.erase(I); }
/// mergeSetIn - Merge the specified alias set into this alias set. /// void AliasSet::mergeSetIn(AliasSet &AS, AliasSetTracker &AST) { assert(!AS.Forward && "Alias set is already forwarding!"); assert(!Forward && "This set is a forwarding set!!"); // Update the alias and access types of this set... AccessTy |= AS.AccessTy; AliasTy |= AS.AliasTy; Volatile |= AS.Volatile; if (AliasTy == MustAlias) { // Check that these two merged sets really are must aliases. Since both // used to be must-alias sets, we can just check any pointer from each set // for aliasing. AliasAnalysis &AA = AST.getAliasAnalysis(); PointerRec *L = getSomePointer(); PointerRec *R = AS.getSomePointer(); // If the pointers are not a must-alias pair, this set becomes a may alias. if (AA.alias(AliasAnalysis::Location(L->getValue(), L->getSize(), L->getAAInfo()), AliasAnalysis::Location(R->getValue(), R->getSize(), R->getAAInfo())) != AliasAnalysis::MustAlias) AliasTy = MayAlias; } bool ASHadUnknownInsts = !AS.UnknownInsts.empty(); if (UnknownInsts.empty()) { // Merge call sites... if (ASHadUnknownInsts) { std::swap(UnknownInsts, AS.UnknownInsts); addRef(); } } else if (ASHadUnknownInsts) { UnknownInsts.insert(UnknownInsts.end(), AS.UnknownInsts.begin(), AS.UnknownInsts.end()); AS.UnknownInsts.clear(); } AS.Forward = this; // Forward across AS now... addRef(); // AS is now pointing to us... // Merge the list of constituent pointers... if (AS.PtrList) { *PtrListEnd = AS.PtrList; AS.PtrList->setPrevInList(PtrListEnd); PtrListEnd = AS.PtrListEnd; AS.PtrList = nullptr; AS.PtrListEnd = &AS.PtrList; assert(*AS.PtrListEnd == nullptr && "End of list is not null?"); } if (ASHadUnknownInsts) AS.dropRef(AST); }
// deleteValue method - This method is used to remove a pointer value from the // AliasSetTracker entirely. It should be used when an instruction is deleted // from the program to update the AST. If you don't use this, you would have // dangling pointers to deleted instructions. // void AliasSetTracker::deleteValue(Value *PtrVal) { // First, look up the PointerRec for this pointer. PointerMapType::iterator I = PointerMap.find_as(PtrVal); if (I == PointerMap.end()) return; // Noop // If we found one, remove the pointer from the alias set it is in. AliasSet::PointerRec *PtrValEnt = I->second; AliasSet *AS = PtrValEnt->getAliasSet(*this); // Unlink and delete from the list of values. PtrValEnt->eraseFromList(); if (AS->Alias == AliasSet::SetMayAlias) { AS->SetSize--; TotalMayAliasSetSize--; } // Stop using the alias set. AS->dropRef(*this); PointerMap.erase(I); }
AliasSet &AliasSetTracker::mergeAllAliasSets() { assert(!AliasAnyAS && (TotalMayAliasSetSize > SaturationThreshold) && "Full merge should happen once, when the saturation threshold is " "reached"); // Collect all alias sets, so that we can drop references with impunity // without worrying about iterator invalidation. std::vector<AliasSet *> ASVector; ASVector.reserve(SaturationThreshold); for (iterator I = begin(), E = end(); I != E; I++) ASVector.push_back(&*I); // Copy all instructions and pointers into a new set, and forward all other // sets to it. AliasSets.push_back(new AliasSet()); AliasAnyAS = &AliasSets.back(); AliasAnyAS->Alias = AliasSet::SetMayAlias; AliasAnyAS->Access = AliasSet::ModRefAccess; AliasAnyAS->AliasAny = true; for (auto Cur : ASVector) { // If Cur was already forwarding, just forward to the new AS instead. AliasSet *FwdTo = Cur->Forward; if (FwdTo) { Cur->Forward = AliasAnyAS; AliasAnyAS->addRef(); FwdTo->dropRef(*this); continue; } // Otherwise, perform the actual merge. AliasAnyAS->mergeSetIn(*Cur, *this); } return *AliasAnyAS; }