//===------ Support/ScopHelper.h -- Some Helper Functions for Scop. -------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Small functions that help with LLVM-IR.
//
//===----------------------------------------------------------------------===//

#ifndef POLLY_SUPPORT_IRHELPER_H
#define POLLY_SUPPORT_IRHELPER_H

#include "llvm/ADT/SetVector.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/ValueHandle.h"
#include "isl/isl-noexceptions.h"
#include <optional>

namespace llvm {
class LoopInfo;
class Loop;
class ScalarEvolution;
class SCEV;
class Region;
class Pass;
class DominatorTree;
class RegionInfo;
class RegionNode;
} // namespace llvm

namespace polly {
class Scop;
class ScopStmt;

/// Enumeration of assumptions Polly can take.
enum AssumptionKind {
  ALIASING,
  INBOUNDS,
  WRAPPING,
  UNSIGNED,
  PROFITABLE,
  ERRORBLOCK,
  COMPLEXITY,
  INFINITELOOP,
  INVARIANTLOAD,
  DELINEARIZATION,
};

/// Enum to distinguish between assumptions and restrictions.
enum AssumptionSign { AS_ASSUMPTION, AS_RESTRICTION };

/// Helper struct to remember assumptions.
struct Assumption {
  /// The kind of the assumption (e.g., WRAPPING).
  AssumptionKind Kind;

  /// Flag to distinguish assumptions and restrictions.
  AssumptionSign Sign;

  /// The valid/invalid context if this is an assumption/restriction.
  isl::set Set;

  /// The location that caused this assumption.
  llvm::DebugLoc Loc;

  /// An optional block whose domain can simplify the assumption.
  llvm::BasicBlock *BB;

  // Whether the assumption must be checked at runtime.
  bool RequiresRTC;
};

using RecordedAssumptionsTy = llvm::SmallVector<Assumption, 8>;

/// Record an assumption for later addition to the assumed context.
///
/// This function will add the assumption to the RecordedAssumptions. This
/// collection will be added (@see addAssumption) to the assumed context once
/// all paramaters are known and the context is fully built.
///
/// @param RecordedAssumption container which keeps all recorded assumptions.
/// @param Kind The assumption kind describing the underlying cause.
/// @param Set  The relations between parameters that are assumed to hold.
/// @param Loc  The location in the source that caused this assumption.
/// @param Sign Enum to indicate if the assumptions in @p Set are positive
///             (needed/assumptions) or negative (invalid/restrictions).
/// @param BB   The block in which this assumption was taken. If it is
///             set, the domain of that block will be used to simplify the
///             actual assumption in @p Set once it is added. This is useful
///             if the assumption was created prior to the domain.
/// @param RTC  Does the assumption require a runtime check?
void recordAssumption(RecordedAssumptionsTy *RecordedAssumptions,
                      AssumptionKind Kind, isl::set Set, llvm::DebugLoc Loc,
                      AssumptionSign Sign, llvm::BasicBlock *BB = nullptr,
                      bool RTC = true);

/// Type to remap values.
using ValueMapT = llvm::DenseMap<llvm::AssertingVH<llvm::Value>,
                                 llvm::AssertingVH<llvm::Value>>;

/// Type for a set of invariant loads.
using InvariantLoadsSetTy = llvm::SetVector<llvm::AssertingVH<llvm::LoadInst>>;

/// Set type for parameters.
using ParameterSetTy = llvm::SetVector<const llvm::SCEV *>;

/// Set of loops (used to remember loops in non-affine subregions).
using BoxedLoopsSetTy = llvm::SetVector<const llvm::Loop *>;

/// Utility proxy to wrap the common members of LoadInst and StoreInst.
///
/// This works like the LLVM utility class CallSite, ie. it forwards all calls
/// to either a LoadInst, StoreInst, MemIntrinsic or MemTransferInst.
/// It is similar to LLVM's utility classes IntrinsicInst, MemIntrinsic,
/// MemTransferInst, etc. in that it offers a common interface, but does not act
/// as a fake base class.
/// It is similar to StringRef and ArrayRef in that it holds a pointer to the
/// referenced object and should be passed by-value as it is small enough.
///
/// This proxy can either represent a LoadInst instance, a StoreInst instance,
/// a MemIntrinsic instance (memset, memmove, memcpy), a CallInst instance or a
/// nullptr (only creatable using the default constructor); never an Instruction
/// that is neither of the above mentioned. When representing a nullptr, only
/// the following methods are defined:
/// isNull(), isInstruction(), isLoad(), isStore(), ..., isMemTransferInst(),
/// operator bool(), operator!()
///
/// The functions isa, cast, cast_or_null, dyn_cast are modeled te resemble
/// those from llvm/Support/Casting.h. Partial template function specialization
/// is currently not supported in C++ such that those cannot be used directly.
/// (llvm::isa could, but then llvm:cast etc. would not have the expected
/// behavior)
class MemAccInst final {
private:
  llvm::Instruction *I;

public:
  MemAccInst() : I(nullptr) {}
  MemAccInst(const MemAccInst &Inst) : I(Inst.I) {}
  /* implicit */ MemAccInst(llvm::LoadInst &LI) : I(&LI) {}
  /* implicit */ MemAccInst(llvm::LoadInst *LI) : I(LI) {}
  /* implicit */ MemAccInst(llvm::StoreInst &SI) : I(&SI) {}
  /* implicit */ MemAccInst(llvm::StoreInst *SI) : I(SI) {}
  /* implicit */ MemAccInst(llvm::MemIntrinsic *MI) : I(MI) {}
  /* implicit */ MemAccInst(llvm::CallInst *CI) : I(CI) {}
  explicit MemAccInst(llvm::Instruction &I) : I(&I) { assert(isa(I)); }
  explicit MemAccInst(llvm::Instruction *I) : I(I) { assert(isa(I)); }

  static bool isa(const llvm::Value &V) {
    return llvm::isa<llvm::LoadInst>(V) || llvm::isa<llvm::StoreInst>(V) ||
           llvm::isa<llvm::CallInst>(V) || llvm::isa<llvm::MemIntrinsic>(V);
  }
  static bool isa(const llvm::Value *V) {
    return llvm::isa<llvm::LoadInst>(V) || llvm::isa<llvm::StoreInst>(V) ||
           llvm::isa<llvm::CallInst>(V) || llvm::isa<llvm::MemIntrinsic>(V);
  }
  static MemAccInst cast(llvm::Value &V) {
    return MemAccInst(llvm::cast<llvm::Instruction>(V));
  }
  static MemAccInst cast(llvm::Value *V) {
    return MemAccInst(llvm::cast<llvm::Instruction>(V));
  }
  static MemAccInst cast_or_null(llvm::Value &V) {
    return MemAccInst(llvm::cast<llvm::Instruction>(V));
  }
  static MemAccInst cast_or_null(llvm::Value *V) {
    if (!V)
      return MemAccInst();
    return MemAccInst(llvm::cast<llvm::Instruction>(V));
  }
  static MemAccInst dyn_cast(llvm::Value &V) {
    if (isa(V))
      return MemAccInst(llvm::cast<llvm::Instruction>(V));
    return MemAccInst();
  }
  static MemAccInst dyn_cast(llvm::Value *V) {
    assert(V);
    if (isa(V))
      return MemAccInst(llvm::cast<llvm::Instruction>(V));
    return MemAccInst();
  }

  MemAccInst &operator=(const MemAccInst &Inst) {
    I = Inst.I;
    return *this;
  }
  MemAccInst &operator=(llvm::LoadInst &LI) {
    I = &LI;
    return *this;
  }
  MemAccInst &operator=(llvm::LoadInst *LI) {
    I = LI;
    return *this;
  }
  MemAccInst &operator=(llvm::StoreInst &SI) {
    I = &SI;
    return *this;
  }
  MemAccInst &operator=(llvm::StoreInst *SI) {
    I = SI;
    return *this;
  }
  MemAccInst &operator=(llvm::MemIntrinsic &MI) {
    I = &MI;
    return *this;
  }
  MemAccInst &operator=(llvm::MemIntrinsic *MI) {
    I = MI;
    return *this;
  }
  MemAccInst &operator=(llvm::CallInst &CI) {
    I = &CI;
    return *this;
  }
  MemAccInst &operator=(llvm::CallInst *CI) {
    I = CI;
    return *this;
  }

  llvm::Instruction *get() const {
    assert(I && "Unexpected nullptr!");
    return I;
  }
  operator llvm::Instruction *() const { return asInstruction(); }
  llvm::Instruction *operator->() const { return get(); }

  explicit operator bool() const { return isInstruction(); }
  bool operator!() const { return isNull(); }

  llvm::Value *getValueOperand() const {
    if (isLoad())
      return asLoad();
    if (isStore())
      return asStore()->getValueOperand();
    if (isMemIntrinsic())
      return nullptr;
    if (isCallInst())
      return nullptr;
    llvm_unreachable("Operation not supported on nullptr");
  }
  llvm::Value *getPointerOperand() const {
    if (isLoad())
      return asLoad()->getPointerOperand();
    if (isStore())
      return asStore()->getPointerOperand();
    if (isMemIntrinsic())
      return asMemIntrinsic()->getRawDest();
    if (isCallInst())
      return nullptr;
    llvm_unreachable("Operation not supported on nullptr");
  }
  bool isVolatile() const {
    if (isLoad())
      return asLoad()->isVolatile();
    if (isStore())
      return asStore()->isVolatile();
    if (isMemIntrinsic())
      return asMemIntrinsic()->isVolatile();
    if (isCallInst())
      return false;
    llvm_unreachable("Operation not supported on nullptr");
  }
  bool isSimple() const {
    if (isLoad())
      return asLoad()->isSimple();
    if (isStore())
      return asStore()->isSimple();
    if (isMemIntrinsic())
      return !asMemIntrinsic()->isVolatile();
    if (isCallInst())
      return true;
    llvm_unreachable("Operation not supported on nullptr");
  }
  llvm::AtomicOrdering getOrdering() const {
    if (isLoad())
      return asLoad()->getOrdering();
    if (isStore())
      return asStore()->getOrdering();
    if (isMemIntrinsic())
      return llvm::AtomicOrdering::NotAtomic;
    if (isCallInst())
      return llvm::AtomicOrdering::NotAtomic;
    llvm_unreachable("Operation not supported on nullptr");
  }
  bool isUnordered() const {
    if (isLoad())
      return asLoad()->isUnordered();
    if (isStore())
      return asStore()->isUnordered();
    // Copied from the Load/Store implementation of isUnordered:
    if (isMemIntrinsic())
      return !asMemIntrinsic()->isVolatile();
    if (isCallInst())
      return true;
    llvm_unreachable("Operation not supported on nullptr");
  }

  bool isNull() const { return !I; }
  bool isInstruction() const { return I; }

  llvm::Instruction *asInstruction() const { return I; }

  bool isLoad() const { return I && llvm::isa<llvm::LoadInst>(I); }
  bool isStore() const { return I && llvm::isa<llvm::StoreInst>(I); }
  bool isCallInst() const { return I && llvm::isa<llvm::CallInst>(I); }
  bool isMemIntrinsic() const { return I && llvm::isa<llvm::MemIntrinsic>(I); }
  bool isMemSetInst() const { return I && llvm::isa<llvm::MemSetInst>(I); }
  bool isMemTransferInst() const {
    return I && llvm::isa<llvm::MemTransferInst>(I);
  }

  llvm::LoadInst *asLoad() const { return llvm::cast<llvm::LoadInst>(I); }
  llvm::StoreInst *asStore() const { return llvm::cast<llvm::StoreInst>(I); }
  llvm::CallInst *asCallInst() const { return llvm::cast<llvm::CallInst>(I); }
  llvm::MemIntrinsic *asMemIntrinsic() const {
    return llvm::cast<llvm::MemIntrinsic>(I);
  }
  llvm::MemSetInst *asMemSetInst() const {
    return llvm::cast<llvm::MemSetInst>(I);
  }
  llvm::MemTransferInst *asMemTransferInst() const {
    return llvm::cast<llvm::MemTransferInst>(I);
  }
};
} // namespace polly

namespace llvm {
/// Specialize simplify_type for MemAccInst to enable dyn_cast and cast
///        from a MemAccInst object.
template <> struct simplify_type<polly::MemAccInst> {
  typedef Instruction *SimpleType;
  static SimpleType getSimplifiedValue(polly::MemAccInst &I) {
    return I.asInstruction();
  }
};
} // namespace llvm

namespace polly {

/// Simplify the region to have a single unconditional entry edge and a
/// single exit edge.
///
/// Although this function allows DT and RI to be null, regions only work
/// properly if the DominatorTree (for Region::contains) and RegionInfo are kept
/// up-to-date.
///
/// @param R  The region to be simplified
/// @param DT DominatorTree to be updated.
/// @param LI LoopInfo to be updated.
/// @param RI RegionInfo to be updated.
void simplifyRegion(llvm::Region *R, llvm::DominatorTree *DT,
                    llvm::LoopInfo *LI, llvm::RegionInfo *RI);

/// Split the entry block of a function to store the newly inserted
///        allocations outside of all Scops.
///
/// @param EntryBlock The entry block of the current function.
/// @param P          The pass that currently running.
///
void splitEntryBlockForAlloca(llvm::BasicBlock *EntryBlock, llvm::Pass *P);

/// Split the entry block of a function to store the newly inserted
///        allocations outside of all Scops.
///
/// @param DT DominatorTree to be updated.
/// @param LI LoopInfo to be updated.
/// @param RI RegionInfo to be updated.
void splitEntryBlockForAlloca(llvm::BasicBlock *EntryBlock,
                              llvm::DominatorTree *DT, llvm::LoopInfo *LI,
                              llvm::RegionInfo *RI);

/// Wrapper for SCEVExpander extended to all Polly features.
///
/// This wrapper will internally call the SCEVExpander but also makes sure that
/// all additional features not represented in SCEV (e.g., SDiv/SRem are not
/// black boxes but can be part of the function) will be expanded correctly.
///
/// The parameters are the same as for the creation of a SCEVExpander as well
/// as the call to SCEVExpander::expandCodeFor:
///
/// @param S     The current Scop.
/// @param SE    The Scalar Evolution pass.
/// @param DL    The module data layout.
/// @param Name  The suffix added to the new instruction names.
/// @param E     The expression for which code is actually generated.
/// @param Ty    The type of the resulting code.
/// @param IP    The insertion point for the new code.
/// @param VMap  A remapping of values used in @p E.
/// @param RTCBB The last block of the RTC. Used to insert loop-invariant
///              instructions in rare cases.
llvm::Value *expandCodeFor(Scop &S, llvm::ScalarEvolution &SE,
                           const llvm::DataLayout &DL, const char *Name,
                           const llvm::SCEV *E, llvm::Type *Ty,
                           llvm::Instruction *IP, ValueMapT *VMap,
                           llvm::BasicBlock *RTCBB);

/// Return the condition for the terminator @p TI.
///
/// For unconditional branches the "i1 true" condition will be returned.
///
/// @param TI The terminator to get the condition from.
///
/// @return The condition of @p TI and nullptr if none could be extracted.
llvm::Value *getConditionFromTerminator(llvm::Instruction *TI);

/// Get the smallest loop that contains @p S but is not in @p S.
llvm::Loop *getLoopSurroundingScop(Scop &S, llvm::LoopInfo &LI);

/// Get the number of blocks in @p L.
///
/// The number of blocks in a loop are the number of basic blocks actually
/// belonging to the loop, as well as all single basic blocks that the loop
/// exits to and which terminate in an unreachable instruction. We do not
/// allow such basic blocks in the exit of a scop, hence they belong to the
/// scop and represent run-time conditions which we want to model and
/// subsequently speculate away.
///
/// @see getRegionNodeLoop for additional details.
unsigned getNumBlocksInLoop(llvm::Loop *L);

/// Get the number of blocks in @p RN.
unsigned getNumBlocksInRegionNode(llvm::RegionNode *RN);

/// Return the smallest loop surrounding @p RN.
llvm::Loop *getRegionNodeLoop(llvm::RegionNode *RN, llvm::LoopInfo &LI);

/// Check if @p LInst can be hoisted in @p R.
///
/// @param LInst The load to check.
/// @param R     The analyzed region.
/// @param LI    The loop info.
/// @param SE    The scalar evolution analysis.
/// @param DT    The dominator tree of the function.
/// @param KnownInvariantLoads The invariant load set.
///
/// @return True if @p LInst can be hoisted in @p R.
bool isHoistableLoad(llvm::LoadInst *LInst, llvm::Region &R, llvm::LoopInfo &LI,
                     llvm::ScalarEvolution &SE, const llvm::DominatorTree &DT,
                     const InvariantLoadsSetTy &KnownInvariantLoads);

/// Return true iff @p V is an intrinsic that we ignore during code
///        generation.
bool isIgnoredIntrinsic(const llvm::Value *V);

/// Check whether a value an be synthesized by the code generator.
///
/// Some value will be recalculated only from information that is code generated
/// from the polyhedral representation. For such instructions we do not need to
/// ensure that their operands are available during code generation.
///
/// @param V The value to check.
/// @param S The current SCoP.
/// @param SE The scalar evolution database.
/// @param Scope Location where the value would by synthesized.
/// @return If the instruction I can be regenerated from its
///         scalar evolution representation, return true,
///         otherwise return false.
bool canSynthesize(const llvm::Value *V, const Scop &S,
                   llvm::ScalarEvolution *SE, llvm::Loop *Scope);

/// Return the block in which a value is used.
///
/// For normal instructions, this is the instruction's parent block. For PHI
/// nodes, this is the incoming block of that use, because this is where the
/// operand must be defined (i.e. its definition dominates this block).
/// Non-instructions do not use operands at a specific point such that in this
/// case this function returns nullptr.
llvm::BasicBlock *getUseBlock(const llvm::Use &U);

// If the loop is nonaffine/boxed, return the first non-boxed surrounding loop
// for Polly. If the loop is affine, return the loop itself.
//
// @param L             Pointer to the Loop object to analyze.
// @param LI            Reference to the LoopInfo.
// @param BoxedLoops    Set of Boxed Loops we get from the SCoP.
llvm::Loop *getFirstNonBoxedLoopFor(llvm::Loop *L, llvm::LoopInfo &LI,
                                    const BoxedLoopsSetTy &BoxedLoops);

// If the Basic Block belongs to a loop that is nonaffine/boxed, return the
// first non-boxed surrounding loop for Polly. If the loop is affine, return
// the loop itself.
//
// @param BB            Pointer to the Basic Block to analyze.
// @param LI            Reference to the LoopInfo.
// @param BoxedLoops    Set of Boxed Loops we get from the SCoP.
llvm::Loop *getFirstNonBoxedLoopFor(llvm::BasicBlock *BB, llvm::LoopInfo &LI,
                                    const BoxedLoopsSetTy &BoxedLoops);

/// Is the given instruction a call to a debug function?
///
/// A debug function can be used to insert output in Polly-optimized code which
/// normally does not allow function calls with side-effects. For instance, a
/// printf can be inserted to check whether a value still has the expected value
/// after Polly generated code:
///
///     int sum = 0;
///     for (int i = 0; i < 16; i+=1) {
///       sum += i;
///       printf("The value of sum at i=%d is %d\n", sum, i);
///     }
bool isDebugCall(llvm::Instruction *Inst);

/// Does the statement contain a call to a debug function?
///
/// Such a statement must not be removed, even if has no side-effects.
bool hasDebugCall(ScopStmt *Stmt);

/// Find a property value in a LoopID.
///
/// Generally, a property MDNode has the format
///
///   !{ !"Name", value }
///
/// In which case the value is returned.
///
/// If the property is just
///
///   !{ !"Name" }
///
/// Then `nullptr` is set to mark the property is existing, but does not carry
/// any value. If the property does not exist, `None` is returned.
std::optional<llvm::Metadata *> findMetadataOperand(llvm::MDNode *LoopMD,
                                                    llvm::StringRef Name);

/// Find a boolean property value in a LoopID. The value not being defined is
/// interpreted as a false value.
bool getBooleanLoopAttribute(llvm::MDNode *LoopID, llvm::StringRef Name);

/// Find an integers property value in a LoopID.
std::optional<int> getOptionalIntLoopAttribute(llvm::MDNode *LoopID,
                                               llvm::StringRef Name);

/// Does the loop's LoopID contain a 'llvm.loop.disable_heuristics' property?
///
/// This is equivalent to llvm::hasDisableAllTransformsHint(Loop*), but
/// including the LoopUtils.h header indirectly also declares llvm::MemoryAccess
/// which clashes with polly::MemoryAccess. Declaring this alias here avoid
/// having to include LoopUtils.h in other files.
bool hasDisableAllTransformsHint(llvm::Loop *L);
bool hasDisableAllTransformsHint(llvm::MDNode *LoopID);

/// Represent the attributes of a loop.
struct BandAttr {
  /// LoopID which stores the properties of the loop, such as transformations to
  /// apply and the metadata of followup-loops.
  ///
  /// Cannot be used to identify a loop. Two different loops can have the same
  /// metadata.
  llvm::MDNode *Metadata = nullptr;

  /// The LoopInfo reference for this loop.
  ///
  /// Only loops from the original IR are represented by LoopInfo. Loops that
  /// were generated by Polly are not tracked by LoopInfo.
  llvm::Loop *OriginalLoop = nullptr;
};

/// Get an isl::id representing a loop.
///
/// This takes the ownership of the BandAttr and will be free'd when the
/// returned isl::Id is free'd.
isl::id getIslLoopAttr(isl::ctx Ctx, BandAttr *Attr);

/// Create an isl::id that identifies an original loop.
///
/// Return nullptr if the loop does not need a BandAttr (i.e. has no
/// properties);
///
/// This creates a BandAttr which must be unique per loop and therefore this
/// must not be called multiple times on the same loop as their id would be
/// different.
isl::id createIslLoopAttr(isl::ctx Ctx, llvm::Loop *L);

/// Is @p Id representing a loop?
///
/// Such ids contain a polly::BandAttr as its user pointer.
bool isLoopAttr(const isl::id &Id);

/// Return the BandAttr of a loop's isl::id.
BandAttr *getLoopAttr(const isl::id &Id);

} // namespace polly
#endif
