//===- llvm/Analysis/IVUsers.h - Induction Variable Users -------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements bookkeeping for "interesting" users of expressions
// computed from induction variables.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_ANALYSIS_IVUSERS_H
#define LLVM_ANALYSIS_IVUSERS_H

#include "llvm/Analysis/LoopAnalysisManager.h"
#include "llvm/Analysis/LoopPass.h"
#include "llvm/Analysis/ScalarEvolutionNormalization.h"
#include "llvm/IR/ValueHandle.h"

namespace llvm {

class AssumptionCache;
class DominatorTree;
class Instruction;
class Value;
class ScalarEvolution;
class SCEV;
class IVUsers;
class DataLayout;

/// IVStrideUse - Keep track of one use of a strided induction variable.
/// The Expr member keeps track of the expression, User is the actual user
/// instruction of the operand, and 'OperandValToReplace' is the operand of
/// the User that is the use.
class IVStrideUse final : public CallbackVH, public ilist_node<IVStrideUse> {
  friend class IVUsers;
public:
  IVStrideUse(IVUsers *P, Instruction* U, Value *O)
    : CallbackVH(U), Parent(P), OperandValToReplace(O) {
  }

  /// getUser - Return the user instruction for this use.
  Instruction *getUser() const {
    return cast<Instruction>(getValPtr());
  }

  /// setUser - Assign a new user instruction for this use.
  void setUser(Instruction *NewUser) {
    setValPtr(NewUser);
  }

  /// getOperandValToReplace - Return the Value of the operand in the user
  /// instruction that this IVStrideUse is representing.
  Value *getOperandValToReplace() const {
    return OperandValToReplace;
  }

  /// setOperandValToReplace - Assign a new Value as the operand value
  /// to replace.
  void setOperandValToReplace(Value *Op) {
    OperandValToReplace = Op;
  }

  /// getPostIncLoops - Return the set of loops for which the expression has
  /// been adjusted to use post-inc mode.
  const PostIncLoopSet &getPostIncLoops() const {
    return PostIncLoops;
  }

  /// transformToPostInc - Transform the expression to post-inc form for the
  /// given loop.
  void transformToPostInc(const Loop *L);

private:
  /// Parent - a pointer to the IVUsers that owns this IVStrideUse.
  IVUsers *Parent;

  /// OperandValToReplace - The Value of the operand in the user instruction
  /// that this IVStrideUse is representing.
  WeakVH OperandValToReplace;

  /// PostIncLoops - The set of loops for which Expr has been adjusted to
  /// use post-inc mode. This corresponds with SCEVExpander's post-inc concept.
  PostIncLoopSet PostIncLoops;

  /// Deleted - Implementation of CallbackVH virtual function to
  /// receive notification when the User is deleted.
  void deleted() override;
};

class IVUsers {
  friend class IVStrideUse;
  Loop *L;
  AssumptionCache *AC;
  LoopInfo *LI;
  DominatorTree *DT;
  ScalarEvolution *SE;
  SmallPtrSet<Instruction*, 16> Processed;

  /// IVUses - A list of all tracked IV uses of induction variable expressions
  /// we are interested in.
  ilist<IVStrideUse> IVUses;

  // Ephemeral values used by @llvm.assume in this function.
  SmallPtrSet<const Value *, 32> EphValues;

public:
  IVUsers(Loop *L, AssumptionCache *AC, LoopInfo *LI, DominatorTree *DT,
          ScalarEvolution *SE);

  IVUsers(IVUsers &&X)
      : L(std::move(X.L)), AC(std::move(X.AC)), DT(std::move(X.DT)),
        SE(std::move(X.SE)), Processed(std::move(X.Processed)),
        IVUses(std::move(X.IVUses)), EphValues(std::move(X.EphValues)) {
    for (IVStrideUse &U : IVUses)
      U.Parent = this;
  }
  IVUsers(const IVUsers &) = delete;
  IVUsers &operator=(IVUsers &&) = delete;
  IVUsers &operator=(const IVUsers &) = delete;

  Loop *getLoop() const { return L; }

  /// AddUsersIfInteresting - Inspect the specified Instruction.  If it is a
  /// reducible SCEV, recursively add its users to the IVUsesByStride set and
  /// return true.  Otherwise, return false.
  bool AddUsersIfInteresting(Instruction *I);

  IVStrideUse &AddUser(Instruction *User, Value *Operand);

  /// getReplacementExpr - Return a SCEV expression which computes the
  /// value of the OperandValToReplace of the given IVStrideUse.
  const SCEV *getReplacementExpr(const IVStrideUse &IU) const;

  /// getExpr - Return the expression for the use.
  const SCEV *getExpr(const IVStrideUse &IU) const;

  const SCEV *getStride(const IVStrideUse &IU, const Loop *L) const;

  typedef ilist<IVStrideUse>::iterator iterator;
  typedef ilist<IVStrideUse>::const_iterator const_iterator;
  iterator begin() { return IVUses.begin(); }
  iterator end()   { return IVUses.end(); }
  const_iterator begin() const { return IVUses.begin(); }
  const_iterator end() const   { return IVUses.end(); }
  bool empty() const { return IVUses.empty(); }

  bool isIVUserOrOperand(Instruction *Inst) const {
    return Processed.count(Inst);
  }

  void releaseMemory();

  void print(raw_ostream &OS, const Module * = nullptr) const;

  /// dump - This method is used for debugging.
  void dump() const;

protected:
  bool AddUsersImpl(Instruction *I, SmallPtrSetImpl<Loop*> &SimpleLoopNests);
};

Pass *createIVUsersPass();

class IVUsersWrapperPass : public LoopPass {
  std::unique_ptr<IVUsers> IU;

public:
  static char ID;

  IVUsersWrapperPass();

  IVUsers &getIU() { return *IU; }
  const IVUsers &getIU() const { return *IU; }

  void getAnalysisUsage(AnalysisUsage &AU) const override;

  bool runOnLoop(Loop *L, LPPassManager &LPM) override;

  void releaseMemory() override;

  void print(raw_ostream &OS, const Module * = nullptr) const override;
};

/// Analysis pass that exposes the \c IVUsers for a loop.
class IVUsersAnalysis : public AnalysisInfoMixin<IVUsersAnalysis> {
  friend AnalysisInfoMixin<IVUsersAnalysis>;
  static AnalysisKey Key;

public:
  typedef IVUsers Result;

  IVUsers run(Loop &L, LoopAnalysisManager &AM,
              LoopStandardAnalysisResults &AR);
};

}

#endif
