//===- LoopVectorizationPlanner.h - Planner for LoopVectorization ---------===//
//
// 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
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file provides a LoopVectorizationPlanner class.
/// InnerLoopVectorizer vectorizes loops which contain only one basic
/// LoopVectorizationPlanner - drives the vectorization process after having
/// passed Legality checks.
/// The planner builds and optimizes the Vectorization Plans which record the
/// decisions how to vectorize the given loop. In particular, represent the
/// control-flow of the vectorized version, the replication of instructions that
/// are to be scalarized, and interleave access groups.
///
/// Also provides a VPlan-based builder utility analogous to IRBuilder.
/// It provides an instruction-level API for generating VPInstructions while
/// abstracting away the Recipe manipulation details.
//===----------------------------------------------------------------------===//

#ifndef LLVM_TRANSFORMS_VECTORIZE_LOOPVECTORIZATIONPLANNER_H
#define LLVM_TRANSFORMS_VECTORIZE_LOOPVECTORIZATIONPLANNER_H

#include "VPlan.h"
#include "VPlanUtils.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/Support/InstructionCost.h"
#include <optional>

namespace {
class GeneratedRTChecks;
}

namespace llvm {

class BranchProbabilityInfo;
class LoopInfo;
class DominatorTree;
class LoopVectorizationLegality;
class LoopVectorizationCostModel;
class PredicatedScalarEvolution;
class LoopVectorizeHints;
class RecurrenceDescriptor;
class LoopVersioning;
class OptimizationRemarkEmitter;
class TargetLibraryInfo;
class VPRecipeBuilder;
struct VPRegisterUsage;
struct VFRange;

/// \return An upper bound for vscale based on TTI or the vscale_range
/// attribute.
std::optional<unsigned> getMaxVScale(const Function &F);

/// \return The upper bound for the runtime value of \p EC, or std::nullopt
/// if the upper bound is unknown.
std::optional<uint64_t>
getMaxRuntimeElementCount(ElementCount EC, const Function &F);

// Utility functions that are used by different vectorization classes
namespace LoopVectorizationUtils {

/// Reports a vectorization failure: print \p DebugMsg for debugging
/// purposes along with the corresponding optimization remark \p RemarkName.
/// If \p I is passed, it is an instruction that prevents vectorization.
/// Otherwise, the loop \p TheLoop is used for the location of the remark.
void reportVectorizationFailure(const StringRef DebugMsg,
                                const StringRef OREMsg, const StringRef ORETag,
                                OptimizationRemarkEmitter *ORE,
                                const Loop *TheLoop, Instruction *I = nullptr);

/// Same as above, but the debug message and optimization remark are identical
inline void reportVectorizationFailure(const StringRef DebugMsg,
                                       const StringRef ORETag,
                                       OptimizationRemarkEmitter *ORE,
                                       const Loop *TheLoop,
                                       Instruction *I = nullptr) {
  reportVectorizationFailure(DebugMsg, DebugMsg, ORETag, ORE, TheLoop, I);
}

/// Reports an informative message: print \p Msg for debugging purposes as well
/// as an optimization remark. Uses either \p I as location of the remark, or
/// otherwise \p TheLoop. If \p DL is passed, use it as debug location for the
/// remark.
void reportVectorizationInfo(const StringRef Msg, const StringRef ORETag,
                             OptimizationRemarkEmitter *ORE,
                             const Loop *TheLoop, Instruction *I = nullptr,
                             DebugLoc DL = {});

/// Report successful vectorization of the loop. In case an outer loop is
/// vectorized, prepend "outer" to the vectorization remark.
void reportVectorization(OptimizationRemarkEmitter *ORE, Loop *TheLoop,
                         ElementCount VFWidth, unsigned IC);

} // namespace LoopVectorizationUtils

/// Default inserter for VPBuilderBase, inserting \p R at \p It in \p VPBB.
struct VPBuilderDefaultInserter {
  void insertHelper(VPRecipeBase *R, VPBasicBlock *VPBB,
                    VPBasicBlock::iterator It) {
    VPBB->insert(R, It);
  }
};

/// VPlan-based builder utility similar to IRBuilder. Recipes are inserted via
/// \p InserterTy.
template <typename InserterTy> class VPBuilderBase : public InserterTy {
private:
  class VPInsertPoint {
    VPBasicBlock *Block = nullptr;
    VPBasicBlock::iterator Iterator;

  public:
    /// Creates a new insertion point which doesn't point to anything.
    VPInsertPoint() = default;

    /// Creates a new insertion point to insert at \p Iterator in \p Block.
    VPInsertPoint(VPBasicBlock *Block, VPBasicBlock::iterator Iterator)
        : Block(Block), Iterator(Iterator) {}

    /// Creates a new insertion point to insert before \p R.
    VPInsertPoint(VPRecipeBase *R)
        : Block(R->getParent()), Iterator(R->getIterator()) {}

    /// Creates a new insertion point to insert at the end of \p Block.
    VPInsertPoint(VPBasicBlock *Block) : Block(Block), Iterator(Block->end()) {}

    /// Returns true if this insert point is set.
    operator bool() const { return Block; }

    VPBasicBlock *getBlock() const { return Block; }
    VPBasicBlock::iterator getIterator() const { return Iterator; }

    operator VPRecipeBase *() const {
      return Iterator == Block->end() ? nullptr : &*Iterator;
    }
  };

  VPInsertPoint InsertPt;

protected:
  /// Insert \p VPI in BB at InsertPt if BB is set.
  template <typename T> T *tryInsertInstruction(T *R) {
    if (InsertPt)
      InserterTy::insertHelper(R, InsertPt.getBlock(), InsertPt.getIterator());
    return R;
  }

  VPInstruction *createInstruction(unsigned Opcode,
                                   ArrayRef<VPValue *> Operands,
                                   const VPIRMetadata &MD, DebugLoc DL,
                                   const Twine &Name = "") {
    return tryInsertInstruction(
        new VPInstruction(Opcode, Operands, {}, MD, DL, Name));
  }

public:
  VPlan &getPlan() const {
    assert(InsertPt && "Insert block must be set");
    return *InsertPt.getBlock()->getPlan();
  }

  VPBuilderBase() = default;
  VPBuilderBase(const VPInsertPoint &IP) : InsertPt(IP) {}
  VPBuilderBase(InserterTy Inserter) : InserterTy(Inserter) {}
  VPBuilderBase(VPBasicBlock *TheBB, VPBasicBlock::iterator IP)
      : InsertPt(TheBB, IP) {}

  /// Get the recipe at the current insert point or nullptr if the insert point
  /// is the end of the block.
  VPRecipeBase *getRecipeAtInsertPoint() const { return InsertPt; }

  /// Create a builder to insert after \p R.
  static VPBuilderBase getToInsertAfter(VPRecipeBase *R) {
    return {R->getParent(), std::next(R->getIterator())};
  }

  /// Sets the current insert point to a previously-saved location.
  void restoreIP(VPInsertPoint IP) { InsertPt = IP; }

  /// Set the current insert point.
  void setInsertPoint(const VPInsertPoint &IP) {
    assert(IP && "Attempting to set a null insert point");
    InsertPt = IP;
  }
  void setInsertPoint(VPBasicBlock *TheBB, VPBasicBlock::iterator IP) {
    assert(TheBB && "Attempting to set a null insert point");
    InsertPt = VPInsertPoint(TheBB, IP);
  }

  /// Insert \p R at the current insertion point. Returns \p R unchanged.
  template <typename T> [[maybe_unused]] T *insert(T *R) {
    InserterTy::insertHelper(R, InsertPt.getBlock(), InsertPt.getIterator());
    return R;
  }

  /// Create an N-ary operation with \p Opcode, \p Operands and set \p Inst as
  /// its underlying Instruction.
  VPInstruction *createNaryOp(unsigned Opcode, ArrayRef<VPValue *> Operands,
                              Instruction *Inst = nullptr,
                              const VPIRFlags &Flags = {},
                              const VPIRMetadata &MD = {},
                              DebugLoc DL = DebugLoc::getUnknown(),
                              const Twine &Name = "",
                              Type *ResultTy = nullptr) {
    VPInstruction *NewVPInst = tryInsertInstruction(
        new VPInstruction(Opcode, Operands, Flags, MD, DL, Name, ResultTy));
    NewVPInst->setUnderlyingValue(Inst);
    return NewVPInst;
  }
  VPInstruction *createNaryOp(unsigned Opcode, ArrayRef<VPValue *> Operands,
                              DebugLoc DL, const Twine &Name = "") {
    return createInstruction(Opcode, Operands, {}, DL, Name);
  }
  VPInstruction *createNaryOp(unsigned Opcode, ArrayRef<VPValue *> Operands,
                              const VPIRFlags &Flags,
                              DebugLoc DL = DebugLoc::getUnknown(),
                              const Twine &Name = "") {
    return tryInsertInstruction(
        new VPInstruction(Opcode, Operands, Flags, {}, DL, Name));
  }

  VPInstruction *createNaryOp(unsigned Opcode, ArrayRef<VPValue *> Operands,
                              Type *ResultTy, const VPIRFlags &Flags = {},
                              DebugLoc DL = DebugLoc::getUnknown(),
                              const Twine &Name = "") {
    return tryInsertInstruction(
        new VPInstruction(Opcode, Operands, Flags, {}, DL, Name, ResultTy));
  }

  VPInstruction *createFirstActiveLane(ArrayRef<VPValue *> Masks,
                                       DebugLoc DL = DebugLoc::getUnknown(),
                                       const Twine &Name = "") {
    // Assume that the maximum possible number of elements in a vector fits
    // within the index type for the default address space.
    VPlan &Plan = getPlan();
    Type *IndexTy = Plan.getDataLayout().getIndexType(Plan.getContext(), 0);
    return tryInsertInstruction(new VPInstruction(
        VPInstruction::FirstActiveLane, Masks, {}, {}, DL, Name, IndexTy));
  }

  VPInstruction *createLastActiveLane(ArrayRef<VPValue *> Masks,
                                      DebugLoc DL = DebugLoc::getUnknown(),
                                      const Twine &Name = "") {
    // Assume that the maximum possible number of elements in a vector fits
    // within the index type for the default address space.
    VPlan &Plan = getPlan();
    Type *IndexTy = Plan.getDataLayout().getIndexType(Plan.getContext(), 0);
    return tryInsertInstruction(new VPInstruction(
        VPInstruction::LastActiveLane, Masks, {}, {}, DL, Name, IndexTy));
  }

  VPInstruction *createOverflowingOp(
      unsigned Opcode, ArrayRef<VPValue *> Operands,
      VPRecipeWithIRFlags::WrapFlagsTy WrapFlags = {false, false},
      DebugLoc DL = DebugLoc::getUnknown(), const Twine &Name = "") {
    return tryInsertInstruction(
        new VPInstruction(Opcode, Operands, WrapFlags, {}, DL, Name));
  }

  VPInstruction *createNot(VPValue *Operand,
                           DebugLoc DL = DebugLoc::getUnknown(),
                           const Twine &Name = "") {
    return createInstruction(VPInstruction::Not, {Operand}, {}, DL, Name);
  }

  VPInstruction *createAnd(VPValue *LHS, VPValue *RHS,
                           DebugLoc DL = DebugLoc::getUnknown(),
                           const Twine &Name = "") {
    return createInstruction(Instruction::BinaryOps::And, {LHS, RHS}, {}, DL,
                             Name);
  }

  VPInstruction *createOr(VPValue *LHS, VPValue *RHS,
                          DebugLoc DL = DebugLoc::getUnknown(),
                          const Twine &Name = "") {

    return tryInsertInstruction(new VPInstruction(
        Instruction::BinaryOps::Or, {LHS, RHS},
        VPRecipeWithIRFlags::DisjointFlagsTy(false), {}, DL, Name));
  }

  VPInstruction *
  createAdd(VPValue *LHS, VPValue *RHS, DebugLoc DL = DebugLoc::getUnknown(),
            const Twine &Name = "",
            VPRecipeWithIRFlags::WrapFlagsTy WrapFlags = {false, false}) {
    return createOverflowingOp(Instruction::Add, {LHS, RHS}, WrapFlags, DL,
                               Name);
  }

  VPInstruction *
  createSub(VPValue *LHS, VPValue *RHS, DebugLoc DL = DebugLoc::getUnknown(),
            const Twine &Name = "",
            VPRecipeWithIRFlags::WrapFlagsTy WrapFlags = {false, false}) {
    return createOverflowingOp(Instruction::Sub, {LHS, RHS}, WrapFlags, DL,
                               Name);
  }

  VPInstruction *createLogicalAnd(VPValue *LHS, VPValue *RHS,
                                  DebugLoc DL = DebugLoc::getUnknown(),
                                  const Twine &Name = "") {
    return createNaryOp(VPInstruction::LogicalAnd, {LHS, RHS}, DL, Name);
  }

  VPInstruction *createLogicalOr(VPValue *LHS, VPValue *RHS,
                                 DebugLoc DL = DebugLoc::getUnknown(),
                                 const Twine &Name = "") {
    return createNaryOp(VPInstruction::LogicalOr, {LHS, RHS}, DL, Name);
  }

  /// Create a select of \p TrueVal and \p FalseVal based on \p Cond, using the
  /// default flags for the result type, unless \p Flags is set.
  VPInstruction *createSelect(VPValue *Cond, VPValue *TrueVal,
                              VPValue *FalseVal,
                              DebugLoc DL = DebugLoc::getUnknown(),
                              const Twine &Name = "",
                              std::optional<VPIRFlags> Flags = std::nullopt) {
    return tryInsertInstruction(
        new VPInstruction(Instruction::Select, {Cond, TrueVal, FalseVal},
                          Flags.value_or(VPIRFlags::getDefaultFlags(
                              Instruction::Select, TrueVal->getScalarType())),
                          {}, DL, Name));
  }

  /// Create a new ICmp VPInstruction with predicate \p Pred and operands \p A
  /// and \p B.
  VPInstruction *createICmp(CmpInst::Predicate Pred, VPValue *A, VPValue *B,
                            DebugLoc DL = DebugLoc::getUnknown(),
                            const Twine &Name = "") {
    assert(Pred >= CmpInst::FIRST_ICMP_PREDICATE &&
           Pred <= CmpInst::LAST_ICMP_PREDICATE && "invalid predicate");
    return tryInsertInstruction(
        new VPInstruction(Instruction::ICmp, {A, B}, Pred, {}, DL, Name));
  }

  /// Create a new FCmp VPInstruction with predicate \p Pred and operands \p A
  /// and \p B.
  VPInstruction *createFCmp(CmpInst::Predicate Pred, VPValue *A, VPValue *B,
                            DebugLoc DL = DebugLoc::getUnknown(),
                            const Twine &Name = "") {
    assert(Pred >= CmpInst::FIRST_FCMP_PREDICATE &&
           Pred <= CmpInst::LAST_FCMP_PREDICATE && "invalid predicate");
    return tryInsertInstruction(
        new VPInstruction(Instruction::FCmp, {A, B},
                          VPIRFlags(Pred, FastMathFlags()), {}, DL, Name));
  }

  /// Create an AnyOf reduction pattern: or-reduce \p ChainOp, freeze the
  /// result, then select between \p TrueVal and \p FalseVal.
  VPInstruction *createAnyOfReduction(VPValue *ChainOp, VPValue *TrueVal,
                                      VPValue *FalseVal,
                                      DebugLoc DL = DebugLoc::getUnknown()) {
    assert(ChainOp->getScalarType()->isIntegerTy(1) &&
           "ChainOp must be i1 for AnyOf reduction");
    VPIRFlags Flags(RecurKind::Or, /*IsOrdered=*/false, /*IsInLoop=*/false,
                    FastMathFlags());
    auto *OrReduce = createNaryOp(VPInstruction::ComputeReductionResult,
                                  {ChainOp}, Flags, DL);
    auto *Freeze = createNaryOp(Instruction::Freeze, {OrReduce}, DL);
    return createSelect(Freeze, TrueVal, FalseVal, DL, "rdx.select");
  }

  VPInstruction *createPtrAdd(VPValue *Ptr, VPValue *Offset,
                              DebugLoc DL = DebugLoc::getUnknown(),
                              const Twine &Name = "") {
    return createNoWrapPtrAdd(Ptr, Offset, GEPNoWrapFlags::none(), DL, Name);
  }

  VPInstruction *createNoWrapPtrAdd(VPValue *Ptr, VPValue *Offset,
                                    GEPNoWrapFlags GEPFlags,
                                    DebugLoc DL = DebugLoc::getUnknown(),
                                    const Twine &Name = "") {
    return tryInsertInstruction(new VPInstruction(
        VPInstruction::PtrAdd, {Ptr, Offset}, GEPFlags, {}, DL, Name));
  }

  VPInstruction *createWidePtrAdd(VPValue *Ptr, VPValue *Offset,
                                  DebugLoc DL = DebugLoc::getUnknown(),
                                  const Twine &Name = "") {
    return tryInsertInstruction(
        new VPInstruction(VPInstruction::WidePtrAdd, {Ptr, Offset},
                          GEPNoWrapFlags::none(), {}, DL, Name));
  }

  /// Create a phi with \p IncomingValues, using the default flags for the
  /// result type, unless \p Flags is set.
  VPPhi *createScalarPhi(ArrayRef<VPValue *> IncomingValues,
                         DebugLoc DL = DebugLoc::getUnknown(),
                         const Twine &Name = "",
                         std::optional<VPIRFlags> Flags = std::nullopt,
                         Type *ResultTy = nullptr) {
    Type *ScalarTy = ResultTy ? ResultTy : IncomingValues[0]->getScalarType();
    return tryInsertInstruction(new VPPhi(
        IncomingValues,
        Flags.value_or(VPIRFlags::getDefaultFlags(Instruction::PHI, ScalarTy)),
        DL, Name, ResultTy));
  }

  VPWidenPHIRecipe *createWidenPhi(ArrayRef<VPValue *> IncomingValues,
                                   DebugLoc DL = DebugLoc::getUnknown(),
                                   const Twine &Name = "") {
    return tryInsertInstruction(new VPWidenPHIRecipe(IncomingValues, DL, Name));
  }

  VPValue *createElementCount(Type *Ty, ElementCount EC) {
    VPlan &Plan = getPlan();
    unsigned MinEC = EC.getKnownMinValue();
    if (EC.isScalable()) {
      VPValue *VScale = createVScale(Ty);
      if (MinEC == 1)
        return VScale;
      // TODO: Move this optimization into createOverflowingOp directly.
      if (isPowerOf2_32(MinEC)) {
        VPValue *ShtAmt = Plan.getConstantInt(Ty, Log2_32(MinEC));
        return createOverflowingOp(Instruction::Shl, {VScale, ShtAmt},
                                   {true, false});
      }
      VPValue *MulAmt = Plan.getConstantInt(Ty, MinEC);
      return createOverflowingOp(Instruction::Mul, {VScale, MulAmt},
                                 {true, false});
    }
    return Plan.getConstantInt(Ty, MinEC);
  }

  /// Convert \p Current to \p Start + \p Current * \p Step.
  VPDerivedIVRecipe *createDerivedIV(InductionDescriptor::InductionKind Kind,
                                     FPMathOperator *FPBinOp, VPValue *Start,
                                     VPValue *Current, VPValue *Step,
                                     const VPIRFlags::WrapFlagsTy &Flags = {}) {
    return tryInsertInstruction(
        new VPDerivedIVRecipe(Kind, FPBinOp, Start, Current, Step, Flags));
  }

  VPInstruction *createScalarCast(Instruction::CastOps Opcode, VPValue *Op,
                                  Type *ResultTy, DebugLoc DL,
                                  std::optional<VPIRFlags> Flags = std::nullopt,
                                  const VPIRMetadata &Metadata = {}) {
    return tryInsertInstruction(new VPInstruction(
        Opcode, Op, Flags.value_or(VPIRFlags::getDefaultFlags(Opcode)),
        Metadata, DL, "", ResultTy));
  }

  /// Create a scalar call to the intrinsic \p IntrinsicID with \p Operands, and
  /// result type \p ResultTy
  VPInstruction *createScalarIntrinsic(Intrinsic::ID IntrinsicID,
                                       ArrayRef<VPValue *> Operands,
                                       Type *ResultTy, DebugLoc DL) {
    VPlan &Plan = getPlan();
    SmallVector<VPValue *, 2> Ops(Operands);
    Ops.push_back(Plan.getConstantInt(8 * sizeof(IntrinsicID), IntrinsicID));
    return tryInsertInstruction(new VPInstruction(VPInstruction::Intrinsic, Ops,
                                                  {}, {}, DL, "", ResultTy));
  }

  /// Create a scalar llvm.vscale call.
  VPInstruction *createVScale(Type *ResultTy,
                              DebugLoc DL = DebugLoc::getUnknown()) {
    return createScalarIntrinsic(Intrinsic::vscale, {}, ResultTy, DL);
  }

  VPValue *createScalarZExtOrTrunc(VPValue *Op, Type *ResultTy, DebugLoc DL) {
    Type *SrcTy = Op->getScalarType();
    if (ResultTy == SrcTy)
      return Op;
    Instruction::CastOps CastOp =
        ResultTy->getScalarSizeInBits() < SrcTy->getScalarSizeInBits()
            ? Instruction::Trunc
            : Instruction::ZExt;
    return createScalarCast(CastOp, Op, ResultTy, DL);
  }

  VPValue *createScalarSExtOrTrunc(VPValue *Op, Type *ResultTy, DebugLoc DL) {
    Type *SrcTy = Op->getScalarType();
    if (ResultTy == SrcTy)
      return Op;
    Instruction::CastOps CastOp =
        ResultTy->getScalarSizeInBits() < SrcTy->getScalarSizeInBits()
            ? Instruction::Trunc
            : Instruction::SExt;
    return createScalarCast(CastOp, Op, ResultTy, DL);
  }

  VPInstruction *createFreeze(VPValue *Op, DebugLoc DL = DebugLoc::getUnknown(),
                              const Twine &Name = "") {
    return createNaryOp(Instruction::Freeze, Op, DL, Name);
  }

  VPWidenCastRecipe *createWidenCast(Instruction::CastOps Opcode, VPValue *Op,
                                     Type *ResultTy) {
    assert(Op->getScalarType() != ResultTy &&
           "must not create a no-op cast recipe");
    return tryInsertInstruction(new VPWidenCastRecipe(
        Opcode, Op, ResultTy, nullptr, VPIRFlags::getDefaultFlags(Opcode)));
  }

  /// Create a single-scalar recipe with \p Opcode and \p Operands without
  /// inserting it.
  static VPSingleDefRecipe *createSingleScalarOp(unsigned Opcode,
                                                 ArrayRef<VPValue *> Operands,
                                                 VPValue *Mask,
                                                 const VPIRFlags &Flags,
                                                 const VPIRMetadata &Metadata,
                                                 DebugLoc DL, Instruction *UV) {
    if (Instruction::isCast(Opcode)) {
      assert(!Mask && "Cast cannot be predicated");
      auto *VPI = new VPInstruction(Opcode, Operands, Flags, Metadata, DL,
                                    UV->getName(), UV->getType());
      VPI->setUnderlyingValue(UV);
      return VPI;
    }
    return new VPReplicateRecipe(UV, Operands, /*IsSingleScalar=*/true, Mask,
                                 Flags, Metadata, DL);
  }

  VPScalarIVStepsRecipe *
  createScalarIVSteps(Instruction::BinaryOps InductionOpcode,
                      FPMathOperator *FPBinOp, VPValue *IV, VPValue *Step,
                      VPValue *VF, DebugLoc DL) {
    return tryInsertInstruction(new VPScalarIVStepsRecipe(
        IV, Step, VF, InductionOpcode,
        FPBinOp ? FPBinOp->getFastMathFlags() : FastMathFlags(), DL));
  }

  VPExpandSCEVRecipe *createExpandSCEV(const SCEV *Expr) {
    return tryInsertInstruction(new VPExpandSCEVRecipe(Expr));
  }

  VPVectorPointerRecipe *
  createVectorPointer(VPValue *Ptr, Type *SourceElementTy, VPValue *Stride,
                      GEPNoWrapFlags GEPFlags, DebugLoc DL) {
    return tryInsertInstruction(
        new VPVectorPointerRecipe(Ptr, SourceElementTy, Stride, GEPFlags, DL));
  }

  /// Create a vector pointer recipe for a consecutive memory access to \p Ptr
  /// with element type \p SourceElementTy.
  VPSingleDefRecipe *createConsecutiveVectorPointer(VPValue *Ptr,
                                                    Type *SourceElementTy,
                                                    bool Reverse, DebugLoc DL) {
    VPlan &Plan = getPlan();
    GEPNoWrapFlags Flags = vputils::getGEPFlagsForPtr(Ptr);
    if (Reverse) {
      // When folding the tail, we may compute an address that we don't in the
      // original scalar loop: drop the GEP no-wrap flags in this case.
      // Otherwise preserve existing flags without no-unsigned-wrap, as we will
      // emit negative indices.
      GEPNoWrapFlags ReverseFlags = Plan.hasTailFolded()
                                        ? GEPNoWrapFlags::none()
                                        : Flags.withoutNoUnsignedWrap();
      return tryInsertInstruction(
          new VPVectorEndPointerRecipe(Ptr, &Plan.getVF(), SourceElementTy,
                                       /*Stride=*/-1, ReverseFlags, DL));
    }
    Type *StrideTy = Plan.getDataLayout().getIndexType(Ptr->getScalarType());
    VPValue *StrideOne = Plan.getConstantInt(StrideTy, 1);
    return createVectorPointer(Ptr, SourceElementTy, StrideOne, Flags, DL);
  }

  VPWidenMemIntrinsicRecipe *createWidenMemIntrinsic(
      Intrinsic::ID VectorIntrinsicID, ArrayRef<VPValue *> CallArguments,
      Type *Ty, Align Alignment, const VPIRMetadata &MD, DebugLoc DL) {
    return tryInsertInstruction(new VPWidenMemIntrinsicRecipe(
        VectorIntrinsicID, CallArguments, Ty, Alignment, MD, DL));
  }

  /// Create a recipe widening \p Load, loading from \p Addr with \p Mask (may
  /// be null).
  VPWidenLoadRecipe *createWidenLoad(LoadInst &Load, VPValue *Addr,
                                     VPValue *Mask, bool Consecutive,
                                     const VPIRMetadata &Metadata,
                                     DebugLoc DL) {
    return tryInsertInstruction(
        new VPWidenLoadRecipe(Load, Addr, Mask, Consecutive, Metadata, DL));
  }

  /// Create a recipe widening \p Store, storing \p StoredVal to \p Addr with
  /// \p Mask (may be null).
  VPWidenStoreRecipe *createWidenStore(StoreInst &Store, VPValue *Addr,
                                       VPValue *StoredVal, VPValue *Mask,
                                       bool Consecutive,
                                       const VPIRMetadata &Metadata,
                                       DebugLoc DL) {
    return tryInsertInstruction(new VPWidenStoreRecipe(
        Store, Addr, StoredVal, Mask, Consecutive, Metadata, DL));
  }

  //===--------------------------------------------------------------------===//
  // RAII helpers.
  //===--------------------------------------------------------------------===//

  /// RAII object that stores the current insertion point and restores it when
  /// the object is destroyed.
  class InsertPointGuard {
    VPBuilderBase &Builder;
    VPInsertPoint InsertPt;

  public:
    InsertPointGuard(VPBuilderBase &B) : Builder(B), InsertPt(B.InsertPt) {}

    InsertPointGuard(const InsertPointGuard &) = delete;
    InsertPointGuard &operator=(const InsertPointGuard &) = delete;

    ~InsertPointGuard() { Builder.restoreIP(InsertPt); }
  };
};

/// TODO: The following VectorizationFactor was pulled out of
/// LoopVectorizationCostModel class. LV also deals with
/// VectorizerParams::VectorizationFactor.
/// We need to streamline them.

/// Information about vectorization costs.
struct VectorizationFactor {
  /// Vector width with best cost.
  ElementCount Width;

  /// Cost of the loop with that width.
  InstructionCost Cost;

  /// Cost of the scalar loop.
  InstructionCost ScalarCost;

  /// The minimum trip count required to make vectorization profitable, e.g. due
  /// to runtime checks.
  ElementCount MinProfitableTripCount;

  VectorizationFactor(ElementCount Width, InstructionCost Cost,
                      InstructionCost ScalarCost)
      : Width(Width), Cost(Cost), ScalarCost(ScalarCost) {}

  /// Width 1 means no vectorization, cost 0 means uncomputed cost.
  static VectorizationFactor Disabled() {
    return {ElementCount::getFixed(1), 0, 0};
  }
};

/// A class that represents two vectorization factors (initialized with 0 by
/// default). One for fixed-width vectorization and one for scalable
/// vectorization. This can be used by the vectorizer to choose from a range of
/// fixed and/or scalable VFs in order to find the most cost-effective VF to
/// vectorize with.
struct FixedScalableVFPair {
  ElementCount FixedVF;
  ElementCount ScalableVF;

  FixedScalableVFPair()
      : FixedVF(ElementCount::getFixed(0)),
        ScalableVF(ElementCount::getScalable(0)) {}
  FixedScalableVFPair(const ElementCount &Max) : FixedScalableVFPair() {
    *(Max.isScalable() ? &ScalableVF : &FixedVF) = Max;
  }
  FixedScalableVFPair(const ElementCount &FixedVF,
                      const ElementCount &ScalableVF)
      : FixedVF(FixedVF), ScalableVF(ScalableVF) {
    assert(!FixedVF.isScalable() && ScalableVF.isScalable() &&
           "Invalid scalable properties");
  }

  static FixedScalableVFPair getNone() { return FixedScalableVFPair(); }

  /// \return true if either fixed- or scalable VF is non-zero.
  explicit operator bool() const { return FixedVF || ScalableVF; }
};

/// Holds state needed to make cost decisions before computing costs per-VF,
/// including the maximum VFs.
class VFSelectionContext {
  /// \return True if maximizing vector bandwidth is enabled by the target or
  /// user options, for the given register kind (scalable or fixed-width).
  bool useMaxBandwidth(bool IsScalable) const;

  /// \return the maximized element count based on the targets vector
  /// registers and the loop trip-count, but limited to a maximum safe VF.
  /// This is a helper function of computeFeasibleMaxVF.
  ElementCount getMaximizedVFForTarget(unsigned MaxTripCount,
                                       unsigned SmallestType,
                                       unsigned WidestType,
                                       ElementCount MaxSafeVF, unsigned UserIC,
                                       bool FoldTailByMasking,
                                       bool RequiresScalarEpilogue);

  /// If \p VF * \p UserIC > MaxTripcount, clamps VF to the next lower VF
  /// that results in VF * UserIC <= MaxTripCount.
  ElementCount clampVFByMaxTripCount(ElementCount VF, unsigned MaxTripCount,
                                     unsigned UserIC, bool FoldTailByMasking,
                                     bool RequiresScalarEpilogue) const;

  /// Checks if scalable vectorization is supported and enabled. Caches the
  /// result to avoid repeated debug dumps for repeated queries.
  bool isScalableVectorizationAllowed();

  /// \return the maximum legal scalable VF, based on the safe max number
  /// of elements.
  ElementCount getMaxLegalScalableVF(unsigned MaxSafeElements);

  /// Initializes the value of vscale used for tuning the cost model. If
  /// vscale_range.min == vscale_range.max then return vscale_range.max, else
  /// return the value returned by the corresponding TTI method.
  void initializeVScaleForTuning();

  const TargetTransformInfo &TTI;
  const LoopVectorizationLegality *Legal;
  const Loop *TheLoop;
  const Function &F;
  PredicatedScalarEvolution &PSE;
  DemandedBits *DB;
  OptimizationRemarkEmitter *ORE;
  const LoopVectorizeHints *Hints;

  /// Cached result of isScalableVectorizationAllowed.
  std::optional<bool> IsScalableVectorizationAllowed;

  /// Used to store the value of vscale used for tuning the cost model. It is
  /// initialized during object construction.
  std::optional<unsigned> VScaleForTuning;

  /// The highest VF possible for this loop, without using MaxBandwidth.
  FixedScalableVFPair MaxPermissibleVFWithoutMaxBW;

  /// All element types found in the loop.
  SmallPtrSet<Type *, 16> ElementTypesInLoop;

  /// PHINodes of the reductions that should be expanded in-loop. Set by
  /// collectInLoopReductions.
  SmallPtrSet<PHINode *, 4> InLoopReductions;

  /// Maximum safe number of elements to be processed per vector iteration,
  /// which do not prevent store-load forwarding and are safe with regard to the
  /// memory dependencies. Required for EVL-based vectorization, where this
  /// value is used as the upper bound of the safe AVL. Set by
  /// computeFeasibleMaxVF.
  std::optional<unsigned> MaxSafeElements;

  /// Map of scalar integer values to the smallest bitwidth they can be legally
  /// represented as. The vector equivalents of these values should be truncated
  /// to this type.
  MapVector<Instruction *, uint64_t> MinBWs;

public:
  /// The kind of cost that we are calculating.
  const TTI::TargetCostKind CostKind;

  /// Whether this loop should be optimized for size based on function attribute
  /// or profile information.
  const bool OptForSize;

  VFSelectionContext(const TargetTransformInfo &TTI,
                     const LoopVectorizationLegality *Legal,
                     const Loop *TheLoop, const Function &F,
                     PredicatedScalarEvolution &PSE, DemandedBits *DB,
                     OptimizationRemarkEmitter *ORE,
                     const LoopVectorizeHints *Hints, bool OptForSize)
      : TTI(TTI), Legal(Legal), TheLoop(TheLoop), F(F), PSE(PSE), DB(DB),
        ORE(ORE), Hints(Hints),
        CostKind(F.hasMinSize() ? TTI::TCK_CodeSize : TTI::TCK_RecipThroughput),
        OptForSize(OptForSize) {
    initializeVScaleForTuning();
  }

  /// \return The vscale value used for tuning the cost model.
  std::optional<unsigned> getVScaleForTuning() const { return VScaleForTuning; }

  const TargetTransformInfo &getTTI() const { return TTI; }

  PredicatedScalarEvolution &getPSE() const { return PSE; }

  /// \return The loop being analyzed.
  const Loop *getLoop() const { return TheLoop; }

  /// \return The vectorization hints for the loop being analyzed.
  const LoopVectorizeHints &getHints() const { return *Hints; }

  /// Returns true if epilogue vectorization is considered profitable for a
  /// main loop with vectorization factor \p VF and interleave count \p IC.
  bool isEpilogueVectorizationProfitable(ElementCount VF, unsigned IC) const;

  /// \return True if register pressure should be considered for the given VF.
  bool shouldConsiderRegPressureForVF(ElementCount VF) const;

  /// \return True if scalable vectors are supported by the target or forced.
  bool supportsScalableVectors() const;

  /// Collect element types in the loop that need widening.
  void collectElementTypesForWidening(
      const SmallPtrSetImpl<const Value *> *ValuesToIgnore = nullptr);

  /// \return The size (in bits) of the smallest and widest types in the code
  /// that need to be vectorized. We ignore values that remain scalar such as
  /// 64 bit loop indices.
  std::pair<unsigned, unsigned> getSmallestAndWidestTypes() const;

  /// \return An upper bound for the vectorization factors for both
  /// fixed and scalable vectorization, where the minimum-known number of
  /// elements is a power-of-2 larger than zero. If scalable vectorization is
  /// disabled or unsupported, then the scalable part will be equal to
  /// ElementCount::getScalable(0). Also sets MaxSafeElements.
  FixedScalableVFPair computeFeasibleMaxVF(unsigned MaxTripCount,
                                           ElementCount UserVF, unsigned UserIC,
                                           bool FoldTailByMasking,
                                           bool RequiresScalarEpilogue);

  /// Return maximum safe number of elements to be processed per vector
  /// iteration, which do not prevent store-load forwarding and are safe with
  /// regard to the memory dependencies. Required for EVL-based VPlans to
  /// correctly calculate AVL (application vector length) as min(remaining AVL,
  /// MaxSafeElements). Set by computeFeasibleMaxVF.
  /// TODO: need to consider adjusting cost model to use this value as a
  /// vectorization factor for EVL-based vectorization.
  std::optional<unsigned> getMaxSafeElements() const { return MaxSafeElements; }

  /// Returns true if we should use strict in-order reductions for the given
  /// RdxDesc. This is true if the -enable-strict-reductions flag is passed,
  /// the IsOrdered flag of RdxDesc is set and we do not allow reordering
  /// of FP operations.
  bool useOrderedReductions(const RecurrenceDescriptor &RdxDesc) const;

  /// Returns true if the target machine supports a masked load (if \p IsLoad)
  /// or masked store of scalar type \p ScalarTy with \p Alignment in address
  /// space \p AddressSpace. The caller must ensure the access is consecutive or
  /// part of an interleave group.
  bool isLegalMaskedLoadOrStore(bool IsLoad, Type *ScalarTy, Align Alignment,
                                unsigned AddressSpace) const;

  /// Returns true if the target machine supports a gather (if \p IsLoad)
  /// or scatter of scalar type \p ScalarTy with \p Alignment for vectorization
  /// factor \p VF.
  bool isLegalGatherOrScatter(bool IsLoad, Type *ScalarTy, Align Alignment,
                              ElementCount VF) const;

  /// Split reductions into those that happen in the loop, and those that
  /// happen outside. In-loop reductions are collected into InLoopReductions.
  void collectInLoopReductions();

  /// Returns true if the Phi is part of an inloop reduction.
  bool isInLoopReduction(PHINode *Phi) const {
    return InLoopReductions.contains(Phi);
  }

  /// Returns the set of in-loop reduction PHIs.
  const SmallPtrSetImpl<PHINode *> &getInLoopReductions() const {
    return InLoopReductions;
  }

  /// Check whether vectorization would require runtime checks. When optimizing
  /// for size, returning true here aborts vectorization.
  bool runtimeChecksRequired();

  /// Returns a scalable VF to use for outer-loop vectorization if the target
  /// supports it and a fixed VF otherwise.
  FixedScalableVFPair computeVPlanOuterloopVF(ElementCount UserVF);

  /// Compute smallest bitwidth each instruction can be represented with.
  /// The vector equivalents of these instructions should be truncated to this
  /// type.
  void computeMinimalBitwidths();

  /// \returns The smallest bitwidth each instruction can be represented with.
  const MapVector<Instruction *, uint64_t> &getMinimalBitwidths() const {
    return MinBWs;
  }
};

/// Planner drives the vectorization process after having passed
/// Legality checks.
class LoopVectorizationPlanner {
  /// The loop that we evaluate.
  Loop *OrigLoop;

  /// Loop Info analysis.
  LoopInfo *LI;

  /// The dominator tree.
  DominatorTree *DT;

  /// Target Library Info.
  const TargetLibraryInfo *TLI;

  /// Target Transform Info.
  const TargetTransformInfo &TTI;

  /// The legality analysis.
  LoopVectorizationLegality *Legal;

  /// The profitability analysis. Cleared after making cost based decisions.
  std::unique_ptr<LoopVectorizationCostModel> CM;

  /// VF selection state independent of cost-modeling decisions.
  VFSelectionContext &Config;

  /// The interleaved access analysis.
  InterleavedAccessInfo &IAI;

  PredicatedScalarEvolution &PSE;

  OptimizationRemarkEmitter *ORE;

  /// Lazily fetch BranchProbabilityInfo, independent of BlockFrequencyInfo.
  std::function<const BranchProbabilityInfo &()> GetBPI;

  SmallVector<VPlanPtr, 4> VPlans;

  /// Profitable vector factors.
  SmallVector<VectorizationFactor, 8> ProfitableVFs;

  /// A builder used to construct the current plan.
  VPBuilder Builder;

  /// Computes the cost of \p Plan for vectorization factor \p VF.
  ///
  /// The current implementation requires access to the
  /// LoopVectorizationLegality to handle inductions and reductions, which is
  /// why it is kept separate from the VPlan-only cost infrastructure.
  ///
  /// TODO: Move to VPlan::cost once the use of LoopVectorizationLegality has
  /// been retired.
  InstructionCost cost(VPlan &Plan, ElementCount VF, VPRegisterUsage *RU) const;

  /// Precompute costs for certain instructions using the legacy cost model. The
  /// function is used to bring up the VPlan-based cost model to initially avoid
  /// taking different decisions due to inaccuracies in the legacy cost model.
  InstructionCost precomputeCosts(VPlan &Plan, ElementCount VF,
                                  VPCostContext &CostCtx) const;

public:
  LoopVectorizationPlanner(
      Loop *L, LoopInfo *LI, DominatorTree *DT, const TargetLibraryInfo *TLI,
      const TargetTransformInfo &TTI, LoopVectorizationLegality *Legal,
      std::unique_ptr<LoopVectorizationCostModel> CM,
      VFSelectionContext &Config, InterleavedAccessInfo &IAI,
      PredicatedScalarEvolution &PSE, OptimizationRemarkEmitter *ORE,
      std::function<const BranchProbabilityInfo &()> GetBPI);

  ~LoopVectorizationPlanner();

  /// Return the cost model. Must not be called after clearCostModel().
  LoopVectorizationCostModel &getCostModel() {
    assert(CM && "Cost model has already been cleared");
    return *CM;
  }

  /// Destroy the cost model.
  void clearCostModel();

  /// Build VPlans for the specified \p UserVF and \p UserIC if they are
  /// non-zero or all applicable candidate VFs otherwise. If vectorization and
  /// interleaving should be avoided up-front, no plans are generated.
  void plan(ElementCount UserVF, unsigned UserIC);

  /// Return the VPlan for \p VF. At the moment, there is always a single VPlan
  /// for each VF.
  VPlan &getPlanFor(ElementCount VF) const;

  /// Compute and return the most profitable vectorization factor and the
  /// corresponding best VPlan. Also collect all profitable VFs in
  /// ProfitableVFs.
  std::pair<VectorizationFactor, VPlan *> computeBestVF();

  /// \return The desired interleave count.
  /// If interleave count has been specified by metadata it will be returned.
  /// Otherwise, the interleave count is computed and returned. VF and LoopCost
  /// are the selected vectorization factor and the cost of the selected VF.
  unsigned selectInterleaveCount(VPlan &Plan, ElementCount VF,
                                 InstructionCost LoopCost);

  /// Generate the IR code for the vectorized loop captured in VPlan \p BestPlan
  /// according to the best selected \p VF and  \p UF.
  ///
  /// TODO: \p EpilogueVecKind should be removed once the re-use issue has been
  /// fixed.
  ///
  /// Returns a mapping of SCEVs to their expanded IR values.
  /// Note that this is a temporary workaround needed due to the current
  /// epilogue handling.
  enum class EpilogueVectorizationKind {
    None,     ///< Not part of epilogue vectorization.
    MainLoop, ///< Vectorizing the main loop of epilogue vectorization.
    Epilogue  ///< Vectorizing the epilogue loop.
  };
  DenseMap<const SCEV *, Value *>
  executePlan(ElementCount VF, unsigned UF, VPlan &BestPlan,
              InnerLoopVectorizer &LB, DominatorTree *DT,
              EpilogueVectorizationKind EpilogueVecKind =
                  EpilogueVectorizationKind::None);

#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
  void printPlans(raw_ostream &O);
#endif

  /// Look through the existing plans and return true if we have one with
  /// vectorization factor \p VF.
  bool hasPlanWithVF(ElementCount VF) const {
    return any_of(VPlans,
                  [&](const VPlanPtr &Plan) { return Plan->hasVF(VF); });
  }

  /// Test a \p Predicate on a \p Range of VF's. Return the value of applying
  /// \p Predicate on Range.Start, possibly decreasing Range.End such that the
  /// returned value holds for the entire \p Range.
  static bool
  getDecisionAndClampRange(const std::function<bool(ElementCount)> &Predicate,
                           VFRange &Range);

  /// \return A VPlan for the most profitable epilogue vectorization, with its
  /// VF narrowed to the chosen factor. The returned plan is a duplicate.
  /// Returns nullptr if epilogue vectorization is not supported or not
  /// profitable for the loop. \p ScalarEpilogueAllowed indicates whether the
  /// epilogue lowering policy permits creating a scalar epilogue at all.
  std::unique_ptr<VPlan> selectBestEpiloguePlan(VPlan &MainPlan,
                                                ElementCount MainLoopVF,
                                                unsigned IC,
                                                bool ScalarEpilogueAllowed);

  /// Emit remarks for recipes with invalid costs in the available VPlans.
  void emitInvalidCostRemarks(OptimizationRemarkEmitter *ORE);

  /// Create a check to \p Plan to see if the vector loop should be executed
  /// based on its trip count.
  void addMinimumIterationCheck(VPlan &Plan, ElementCount VF, unsigned UF,
                                ElementCount MinProfitableTripCount) const;

  /// Attach the runtime checks of \p RTChecks to \p Plan.
  void attachRuntimeChecks(VPlan &Plan, GeneratedRTChecks &RTChecks,
                           bool HasBranchWeights) const;

  /// Update loop metadata and profile info for both the scalar remainder loop
  /// and \p VectorLoop, if it exists. Keeps all loop hints from the original
  /// loop on the vector loop and replaces vectorizer-specific metadata. The
  /// loop ID of the original loop \p OrigLoopID must be passed, together with
  /// the average trip count and invocation weight of the original loop (\p
  /// OrigAverageTripCount and \p OrigLoopInvocationWeight respectively). They
  /// cannot be retrieved after the plan has been executed, as the original loop
  /// may have been removed. \p UnrollVectorizedLoop indicates whether the
  /// target wants the vector loop left eligible for runtime unrolling.
  void updateLoopMetadataAndProfileInfo(
      Loop *VectorLoop, VPBasicBlock *HeaderVPBB, const VPlan &Plan,
      bool VectorizingEpilogue, MDNode *OrigLoopID,
      std::optional<unsigned> OrigAverageTripCount,
      unsigned OrigLoopInvocationWeight, unsigned EstimatedVFxUF,
      bool DisableRuntimeUnroll, bool UnrollVectorizedLoop);

private:
  /// Build an initial VPlan, with HCFG wrapping the original scalar loop and
  /// scalar transformations applied. Returns null if an initial VPlan cannot
  /// be built.
  VPlanPtr tryToBuildVPlan1();

  /// Build a VPlan using VPRecipes according to the information gathered by
  /// Legal and VPlan-based analysis. For outer loops, performs basic recipe
  /// conversion only. For inner loops, \p Range's largest included VF is
  /// restricted to the maximum VF the returned VPlan is valid for. If no VPlan
  /// can be built for the input range, set the largest included VF to the
  /// maximum VF for which no plan could be built. Each VPlan is built starting
  /// from a copy of \p InitialPlan, which is a plain CFG VPlan wrapping the
  /// original scalar loop.
  VPlanPtr tryToBuildVPlan(VPlanPtr InitialPlan, VFRange &Range);

  /// Build VPlans for power-of-2 VF's between \p MinVF and \p MaxVF inclusive,
  /// based on \p VPlan1 and according to the information gathered by Legal
  /// when it checked if it is legal to vectorize the loop.
  void buildVPlans(VPlan &VPlan1, ElementCount MinVF, ElementCount MaxVF);

  /// Add ComputeReductionResult recipes to the middle block to compute the
  /// final reduction results. Add Select recipes to the latch block when
  /// folding tail, to feed ComputeReductionResult with the last or penultimate
  /// iteration values according to the header mask.
  void addReductionResultComputation(VPlanPtr &Plan, ElementCount MinVF);

  /// Returns true if the per-lane cost of VectorizationFactor A is lower than
  /// that of B.
  bool isMoreProfitable(const VectorizationFactor &A,
                        const VectorizationFactor &B, bool HasTail,
                        bool IsEpilogue = false) const;

  /// Returns true if the per-lane cost of VectorizationFactor A is lower than
  /// that of B in the context of vectorizing a loop with known \p MaxTripCount.
  bool isMoreProfitable(const VectorizationFactor &A,
                        const VectorizationFactor &B,
                        const unsigned MaxTripCount, bool HasTail,
                        bool IsEpilogue = false) const;

  /// Determines if we have the infrastructure to vectorize the loop and its
  /// epilogue, assuming the main loop is vectorized by \p MainPlan.
  bool isCandidateForEpilogueVectorization(VPlan &MainPlan) const;
};

/// A helper function that returns true if the given type is irregular. The
/// type is irregular if its allocated size doesn't equal the store size of an
/// element of the corresponding vector type.
inline bool hasIrregularType(Type *Ty, const DataLayout &DL) {
  // Determine if an array of N elements of type Ty is "bitcast compatible"
  // with a <N x Ty> vector.
  // This is only true if there is no padding between the array elements.
  return DL.getTypeAllocSizeInBits(Ty) != DL.getTypeSizeInBits(Ty);
}

} // namespace llvm

#endif // LLVM_TRANSFORMS_VECTORIZE_LOOPVECTORIZATIONPLANNER_H
