//===- CFLAliasAnalysis.cpp - CFL-Based Alias Analysis Implementation ------==//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements a CFL-based context-insensitive alias analysis
// algorithm. It does not depend on types. The algorithm is a mixture of the one
// described in "Demand-driven alias analysis for C" by Xin Zheng and Radu
// Rugina, and "Fast algorithms for Dyck-CFL-reachability with applications to
// Alias Analysis" by Zhang Q, Lyu M R, Yuan H, and Su Z. -- to summarize the
// papers, we build a graph of the uses of a variable, where each node is a
// memory location, and each edge is an action that happened on that memory
// location.  The "actions" can be one of Dereference, Reference, Assign, or
// Assign.
//
// Two variables are considered as aliasing iff you can reach one value's node
// from the other value's node and the language formed by concatenating all of
// the edge labels (actions) conforms to a context-free grammar.
//
// Because this algorithm requires a graph search on each query, we execute the
// algorithm outlined in "Fast algorithms..." (mentioned above)
// in order to transform the graph into sets of variables that may alias in
// ~nlogn time (n = number of variables.), which makes queries take constant
// time.
//===----------------------------------------------------------------------===//

#include "StratifiedSets.h"
#include "llvm/Analysis/Passes.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/None.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/InstVisitor.h"
#include "llvm/IR/ValueHandle.h"
#include "llvm/Pass.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
#include <algorithm>
#include <cassert>
#include <forward_list>
#include <tuple>

using namespace llvm;

// Try to go from a Value* to a Function*. Never returns nullptr.
static Optional<Function *> parentFunctionOfValue(Value *);

// Returns possible functions called by the Inst* into the given
// SmallVectorImpl. Returns true if targets found, false otherwise.
// This is templated because InvokeInst/CallInst give us the same
// set of functions that we care about, and I don't like repeating
// myself.
template <typename Inst>
static bool getPossibleTargets(Inst *, SmallVectorImpl<Function *> &);

// Some instructions need to have their users tracked. Instructions like
// `add` require you to get the users of the Instruction* itself, other
// instructions like `store` require you to get the users of the first
// operand. This function gets the "proper" value to track for each
// type of instruction we support.
static Optional<Value *> getTargetValue(Instruction *);

// There are certain instructions (i.e. FenceInst, etc.) that we ignore.
// This notes that we should ignore those.
static bool hasUsefulEdges(Instruction *);

const StratifiedIndex StratifiedLink::SetSentinel =
  std::numeric_limits<StratifiedIndex>::max();

namespace {
// StratifiedInfo Attribute things.
typedef unsigned StratifiedAttr;
LLVM_CONSTEXPR unsigned MaxStratifiedAttrIndex = NumStratifiedAttrs;
LLVM_CONSTEXPR unsigned AttrAllIndex = 0;
LLVM_CONSTEXPR unsigned AttrGlobalIndex = 1;
LLVM_CONSTEXPR unsigned AttrFirstArgIndex = 2;
LLVM_CONSTEXPR unsigned AttrLastArgIndex = MaxStratifiedAttrIndex;
LLVM_CONSTEXPR unsigned AttrMaxNumArgs = AttrLastArgIndex - AttrFirstArgIndex;

LLVM_CONSTEXPR StratifiedAttr AttrNone = 0;
LLVM_CONSTEXPR StratifiedAttr AttrAll = ~AttrNone;

// \brief StratifiedSets call for knowledge of "direction", so this is how we
// represent that locally.
enum class Level { Same, Above, Below };

// \brief Edges can be one of four "weights" -- each weight must have an inverse
// weight (Assign has Assign; Reference has Dereference).
enum class EdgeType {
  // The weight assigned when assigning from or to a value. For example, in:
  // %b = getelementptr %a, 0
  // ...The relationships are %b assign %a, and %a assign %b. This used to be
  // two edges, but having a distinction bought us nothing.
  Assign,

  // The edge used when we have an edge going from some handle to a Value.
  // Examples of this include:
  // %b = load %a              (%b Dereference %a)
  // %b = extractelement %a, 0 (%a Dereference %b)
  Dereference,

  // The edge used when our edge goes from a value to a handle that may have
  // contained it at some point. Examples:
  // %b = load %a              (%a Reference %b)
  // %b = extractelement %a, 0 (%b Reference %a)
  Reference
};

// \brief Encodes the notion of a "use"
struct Edge {
  // \brief Which value the edge is coming from
  Value *From;

  // \brief Which value the edge is pointing to
  Value *To;

  // \brief Edge weight
  EdgeType Weight;

  // \brief Whether we aliased any external values along the way that may be
  // invisible to the analysis (i.e. landingpad for exceptions, calls for
  // interprocedural analysis, etc.)
  StratifiedAttrs AdditionalAttrs;

  Edge(Value *From, Value *To, EdgeType W, StratifiedAttrs A)
      : From(From), To(To), Weight(W), AdditionalAttrs(A) {}
};

// \brief Information we have about a function and would like to keep around
struct FunctionInfo {
  StratifiedSets<Value *> Sets;
  // Lots of functions have < 4 returns. Adjust as necessary.
  SmallVector<Value *, 4> ReturnedValues;

  FunctionInfo(StratifiedSets<Value *> &&S,
               SmallVector<Value *, 4> &&RV)
    : Sets(std::move(S)), ReturnedValues(std::move(RV)) {}
};

struct CFLAliasAnalysis;

struct FunctionHandle : public CallbackVH {
  FunctionHandle(Function *Fn, CFLAliasAnalysis *CFLAA)
      : CallbackVH(Fn), CFLAA(CFLAA) {
    assert(Fn != nullptr);
    assert(CFLAA != nullptr);
  }

  virtual ~FunctionHandle() {}

  void deleted() override { removeSelfFromCache(); }
  void allUsesReplacedWith(Value *) override { removeSelfFromCache(); }

private:
  CFLAliasAnalysis *CFLAA;

  void removeSelfFromCache();
};

struct CFLAliasAnalysis : public ImmutablePass, public AliasAnalysis {
private:
  /// \brief Cached mapping of Functions to their StratifiedSets.
  /// If a function's sets are currently being built, it is marked
  /// in the cache as an Optional without a value. This way, if we
  /// have any kind of recursion, it is discernable from a function
  /// that simply has empty sets.
  DenseMap<Function *, Optional<FunctionInfo>> Cache;
  std::forward_list<FunctionHandle> Handles;

public:
  static char ID;

  CFLAliasAnalysis() : ImmutablePass(ID) {
    initializeCFLAliasAnalysisPass(*PassRegistry::getPassRegistry());
  }

  virtual ~CFLAliasAnalysis() {}

  void getAnalysisUsage(AnalysisUsage &AU) const override {
    AliasAnalysis::getAnalysisUsage(AU);
  }

  void *getAdjustedAnalysisPointer(const void *ID) override {
    if (ID == &AliasAnalysis::ID)
      return (AliasAnalysis *)this;
    return this;
  }

  /// \brief Inserts the given Function into the cache.
  void scan(Function *Fn);

  void evict(Function *Fn) { Cache.erase(Fn); }

  /// \brief Ensures that the given function is available in the cache.
  /// Returns the appropriate entry from the cache.
  const Optional<FunctionInfo> &ensureCached(Function *Fn) {
    auto Iter = Cache.find(Fn);
    if (Iter == Cache.end()) {
      scan(Fn);
      Iter = Cache.find(Fn);
      assert(Iter != Cache.end());
      assert(Iter->second.hasValue());
    }
    return Iter->second;
  }

  AliasResult query(const Location &LocA, const Location &LocB);

  AliasResult alias(const Location &LocA, const Location &LocB) override {
    if (LocA.Ptr == LocB.Ptr) {
      if (LocA.Size == LocB.Size) {
        return MustAlias;
      } else {
        return PartialAlias;
      }
    }

    // Comparisons between global variables and other constants should be
    // handled by BasicAA.
    if (isa<Constant>(LocA.Ptr) && isa<Constant>(LocB.Ptr)) {
      return MayAlias;
    }

    return query(LocA, LocB);
  }

  void initializePass() override { InitializeAliasAnalysis(this); }
};

void FunctionHandle::removeSelfFromCache() {
  assert(CFLAA != nullptr);
  auto *Val = getValPtr();
  CFLAA->evict(cast<Function>(Val));
  setValPtr(nullptr);
}

// \brief Gets the edges our graph should have, based on an Instruction*
class GetEdgesVisitor : public InstVisitor<GetEdgesVisitor, void> {
  CFLAliasAnalysis &AA;
  SmallVectorImpl<Edge> &Output;

public:
  GetEdgesVisitor(CFLAliasAnalysis &AA, SmallVectorImpl<Edge> &Output)
      : AA(AA), Output(Output) {}

  void visitInstruction(Instruction &) {
    llvm_unreachable("Unsupported instruction encountered");
  }

  void visitCastInst(CastInst &Inst) {
    Output.push_back(Edge(&Inst, Inst.getOperand(0), EdgeType::Assign,
                          AttrNone));
  }

  void visitBinaryOperator(BinaryOperator &Inst) {
    auto *Op1 = Inst.getOperand(0);
    auto *Op2 = Inst.getOperand(1);
    Output.push_back(Edge(&Inst, Op1, EdgeType::Assign, AttrNone));
    Output.push_back(Edge(&Inst, Op2, EdgeType::Assign, AttrNone));
  }

  void visitAtomicCmpXchgInst(AtomicCmpXchgInst &Inst) {
    auto *Ptr = Inst.getPointerOperand();
    auto *Val = Inst.getNewValOperand();
    Output.push_back(Edge(Ptr, Val, EdgeType::Dereference, AttrNone));
  }

  void visitAtomicRMWInst(AtomicRMWInst &Inst) {
    auto *Ptr = Inst.getPointerOperand();
    auto *Val = Inst.getValOperand();
    Output.push_back(Edge(Ptr, Val, EdgeType::Dereference, AttrNone));
  }

  void visitPHINode(PHINode &Inst) {
    for (unsigned I = 0, E = Inst.getNumIncomingValues(); I != E; ++I) {
      Value *Val = Inst.getIncomingValue(I);
      Output.push_back(Edge(&Inst, Val, EdgeType::Assign, AttrNone));
    }
  }

  void visitGetElementPtrInst(GetElementPtrInst &Inst) {
    auto *Op = Inst.getPointerOperand();
    Output.push_back(Edge(&Inst, Op, EdgeType::Assign, AttrNone));
    for (auto I = Inst.idx_begin(), E = Inst.idx_end(); I != E; ++I)
      Output.push_back(Edge(&Inst, *I, EdgeType::Assign, AttrNone));
  }

  void visitSelectInst(SelectInst &Inst) {
    auto *Condition = Inst.getCondition();
    Output.push_back(Edge(&Inst, Condition, EdgeType::Assign, AttrNone));
    auto *TrueVal = Inst.getTrueValue();
    Output.push_back(Edge(&Inst, TrueVal, EdgeType::Assign, AttrNone));
    auto *FalseVal = Inst.getFalseValue();
    Output.push_back(Edge(&Inst, FalseVal, EdgeType::Assign, AttrNone));
  }

  void visitAllocaInst(AllocaInst &) {}

  void visitLoadInst(LoadInst &Inst) {
    auto *Ptr = Inst.getPointerOperand();
    auto *Val = &Inst;
    Output.push_back(Edge(Val, Ptr, EdgeType::Reference, AttrNone));
  }

  void visitStoreInst(StoreInst &Inst) {
    auto *Ptr = Inst.getPointerOperand();
    auto *Val = Inst.getValueOperand();
    Output.push_back(Edge(Ptr, Val, EdgeType::Dereference, AttrNone));
  }

  void visitVAArgInst(VAArgInst &Inst) {
    // We can't fully model va_arg here. For *Ptr = Inst.getOperand(0), it does
    // two things:
    //  1. Loads a value from *((T*)*Ptr).
    //  2. Increments (stores to) *Ptr by some target-specific amount.
    // For now, we'll handle this like a landingpad instruction (by placing the
    // result in its own group, and having that group alias externals).
    auto *Val = &Inst;
    Output.push_back(Edge(Val, Val, EdgeType::Assign, AttrAll));
  }

  static bool isFunctionExternal(Function *Fn) {
    return Fn->isDeclaration() || !Fn->hasLocalLinkage();
  }

  // Gets whether the sets at Index1 above, below, or equal to the sets at
  // Index2. Returns None if they are not in the same set chain.
  static Optional<Level> getIndexRelation(const StratifiedSets<Value *> &Sets,
                                          StratifiedIndex Index1,
                                          StratifiedIndex Index2) {
    if (Index1 == Index2)
      return Level::Same;

    const auto *Current = &Sets.getLink(Index1);
    while (Current->hasBelow()) {
      if (Current->Below == Index2)
        return Level::Below;
      Current = &Sets.getLink(Current->Below);
    }

    Current = &Sets.getLink(Index1);
    while (Current->hasAbove()) {
      if (Current->Above == Index2)
        return Level::Above;
      Current = &Sets.getLink(Current->Above);
    }

    return NoneType();
  }

  bool
  tryInterproceduralAnalysis(const SmallVectorImpl<Function *> &Fns,
                             Value *FuncValue,
                             const iterator_range<User::op_iterator> &Args) {
    const unsigned ExpectedMaxArgs = 8;
    const unsigned MaxSupportedArgs = 50;
    assert(Fns.size() > 0);

    // I put this here to give us an upper bound on time taken by IPA. Is it
    // really (realistically) needed? Keep in mind that we do have an n^2 algo.
    if (std::distance(Args.begin(), Args.end()) > (int) MaxSupportedArgs)
      return false;

    // Exit early if we'll fail anyway
    for (auto *Fn : Fns) {
      if (isFunctionExternal(Fn) || Fn->isVarArg())
        return false;
      auto &MaybeInfo = AA.ensureCached(Fn);
      if (!MaybeInfo.hasValue())
        return false;
    }

    SmallVector<Value *, ExpectedMaxArgs> Arguments(Args.begin(), Args.end());
    SmallVector<StratifiedInfo, ExpectedMaxArgs> Parameters;
    for (auto *Fn : Fns) {
      auto &Info = *AA.ensureCached(Fn);
      auto &Sets = Info.Sets;
      auto &RetVals = Info.ReturnedValues;

      Parameters.clear();
      for (auto &Param : Fn->args()) {
        auto MaybeInfo = Sets.find(&Param);
        // Did a new parameter somehow get added to the function/slip by?
        if (!MaybeInfo.hasValue())
          return false;
        Parameters.push_back(*MaybeInfo);
      }

      // Adding an edge from argument -> return value for each parameter that
      // may alias the return value
      for (unsigned I = 0, E = Parameters.size(); I != E; ++I) {
        auto &ParamInfo = Parameters[I];
        auto &ArgVal = Arguments[I];
        bool AddEdge = false;
        StratifiedAttrs Externals;
        for (unsigned X = 0, XE = RetVals.size(); X != XE; ++X) {
          auto MaybeInfo = Sets.find(RetVals[X]);
          if (!MaybeInfo.hasValue())
            return false;

          auto &RetInfo = *MaybeInfo;
          auto RetAttrs = Sets.getLink(RetInfo.Index).Attrs;
          auto ParamAttrs = Sets.getLink(ParamInfo.Index).Attrs;
          auto MaybeRelation =
              getIndexRelation(Sets, ParamInfo.Index, RetInfo.Index);
          if (MaybeRelation.hasValue()) {
            AddEdge = true;
            Externals |= RetAttrs | ParamAttrs;
          }
        }
        if (AddEdge)
          Output.push_back(Edge(FuncValue, ArgVal, EdgeType::Assign,
                            StratifiedAttrs().flip()));
      }

      if (Parameters.size() != Arguments.size())
        return false;

      // Adding edges between arguments for arguments that may end up aliasing
      // each other. This is necessary for functions such as
      // void foo(int** a, int** b) { *a = *b; }
      // (Technically, the proper sets for this would be those below
      // Arguments[I] and Arguments[X], but our algorithm will produce
      // extremely similar, and equally correct, results either way)
      for (unsigned I = 0, E = Arguments.size(); I != E; ++I) {
        auto &MainVal = Arguments[I];
        auto &MainInfo = Parameters[I];
        auto &MainAttrs = Sets.getLink(MainInfo.Index).Attrs;
        for (unsigned X = I + 1; X != E; ++X) {
          auto &SubInfo = Parameters[X];
          auto &SubVal = Arguments[X];
          auto &SubAttrs = Sets.getLink(SubInfo.Index).Attrs;
          auto MaybeRelation =
              getIndexRelation(Sets, MainInfo.Index, SubInfo.Index);

          if (!MaybeRelation.hasValue())
            continue;

          auto NewAttrs = SubAttrs | MainAttrs;
          Output.push_back(Edge(MainVal, SubVal, EdgeType::Assign, NewAttrs));
        }
      }
    }
    return true;
  }

  template <typename InstT> void visitCallLikeInst(InstT &Inst) {
    SmallVector<Function *, 4> Targets;
    if (getPossibleTargets(&Inst, Targets)) {
      if (tryInterproceduralAnalysis(Targets, &Inst, Inst.arg_operands()))
        return;
      // Cleanup from interprocedural analysis
      Output.clear();
    }

    for (Value *V : Inst.arg_operands())
      Output.push_back(Edge(&Inst, V, EdgeType::Assign, AttrAll));
  }

  void visitCallInst(CallInst &Inst) { visitCallLikeInst(Inst); }

  void visitInvokeInst(InvokeInst &Inst) { visitCallLikeInst(Inst); }

  // Because vectors/aggregates are immutable and unaddressable,
  // there's nothing we can do to coax a value out of them, other
  // than calling Extract{Element,Value}. We can effectively treat
  // them as pointers to arbitrary memory locations we can store in
  // and load from.
  void visitExtractElementInst(ExtractElementInst &Inst) {
    auto *Ptr = Inst.getVectorOperand();
    auto *Val = &Inst;
    Output.push_back(Edge(Val, Ptr, EdgeType::Reference, AttrNone));
  }

  void visitInsertElementInst(InsertElementInst &Inst) {
    auto *Vec = Inst.getOperand(0);
    auto *Val = Inst.getOperand(1);
    Output.push_back(Edge(&Inst, Vec, EdgeType::Assign, AttrNone));
    Output.push_back(Edge(&Inst, Val, EdgeType::Dereference, AttrNone));
  }

  void visitLandingPadInst(LandingPadInst &Inst) {
    // Exceptions come from "nowhere", from our analysis' perspective.
    // So we place the instruction its own group, noting that said group may
    // alias externals
    Output.push_back(Edge(&Inst, &Inst, EdgeType::Assign, AttrAll));
  }

  void visitInsertValueInst(InsertValueInst &Inst) {
    auto *Agg = Inst.getOperand(0);
    auto *Val = Inst.getOperand(1);
    Output.push_back(Edge(&Inst, Agg, EdgeType::Assign, AttrNone));
    Output.push_back(Edge(&Inst, Val, EdgeType::Dereference, AttrNone));
  }

  void visitExtractValueInst(ExtractValueInst &Inst) {
    auto *Ptr = Inst.getAggregateOperand();
    Output.push_back(Edge(&Inst, Ptr, EdgeType::Reference, AttrNone));
  }

  void visitShuffleVectorInst(ShuffleVectorInst &Inst) {
    auto *From1 = Inst.getOperand(0);
    auto *From2 = Inst.getOperand(1);
    Output.push_back(Edge(&Inst, From1, EdgeType::Assign, AttrNone));
    Output.push_back(Edge(&Inst, From2, EdgeType::Assign, AttrNone));
  }
};

// For a given instruction, we need to know which Value* to get the
// users of in order to build our graph. In some cases (i.e. add),
// we simply need the Instruction*. In other cases (i.e. store),
// finding the users of the Instruction* is useless; we need to find
// the users of the first operand. This handles determining which
// value to follow for us.
//
// Note: we *need* to keep this in sync with GetEdgesVisitor. Add
// something to GetEdgesVisitor, add it here -- remove something from
// GetEdgesVisitor, remove it here.
class GetTargetValueVisitor
    : public InstVisitor<GetTargetValueVisitor, Value *> {
public:
  Value *visitInstruction(Instruction &Inst) { return &Inst; }

  Value *visitStoreInst(StoreInst &Inst) { return Inst.getPointerOperand(); }

  Value *visitAtomicCmpXchgInst(AtomicCmpXchgInst &Inst) {
    return Inst.getPointerOperand();
  }

  Value *visitAtomicRMWInst(AtomicRMWInst &Inst) {
    return Inst.getPointerOperand();
  }

  Value *visitInsertElementInst(InsertElementInst &Inst) {
    return Inst.getOperand(0);
  }

  Value *visitInsertValueInst(InsertValueInst &Inst) {
    return Inst.getAggregateOperand();
  }
};

// Set building requires a weighted bidirectional graph.
template <typename EdgeTypeT> class WeightedBidirectionalGraph {
public:
  typedef std::size_t Node;

private:
  const static Node StartNode = Node(0);

  struct Edge {
    EdgeTypeT Weight;
    Node Other;

    Edge(const EdgeTypeT &W, const Node &N)
      : Weight(W), Other(N) {}

    bool operator==(const Edge &E) const {
      return Weight == E.Weight && Other == E.Other;
    }

    bool operator!=(const Edge &E) const { return !operator==(E); }
  };

  struct NodeImpl {
    std::vector<Edge> Edges;
  };

  std::vector<NodeImpl> NodeImpls;

  bool inbounds(Node NodeIndex) const { return NodeIndex < NodeImpls.size(); }

  const NodeImpl &getNode(Node N) const { return NodeImpls[N]; }
  NodeImpl &getNode(Node N) { return NodeImpls[N]; }

public:
  // ----- Various Edge iterators for the graph ----- //

  // \brief Iterator for edges. Because this graph is bidirected, we don't
  // allow modificaiton of the edges using this iterator. Additionally, the
  // iterator becomes invalid if you add edges to or from the node you're
  // getting the edges of.
  struct EdgeIterator : public std::iterator<std::forward_iterator_tag,
                                             std::tuple<EdgeTypeT, Node *>> {
    EdgeIterator(const typename std::vector<Edge>::const_iterator &Iter)
        : Current(Iter) {}

    EdgeIterator(NodeImpl &Impl) : Current(Impl.begin()) {}

    EdgeIterator &operator++() {
      ++Current;
      return *this;
    }

    EdgeIterator operator++(int) {
      EdgeIterator Copy(Current);
      operator++();
      return Copy;
    }

    std::tuple<EdgeTypeT, Node> &operator*() {
      Store = std::make_tuple(Current->Weight, Current->Other);
      return Store;
    }

    bool operator==(const EdgeIterator &Other) const {
      return Current == Other.Current;
    }

    bool operator!=(const EdgeIterator &Other) const {
      return !operator==(Other);
    }

  private:
    typename std::vector<Edge>::const_iterator Current;
    std::tuple<EdgeTypeT, Node> Store;
  };

  // Wrapper for EdgeIterator with begin()/end() calls.
  struct EdgeIterable {
    EdgeIterable(const std::vector<Edge> &Edges)
        : BeginIter(Edges.begin()), EndIter(Edges.end()) {}

    EdgeIterator begin() { return EdgeIterator(BeginIter); }

    EdgeIterator end() { return EdgeIterator(EndIter); }

  private:
    typename std::vector<Edge>::const_iterator BeginIter;
    typename std::vector<Edge>::const_iterator EndIter;
  };

  // ----- Actual graph-related things ----- //

  WeightedBidirectionalGraph() {}

  WeightedBidirectionalGraph(WeightedBidirectionalGraph<EdgeTypeT> &&Other)
      : NodeImpls(std::move(Other.NodeImpls)) {}

  WeightedBidirectionalGraph<EdgeTypeT> &
  operator=(WeightedBidirectionalGraph<EdgeTypeT> &&Other) {
    NodeImpls = std::move(Other.NodeImpls);
    return *this;
  }

  Node addNode() {
    auto Index = NodeImpls.size();
    auto NewNode = Node(Index);
    NodeImpls.push_back(NodeImpl());
    return NewNode;
  }

  void addEdge(Node From, Node To, const EdgeTypeT &Weight,
               const EdgeTypeT &ReverseWeight) {
    assert(inbounds(From));
    assert(inbounds(To));
    auto &FromNode = getNode(From);
    auto &ToNode = getNode(To);
    FromNode.Edges.push_back(Edge(Weight, To));
    ToNode.Edges.push_back(Edge(ReverseWeight, From));
  }

  EdgeIterable edgesFor(const Node &N) const {
    const auto &Node = getNode(N);
    return EdgeIterable(Node.Edges);
  }

  bool empty() const { return NodeImpls.empty(); }
  std::size_t size() const { return NodeImpls.size(); }

  // \brief Gets an arbitrary node in the graph as a starting point for
  // traversal.
  Node getEntryNode() {
    assert(inbounds(StartNode));
    return StartNode;
  }
};

typedef WeightedBidirectionalGraph<std::pair<EdgeType, StratifiedAttrs>> GraphT;
typedef DenseMap<Value *, GraphT::Node> NodeMapT;
}

// -- Setting up/registering CFLAA pass -- //
char CFLAliasAnalysis::ID = 0;

INITIALIZE_AG_PASS(CFLAliasAnalysis, AliasAnalysis, "cfl-aa",
                   "CFL-Based AA implementation", false, true, false)

ImmutablePass *llvm::createCFLAliasAnalysisPass() {
  return new CFLAliasAnalysis();
}

//===----------------------------------------------------------------------===//
// Function declarations that require types defined in the namespace above
//===----------------------------------------------------------------------===//

// Given an argument number, returns the appropriate Attr index to set.
static StratifiedAttr argNumberToAttrIndex(StratifiedAttr);

// Given a Value, potentially return which AttrIndex it maps to.
static Optional<StratifiedAttr> valueToAttrIndex(Value *Val);

// Gets the inverse of a given EdgeType.
static EdgeType flipWeight(EdgeType);

// Gets edges of the given Instruction*, writing them to the SmallVector*.
static void argsToEdges(CFLAliasAnalysis &, Instruction *,
                        SmallVectorImpl<Edge> &);

// Gets the "Level" that one should travel in StratifiedSets
// given an EdgeType.
static Level directionOfEdgeType(EdgeType);

// Builds the graph needed for constructing the StratifiedSets for the
// given function
static void buildGraphFrom(CFLAliasAnalysis &, Function *,
                           SmallVectorImpl<Value *> &, NodeMapT &, GraphT &);

// Builds the graph + StratifiedSets for a function.
static FunctionInfo buildSetsFrom(CFLAliasAnalysis &, Function *);

static Optional<Function *> parentFunctionOfValue(Value *Val) {
  if (auto *Inst = dyn_cast<Instruction>(Val)) {
    auto *Bb = Inst->getParent();
    return Bb->getParent();
  }

  if (auto *Arg = dyn_cast<Argument>(Val))
    return Arg->getParent();
  return NoneType();
}

template <typename Inst>
static bool getPossibleTargets(Inst *Call,
                               SmallVectorImpl<Function *> &Output) {
  if (auto *Fn = Call->getCalledFunction()) {
    Output.push_back(Fn);
    return true;
  }

  // TODO: If the call is indirect, we might be able to enumerate all potential
  // targets of the call and return them, rather than just failing.
  return false;
}

static Optional<Value *> getTargetValue(Instruction *Inst) {
  GetTargetValueVisitor V;
  return V.visit(Inst);
}

static bool hasUsefulEdges(Instruction *Inst) {
  bool IsNonInvokeTerminator =
      isa<TerminatorInst>(Inst) && !isa<InvokeInst>(Inst);
  return !isa<CmpInst>(Inst) && !isa<FenceInst>(Inst) && !IsNonInvokeTerminator;
}

static Optional<StratifiedAttr> valueToAttrIndex(Value *Val) {
  if (isa<GlobalValue>(Val))
    return AttrGlobalIndex;

  if (auto *Arg = dyn_cast<Argument>(Val))
    if (!Arg->hasNoAliasAttr())
      return argNumberToAttrIndex(Arg->getArgNo());
  return NoneType();
}

static StratifiedAttr argNumberToAttrIndex(unsigned ArgNum) {
  if (ArgNum > AttrMaxNumArgs)
    return AttrAllIndex;
  return ArgNum + AttrFirstArgIndex;
}

static EdgeType flipWeight(EdgeType Initial) {
  switch (Initial) {
  case EdgeType::Assign:
    return EdgeType::Assign;
  case EdgeType::Dereference:
    return EdgeType::Reference;
  case EdgeType::Reference:
    return EdgeType::Dereference;
  }
  llvm_unreachable("Incomplete coverage of EdgeType enum");
}

static void argsToEdges(CFLAliasAnalysis &Analysis, Instruction *Inst,
                        SmallVectorImpl<Edge> &Output) {
  GetEdgesVisitor v(Analysis, Output);
  v.visit(Inst);
}

static Level directionOfEdgeType(EdgeType Weight) {
  switch (Weight) {
  case EdgeType::Reference:
    return Level::Above;
  case EdgeType::Dereference:
    return Level::Below;
  case EdgeType::Assign:
    return Level::Same;
  }
  llvm_unreachable("Incomplete switch coverage");
}

// Aside: We may remove graph construction entirely, because it doesn't really
// buy us much that we don't already have. I'd like to add interprocedural
// analysis prior to this however, in case that somehow requires the graph
// produced by this for efficient execution
static void buildGraphFrom(CFLAliasAnalysis &Analysis, Function *Fn,
                           SmallVectorImpl<Value *> &ReturnedValues,
                           NodeMapT &Map, GraphT &Graph) {
  const auto findOrInsertNode = [&Map, &Graph](Value *Val) {
    auto Pair = Map.insert(std::make_pair(Val, GraphT::Node()));
    auto &Iter = Pair.first;
    if (Pair.second) {
      auto NewNode = Graph.addNode();
      Iter->second = NewNode;
    }
    return Iter->second;
  };

  SmallVector<Edge, 8> Edges;
  for (auto &Bb : Fn->getBasicBlockList()) {
    for (auto &Inst : Bb.getInstList()) {
      // We don't want the edges of most "return" instructions, but we *do* want
      // to know what can be returned.
      if (auto *Ret = dyn_cast<ReturnInst>(&Inst))
        ReturnedValues.push_back(Ret);

      if (!hasUsefulEdges(&Inst))
        continue;

      Edges.clear();
      argsToEdges(Analysis, &Inst, Edges);

      // In the case of an unused alloca (or similar), edges may be empty. Note
      // that it exists so we can potentially answer NoAlias.
      if (Edges.empty()) {
        auto MaybeVal = getTargetValue(&Inst);
        assert(MaybeVal.hasValue());
        auto *Target = *MaybeVal;
        findOrInsertNode(Target);
        continue;
      }

      for (const Edge &E : Edges) {
        auto To = findOrInsertNode(E.To);
        auto From = findOrInsertNode(E.From);
        auto FlippedWeight = flipWeight(E.Weight);
        auto Attrs = E.AdditionalAttrs;
        Graph.addEdge(From, To, std::make_pair(E.Weight, Attrs),
                                std::make_pair(FlippedWeight, Attrs));
      }
    }
  }
}

static FunctionInfo buildSetsFrom(CFLAliasAnalysis &Analysis, Function *Fn) {
  NodeMapT Map;
  GraphT Graph;
  SmallVector<Value *, 4> ReturnedValues;

  buildGraphFrom(Analysis, Fn, ReturnedValues, Map, Graph);

  DenseMap<GraphT::Node, Value *> NodeValueMap;
  NodeValueMap.resize(Map.size());
  for (const auto &Pair : Map)
    NodeValueMap.insert(std::make_pair(Pair.second, Pair.first));

  const auto findValueOrDie = [&NodeValueMap](GraphT::Node Node) {
    auto ValIter = NodeValueMap.find(Node);
    assert(ValIter != NodeValueMap.end());
    return ValIter->second;
  };

  StratifiedSetsBuilder<Value *> Builder;

  SmallVector<GraphT::Node, 16> Worklist;
  for (auto &Pair : Map) {
    Worklist.clear();

    auto *Value = Pair.first;
    Builder.add(Value);
    auto InitialNode = Pair.second;
    Worklist.push_back(InitialNode);
    while (!Worklist.empty()) {
      auto Node = Worklist.pop_back_val();
      auto *CurValue = findValueOrDie(Node);
      if (isa<Constant>(CurValue) && !isa<GlobalValue>(CurValue))
        continue;

      for (const auto &EdgeTuple : Graph.edgesFor(Node)) {
        auto Weight = std::get<0>(EdgeTuple);
        auto Label = Weight.first;
        auto &OtherNode = std::get<1>(EdgeTuple);
        auto *OtherValue = findValueOrDie(OtherNode);

        if (isa<Constant>(OtherValue) && !isa<GlobalValue>(OtherValue))
          continue;

        bool Added;
        switch (directionOfEdgeType(Label)) {
        case Level::Above:
          Added = Builder.addAbove(CurValue, OtherValue);
          break;
        case Level::Below:
          Added = Builder.addBelow(CurValue, OtherValue);
          break;
        case Level::Same:
          Added = Builder.addWith(CurValue, OtherValue);
          break;
        }

        if (Added) {
          auto Aliasing = Weight.second;
          if (auto MaybeCurIndex = valueToAttrIndex(CurValue))
            Aliasing.set(*MaybeCurIndex);
          if (auto MaybeOtherIndex = valueToAttrIndex(OtherValue))
            Aliasing.set(*MaybeOtherIndex);
          Builder.noteAttributes(CurValue, Aliasing);
          Builder.noteAttributes(OtherValue, Aliasing);
          Worklist.push_back(OtherNode);
        }
      }
    }
  }

  // There are times when we end up with parameters not in our graph (i.e. if
  // it's only used as the condition of a branch). Other bits of code depend on
  // things that were present during construction being present in the graph.
  // So, we add all present arguments here.
  for (auto &Arg : Fn->args()) {
    Builder.add(&Arg);
  }

  return FunctionInfo(Builder.build(), std::move(ReturnedValues));
}

void CFLAliasAnalysis::scan(Function *Fn) {
  auto InsertPair = Cache.insert(std::make_pair(Fn, Optional<FunctionInfo>()));
  (void)InsertPair;
  assert(InsertPair.second &&
         "Trying to scan a function that has already been cached");

  FunctionInfo Info(buildSetsFrom(*this, Fn));
  Cache[Fn] = std::move(Info);
  Handles.push_front(FunctionHandle(Fn, this));
}

AliasAnalysis::AliasResult
CFLAliasAnalysis::query(const AliasAnalysis::Location &LocA,
                        const AliasAnalysis::Location &LocB) {
  auto *ValA = const_cast<Value *>(LocA.Ptr);
  auto *ValB = const_cast<Value *>(LocB.Ptr);

  Function *Fn = nullptr;
  auto MaybeFnA = parentFunctionOfValue(ValA);
  auto MaybeFnB = parentFunctionOfValue(ValB);
  if (!MaybeFnA.hasValue() && !MaybeFnB.hasValue()) {
    llvm_unreachable("Don't know how to extract the parent function "
                     "from values A or B");
  }

  if (MaybeFnA.hasValue()) {
    Fn = *MaybeFnA;
    assert((!MaybeFnB.hasValue() || *MaybeFnB == *MaybeFnA) &&
           "Interprocedural queries not supported");
  } else {
    Fn = *MaybeFnB;
  }

  assert(Fn != nullptr);
  auto &MaybeInfo = ensureCached(Fn);
  assert(MaybeInfo.hasValue());

  auto &Sets = MaybeInfo->Sets;
  auto MaybeA = Sets.find(ValA);
  if (!MaybeA.hasValue())
    return AliasAnalysis::MayAlias;

  auto MaybeB = Sets.find(ValB);
  if (!MaybeB.hasValue())
    return AliasAnalysis::MayAlias;

  auto SetA = *MaybeA;
  auto SetB = *MaybeB;

  if (SetA.Index == SetB.Index)
    return AliasAnalysis::PartialAlias;

  auto AttrsA = Sets.getLink(SetA.Index).Attrs;
  auto AttrsB = Sets.getLink(SetB.Index).Attrs;
  // Stratified set attributes are used as markets to signify whether a member
  // of a StratifiedSet (or a member of a set above the current set) has 
  // interacted with either arguments or globals. "Interacted with" meaning
  // its value may be different depending on the value of an argument or 
  // global. The thought behind this is that, because arguments and globals
  // may alias each other, if AttrsA and AttrsB have touched args/globals,
  // we must conservatively say that they alias. However, if at least one of 
  // the sets has no values that could legally be altered by changing the value 
  // of an argument or global, then we don't have to be as conservative.
  if (AttrsA.any() && AttrsB.any())
    return AliasAnalysis::MayAlias;

  return AliasAnalysis::NoAlias;
}
