AliasSetTracker.cpp revision 221345
1//===- AliasSetTracker.cpp - Alias Sets Tracker implementation-------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the AliasSetTracker and AliasSet classes.
11//
12//===----------------------------------------------------------------------===//
13
14#include "llvm/Analysis/AliasSetTracker.h"
15#include "llvm/Analysis/AliasAnalysis.h"
16#include "llvm/Instructions.h"
17#include "llvm/IntrinsicInst.h"
18#include "llvm/LLVMContext.h"
19#include "llvm/Pass.h"
20#include "llvm/Type.h"
21#include "llvm/Target/TargetData.h"
22#include "llvm/Assembly/Writer.h"
23#include "llvm/Support/Debug.h"
24#include "llvm/Support/ErrorHandling.h"
25#include "llvm/Support/InstIterator.h"
26#include "llvm/Support/raw_ostream.h"
27using namespace llvm;
28
29/// mergeSetIn - Merge the specified alias set into this alias set.
30///
31void AliasSet::mergeSetIn(AliasSet &AS, AliasSetTracker &AST) {
32  assert(!AS.Forward && "Alias set is already forwarding!");
33  assert(!Forward && "This set is a forwarding set!!");
34
35  // Update the alias and access types of this set...
36  AccessTy |= AS.AccessTy;
37  AliasTy  |= AS.AliasTy;
38  Volatile |= AS.Volatile;
39
40  if (AliasTy == MustAlias) {
41    // Check that these two merged sets really are must aliases.  Since both
42    // used to be must-alias sets, we can just check any pointer from each set
43    // for aliasing.
44    AliasAnalysis &AA = AST.getAliasAnalysis();
45    PointerRec *L = getSomePointer();
46    PointerRec *R = AS.getSomePointer();
47
48    // If the pointers are not a must-alias pair, this set becomes a may alias.
49    if (AA.alias(AliasAnalysis::Location(L->getValue(),
50                                         L->getSize(),
51                                         L->getTBAAInfo()),
52                 AliasAnalysis::Location(R->getValue(),
53                                         R->getSize(),
54                                         R->getTBAAInfo()))
55        != AliasAnalysis::MustAlias)
56      AliasTy = MayAlias;
57  }
58
59  if (CallSites.empty()) {            // Merge call sites...
60    if (!AS.CallSites.empty())
61      std::swap(CallSites, AS.CallSites);
62  } else if (!AS.CallSites.empty()) {
63    CallSites.insert(CallSites.end(), AS.CallSites.begin(), AS.CallSites.end());
64    AS.CallSites.clear();
65  }
66
67  AS.Forward = this;  // Forward across AS now...
68  addRef();           // AS is now pointing to us...
69
70  // Merge the list of constituent pointers...
71  if (AS.PtrList) {
72    *PtrListEnd = AS.PtrList;
73    AS.PtrList->setPrevInList(PtrListEnd);
74    PtrListEnd = AS.PtrListEnd;
75
76    AS.PtrList = 0;
77    AS.PtrListEnd = &AS.PtrList;
78    assert(*AS.PtrListEnd == 0 && "End of list is not null?");
79  }
80}
81
82void AliasSetTracker::removeAliasSet(AliasSet *AS) {
83  if (AliasSet *Fwd = AS->Forward) {
84    Fwd->dropRef(*this);
85    AS->Forward = 0;
86  }
87  AliasSets.erase(AS);
88}
89
90void AliasSet::removeFromTracker(AliasSetTracker &AST) {
91  assert(RefCount == 0 && "Cannot remove non-dead alias set from tracker!");
92  AST.removeAliasSet(this);
93}
94
95void AliasSet::addPointer(AliasSetTracker &AST, PointerRec &Entry,
96                          uint64_t Size, const MDNode *TBAAInfo,
97                          bool KnownMustAlias) {
98  assert(!Entry.hasAliasSet() && "Entry already in set!");
99
100  // Check to see if we have to downgrade to _may_ alias.
101  if (isMustAlias() && !KnownMustAlias)
102    if (PointerRec *P = getSomePointer()) {
103      AliasAnalysis &AA = AST.getAliasAnalysis();
104      AliasAnalysis::AliasResult Result =
105        AA.alias(AliasAnalysis::Location(P->getValue(), P->getSize(),
106                                         P->getTBAAInfo()),
107                 AliasAnalysis::Location(Entry.getValue(), Size, TBAAInfo));
108      if (Result != AliasAnalysis::MustAlias)
109        AliasTy = MayAlias;
110      else                  // First entry of must alias must have maximum size!
111        P->updateSizeAndTBAAInfo(Size, TBAAInfo);
112      assert(Result != AliasAnalysis::NoAlias && "Cannot be part of must set!");
113    }
114
115  Entry.setAliasSet(this);
116  Entry.updateSizeAndTBAAInfo(Size, TBAAInfo);
117
118  // Add it to the end of the list...
119  assert(*PtrListEnd == 0 && "End of list is not null?");
120  *PtrListEnd = &Entry;
121  PtrListEnd = Entry.setPrevInList(PtrListEnd);
122  assert(*PtrListEnd == 0 && "End of list is not null?");
123  addRef();               // Entry points to alias set.
124}
125
126void AliasSet::addCallSite(CallSite CS, AliasAnalysis &AA) {
127  CallSites.push_back(CS.getInstruction());
128
129  AliasAnalysis::ModRefBehavior Behavior = AA.getModRefBehavior(CS);
130  if (Behavior == AliasAnalysis::DoesNotAccessMemory)
131    return;
132  if (AliasAnalysis::onlyReadsMemory(Behavior)) {
133    AliasTy = MayAlias;
134    AccessTy |= Refs;
135    return;
136  }
137
138  // FIXME: This should use mod/ref information to make this not suck so bad
139  AliasTy = MayAlias;
140  AccessTy = ModRef;
141}
142
143/// aliasesPointer - Return true if the specified pointer "may" (or must)
144/// alias one of the members in the set.
145///
146bool AliasSet::aliasesPointer(const Value *Ptr, uint64_t Size,
147                              const MDNode *TBAAInfo,
148                              AliasAnalysis &AA) const {
149  if (AliasTy == MustAlias) {
150    assert(CallSites.empty() && "Illegal must alias set!");
151
152    // If this is a set of MustAliases, only check to see if the pointer aliases
153    // SOME value in the set.
154    PointerRec *SomePtr = getSomePointer();
155    assert(SomePtr && "Empty must-alias set??");
156    return AA.alias(AliasAnalysis::Location(SomePtr->getValue(),
157                                            SomePtr->getSize(),
158                                            SomePtr->getTBAAInfo()),
159                    AliasAnalysis::Location(Ptr, Size, TBAAInfo));
160  }
161
162  // If this is a may-alias set, we have to check all of the pointers in the set
163  // to be sure it doesn't alias the set...
164  for (iterator I = begin(), E = end(); I != E; ++I)
165    if (AA.alias(AliasAnalysis::Location(Ptr, Size, TBAAInfo),
166                 AliasAnalysis::Location(I.getPointer(), I.getSize(),
167                                         I.getTBAAInfo())))
168      return true;
169
170  // Check the call sites list and invoke list...
171  if (!CallSites.empty()) {
172    for (unsigned i = 0, e = CallSites.size(); i != e; ++i)
173      if (AA.getModRefInfo(CallSites[i],
174                           AliasAnalysis::Location(Ptr, Size, TBAAInfo)) !=
175            AliasAnalysis::NoModRef)
176        return true;
177  }
178
179  return false;
180}
181
182bool AliasSet::aliasesCallSite(CallSite CS, AliasAnalysis &AA) const {
183  if (AA.doesNotAccessMemory(CS))
184    return false;
185
186  for (unsigned i = 0, e = CallSites.size(); i != e; ++i) {
187    if (AA.getModRefInfo(getCallSite(i), CS) != AliasAnalysis::NoModRef ||
188        AA.getModRefInfo(CS, getCallSite(i)) != AliasAnalysis::NoModRef)
189      return true;
190  }
191
192  for (iterator I = begin(), E = end(); I != E; ++I)
193    if (AA.getModRefInfo(CS, I.getPointer(), I.getSize()) !=
194           AliasAnalysis::NoModRef)
195      return true;
196
197  return false;
198}
199
200void AliasSetTracker::clear() {
201  // Delete all the PointerRec entries.
202  for (PointerMapType::iterator I = PointerMap.begin(), E = PointerMap.end();
203       I != E; ++I)
204    I->second->eraseFromList();
205
206  PointerMap.clear();
207
208  // The alias sets should all be clear now.
209  AliasSets.clear();
210}
211
212
213/// findAliasSetForPointer - Given a pointer, find the one alias set to put the
214/// instruction referring to the pointer into.  If there are multiple alias sets
215/// that may alias the pointer, merge them together and return the unified set.
216///
217AliasSet *AliasSetTracker::findAliasSetForPointer(const Value *Ptr,
218                                                  uint64_t Size,
219                                                  const MDNode *TBAAInfo) {
220  AliasSet *FoundSet = 0;
221  for (iterator I = begin(), E = end(); I != E; ++I) {
222    if (I->Forward || !I->aliasesPointer(Ptr, Size, TBAAInfo, AA)) continue;
223
224    if (FoundSet == 0) {  // If this is the first alias set ptr can go into.
225      FoundSet = I;       // Remember it.
226    } else {              // Otherwise, we must merge the sets.
227      FoundSet->mergeSetIn(*I, *this);     // Merge in contents.
228    }
229  }
230
231  return FoundSet;
232}
233
234/// containsPointer - Return true if the specified location is represented by
235/// this alias set, false otherwise.  This does not modify the AST object or
236/// alias sets.
237bool AliasSetTracker::containsPointer(Value *Ptr, uint64_t Size,
238                                      const MDNode *TBAAInfo) const {
239  for (const_iterator I = begin(), E = end(); I != E; ++I)
240    if (!I->Forward && I->aliasesPointer(Ptr, Size, TBAAInfo, AA))
241      return true;
242  return false;
243}
244
245
246
247AliasSet *AliasSetTracker::findAliasSetForCallSite(CallSite CS) {
248  AliasSet *FoundSet = 0;
249  for (iterator I = begin(), E = end(); I != E; ++I) {
250    if (I->Forward || !I->aliasesCallSite(CS, AA))
251      continue;
252
253    if (FoundSet == 0)        // If this is the first alias set ptr can go into.
254      FoundSet = I;           // Remember it.
255    else if (!I->Forward)     // Otherwise, we must merge the sets.
256      FoundSet->mergeSetIn(*I, *this);     // Merge in contents.
257  }
258  return FoundSet;
259}
260
261
262
263
264/// getAliasSetForPointer - Return the alias set that the specified pointer
265/// lives in.
266AliasSet &AliasSetTracker::getAliasSetForPointer(Value *Pointer, uint64_t Size,
267                                                 const MDNode *TBAAInfo,
268                                                 bool *New) {
269  AliasSet::PointerRec &Entry = getEntryFor(Pointer);
270
271  // Check to see if the pointer is already known.
272  if (Entry.hasAliasSet()) {
273    Entry.updateSizeAndTBAAInfo(Size, TBAAInfo);
274    // Return the set!
275    return *Entry.getAliasSet(*this)->getForwardedTarget(*this);
276  }
277
278  if (AliasSet *AS = findAliasSetForPointer(Pointer, Size, TBAAInfo)) {
279    // Add it to the alias set it aliases.
280    AS->addPointer(*this, Entry, Size, TBAAInfo);
281    return *AS;
282  }
283
284  if (New) *New = true;
285  // Otherwise create a new alias set to hold the loaded pointer.
286  AliasSets.push_back(new AliasSet());
287  AliasSets.back().addPointer(*this, Entry, Size, TBAAInfo);
288  return AliasSets.back();
289}
290
291bool AliasSetTracker::add(Value *Ptr, uint64_t Size, const MDNode *TBAAInfo) {
292  bool NewPtr;
293  addPointer(Ptr, Size, TBAAInfo, AliasSet::NoModRef, NewPtr);
294  return NewPtr;
295}
296
297
298bool AliasSetTracker::add(LoadInst *LI) {
299  bool NewPtr;
300  AliasSet &AS = addPointer(LI->getOperand(0),
301                            AA.getTypeStoreSize(LI->getType()),
302                            LI->getMetadata(LLVMContext::MD_tbaa),
303                            AliasSet::Refs, NewPtr);
304  if (LI->isVolatile()) AS.setVolatile();
305  return NewPtr;
306}
307
308bool AliasSetTracker::add(StoreInst *SI) {
309  bool NewPtr;
310  Value *Val = SI->getOperand(0);
311  AliasSet &AS = addPointer(SI->getOperand(1),
312                            AA.getTypeStoreSize(Val->getType()),
313                            SI->getMetadata(LLVMContext::MD_tbaa),
314                            AliasSet::Mods, NewPtr);
315  if (SI->isVolatile()) AS.setVolatile();
316  return NewPtr;
317}
318
319bool AliasSetTracker::add(VAArgInst *VAAI) {
320  bool NewPtr;
321  addPointer(VAAI->getOperand(0), AliasAnalysis::UnknownSize,
322             VAAI->getMetadata(LLVMContext::MD_tbaa),
323             AliasSet::ModRef, NewPtr);
324  return NewPtr;
325}
326
327
328bool AliasSetTracker::add(CallSite CS) {
329  if (isa<DbgInfoIntrinsic>(CS.getInstruction()))
330    return true; // Ignore DbgInfo Intrinsics.
331  if (AA.doesNotAccessMemory(CS))
332    return true; // doesn't alias anything
333
334  AliasSet *AS = findAliasSetForCallSite(CS);
335  if (AS) {
336    AS->addCallSite(CS, AA);
337    return false;
338  }
339  AliasSets.push_back(new AliasSet());
340  AS = &AliasSets.back();
341  AS->addCallSite(CS, AA);
342  return true;
343}
344
345bool AliasSetTracker::add(Instruction *I) {
346  // Dispatch to one of the other add methods.
347  if (LoadInst *LI = dyn_cast<LoadInst>(I))
348    return add(LI);
349  if (StoreInst *SI = dyn_cast<StoreInst>(I))
350    return add(SI);
351  if (CallInst *CI = dyn_cast<CallInst>(I))
352    return add(CI);
353  if (InvokeInst *II = dyn_cast<InvokeInst>(I))
354    return add(II);
355  if (VAArgInst *VAAI = dyn_cast<VAArgInst>(I))
356    return add(VAAI);
357  return true;
358}
359
360void AliasSetTracker::add(BasicBlock &BB) {
361  for (BasicBlock::iterator I = BB.begin(), E = BB.end(); I != E; ++I)
362    add(I);
363}
364
365void AliasSetTracker::add(const AliasSetTracker &AST) {
366  assert(&AA == &AST.AA &&
367         "Merging AliasSetTracker objects with different Alias Analyses!");
368
369  // Loop over all of the alias sets in AST, adding the pointers contained
370  // therein into the current alias sets.  This can cause alias sets to be
371  // merged together in the current AST.
372  for (const_iterator I = AST.begin(), E = AST.end(); I != E; ++I) {
373    if (I->Forward) continue;   // Ignore forwarding alias sets
374
375    AliasSet &AS = const_cast<AliasSet&>(*I);
376
377    // If there are any call sites in the alias set, add them to this AST.
378    for (unsigned i = 0, e = AS.CallSites.size(); i != e; ++i)
379      add(AS.CallSites[i]);
380
381    // Loop over all of the pointers in this alias set.
382    bool X;
383    for (AliasSet::iterator ASI = AS.begin(), E = AS.end(); ASI != E; ++ASI) {
384      AliasSet &NewAS = addPointer(ASI.getPointer(), ASI.getSize(),
385                                   ASI.getTBAAInfo(),
386                                   (AliasSet::AccessType)AS.AccessTy, X);
387      if (AS.isVolatile()) NewAS.setVolatile();
388    }
389  }
390}
391
392/// remove - Remove the specified (potentially non-empty) alias set from the
393/// tracker.
394void AliasSetTracker::remove(AliasSet &AS) {
395  // Drop all call sites.
396  AS.CallSites.clear();
397
398  // Clear the alias set.
399  unsigned NumRefs = 0;
400  while (!AS.empty()) {
401    AliasSet::PointerRec *P = AS.PtrList;
402
403    Value *ValToRemove = P->getValue();
404
405    // Unlink and delete entry from the list of values.
406    P->eraseFromList();
407
408    // Remember how many references need to be dropped.
409    ++NumRefs;
410
411    // Finally, remove the entry.
412    PointerMap.erase(ValToRemove);
413  }
414
415  // Stop using the alias set, removing it.
416  AS.RefCount -= NumRefs;
417  if (AS.RefCount == 0)
418    AS.removeFromTracker(*this);
419}
420
421bool
422AliasSetTracker::remove(Value *Ptr, uint64_t Size, const MDNode *TBAAInfo) {
423  AliasSet *AS = findAliasSetForPointer(Ptr, Size, TBAAInfo);
424  if (!AS) return false;
425  remove(*AS);
426  return true;
427}
428
429bool AliasSetTracker::remove(LoadInst *LI) {
430  uint64_t Size = AA.getTypeStoreSize(LI->getType());
431  const MDNode *TBAAInfo = LI->getMetadata(LLVMContext::MD_tbaa);
432  AliasSet *AS = findAliasSetForPointer(LI->getOperand(0), Size, TBAAInfo);
433  if (!AS) return false;
434  remove(*AS);
435  return true;
436}
437
438bool AliasSetTracker::remove(StoreInst *SI) {
439  uint64_t Size = AA.getTypeStoreSize(SI->getOperand(0)->getType());
440  const MDNode *TBAAInfo = SI->getMetadata(LLVMContext::MD_tbaa);
441  AliasSet *AS = findAliasSetForPointer(SI->getOperand(1), Size, TBAAInfo);
442  if (!AS) return false;
443  remove(*AS);
444  return true;
445}
446
447bool AliasSetTracker::remove(VAArgInst *VAAI) {
448  AliasSet *AS = findAliasSetForPointer(VAAI->getOperand(0),
449                                        AliasAnalysis::UnknownSize,
450                                        VAAI->getMetadata(LLVMContext::MD_tbaa));
451  if (!AS) return false;
452  remove(*AS);
453  return true;
454}
455
456bool AliasSetTracker::remove(CallSite CS) {
457  if (AA.doesNotAccessMemory(CS))
458    return false; // doesn't alias anything
459
460  AliasSet *AS = findAliasSetForCallSite(CS);
461  if (!AS) return false;
462  remove(*AS);
463  return true;
464}
465
466bool AliasSetTracker::remove(Instruction *I) {
467  // Dispatch to one of the other remove methods...
468  if (LoadInst *LI = dyn_cast<LoadInst>(I))
469    return remove(LI);
470  if (StoreInst *SI = dyn_cast<StoreInst>(I))
471    return remove(SI);
472  if (CallInst *CI = dyn_cast<CallInst>(I))
473    return remove(CI);
474  if (VAArgInst *VAAI = dyn_cast<VAArgInst>(I))
475    return remove(VAAI);
476  return true;
477}
478
479
480// deleteValue method - This method is used to remove a pointer value from the
481// AliasSetTracker entirely.  It should be used when an instruction is deleted
482// from the program to update the AST.  If you don't use this, you would have
483// dangling pointers to deleted instructions.
484//
485void AliasSetTracker::deleteValue(Value *PtrVal) {
486  // Notify the alias analysis implementation that this value is gone.
487  AA.deleteValue(PtrVal);
488
489  // If this is a call instruction, remove the callsite from the appropriate
490  // AliasSet (if present).
491  if (CallSite CS = PtrVal) {
492    if (!AA.doesNotAccessMemory(CS)) {
493      // Scan all the alias sets to see if this call site is contained.
494      for (iterator I = begin(), E = end(); I != E; ++I) {
495        if (I->Forward) continue;
496
497        I->removeCallSite(CS);
498      }
499    }
500  }
501
502  // First, look up the PointerRec for this pointer.
503  PointerMapType::iterator I = PointerMap.find(PtrVal);
504  if (I == PointerMap.end()) return;  // Noop
505
506  // If we found one, remove the pointer from the alias set it is in.
507  AliasSet::PointerRec *PtrValEnt = I->second;
508  AliasSet *AS = PtrValEnt->getAliasSet(*this);
509
510  // Unlink and delete from the list of values.
511  PtrValEnt->eraseFromList();
512
513  // Stop using the alias set.
514  AS->dropRef(*this);
515
516  PointerMap.erase(I);
517}
518
519// copyValue - This method should be used whenever a preexisting value in the
520// program is copied or cloned, introducing a new value.  Note that it is ok for
521// clients that use this method to introduce the same value multiple times: if
522// the tracker already knows about a value, it will ignore the request.
523//
524void AliasSetTracker::copyValue(Value *From, Value *To) {
525  // Notify the alias analysis implementation that this value is copied.
526  AA.copyValue(From, To);
527
528  // First, look up the PointerRec for this pointer.
529  PointerMapType::iterator I = PointerMap.find(From);
530  if (I == PointerMap.end())
531    return;  // Noop
532  assert(I->second->hasAliasSet() && "Dead entry?");
533
534  AliasSet::PointerRec &Entry = getEntryFor(To);
535  if (Entry.hasAliasSet()) return;    // Already in the tracker!
536
537  // Add it to the alias set it aliases...
538  I = PointerMap.find(From);
539  AliasSet *AS = I->second->getAliasSet(*this);
540  AS->addPointer(*this, Entry, I->second->getSize(),
541                 I->second->getTBAAInfo(),
542                 true);
543}
544
545
546
547//===----------------------------------------------------------------------===//
548//               AliasSet/AliasSetTracker Printing Support
549//===----------------------------------------------------------------------===//
550
551void AliasSet::print(raw_ostream &OS) const {
552  OS << "  AliasSet[" << (void*)this << ", " << RefCount << "] ";
553  OS << (AliasTy == MustAlias ? "must" : "may") << " alias, ";
554  switch (AccessTy) {
555  case NoModRef: OS << "No access "; break;
556  case Refs    : OS << "Ref       "; break;
557  case Mods    : OS << "Mod       "; break;
558  case ModRef  : OS << "Mod/Ref   "; break;
559  default: llvm_unreachable("Bad value for AccessTy!");
560  }
561  if (isVolatile()) OS << "[volatile] ";
562  if (Forward)
563    OS << " forwarding to " << (void*)Forward;
564
565
566  if (!empty()) {
567    OS << "Pointers: ";
568    for (iterator I = begin(), E = end(); I != E; ++I) {
569      if (I != begin()) OS << ", ";
570      WriteAsOperand(OS << "(", I.getPointer());
571      OS << ", " << I.getSize() << ")";
572    }
573  }
574  if (!CallSites.empty()) {
575    OS << "\n    " << CallSites.size() << " Call Sites: ";
576    for (unsigned i = 0, e = CallSites.size(); i != e; ++i) {
577      if (i) OS << ", ";
578      WriteAsOperand(OS, CallSites[i]);
579    }
580  }
581  OS << "\n";
582}
583
584void AliasSetTracker::print(raw_ostream &OS) const {
585  OS << "Alias Set Tracker: " << AliasSets.size() << " alias sets for "
586     << PointerMap.size() << " pointer values.\n";
587  for (const_iterator I = begin(), E = end(); I != E; ++I)
588    I->print(OS);
589  OS << "\n";
590}
591
592void AliasSet::dump() const { print(dbgs()); }
593void AliasSetTracker::dump() const { print(dbgs()); }
594
595//===----------------------------------------------------------------------===//
596//                     ASTCallbackVH Class Implementation
597//===----------------------------------------------------------------------===//
598
599void AliasSetTracker::ASTCallbackVH::deleted() {
600  assert(AST && "ASTCallbackVH called with a null AliasSetTracker!");
601  AST->deleteValue(getValPtr());
602  // this now dangles!
603}
604
605void AliasSetTracker::ASTCallbackVH::allUsesReplacedWith(Value *V) {
606  AST->copyValue(getValPtr(), V);
607}
608
609AliasSetTracker::ASTCallbackVH::ASTCallbackVH(Value *V, AliasSetTracker *ast)
610  : CallbackVH(V), AST(ast) {}
611
612AliasSetTracker::ASTCallbackVH &
613AliasSetTracker::ASTCallbackVH::operator=(Value *V) {
614  return *this = ASTCallbackVH(V, AST);
615}
616
617//===----------------------------------------------------------------------===//
618//                            AliasSetPrinter Pass
619//===----------------------------------------------------------------------===//
620
621namespace {
622  class AliasSetPrinter : public FunctionPass {
623    AliasSetTracker *Tracker;
624  public:
625    static char ID; // Pass identification, replacement for typeid
626    AliasSetPrinter() : FunctionPass(ID) {
627      initializeAliasSetPrinterPass(*PassRegistry::getPassRegistry());
628    }
629
630    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
631      AU.setPreservesAll();
632      AU.addRequired<AliasAnalysis>();
633    }
634
635    virtual bool runOnFunction(Function &F) {
636      Tracker = new AliasSetTracker(getAnalysis<AliasAnalysis>());
637
638      for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I)
639        Tracker->add(&*I);
640      Tracker->print(errs());
641      delete Tracker;
642      return false;
643    }
644  };
645}
646
647char AliasSetPrinter::ID = 0;
648INITIALIZE_PASS_BEGIN(AliasSetPrinter, "print-alias-sets",
649                "Alias Set Printer", false, true)
650INITIALIZE_AG_DEPENDENCY(AliasAnalysis)
651INITIALIZE_PASS_END(AliasSetPrinter, "print-alias-sets",
652                "Alias Set Printer", false, true)
653