+
+ // 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);
+}
+
+// copyValue - This method should be used whenever a preexisting value in the
+// program is copied or cloned, introducing a new value. Note that it is ok for
+// clients that use this method to introduce the same value multiple times: if
+// the tracker already knows about a value, it will ignore the request.
+//
+void AliasSetTracker::copyValue(Value *From, Value *To) {
+ // Notify the alias analysis implementation that this value is copied.
+ AA.copyValue(From, To);
+
+ // First, look up the PointerRec for this pointer.
+ hash_map<Value*, AliasSet::PointerRec>::iterator I = PointerMap.find(From);
+ if (I == PointerMap.end() || !I->second.hasAliasSet())
+ return; // Noop
+
+ AliasSet::HashNodePair &Entry = getEntryFor(To);
+ if (Entry.second.hasAliasSet()) return; // Already in the tracker!
+
+ // Add it to the alias set it aliases...
+ AliasSet *AS = I->second.getAliasSet(*this);
+ AS->addPointer(*this, Entry, I->second.getSize(), true);
+}
+
+
+
+//===----------------------------------------------------------------------===//
+// AliasSet/AliasSetTracker Printing Support
+//===----------------------------------------------------------------------===//
+
+void AliasSet::print(std::ostream &OS) const {
+ OS << " AliasSet[" << (void*)this << "," << RefCount << "] ";
+ OS << (AliasTy == MustAlias ? "must" : "may ") << " alias, ";
+ switch (AccessTy) {
+ case NoModRef: OS << "No access "; break;
+ case Refs : OS << "Ref "; break;
+ case Mods : OS << "Mod "; break;
+ case ModRef : OS << "Mod/Ref "; break;
+ default: assert(0 && "Bad value for AccessTy!");
+ }
+ if (isVolatile()) OS << "[volatile] ";
+ if (Forward)
+ OS << " forwarding to " << (void*)Forward;
+
+
+ if (begin() != end()) {
+ OS << "Pointers: ";
+ for (iterator I = begin(), E = end(); I != E; ++I) {
+ if (I != begin()) OS << ", ";
+ WriteAsOperand(OS << "(", I.getPointer());
+ OS << ", " << I.getSize() << ")";
+ }
+ }
+ if (!CallSites.empty()) {
+ OS << "\n " << CallSites.size() << " Call Sites: ";
+ for (unsigned i = 0, e = CallSites.size(); i != e; ++i) {
+ if (i) OS << ", ";
+ WriteAsOperand(OS, CallSites[i].getCalledValue());
+ }
+ }
+ OS << "\n";
+}
+
+void AliasSetTracker::print(std::ostream &OS) const {
+ OS << "Alias Set Tracker: " << AliasSets.size() << " alias sets for "
+ << PointerMap.size() << " pointer values.\n";
+ for (const_iterator I = begin(), E = end(); I != E; ++I)
+ I->print(OS);
+ OS << "\n";
+}
+
+void AliasSet::dump() const { print (cerr); }
+void AliasSetTracker::dump() const { print(cerr); }
+
+//===----------------------------------------------------------------------===//
+// AliasSetPrinter Pass
+//===----------------------------------------------------------------------===//
+
+namespace {
+ class VISIBILITY_HIDDEN AliasSetPrinter : public FunctionPass {
+ AliasSetTracker *Tracker;
+ public:
+ static char ID; // Pass identification, replacement for typeid
+ AliasSetPrinter() : FunctionPass((intptr_t)&ID) {}
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ AU.addRequired<AliasAnalysis>();
+ }
+
+ virtual bool runOnFunction(Function &F) {
+ Tracker = new AliasSetTracker(getAnalysis<AliasAnalysis>());
+
+ for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I)
+ Tracker->add(&*I);
+ Tracker->print(cerr);
+ delete Tracker;
+ return false;
+ }
+ };
+ char AliasSetPrinter::ID = 0;
+ RegisterPass<AliasSetPrinter> X("print-alias-sets", "Alias Set Printer");