//===- llvm/Analysis/AliasSetTracker.h - Build Alias Sets -------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines two classes: AliasSetTracker and AliasSet.  These interface
// are used to classify a collection of pointer references into a maximal number
// of disjoint sets.  Each AliasSet object constructed by the AliasSetTracker
// object refers to memory disjoint from the other sets.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_ANALYSIS_ALIASSETTRACKER_H
#define LLVM_ANALYSIS_ALIASSETTRACKER_H

#include "llvm/Support/CallSite.h"
#include "llvm/Support/ValueHandle.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/ilist.h"
#include "llvm/ADT/ilist_node.h"
#include <vector>

namespace llvm {

class AliasAnalysis;
class LoadInst;
class StoreInst;
class VAArgInst;
class AliasSetTracker;
class AliasSet;

class AliasSet : public ilist_node<AliasSet> {
  friend class AliasSetTracker;

  class PointerRec {
    Value *Val;  // The pointer this record corresponds to.
    PointerRec **PrevInList, *NextInList;
    AliasSet *AS;
    uint64_t Size;
    const MDNode *TBAAInfo;
  public:
    PointerRec(Value *V)
      : Val(V), PrevInList(0), NextInList(0), AS(0), Size(0),
        TBAAInfo(DenseMapInfo<const MDNode *>::getEmptyKey()) {}

    Value *getValue() const { return Val; }
    
    PointerRec *getNext() const { return NextInList; }
    bool hasAliasSet() const { return AS != 0; }

    PointerRec** setPrevInList(PointerRec **PIL) {
      PrevInList = PIL;
      return &NextInList;
    }

    void updateSizeAndTBAAInfo(uint64_t NewSize, const MDNode *NewTBAAInfo) {
      if (NewSize > Size) Size = NewSize;

      if (TBAAInfo == DenseMapInfo<const MDNode *>::getEmptyKey())
        // We don't have a TBAAInfo yet. Set it to NewTBAAInfo.
        TBAAInfo = NewTBAAInfo;
      else if (TBAAInfo != NewTBAAInfo)
        // NewTBAAInfo conflicts with TBAAInfo.
        TBAAInfo = DenseMapInfo<const MDNode *>::getTombstoneKey();
    }

    uint64_t getSize() const { return Size; }

    /// getTBAAInfo - Return the TBAAInfo, or null if there is no
    /// information or conflicting information.
    const MDNode *getTBAAInfo() const {
      // If we have missing or conflicting TBAAInfo, return null.
      if (TBAAInfo == DenseMapInfo<const MDNode *>::getEmptyKey() ||
          TBAAInfo == DenseMapInfo<const MDNode *>::getTombstoneKey())
        return 0;
      return TBAAInfo;
    }

    AliasSet *getAliasSet(AliasSetTracker &AST) {
      assert(AS && "No AliasSet yet!");
      if (AS->Forward) {
        AliasSet *OldAS = AS;
        AS = OldAS->getForwardedTarget(AST);
        AS->addRef();
        OldAS->dropRef(AST);
      }
      return AS;
    }

    void setAliasSet(AliasSet *as) {
      assert(AS == 0 && "Already have an alias set!");
      AS = as;
    }

    void eraseFromList() {
      if (NextInList) NextInList->PrevInList = PrevInList;
      *PrevInList = NextInList;
      if (AS->PtrListEnd == &NextInList) {
        AS->PtrListEnd = PrevInList;
        assert(*AS->PtrListEnd == 0 && "List not terminated right!");
      }
      delete this;
    }
  };

  PointerRec *PtrList, **PtrListEnd;  // Doubly linked list of nodes.
  AliasSet *Forward;             // Forwarding pointer.
  AliasSet *Next, *Prev;         // Doubly linked list of AliasSets.

  // All instructions without a specific address in this alias set.
  std::vector<AssertingVH<Instruction> > UnknownInsts;

  // RefCount - Number of nodes pointing to this AliasSet plus the number of
  // AliasSets forwarding to it.
  unsigned RefCount : 28;

  /// AccessType - Keep track of whether this alias set merely refers to the
  /// locations of memory, whether it modifies the memory, or whether it does
  /// both.  The lattice goes from "NoModRef" to either Refs or Mods, then to
  /// ModRef as necessary.
  ///
  enum AccessType {
    NoModRef = 0, Refs = 1,         // Ref = bit 1
    Mods     = 2, ModRef = 3        // Mod = bit 2
  };
  unsigned AccessTy : 2;

  /// AliasType - Keep track the relationships between the pointers in the set.
  /// Lattice goes from MustAlias to MayAlias.
  ///
  enum AliasType {
    MustAlias = 0, MayAlias = 1
  };
  unsigned AliasTy : 1;

  // Volatile - True if this alias set contains volatile loads or stores.
  bool Volatile : 1;

  void addRef() { ++RefCount; }
  void dropRef(AliasSetTracker &AST) {
    assert(RefCount >= 1 && "Invalid reference count detected!");
    if (--RefCount == 0)
      removeFromTracker(AST);
  }

  Instruction *getUnknownInst(unsigned i) const {
    assert(i < UnknownInsts.size());
    return UnknownInsts[i];
  }
  
public:
  /// Accessors...
  bool isRef() const { return AccessTy & Refs; }
  bool isMod() const { return AccessTy & Mods; }
  bool isMustAlias() const { return AliasTy == MustAlias; }
  bool isMayAlias()  const { return AliasTy == MayAlias; }

  // isVolatile - Return true if this alias set contains volatile loads or
  // stores.
  bool isVolatile() const { return Volatile; }

  /// isForwardingAliasSet - Return true if this alias set should be ignored as
  /// part of the AliasSetTracker object.
  bool isForwardingAliasSet() const { return Forward; }

  /// mergeSetIn - Merge the specified alias set into this alias set...
  ///
  void mergeSetIn(AliasSet &AS, AliasSetTracker &AST);

  // Alias Set iteration - Allow access to all of the pointer which are part of
  // this alias set...
  class iterator;
  iterator begin() const { return iterator(PtrList); }
  iterator end()   const { return iterator(); }
  bool empty() const { return PtrList == 0; }

  void print(raw_ostream &OS) const;
  void dump() const;

  /// Define an iterator for alias sets... this is just a forward iterator.
  class iterator : public std::iterator<std::forward_iterator_tag,
                                        PointerRec, ptrdiff_t> {
    PointerRec *CurNode;
  public:
    explicit iterator(PointerRec *CN = 0) : CurNode(CN) {}

    bool operator==(const iterator& x) const {
      return CurNode == x.CurNode;
    }
    bool operator!=(const iterator& x) const { return !operator==(x); }

    const iterator &operator=(const iterator &I) {
      CurNode = I.CurNode;
      return *this;
    }

    value_type &operator*() const {
      assert(CurNode && "Dereferencing AliasSet.end()!");
      return *CurNode;
    }
    value_type *operator->() const { return &operator*(); }

    Value *getPointer() const { return CurNode->getValue(); }
    uint64_t getSize() const { return CurNode->getSize(); }
    const MDNode *getTBAAInfo() const { return CurNode->getTBAAInfo(); }

    iterator& operator++() {                // Preincrement
      assert(CurNode && "Advancing past AliasSet.end()!");
      CurNode = CurNode->getNext();
      return *this;
    }
    iterator operator++(int) { // Postincrement
      iterator tmp = *this; ++*this; return tmp;
    }
  };

private:
  // Can only be created by AliasSetTracker. Also, ilist creates one
  // to serve as a sentinel.
  friend struct ilist_sentinel_traits<AliasSet>;
  AliasSet() : PtrList(0), PtrListEnd(&PtrList), Forward(0), RefCount(0),
               AccessTy(NoModRef), AliasTy(MustAlias), Volatile(false) {
  }

  AliasSet(const AliasSet &AS);        // do not implement
  void operator=(const AliasSet &AS);  // do not implement

  PointerRec *getSomePointer() const {
    return PtrList;
  }

  /// getForwardedTarget - Return the real alias set this represents.  If this
  /// has been merged with another set and is forwarding, return the ultimate
  /// destination set.  This also implements the union-find collapsing as well.
  AliasSet *getForwardedTarget(AliasSetTracker &AST) {
    if (!Forward) return this;

    AliasSet *Dest = Forward->getForwardedTarget(AST);
    if (Dest != Forward) {
      Dest->addRef();
      Forward->dropRef(AST);
      Forward = Dest;
    }
    return Dest;
  }

  void removeFromTracker(AliasSetTracker &AST);

  void addPointer(AliasSetTracker &AST, PointerRec &Entry, uint64_t Size,
                  const MDNode *TBAAInfo,
                  bool KnownMustAlias = false);
  void addUnknownInst(Instruction *I, AliasAnalysis &AA);
  void removeUnknownInst(Instruction *I) {
    for (size_t i = 0, e = UnknownInsts.size(); i != e; ++i)
      if (UnknownInsts[i] == I) {
        UnknownInsts[i] = UnknownInsts.back();
        UnknownInsts.pop_back();
        --i; --e;  // Revisit the moved entry.
      }
  }
  void setVolatile() { Volatile = true; }

  /// aliasesPointer - Return true if the specified pointer "may" (or must)
  /// alias one of the members in the set.
  ///
  bool aliasesPointer(const Value *Ptr, uint64_t Size, const MDNode *TBAAInfo,
                      AliasAnalysis &AA) const;
  bool aliasesUnknownInst(Instruction *Inst, AliasAnalysis &AA) const;
};

inline raw_ostream& operator<<(raw_ostream &OS, const AliasSet &AS) {
  AS.print(OS);
  return OS;
}


class AliasSetTracker {
  /// CallbackVH - A CallbackVH to arrange for AliasSetTracker to be
  /// notified whenever a Value is deleted.
  class ASTCallbackVH : public CallbackVH {
    AliasSetTracker *AST;
    virtual void deleted();
    virtual void allUsesReplacedWith(Value *);
  public:
    ASTCallbackVH(Value *V, AliasSetTracker *AST = 0);
    ASTCallbackVH &operator=(Value *V);
  };
  /// ASTCallbackVHDenseMapInfo - Traits to tell DenseMap that tell us how to
  /// compare and hash the value handle.
  struct ASTCallbackVHDenseMapInfo : public DenseMapInfo<Value *> {};

  AliasAnalysis &AA;
  ilist<AliasSet> AliasSets;

  typedef DenseMap<ASTCallbackVH, AliasSet::PointerRec*,
                   ASTCallbackVHDenseMapInfo>
    PointerMapType;

  // Map from pointers to their node
  PointerMapType PointerMap;

public:
  /// AliasSetTracker ctor - Create an empty collection of AliasSets, and use
  /// the specified alias analysis object to disambiguate load and store
  /// addresses.
  explicit AliasSetTracker(AliasAnalysis &aa) : AA(aa) {}
  ~AliasSetTracker() { clear(); }

  /// add methods - These methods are used to add different types of
  /// instructions to the alias sets.  Adding a new instruction can result in
  /// one of three actions happening:
  ///
  ///   1. If the instruction doesn't alias any other sets, create a new set.
  ///   2. If the instruction aliases exactly one set, add it to the set
  ///   3. If the instruction aliases multiple sets, merge the sets, and add
  ///      the instruction to the result.
  ///
  /// These methods return true if inserting the instruction resulted in the
  /// addition of a new alias set (i.e., the pointer did not alias anything).
  ///
  bool add(Value *Ptr, uint64_t Size, const MDNode *TBAAInfo); // Add a location
  bool add(LoadInst *LI);
  bool add(StoreInst *SI);
  bool add(VAArgInst *VAAI);
  bool add(Instruction *I);       // Dispatch to one of the other add methods...
  void add(BasicBlock &BB);       // Add all instructions in basic block
  void add(const AliasSetTracker &AST); // Add alias relations from another AST
  bool addUnknown(Instruction *I);

  /// remove methods - These methods are used to remove all entries that might
  /// be aliased by the specified instruction.  These methods return true if any
  /// alias sets were eliminated.
  // Remove a location
  bool remove(Value *Ptr, uint64_t Size, const MDNode *TBAAInfo);
  bool remove(LoadInst *LI);
  bool remove(StoreInst *SI);
  bool remove(VAArgInst *VAAI);
  bool remove(Instruction *I);
  void remove(AliasSet &AS);
  bool removeUnknown(Instruction *I);
  
  void clear();

  /// getAliasSets - Return the alias sets that are active.
  ///
  const ilist<AliasSet> &getAliasSets() const { return AliasSets; }

  /// getAliasSetForPointer - Return the alias set that the specified pointer
  /// lives in.  If the New argument is non-null, this method sets the value to
  /// true if a new alias set is created to contain the pointer (because the
  /// pointer didn't alias anything).
  AliasSet &getAliasSetForPointer(Value *P, uint64_t Size,
                                  const MDNode *TBAAInfo,
                                  bool *New = 0);

  /// getAliasSetForPointerIfExists - Return the alias set containing the
  /// location specified if one exists, otherwise return null.
  AliasSet *getAliasSetForPointerIfExists(Value *P, uint64_t Size,
                                          const MDNode *TBAAInfo) {
    return findAliasSetForPointer(P, Size, TBAAInfo);
  }

  /// containsPointer - Return true if the specified location is represented by
  /// this alias set, false otherwise.  This does not modify the AST object or
  /// alias sets.
  bool containsPointer(Value *P, uint64_t Size, const MDNode *TBAAInfo) const;

  /// getAliasAnalysis - Return the underlying alias analysis object used by
  /// this tracker.
  AliasAnalysis &getAliasAnalysis() const { return AA; }

  /// 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 deleteValue(Value *PtrVal);

  /// 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 copyValue(Value *From, Value *To);


  typedef ilist<AliasSet>::iterator iterator;
  typedef ilist<AliasSet>::const_iterator const_iterator;

  const_iterator begin() const { return AliasSets.begin(); }
  const_iterator end()   const { return AliasSets.end(); }

  iterator begin() { return AliasSets.begin(); }
  iterator end()   { return AliasSets.end(); }

  void print(raw_ostream &OS) const;
  void dump() const;

private:
  friend class AliasSet;
  void removeAliasSet(AliasSet *AS);

  // getEntryFor - Just like operator[] on the map, except that it creates an
  // entry for the pointer if it doesn't already exist.
  AliasSet::PointerRec &getEntryFor(Value *V) {
    AliasSet::PointerRec *&Entry = PointerMap[ASTCallbackVH(V, this)];
    if (Entry == 0)
      Entry = new AliasSet::PointerRec(V);
    return *Entry;
  }

  AliasSet &addPointer(Value *P, uint64_t Size, const MDNode *TBAAInfo,
                       AliasSet::AccessType E,
                       bool &NewSet) {
    NewSet = false;
    AliasSet &AS = getAliasSetForPointer(P, Size, TBAAInfo, &NewSet);
    AS.AccessTy |= E;
    return AS;
  }
  AliasSet *findAliasSetForPointer(const Value *Ptr, uint64_t Size,
                                   const MDNode *TBAAInfo);

  AliasSet *findAliasSetForUnknownInst(Instruction *Inst);
};

inline raw_ostream& operator<<(raw_ostream &OS, const AliasSetTracker &AST) {
  AST.print(OS);
  return OS;
}

} // End llvm namespace

#endif
