//===- llvm/VectorBuilder.h - Builder for VP Intrinsics ---------*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// This file defines the VectorBuilder class, which is used as a convenient way
// to create VP intrinsics as if they were LLVM instructions with a consistent
// and simplified interface.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_IR_VECTORBUILDER_H
#define LLVM_IR_VECTORBUILDER_H

#include <llvm/IR/IRBuilder.h>
#include <llvm/IR/InstrTypes.h>
#include <llvm/IR/Instruction.h>
#include <llvm/IR/Value.h>

namespace llvm {

class VectorBuilder {
public:
  enum class Behavior {
    // Abort if the requested VP intrinsic could not be created.
    // This is useful for strict consistency.
    ReportAndAbort = 0,

    // Return a default-initialized value if the requested VP intrinsic could
    // not be created.
    // This is useful for a defensive fallback to non-VP code.
    SilentlyReturnNone = 1,
  };

private:
  IRBuilderBase &Builder;
  Behavior ErrorHandling;

  // Explicit mask parameter.
  Value *Mask;
  // Explicit vector length parameter.
  Value *ExplicitVectorLength;
  // Compile-time vector length.
  ElementCount StaticVectorLength;

  // Get mask/evl value handles for the current configuration.
  Value &requestMask();
  Value &requestEVL();

  void handleError(const char *ErrorMsg) const;
  template <typename RetType>
  RetType returnWithError(const char *ErrorMsg) const {
    handleError(ErrorMsg);
    return RetType();
  }

public:
  VectorBuilder(IRBuilderBase &Builder,
                Behavior ErrorHandling = Behavior::ReportAndAbort)
      : Builder(Builder), ErrorHandling(ErrorHandling), Mask(nullptr),
        ExplicitVectorLength(nullptr),
        StaticVectorLength(ElementCount::getFixed(0)) {}

  Module &getModule() const;
  LLVMContext &getContext() const { return Builder.getContext(); }

  // All-true mask for the currently configured explicit vector length.
  Value *getAllTrueMask();

  VectorBuilder &setMask(Value *NewMask) {
    Mask = NewMask;
    return *this;
  }
  VectorBuilder &setEVL(Value *NewExplicitVectorLength) {
    ExplicitVectorLength = NewExplicitVectorLength;
    return *this;
  }
  VectorBuilder &setStaticVL(unsigned NewFixedVL) {
    StaticVectorLength = ElementCount::getFixed(NewFixedVL);
    return *this;
  }
  // TODO: setStaticVL(ElementCount) for scalable types.

  // Emit a VP intrinsic call that mimics a regular instruction.
  // This operation behaves according to the VectorBuilderBehavior.
  // \p Opcode      The functional instruction opcode of the emitted intrinsic.
  // \p ReturnTy    The return type of the operation.
  // \p VecOpArray  The operand list.
  Value *createVectorInstruction(unsigned Opcode, Type *ReturnTy,
                                 ArrayRef<Value *> VecOpArray,
                                 const Twine &Name = Twine());
};

} // namespace llvm

#endif // LLVM_IR_VECTORBUILDER_H
