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