//===- llvm/Analysis/MemoryDependenceAnalysis.h - Memory Deps  --*- 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 the MemoryDependenceAnalysis analysis pass.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_ANALYSIS_MEMORYDEPENDENCEANALYSIS_H
#define LLVM_ANALYSIS_MEMORYDEPENDENCEANALYSIS_H

#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/ValueHandle.h"
#include "llvm/Pass.h"

namespace llvm {
  class Function;
  class FunctionPass;
  class Instruction;
  class CallSite;
  class AliasAnalysis;
  class DataLayout;
  class MemoryDependenceAnalysis;
  class PredIteratorCache;
  class DominatorTree;
  class PHITransAddr;

  /// MemDepResult - A memory dependence query can return one of three different
  /// answers, described below.
  class MemDepResult {
    enum DepType {
      /// Invalid - Clients of MemDep never see this.
      Invalid = 0,

      /// Clobber - This is a dependence on the specified instruction which
      /// clobbers the desired value.  The pointer member of the MemDepResult
      /// pair holds the instruction that clobbers the memory.  For example,
      /// this occurs when we see a may-aliased store to the memory location we
      /// care about.
      ///
      /// There are several cases that may be interesting here:
      ///   1. Loads are clobbered by may-alias stores.
      ///   2. Loads are considered clobbered by partially-aliased loads.  The
      ///      client may choose to analyze deeper into these cases.
      Clobber,

      /// Def - This is a dependence on the specified instruction which
      /// defines/produces the desired memory location.  The pointer member of
      /// the MemDepResult pair holds the instruction that defines the memory.
      /// Cases of interest:
      ///   1. This could be a load or store for dependence queries on
      ///      load/store.  The value loaded or stored is the produced value.
      ///      Note that the pointer operand may be different than that of the
      ///      queried pointer due to must aliases and phi translation.  Note
      ///      that the def may not be the same type as the query, the pointers
      ///      may just be must aliases.
      ///   2. For loads and stores, this could be an allocation instruction. In
      ///      this case, the load is loading an undef value or a store is the
      ///      first store to (that part of) the allocation.
      ///   3. Dependence queries on calls return Def only when they are
      ///      readonly calls or memory use intrinsics with identical callees
      ///      and no intervening clobbers.  No validation is done that the
      ///      operands to the calls are the same.
      Def,

      /// Other - This marker indicates that the query has no known dependency
      /// in the specified block.  More detailed state info is encoded in the
      /// upper part of the pair (i.e. the Instruction*)
      Other
    };
    /// If DepType is "Other", the upper part of the pair
    /// (i.e. the Instruction* part) is instead used to encode more detailed
    /// type information as follows
    enum OtherType {
      /// NonLocal - This marker indicates that the query has no dependency in
      /// the specified block.  To find out more, the client should query other
      /// predecessor blocks.
      NonLocal = 0x4,
      /// NonFuncLocal - This marker indicates that the query has no
      /// dependency in the specified function.
      NonFuncLocal = 0x8,
      /// Unknown - This marker indicates that the query dependency
      /// is unknown.
      Unknown = 0xc
    };

    typedef PointerIntPair<Instruction*, 2, DepType> PairTy;
    PairTy Value;
    explicit MemDepResult(PairTy V) : Value(V) {}
  public:
    MemDepResult() : Value(nullptr, Invalid) {}

    /// get methods: These are static ctor methods for creating various
    /// MemDepResult kinds.
    static MemDepResult getDef(Instruction *Inst) {
      assert(Inst && "Def requires inst");
      return MemDepResult(PairTy(Inst, Def));
    }
    static MemDepResult getClobber(Instruction *Inst) {
      assert(Inst && "Clobber requires inst");
      return MemDepResult(PairTy(Inst, Clobber));
    }
    static MemDepResult getNonLocal() {
      return MemDepResult(
        PairTy(reinterpret_cast<Instruction*>(NonLocal), Other));
    }
    static MemDepResult getNonFuncLocal() {
      return MemDepResult(
        PairTy(reinterpret_cast<Instruction*>(NonFuncLocal), Other));
    }
    static MemDepResult getUnknown() {
      return MemDepResult(
        PairTy(reinterpret_cast<Instruction*>(Unknown), Other));
    }

    /// isClobber - Return true if this MemDepResult represents a query that is
    /// an instruction clobber dependency.
    bool isClobber() const { return Value.getInt() == Clobber; }

    /// isDef - Return true if this MemDepResult represents a query that is
    /// an instruction definition dependency.
    bool isDef() const { return Value.getInt() == Def; }

    /// isNonLocal - Return true if this MemDepResult represents a query that
    /// is transparent to the start of the block, but where a non-local hasn't
    /// been done.
    bool isNonLocal() const {
      return Value.getInt() == Other
        && Value.getPointer() == reinterpret_cast<Instruction*>(NonLocal);
    }

    /// isNonFuncLocal - Return true if this MemDepResult represents a query
    /// that is transparent to the start of the function.
    bool isNonFuncLocal() const {
      return Value.getInt() == Other
        && Value.getPointer() == reinterpret_cast<Instruction*>(NonFuncLocal);
    }

    /// isUnknown - Return true if this MemDepResult represents a query which
    /// cannot and/or will not be computed.
    bool isUnknown() const {
      return Value.getInt() == Other
        && Value.getPointer() == reinterpret_cast<Instruction*>(Unknown);
    }

    /// getInst() - If this is a normal dependency, return the instruction that
    /// is depended on.  Otherwise, return null.
    Instruction *getInst() const {
      if (Value.getInt() == Other) return nullptr;
      return Value.getPointer();
    }

    bool operator==(const MemDepResult &M) const { return Value == M.Value; }
    bool operator!=(const MemDepResult &M) const { return Value != M.Value; }
    bool operator<(const MemDepResult &M) const { return Value < M.Value; }
    bool operator>(const MemDepResult &M) const { return Value > M.Value; }
  private:
    friend class MemoryDependenceAnalysis;
    /// Dirty - Entries with this marker occur in a LocalDeps map or
    /// NonLocalDeps map when the instruction they previously referenced was
    /// removed from MemDep.  In either case, the entry may include an
    /// instruction pointer.  If so, the pointer is an instruction in the
    /// block where scanning can start from, saving some work.
    ///
    /// In a default-constructed MemDepResult object, the type will be Dirty
    /// and the instruction pointer will be null.
    ///

    /// isDirty - Return true if this is a MemDepResult in its dirty/invalid.
    /// state.
    bool isDirty() const { return Value.getInt() == Invalid; }

    static MemDepResult getDirty(Instruction *Inst) {
      return MemDepResult(PairTy(Inst, Invalid));
    }
  };

  /// NonLocalDepEntry - This is an entry in the NonLocalDepInfo cache.  For
  /// each BasicBlock (the BB entry) it keeps a MemDepResult.
  class NonLocalDepEntry {
    BasicBlock *BB;
    MemDepResult Result;
  public:
    NonLocalDepEntry(BasicBlock *bb, MemDepResult result)
      : BB(bb), Result(result) {}

    // This is used for searches.
    NonLocalDepEntry(BasicBlock *bb) : BB(bb) {}

    // BB is the sort key, it can't be changed.
    BasicBlock *getBB() const { return BB; }

    void setResult(const MemDepResult &R) { Result = R; }

    const MemDepResult &getResult() const { return Result; }

    bool operator<(const NonLocalDepEntry &RHS) const {
      return BB < RHS.BB;
    }
  };

  /// NonLocalDepResult - This is a result from a NonLocal dependence query.
  /// For each BasicBlock (the BB entry) it keeps a MemDepResult and the
  /// (potentially phi translated) address that was live in the block.
  class NonLocalDepResult {
    NonLocalDepEntry Entry;
    Value *Address;
  public:
    NonLocalDepResult(BasicBlock *bb, MemDepResult result, Value *address)
      : Entry(bb, result), Address(address) {}

    // BB is the sort key, it can't be changed.
    BasicBlock *getBB() const { return Entry.getBB(); }

    void setResult(const MemDepResult &R, Value *Addr) {
      Entry.setResult(R);
      Address = Addr;
    }

    const MemDepResult &getResult() const { return Entry.getResult(); }

    /// getAddress - Return the address of this pointer in this block.  This can
    /// be different than the address queried for the non-local result because
    /// of phi translation.  This returns null if the address was not available
    /// in a block (i.e. because phi translation failed) or if this is a cached
    /// result and that address was deleted.
    ///
    /// The address is always null for a non-local 'call' dependence.
    Value *getAddress() const { return Address; }
  };

  /// MemoryDependenceAnalysis - This is an analysis that determines, for a
  /// given memory operation, what preceding memory operations it depends on.
  /// It builds on alias analysis information, and tries to provide a lazy,
  /// caching interface to a common kind of alias information query.
  ///
  /// The dependency information returned is somewhat unusual, but is pragmatic.
  /// If queried about a store or call that might modify memory, the analysis
  /// will return the instruction[s] that may either load from that memory or
  /// store to it.  If queried with a load or call that can never modify memory,
  /// the analysis will return calls and stores that might modify the pointer,
  /// but generally does not return loads unless a) they are volatile, or
  /// b) they load from *must-aliased* pointers.  Returning a dependence on
  /// must-alias'd pointers instead of all pointers interacts well with the
  /// internal caching mechanism.
  ///
  class MemoryDependenceAnalysis : public FunctionPass {
    // A map from instructions to their dependency.
    typedef DenseMap<Instruction*, MemDepResult> LocalDepMapType;
    LocalDepMapType LocalDeps;

  public:
    typedef std::vector<NonLocalDepEntry> NonLocalDepInfo;
  private:
    /// ValueIsLoadPair - This is a pair<Value*, bool> where the bool is true if
    /// the dependence is a read only dependence, false if read/write.
    typedef PointerIntPair<const Value*, 1, bool> ValueIsLoadPair;

    /// BBSkipFirstBlockPair - This pair is used when caching information for a
    /// block.  If the pointer is null, the cache value is not a full query that
    /// starts at the specified block.  If non-null, the bool indicates whether
    /// or not the contents of the block was skipped.
    typedef PointerIntPair<BasicBlock*, 1, bool> BBSkipFirstBlockPair;

    /// NonLocalPointerInfo - This record is the information kept for each
    /// (value, is load) pair.
    struct NonLocalPointerInfo {
      /// Pair - The pair of the block and the skip-first-block flag.
      BBSkipFirstBlockPair Pair;
      /// NonLocalDeps - The results of the query for each relevant block.
      NonLocalDepInfo NonLocalDeps;
      /// Size - The maximum size of the dereferences of the
      /// pointer. May be UnknownSize if the sizes are unknown.
      uint64_t Size;
      /// TBAATag - The TBAA tag associated with dereferences of the
      /// pointer. May be null if there are no tags or conflicting tags.
      const MDNode *TBAATag;

      NonLocalPointerInfo()
        : Size(AliasAnalysis::UnknownSize), TBAATag(nullptr) {}
    };

    /// CachedNonLocalPointerInfo - This map stores the cached results of doing
    /// a pointer lookup at the bottom of a block.  The key of this map is the
    /// pointer+isload bit, the value is a list of <bb->result> mappings.
    typedef DenseMap<ValueIsLoadPair,
                     NonLocalPointerInfo> CachedNonLocalPointerInfo;
    CachedNonLocalPointerInfo NonLocalPointerDeps;

    // A map from instructions to their non-local pointer dependencies.
    typedef DenseMap<Instruction*,
                     SmallPtrSet<ValueIsLoadPair, 4> > ReverseNonLocalPtrDepTy;
    ReverseNonLocalPtrDepTy ReverseNonLocalPtrDeps;


    /// PerInstNLInfo - This is the instruction we keep for each cached access
    /// that we have for an instruction.  The pointer is an owning pointer and
    /// the bool indicates whether we have any dirty bits in the set.
    typedef std::pair<NonLocalDepInfo, bool> PerInstNLInfo;

    // A map from instructions to their non-local dependencies.
    typedef DenseMap<Instruction*, PerInstNLInfo> NonLocalDepMapType;

    NonLocalDepMapType NonLocalDeps;

    // A reverse mapping from dependencies to the dependees.  This is
    // used when removing instructions to keep the cache coherent.
    typedef DenseMap<Instruction*,
                     SmallPtrSet<Instruction*, 4> > ReverseDepMapType;
    ReverseDepMapType ReverseLocalDeps;

    // A reverse mapping from dependencies to the non-local dependees.
    ReverseDepMapType ReverseNonLocalDeps;

    /// Current AA implementation, just a cache.
    AliasAnalysis *AA;
    const DataLayout *DL;
    DominatorTree *DT;
    std::unique_ptr<PredIteratorCache> PredCache;

  public:
    MemoryDependenceAnalysis();
    ~MemoryDependenceAnalysis();
    static char ID;

    /// Pass Implementation stuff.  This doesn't do any analysis eagerly.
    bool runOnFunction(Function &) override;

    /// Clean up memory in between runs
    void releaseMemory() override;

    /// getAnalysisUsage - Does not modify anything.  It uses Value Numbering
    /// and Alias Analysis.
    ///
    void getAnalysisUsage(AnalysisUsage &AU) const override;

    /// getDependency - Return the instruction on which a memory operation
    /// depends.  See the class comment for more details.  It is illegal to call
    /// this on non-memory instructions.
    MemDepResult getDependency(Instruction *QueryInst);

    /// getNonLocalCallDependency - Perform a full dependency query for the
    /// specified call, returning the set of blocks that the value is
    /// potentially live across.  The returned set of results will include a
    /// "NonLocal" result for all blocks where the value is live across.
    ///
    /// This method assumes the instruction returns a "NonLocal" dependency
    /// within its own block.
    ///
    /// This returns a reference to an internal data structure that may be
    /// invalidated on the next non-local query or when an instruction is
    /// removed.  Clients must copy this data if they want it around longer than
    /// that.
    const NonLocalDepInfo &getNonLocalCallDependency(CallSite QueryCS);


    /// getNonLocalPointerDependency - Perform a full dependency query for an
    /// access to the specified (non-volatile) memory location, returning the
    /// set of instructions that either define or clobber the value.
    ///
    /// This method assumes the pointer has a "NonLocal" dependency within BB.
    void getNonLocalPointerDependency(const AliasAnalysis::Location &Loc,
                                      bool isLoad, BasicBlock *BB,
                                    SmallVectorImpl<NonLocalDepResult> &Result);

    /// removeInstruction - Remove an instruction from the dependence analysis,
    /// updating the dependence of instructions that previously depended on it.
    void removeInstruction(Instruction *InstToRemove);

    /// invalidateCachedPointerInfo - This method is used to invalidate cached
    /// information about the specified pointer, because it may be too
    /// conservative in memdep.  This is an optional call that can be used when
    /// the client detects an equivalence between the pointer and some other
    /// value and replaces the other value with ptr. This can make Ptr available
    /// in more places that cached info does not necessarily keep.
    void invalidateCachedPointerInfo(Value *Ptr);

    /// invalidateCachedPredecessors - Clear the PredIteratorCache info.
    /// This needs to be done when the CFG changes, e.g., due to splitting
    /// critical edges.
    void invalidateCachedPredecessors();

    /// getPointerDependencyFrom - Return the instruction on which a memory
    /// location depends.  If isLoad is true, this routine ignores may-aliases
    /// with read-only operations.  If isLoad is false, this routine ignores
    /// may-aliases with reads from read-only locations. If possible, pass
    /// the query instruction as well; this function may take advantage of 
    /// the metadata annotated to the query instruction to refine the result.
    ///
    /// Note that this is an uncached query, and thus may be inefficient.
    ///
    MemDepResult getPointerDependencyFrom(const AliasAnalysis::Location &Loc,
                                          bool isLoad,
                                          BasicBlock::iterator ScanIt,
                                          BasicBlock *BB,
                                          Instruction *QueryInst = nullptr);


    /// getLoadLoadClobberFullWidthSize - This is a little bit of analysis that
    /// looks at a memory location for a load (specified by MemLocBase, Offs,
    /// and Size) and compares it against a load.  If the specified load could
    /// be safely widened to a larger integer load that is 1) still efficient,
    /// 2) safe for the target, and 3) would provide the specified memory
    /// location value, then this function returns the size in bytes of the
    /// load width to use.  If not, this returns zero.
    static unsigned getLoadLoadClobberFullWidthSize(const Value *MemLocBase,
                                                    int64_t MemLocOffs,
                                                    unsigned MemLocSize,
                                                    const LoadInst *LI,
                                                    const DataLayout &DL);

  private:
    MemDepResult getCallSiteDependencyFrom(CallSite C, bool isReadOnlyCall,
                                           BasicBlock::iterator ScanIt,
                                           BasicBlock *BB);
    bool getNonLocalPointerDepFromBB(const PHITransAddr &Pointer,
                                     const AliasAnalysis::Location &Loc,
                                     bool isLoad, BasicBlock *BB,
                                     SmallVectorImpl<NonLocalDepResult> &Result,
                                     DenseMap<BasicBlock*, Value*> &Visited,
                                     bool SkipFirstBlock = false);
    MemDepResult GetNonLocalInfoForBlock(const AliasAnalysis::Location &Loc,
                                         bool isLoad, BasicBlock *BB,
                                         NonLocalDepInfo *Cache,
                                         unsigned NumSortedEntries);

    void RemoveCachedNonLocalPointerDependencies(ValueIsLoadPair P);

    /// verifyRemoved - Verify that the specified instruction does not occur
    /// in our internal data structures.
    void verifyRemoved(Instruction *Inst) const;

  };

} // End llvm namespace

#endif
