//===- MveEmitter.cpp - Generate arm_mve.h for use with clang -*- 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 set of linked tablegen backends is responsible for emitting the bits
// and pieces that implement <arm_mve.h>, which is defined by the ACLE standard
// and provides a set of types and functions for (more or less) direct access
// to the MVE instruction set, including the scalar shifts as well as the
// vector instructions.
//
// MVE's standard intrinsic functions are unusual in that they have a system of
// polymorphism. For example, the function vaddq() can behave like vaddq_u16(),
// vaddq_f32(), vaddq_s8(), etc., depending on the types of the vector
// arguments you give it.
//
// This constrains the implementation strategies. The usual approach to making
// the user-facing functions polymorphic would be to either use
// __attribute__((overloadable)) to make a set of vaddq() functions that are
// all inline wrappers on the underlying clang builtins, or to define a single
// vaddq() macro which expands to an instance of _Generic.
//
// The inline-wrappers approach would work fine for most intrinsics, except for
// the ones that take an argument required to be a compile-time constant,
// because if you wrap an inline function around a call to a builtin, the
// constant nature of the argument is not passed through.
//
// The _Generic approach can be made to work with enough effort, but it takes a
// lot of machinery, because of the design feature of _Generic that even the
// untaken branches are required to pass all front-end validity checks such as
// type-correctness. You can work around that by nesting further _Generics all
// over the place to coerce things to the right type in untaken branches, but
// what you get out is complicated, hard to guarantee its correctness, and
// worst of all, gives _completely unreadable_ error messages if the user gets
// the types wrong for an intrinsic call.
//
// Therefore, my strategy is to introduce a new __attribute__ that allows a
// function to be mapped to a clang builtin even though it doesn't have the
// same name, and then declare all the user-facing MVE function names with that
// attribute, mapping each one directly to the clang builtin. And the
// polymorphic ones have __attribute__((overloadable)) as well. So once the
// compiler has resolved the overload, it knows the internal builtin ID of the
// selected function, and can check the immediate arguments against that; and
// if the user gets the types wrong in a call to a polymorphic intrinsic, they
// get a completely clear error message showing all the declarations of that
// function in the header file and explaining why each one doesn't fit their
// call.
//
// The downside of this is that if every clang builtin has to correspond
// exactly to a user-facing ACLE intrinsic, then you can't save work in the
// frontend by doing it in the header file: CGBuiltin.cpp has to do the entire
// job of converting an ACLE intrinsic call into LLVM IR. So the Tablegen
// description for an MVE intrinsic has to contain a full description of the
// sequence of IRBuilder calls that clang will need to make.
//
//===----------------------------------------------------------------------===//

#include "llvm/ADT/APInt.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"
#include "llvm/TableGen/StringToOffsetTable.h"
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <list>
#include <map>
#include <memory>
#include <set>
#include <string>
#include <vector>

using namespace llvm;

namespace {

class EmitterBase;
class Result;

// -----------------------------------------------------------------------------
// A system of classes to represent all the types we'll need to deal with in
// the prototypes of intrinsics.
//
// Query methods include finding out the C name of a type; the "LLVM name" in
// the sense of a C++ code snippet that can be used in the codegen function;
// the suffix that represents the type in the ACLE intrinsic naming scheme
// (e.g. 's32' represents int32_t in intrinsics such as vaddq_s32); whether the
// type is floating-point related (hence should be under #ifdef in the MVE
// header so that it isn't included in integer-only MVE mode); and the type's
// size in bits. Not all subtypes support all these queries.

class Type {
public:
  enum class TypeKind {
    // Void appears as a return type (for store intrinsics, which are pure
    // side-effect). It's also used as the parameter type in the Tablegen
    // when an intrinsic doesn't need to come in various suffixed forms like
    // vfooq_s8,vfooq_u16,vfooq_f32.
    Void,

    // Scalar is used for ordinary int and float types of all sizes.
    Scalar,

    // Vector is used for anything that occupies exactly one MVE vector
    // register, i.e. {uint,int,float}NxM_t.
    Vector,

    // MultiVector is used for the {uint,int,float}NxMxK_t types used by the
    // interleaving load/store intrinsics v{ld,st}{2,4}q.
    MultiVector,

    // Predicate is used by all the predicated intrinsics. Its C
    // representation is mve_pred16_t (which is just an alias for uint16_t).
    // But we give more detail here, by indicating that a given predicate
    // instruction is logically regarded as a vector of i1 containing the
    // same number of lanes as the input vector type. So our Predicate type
    // comes with a lane count, which we use to decide which kind of <n x i1>
    // we'll invoke the pred_i2v IR intrinsic to translate it into.
    Predicate,

    // Pointer is used for pointer types (obviously), and comes with a flag
    // indicating whether it's a pointer to a const or mutable instance of
    // the pointee type.
    Pointer,
  };

private:
  const TypeKind TKind;

protected:
  Type(TypeKind K) : TKind(K) {}

public:
  TypeKind typeKind() const { return TKind; }
  virtual ~Type() = default;
  virtual bool requiresFloat() const = 0;
  virtual bool requiresMVE() const = 0;
  virtual unsigned sizeInBits() const = 0;
  virtual std::string cName() const = 0;
  virtual std::string llvmName() const {
    PrintFatalError("no LLVM type name available for type " + cName());
  }
  virtual std::string acleSuffix(std::string) const {
    PrintFatalError("no ACLE suffix available for this type");
  }
};

enum class ScalarTypeKind { SignedInt, UnsignedInt, Float };
inline std::string toLetter(ScalarTypeKind kind) {
  switch (kind) {
  case ScalarTypeKind::SignedInt:
    return "s";
  case ScalarTypeKind::UnsignedInt:
    return "u";
  case ScalarTypeKind::Float:
    return "f";
  }
  llvm_unreachable("Unhandled ScalarTypeKind enum");
}
inline std::string toCPrefix(ScalarTypeKind kind) {
  switch (kind) {
  case ScalarTypeKind::SignedInt:
    return "int";
  case ScalarTypeKind::UnsignedInt:
    return "uint";
  case ScalarTypeKind::Float:
    return "float";
  }
  llvm_unreachable("Unhandled ScalarTypeKind enum");
}

class VoidType : public Type {
public:
  VoidType() : Type(TypeKind::Void) {}
  unsigned sizeInBits() const override { return 0; }
  bool requiresFloat() const override { return false; }
  bool requiresMVE() const override { return false; }
  std::string cName() const override { return "void"; }

  static bool classof(const Type *T) { return T->typeKind() == TypeKind::Void; }
  std::string acleSuffix(std::string) const override { return ""; }
};

class PointerType : public Type {
  const Type *Pointee;
  bool Const;

public:
  PointerType(const Type *Pointee, bool Const)
      : Type(TypeKind::Pointer), Pointee(Pointee), Const(Const) {}
  unsigned sizeInBits() const override { return 32; }
  bool requiresFloat() const override { return Pointee->requiresFloat(); }
  bool requiresMVE() const override { return Pointee->requiresMVE(); }
  std::string cName() const override {
    std::string Name = Pointee->cName();

    // The syntax for a pointer in C is different when the pointee is
    // itself a pointer. The MVE intrinsics don't contain any double
    // pointers, so we don't need to worry about that wrinkle.
    assert(!isa<PointerType>(Pointee) && "Pointer to pointer not supported");

    if (Const)
      Name = "const " + Name;
    return Name + " *";
  }
  std::string llvmName() const override {
    return "llvm::PointerType::getUnqual(" + Pointee->llvmName() + ")";
  }

  static bool classof(const Type *T) {
    return T->typeKind() == TypeKind::Pointer;
  }
};

// Base class for all the types that have a name of the form
// [prefix][numbers]_t, like int32_t, uint16x8_t, float32x4x2_t.
//
// For this sub-hierarchy we invent a cNameBase() method which returns the
// whole name except for the trailing "_t", so that Vector and MultiVector can
// append an extra "x2" or whatever to their element type's cNameBase(). Then
// the main cName() query method puts "_t" on the end for the final type name.

class CRegularNamedType : public Type {
  using Type::Type;
  virtual std::string cNameBase() const = 0;

public:
  std::string cName() const override { return cNameBase() + "_t"; }
};

class ScalarType : public CRegularNamedType {
  ScalarTypeKind Kind;
  unsigned Bits;
  std::string NameOverride;

public:
  ScalarType(const Record *Record) : CRegularNamedType(TypeKind::Scalar) {
    Kind = StringSwitch<ScalarTypeKind>(Record->getValueAsString("kind"))
               .Case("s", ScalarTypeKind::SignedInt)
               .Case("u", ScalarTypeKind::UnsignedInt)
               .Case("f", ScalarTypeKind::Float);
    Bits = Record->getValueAsInt("size");
    NameOverride = std::string(Record->getValueAsString("nameOverride"));
  }
  unsigned sizeInBits() const override { return Bits; }
  ScalarTypeKind kind() const { return Kind; }
  std::string suffix() const { return toLetter(Kind) + utostr(Bits); }
  std::string cNameBase() const override {
    return toCPrefix(Kind) + utostr(Bits);
  }
  std::string cName() const override {
    if (NameOverride.empty())
      return CRegularNamedType::cName();
    return NameOverride;
  }
  std::string llvmName() const override {
    if (Kind == ScalarTypeKind::Float) {
      if (Bits == 16)
        return "HalfTy";
      if (Bits == 32)
        return "FloatTy";
      if (Bits == 64)
        return "DoubleTy";
      PrintFatalError("bad size for floating type");
    }
    return "Int" + utostr(Bits) + "Ty";
  }
  std::string acleSuffix(std::string overrideLetter) const override {
    return "_" + (overrideLetter.size() ? overrideLetter : toLetter(Kind))
               + utostr(Bits);
  }
  bool isInteger() const { return Kind != ScalarTypeKind::Float; }
  bool requiresFloat() const override { return !isInteger(); }
  bool requiresMVE() const override { return false; }
  bool hasNonstandardName() const { return !NameOverride.empty(); }

  static bool classof(const Type *T) {
    return T->typeKind() == TypeKind::Scalar;
  }
};

class VectorType : public CRegularNamedType {
  const ScalarType *Element;
  unsigned Lanes;

public:
  VectorType(const ScalarType *Element, unsigned Lanes)
      : CRegularNamedType(TypeKind::Vector), Element(Element), Lanes(Lanes) {}
  unsigned sizeInBits() const override { return Lanes * Element->sizeInBits(); }
  unsigned lanes() const { return Lanes; }
  bool requiresFloat() const override { return Element->requiresFloat(); }
  bool requiresMVE() const override { return true; }
  std::string cNameBase() const override {
    return Element->cNameBase() + "x" + utostr(Lanes);
  }
  std::string llvmName() const override {
    return "llvm::FixedVectorType::get(" + Element->llvmName() + ", " +
           utostr(Lanes) + ")";
  }

  static bool classof(const Type *T) {
    return T->typeKind() == TypeKind::Vector;
  }
};

class MultiVectorType : public CRegularNamedType {
  const VectorType *Element;
  unsigned Registers;

public:
  MultiVectorType(unsigned Registers, const VectorType *Element)
      : CRegularNamedType(TypeKind::MultiVector), Element(Element),
        Registers(Registers) {}
  unsigned sizeInBits() const override {
    return Registers * Element->sizeInBits();
  }
  unsigned registers() const { return Registers; }
  bool requiresFloat() const override { return Element->requiresFloat(); }
  bool requiresMVE() const override { return true; }
  std::string cNameBase() const override {
    return Element->cNameBase() + "x" + utostr(Registers);
  }

  // MultiVectorType doesn't override llvmName, because we don't expect to do
  // automatic code generation for the MVE intrinsics that use it: the {vld2,
  // vld4, vst2, vst4} family are the only ones that use these types, so it was
  // easier to hand-write the codegen for dealing with these structs than to
  // build in lots of extra automatic machinery that would only be used once.

  static bool classof(const Type *T) {
    return T->typeKind() == TypeKind::MultiVector;
  }
};

class PredicateType : public CRegularNamedType {
  unsigned Lanes;

public:
  PredicateType(unsigned Lanes)
      : CRegularNamedType(TypeKind::Predicate), Lanes(Lanes) {}
  unsigned sizeInBits() const override { return 16; }
  std::string cNameBase() const override { return "mve_pred16"; }
  bool requiresFloat() const override { return false; };
  bool requiresMVE() const override { return true; }
  std::string llvmName() const override {
    // Use <4 x i1> instead of <2 x i1> for two-lane vector types. See
    // the comment in llvm/lib/Target/ARM/ARMInstrMVE.td for further
    // explanation.
    unsigned ModifiedLanes = (Lanes == 2 ? 4 : Lanes);

    return "llvm::FixedVectorType::get(Builder.getInt1Ty(), " +
           utostr(ModifiedLanes) + ")";
  }

  static bool classof(const Type *T) {
    return T->typeKind() == TypeKind::Predicate;
  }
};

// -----------------------------------------------------------------------------
// Class to facilitate merging together the code generation for many intrinsics
// by means of varying a few constant or type parameters.
//
// Most obviously, the intrinsics in a single parametrised family will have
// code generation sequences that only differ in a type or two, e.g. vaddq_s8
// and vaddq_u16 will look the same apart from putting a different vector type
// in the call to CGM.getIntrinsic(). But also, completely different intrinsics
// will often code-generate in the same way, with only a different choice of
// _which_ IR intrinsic they lower to (e.g. vaddq_m_s8 and vmulq_m_s8), but
// marshalling the arguments and return values of the IR intrinsic in exactly
// the same way. And others might differ only in some other kind of constant,
// such as a lane index.
//
// So, when we generate the IR-building code for all these intrinsics, we keep
// track of every value that could possibly be pulled out of the code and
// stored ahead of time in a local variable. Then we group together intrinsics
// by textual equivalence of the code that would result if _all_ those
// parameters were stored in local variables. That gives us maximal sets that
// can be implemented by a single piece of IR-building code by changing
// parameter values ahead of time.
//
// After we've done that, we do a second pass in which we only allocate _some_
// of the parameters into local variables, by tracking which ones have the same
// values as each other (so that a single variable can be reused) and which
// ones are the same across the whole set (so that no variable is needed at
// all).
//
// Hence the class below. Its allocParam method is invoked during code
// generation by every method of a Result subclass (see below) that wants to
// give it the opportunity to pull something out into a switchable parameter.
// It returns a variable name for the parameter, or (if it's being used in the
// second pass once we've decided that some parameters don't need to be stored
// in variables after all) it might just return the input expression unchanged.

struct CodeGenParamAllocator {
  // Accumulated during code generation
  std::vector<std::string> *ParamTypes = nullptr;
  std::vector<std::string> *ParamValues = nullptr;

  // Provided ahead of time in pass 2, to indicate which parameters are being
  // assigned to what. This vector contains an entry for each call to
  // allocParam expected during code gen (which we counted up in pass 1), and
  // indicates the number of the parameter variable that should be returned, or
  // -1 if this call shouldn't allocate a parameter variable at all.
  //
  // We rely on the recursive code generation working identically in passes 1
  // and 2, so that the same list of calls to allocParam happen in the same
  // order. That guarantees that the parameter numbers recorded in pass 1 will
  // match the entries in this vector that store what EmitterBase::EmitBuiltinCG
  // decided to do about each one in pass 2.
  std::vector<int> *ParamNumberMap = nullptr;

  // Internally track how many things we've allocated
  unsigned nparams = 0;

  std::string allocParam(StringRef Type, StringRef Value) {
    unsigned ParamNumber;

    if (!ParamNumberMap) {
      // In pass 1, unconditionally assign a new parameter variable to every
      // value we're asked to process.
      ParamNumber = nparams++;
    } else {
      // In pass 2, consult the map provided by the caller to find out which
      // variable we should be keeping things in.
      int MapValue = (*ParamNumberMap)[nparams++];
      if (MapValue < 0)
        return std::string(Value);
      ParamNumber = MapValue;
    }

    // If we've allocated a new parameter variable for the first time, store
    // its type and value to be retrieved after codegen.
    if (ParamTypes && ParamTypes->size() == ParamNumber)
      ParamTypes->push_back(std::string(Type));
    if (ParamValues && ParamValues->size() == ParamNumber)
      ParamValues->push_back(std::string(Value));

    // Unimaginative naming scheme for parameter variables.
    return "Param" + utostr(ParamNumber);
  }
};

// -----------------------------------------------------------------------------
// System of classes that represent all the intermediate values used during
// code-generation for an intrinsic.
//
// The base class 'Result' can represent a value of the LLVM type 'Value', or
// sometimes 'Address' (for loads/stores, including an alignment requirement).
//
// In the case where the Tablegen provides a value in the codegen dag as a
// plain integer literal, the Result object we construct here will be one that
// returns true from hasIntegerConstantValue(). This allows the generated C++
// code to use the constant directly in contexts which can take a literal
// integer, such as Builder.CreateExtractValue(thing, 1), without going to the
// effort of calling llvm::ConstantInt::get() and then pulling the constant
// back out of the resulting llvm:Value later.

class Result {
public:
  // Convenient shorthand for the pointer type we'll be using everywhere.
  using Ptr = std::shared_ptr<Result>;

private:
  Ptr Predecessor;
  std::string VarName;
  bool VarNameUsed = false;
  unsigned Visited = 0;

public:
  virtual ~Result() = default;
  using Scope = std::map<std::string, Ptr>;
  virtual void genCode(raw_ostream &OS, CodeGenParamAllocator &) const = 0;
  virtual bool hasIntegerConstantValue() const { return false; }
  virtual uint32_t integerConstantValue() const { return 0; }
  virtual bool hasIntegerValue() const { return false; }
  virtual std::string getIntegerValue(const std::string &) {
    llvm_unreachable("non-working Result::getIntegerValue called");
  }
  virtual std::string typeName() const { return "Value *"; }

  // Mostly, when a code-generation operation has a dependency on prior
  // operations, it's because it uses the output values of those operations as
  // inputs. But there's one exception, which is the use of 'seq' in Tablegen
  // to indicate that operations have to be performed in sequence regardless of
  // whether they use each others' output values.
  //
  // So, the actual generation of code is done by depth-first search, using the
  // prerequisites() method to get a list of all the other Results that have to
  // be computed before this one. That method divides into the 'predecessor',
  // set by setPredecessor() while processing a 'seq' dag node, and the list
  // returned by 'morePrerequisites', which each subclass implements to return
  // a list of the Results it uses as input to whatever its own computation is
  // doing.

  virtual void morePrerequisites(std::vector<Ptr> &output) const {}
  std::vector<Ptr> prerequisites() const {
    std::vector<Ptr> ToRet;
    if (Predecessor)
      ToRet.push_back(Predecessor);
    morePrerequisites(ToRet);
    return ToRet;
  }

  void setPredecessor(Ptr p) {
    // If the user has nested one 'seq' node inside another, and this
    // method is called on the return value of the inner 'seq' (i.e.
    // the final item inside it), then we can't link _this_ node to p,
    // because it already has a predecessor. Instead, walk the chain
    // until we find the first item in the inner seq, and link that to
    // p, so that nesting seqs has the obvious effect of linking
    // everything together into one long sequential chain.
    Result *r = this;
    while (r->Predecessor)
      r = r->Predecessor.get();
    r->Predecessor = p;
  }

  // Each Result will be assigned a variable name in the output code, but not
  // all those variable names will actually be used (e.g. the return value of
  // Builder.CreateStore has void type, so nobody will want to refer to it). To
  // prevent annoying compiler warnings, we track whether each Result's
  // variable name was ever actually mentioned in subsequent statements, so
  // that it can be left out of the final generated code.
  std::string varname() {
    VarNameUsed = true;
    return VarName;
  }
  void setVarname(const StringRef s) { VarName = std::string(s); }
  bool varnameUsed() const { return VarNameUsed; }

  // Emit code to generate this result as a Value *.
  virtual std::string asValue() {
    return varname();
  }

  // Code generation happens in multiple passes. This method tracks whether a
  // Result has yet been visited in a given pass, without the need for a
  // tedious loop in between passes that goes through and resets a 'visited'
  // flag back to false: you just set Pass=1 the first time round, and Pass=2
  // the second time.
  bool needsVisiting(unsigned Pass) {
    bool ToRet = Visited < Pass;
    Visited = Pass;
    return ToRet;
  }
};

// Result subclass that retrieves one of the arguments to the clang builtin
// function. In cases where the argument has pointer type, we call
// EmitPointerWithAlignment and store the result in a variable of type Address,
// so that load and store IR nodes can know the right alignment. Otherwise, we
// call EmitScalarExpr.
//
// There are aggregate parameters in the MVE intrinsics API, but we don't deal
// with them in this Tablegen back end: they only arise in the vld2q/vld4q and
// vst2q/vst4q family, which is few enough that we just write the code by hand
// for those in CGBuiltin.cpp.
class BuiltinArgResult : public Result {
public:
  unsigned ArgNum;
  bool AddressType;
  bool Immediate;
  BuiltinArgResult(unsigned ArgNum, bool AddressType, bool Immediate)
      : ArgNum(ArgNum), AddressType(AddressType), Immediate(Immediate) {}
  void genCode(raw_ostream &OS, CodeGenParamAllocator &) const override {
    OS << (AddressType ? "EmitPointerWithAlignment" : "EmitScalarExpr")
       << "(E->getArg(" << ArgNum << "))";
  }
  std::string typeName() const override {
    return AddressType ? "Address" : Result::typeName();
  }
  // Emit code to generate this result as a Value *.
  std::string asValue() override {
    if (AddressType)
      return "(" + varname() + ".getPointer())";
    return Result::asValue();
  }
  bool hasIntegerValue() const override { return Immediate; }
  std::string getIntegerValue(const std::string &IntType) override {
    return "GetIntegerConstantValue<" + IntType + ">(E->getArg(" +
           utostr(ArgNum) + "), getContext())";
  }
};

// Result subclass for an integer literal appearing in Tablegen. This may need
// to be turned into an llvm::Result by means of llvm::ConstantInt::get(), or
// it may be used directly as an integer, depending on which IRBuilder method
// it's being passed to.
class IntLiteralResult : public Result {
public:
  const ScalarType *IntegerType;
  uint32_t IntegerValue;
  IntLiteralResult(const ScalarType *IntegerType, uint32_t IntegerValue)
      : IntegerType(IntegerType), IntegerValue(IntegerValue) {}
  void genCode(raw_ostream &OS,
               CodeGenParamAllocator &ParamAlloc) const override {
    OS << "llvm::ConstantInt::get("
       << ParamAlloc.allocParam("llvm::Type *", IntegerType->llvmName())
       << ", ";
    OS << ParamAlloc.allocParam(IntegerType->cName(), utostr(IntegerValue))
       << ")";
  }
  bool hasIntegerConstantValue() const override { return true; }
  uint32_t integerConstantValue() const override { return IntegerValue; }
};

// Result subclass representing a cast between different integer types. We use
// our own ScalarType abstraction as the representation of the target type,
// which gives both size and signedness.
class IntCastResult : public Result {
public:
  const ScalarType *IntegerType;
  Ptr V;
  IntCastResult(const ScalarType *IntegerType, Ptr V)
      : IntegerType(IntegerType), V(V) {}
  void genCode(raw_ostream &OS,
               CodeGenParamAllocator &ParamAlloc) const override {
    OS << "Builder.CreateIntCast(" << V->varname() << ", "
       << ParamAlloc.allocParam("llvm::Type *", IntegerType->llvmName()) << ", "
       << ParamAlloc.allocParam("bool",
                                IntegerType->kind() == ScalarTypeKind::SignedInt
                                    ? "true"
                                    : "false")
       << ")";
  }
  void morePrerequisites(std::vector<Ptr> &output) const override {
    output.push_back(V);
  }
};

// Result subclass representing a cast between different pointer types.
class PointerCastResult : public Result {
public:
  const PointerType *PtrType;
  Ptr V;
  PointerCastResult(const PointerType *PtrType, Ptr V)
      : PtrType(PtrType), V(V) {}
  void genCode(raw_ostream &OS,
               CodeGenParamAllocator &ParamAlloc) const override {
    OS << "Builder.CreatePointerCast(" << V->asValue() << ", "
       << ParamAlloc.allocParam("llvm::Type *", PtrType->llvmName()) << ")";
  }
  void morePrerequisites(std::vector<Ptr> &output) const override {
    output.push_back(V);
  }
};

// Result subclass representing a call to an IRBuilder method. Each IRBuilder
// method we want to use will have a Tablegen record giving the method name and
// describing any important details of how to call it, such as whether a
// particular argument should be an integer constant instead of an llvm::Value.
class IRBuilderResult : public Result {
public:
  StringRef CallPrefix;
  std::vector<Ptr> Args;
  std::set<unsigned> AddressArgs;
  std::map<unsigned, std::string> IntegerArgs;
  IRBuilderResult(StringRef CallPrefix, std::vector<Ptr> Args,
                  std::set<unsigned> AddressArgs,
                  std::map<unsigned, std::string> IntegerArgs)
      : CallPrefix(CallPrefix), Args(Args), AddressArgs(AddressArgs),
        IntegerArgs(IntegerArgs) {}
  void genCode(raw_ostream &OS,
               CodeGenParamAllocator &ParamAlloc) const override {
    OS << CallPrefix;
    const char *Sep = "";
    for (unsigned i = 0, e = Args.size(); i < e; ++i) {
      Ptr Arg = Args[i];
      auto it = IntegerArgs.find(i);

      OS << Sep;
      Sep = ", ";

      if (it != IntegerArgs.end()) {
        if (Arg->hasIntegerConstantValue())
          OS << "static_cast<" << it->second << ">("
             << ParamAlloc.allocParam(it->second,
                                      utostr(Arg->integerConstantValue()))
             << ")";
        else if (Arg->hasIntegerValue())
          OS << ParamAlloc.allocParam(it->second,
                                      Arg->getIntegerValue(it->second));
      } else {
        OS << Arg->varname();
      }
    }
    OS << ")";
  }
  void morePrerequisites(std::vector<Ptr> &output) const override {
    for (unsigned i = 0, e = Args.size(); i < e; ++i) {
      Ptr Arg = Args[i];
      if (IntegerArgs.find(i) != IntegerArgs.end())
        continue;
      output.push_back(Arg);
    }
  }
};

// Result subclass representing making an Address out of a Value.
class AddressResult : public Result {
public:
  Ptr Arg;
  unsigned Align;
  AddressResult(Ptr Arg, unsigned Align) : Arg(Arg), Align(Align) {}
  void genCode(raw_ostream &OS,
               CodeGenParamAllocator &ParamAlloc) const override {
    OS << "Address(" << Arg->varname() << ", CharUnits::fromQuantity("
       << Align << "))";
  }
  std::string typeName() const override {
    return "Address";
  }
  void morePrerequisites(std::vector<Ptr> &output) const override {
    output.push_back(Arg);
  }
};

// Result subclass representing a call to an IR intrinsic, which we first have
// to look up using an Intrinsic::ID constant and an array of types.
class IRIntrinsicResult : public Result {
public:
  std::string IntrinsicID;
  std::vector<const Type *> ParamTypes;
  std::vector<Ptr> Args;
  IRIntrinsicResult(StringRef IntrinsicID, std::vector<const Type *> ParamTypes,
                    std::vector<Ptr> Args)
      : IntrinsicID(std::string(IntrinsicID)), ParamTypes(ParamTypes),
        Args(Args) {}
  void genCode(raw_ostream &OS,
               CodeGenParamAllocator &ParamAlloc) const override {
    std::string IntNo = ParamAlloc.allocParam(
        "Intrinsic::ID", "Intrinsic::" + IntrinsicID);
    OS << "Builder.CreateCall(CGM.getIntrinsic(" << IntNo;
    if (!ParamTypes.empty()) {
      OS << ", {";
      const char *Sep = "";
      for (auto T : ParamTypes) {
        OS << Sep << ParamAlloc.allocParam("llvm::Type *", T->llvmName());
        Sep = ", ";
      }
      OS << "}";
    }
    OS << "), {";
    const char *Sep = "";
    for (auto Arg : Args) {
      OS << Sep << Arg->asValue();
      Sep = ", ";
    }
    OS << "})";
  }
  void morePrerequisites(std::vector<Ptr> &output) const override {
    output.insert(output.end(), Args.begin(), Args.end());
  }
};

// Result subclass that specifies a type, for use in IRBuilder operations such
// as CreateBitCast that take a type argument.
class TypeResult : public Result {
public:
  const Type *T;
  TypeResult(const Type *T) : T(T) {}
  void genCode(raw_ostream &OS, CodeGenParamAllocator &) const override {
    OS << T->llvmName();
  }
  std::string typeName() const override {
    return "llvm::Type *";
  }
};

// -----------------------------------------------------------------------------
// Class that describes a single ACLE intrinsic.
//
// A Tablegen record will typically describe more than one ACLE intrinsic, by
// means of setting the 'list<Type> Params' field to a list of multiple
// parameter types, so as to define vaddq_{s8,u8,...,f16,f32} all in one go.
// We'll end up with one instance of ACLEIntrinsic for *each* parameter type,
// rather than a single one for all of them. Hence, the constructor takes both
// a Tablegen record and the current value of the parameter type.

class ACLEIntrinsic {
  // Structure documenting that one of the intrinsic's arguments is required to
  // be a compile-time constant integer, and what constraints there are on its
  // value. Used when generating Sema checking code.
  struct ImmediateArg {
    enum class BoundsType { ExplicitRange, UInt };
    BoundsType boundsType;
    int64_t i1, i2;
    StringRef ExtraCheckType, ExtraCheckArgs;
    const Type *ArgType;
  };

  // For polymorphic intrinsics, FullName is the explicit name that uniquely
  // identifies this variant of the intrinsic, and ShortName is the name it
  // shares with at least one other intrinsic.
  std::string ShortName, FullName;

  // Name of the architecture extension, used in the Clang builtin name
  StringRef BuiltinExtension;

  // A very small number of intrinsics _only_ have a polymorphic
  // variant (vuninitializedq taking an unevaluated argument).
  bool PolymorphicOnly;

  // Another rarely-used flag indicating that the builtin doesn't
  // evaluate its argument(s) at all.
  bool NonEvaluating;

  // True if the intrinsic needs only the C header part (no codegen, semantic
  // checks, etc). Used for redeclaring MVE intrinsics in the arm_cde.h header.
  bool HeaderOnly;

  const Type *ReturnType;
  std::vector<const Type *> ArgTypes;
  std::map<unsigned, ImmediateArg> ImmediateArgs;
  Result::Ptr Code;

  std::map<std::string, std::string> CustomCodeGenArgs;

  // Recursive function that does the internals of code generation.
  void genCodeDfs(Result::Ptr V, std::list<Result::Ptr> &Used,
                  unsigned Pass) const {
    if (!V->needsVisiting(Pass))
      return;

    for (Result::Ptr W : V->prerequisites())
      genCodeDfs(W, Used, Pass);

    Used.push_back(V);
  }

public:
  const std::string &shortName() const { return ShortName; }
  const std::string &fullName() const { return FullName; }
  StringRef builtinExtension() const { return BuiltinExtension; }
  const Type *returnType() const { return ReturnType; }
  const std::vector<const Type *> &argTypes() const { return ArgTypes; }
  bool requiresFloat() const {
    if (ReturnType->requiresFloat())
      return true;
    for (const Type *T : ArgTypes)
      if (T->requiresFloat())
        return true;
    return false;
  }
  bool requiresMVE() const {
    return ReturnType->requiresMVE() ||
           any_of(ArgTypes, [](const Type *T) { return T->requiresMVE(); });
  }
  bool polymorphic() const { return ShortName != FullName; }
  bool polymorphicOnly() const { return PolymorphicOnly; }
  bool nonEvaluating() const { return NonEvaluating; }
  bool headerOnly() const { return HeaderOnly; }

  // External entry point for code generation, called from EmitterBase.
  void genCode(raw_ostream &OS, CodeGenParamAllocator &ParamAlloc,
               unsigned Pass) const {
    assert(!headerOnly() && "Called genCode for header-only intrinsic");
    if (!hasCode()) {
      for (auto kv : CustomCodeGenArgs)
        OS << "  " << kv.first << " = " << kv.second << ";\n";
      OS << "  break; // custom code gen\n";
      return;
    }
    std::list<Result::Ptr> Used;
    genCodeDfs(Code, Used, Pass);

    unsigned varindex = 0;
    for (Result::Ptr V : Used)
      if (V->varnameUsed())
        V->setVarname("Val" + utostr(varindex++));

    for (Result::Ptr V : Used) {
      OS << "  ";
      if (V == Used.back()) {
        assert(!V->varnameUsed());
        OS << "return "; // FIXME: what if the top-level thing is void?
      } else if (V->varnameUsed()) {
        std::string Type = V->typeName();
        OS << V->typeName();
        if (!StringRef(Type).endswith("*"))
          OS << " ";
        OS << V->varname() << " = ";
      }
      V->genCode(OS, ParamAlloc);
      OS << ";\n";
    }
  }
  bool hasCode() const { return Code != nullptr; }

  static std::string signedHexLiteral(const llvm::APInt &iOrig) {
    llvm::APInt i = iOrig.trunc(64);
    SmallString<40> s;
    i.toString(s, 16, true, true);
    return std::string(s.str());
  }

  std::string genSema() const {
    assert(!headerOnly() && "Called genSema for header-only intrinsic");
    std::vector<std::string> SemaChecks;

    for (const auto &kv : ImmediateArgs) {
      const ImmediateArg &IA = kv.second;

      llvm::APInt lo(128, 0), hi(128, 0);
      switch (IA.boundsType) {
      case ImmediateArg::BoundsType::ExplicitRange:
        lo = IA.i1;
        hi = IA.i2;
        break;
      case ImmediateArg::BoundsType::UInt:
        lo = 0;
        hi = llvm::APInt::getMaxValue(IA.i1).zext(128);
        break;
      }

      std::string Index = utostr(kv.first);

      // Emit a range check if the legal range of values for the
      // immediate is smaller than the _possible_ range of values for
      // its type.
      unsigned ArgTypeBits = IA.ArgType->sizeInBits();
      llvm::APInt ArgTypeRange = llvm::APInt::getMaxValue(ArgTypeBits).zext(128);
      llvm::APInt ActualRange = (hi-lo).trunc(64).sext(128);
      if (ActualRange.ult(ArgTypeRange))
        SemaChecks.push_back("SemaBuiltinConstantArgRange(TheCall, " + Index +
                             ", " + signedHexLiteral(lo) + ", " +
                             signedHexLiteral(hi) + ")");

      if (!IA.ExtraCheckType.empty()) {
        std::string Suffix;
        if (!IA.ExtraCheckArgs.empty()) {
          std::string tmp;
          StringRef Arg = IA.ExtraCheckArgs;
          if (Arg == "!lanesize") {
            tmp = utostr(IA.ArgType->sizeInBits());
            Arg = tmp;
          }
          Suffix = (Twine(", ") + Arg).str();
        }
        SemaChecks.push_back((Twine("SemaBuiltinConstantArg") +
                              IA.ExtraCheckType + "(TheCall, " + Index +
                              Suffix + ")")
                                 .str());
      }

      assert(!SemaChecks.empty());
    }
    if (SemaChecks.empty())
      return "";
    return join(std::begin(SemaChecks), std::end(SemaChecks),
                " ||\n         ") +
           ";\n";
  }

  ACLEIntrinsic(EmitterBase &ME, Record *R, const Type *Param);
};

// -----------------------------------------------------------------------------
// The top-level class that holds all the state from analyzing the entire
// Tablegen input.

class EmitterBase {
protected:
  // EmitterBase holds a collection of all the types we've instantiated.
  VoidType Void;
  std::map<std::string, std::unique_ptr<ScalarType>> ScalarTypes;
  std::map<std::tuple<ScalarTypeKind, unsigned, unsigned>,
           std::unique_ptr<VectorType>>
      VectorTypes;
  std::map<std::pair<std::string, unsigned>, std::unique_ptr<MultiVectorType>>
      MultiVectorTypes;
  std::map<unsigned, std::unique_ptr<PredicateType>> PredicateTypes;
  std::map<std::string, std::unique_ptr<PointerType>> PointerTypes;

  // And all the ACLEIntrinsic instances we've created.
  std::map<std::string, std::unique_ptr<ACLEIntrinsic>> ACLEIntrinsics;

public:
  // Methods to create a Type object, or return the right existing one from the
  // maps stored in this object.
  const VoidType *getVoidType() { return &Void; }
  const ScalarType *getScalarType(StringRef Name) {
    return ScalarTypes[std::string(Name)].get();
  }
  const ScalarType *getScalarType(Record *R) {
    return getScalarType(R->getName());
  }
  const VectorType *getVectorType(const ScalarType *ST, unsigned Lanes) {
    std::tuple<ScalarTypeKind, unsigned, unsigned> key(ST->kind(),
                                                       ST->sizeInBits(), Lanes);
    if (VectorTypes.find(key) == VectorTypes.end())
      VectorTypes[key] = std::make_unique<VectorType>(ST, Lanes);
    return VectorTypes[key].get();
  }
  const VectorType *getVectorType(const ScalarType *ST) {
    return getVectorType(ST, 128 / ST->sizeInBits());
  }
  const MultiVectorType *getMultiVectorType(unsigned Registers,
                                            const VectorType *VT) {
    std::pair<std::string, unsigned> key(VT->cNameBase(), Registers);
    if (MultiVectorTypes.find(key) == MultiVectorTypes.end())
      MultiVectorTypes[key] = std::make_unique<MultiVectorType>(Registers, VT);
    return MultiVectorTypes[key].get();
  }
  const PredicateType *getPredicateType(unsigned Lanes) {
    unsigned key = Lanes;
    if (PredicateTypes.find(key) == PredicateTypes.end())
      PredicateTypes[key] = std::make_unique<PredicateType>(Lanes);
    return PredicateTypes[key].get();
  }
  const PointerType *getPointerType(const Type *T, bool Const) {
    PointerType PT(T, Const);
    std::string key = PT.cName();
    if (PointerTypes.find(key) == PointerTypes.end())
      PointerTypes[key] = std::make_unique<PointerType>(PT);
    return PointerTypes[key].get();
  }

  // Methods to construct a type from various pieces of Tablegen. These are
  // always called in the context of setting up a particular ACLEIntrinsic, so
  // there's always an ambient parameter type (because we're iterating through
  // the Params list in the Tablegen record for the intrinsic), which is used
  // to expand Tablegen classes like 'Vector' which mean something different in
  // each member of a parametric family.
  const Type *getType(Record *R, const Type *Param);
  const Type *getType(DagInit *D, const Type *Param);
  const Type *getType(Init *I, const Type *Param);

  // Functions that translate the Tablegen representation of an intrinsic's
  // code generation into a collection of Value objects (which will then be
  // reprocessed to read out the actual C++ code included by CGBuiltin.cpp).
  Result::Ptr getCodeForDag(DagInit *D, const Result::Scope &Scope,
                            const Type *Param);
  Result::Ptr getCodeForDagArg(DagInit *D, unsigned ArgNum,
                               const Result::Scope &Scope, const Type *Param);
  Result::Ptr getCodeForArg(unsigned ArgNum, const Type *ArgType, bool Promote,
                            bool Immediate);

  void GroupSemaChecks(std::map<std::string, std::set<std::string>> &Checks);

  // Constructor and top-level functions.

  EmitterBase(RecordKeeper &Records);
  virtual ~EmitterBase() = default;

  virtual void EmitHeader(raw_ostream &OS) = 0;
  virtual void EmitBuiltinDef(raw_ostream &OS) = 0;
  virtual void EmitBuiltinSema(raw_ostream &OS) = 0;
  void EmitBuiltinCG(raw_ostream &OS);
  void EmitBuiltinAliases(raw_ostream &OS);
};

const Type *EmitterBase::getType(Init *I, const Type *Param) {
  if (auto Dag = dyn_cast<DagInit>(I))
    return getType(Dag, Param);
  if (auto Def = dyn_cast<DefInit>(I))
    return getType(Def->getDef(), Param);

  PrintFatalError("Could not convert this value into a type");
}

const Type *EmitterBase::getType(Record *R, const Type *Param) {
  // Pass to a subfield of any wrapper records. We don't expect more than one
  // of these: immediate operands are used as plain numbers rather than as
  // llvm::Value, so it's meaningless to promote their type anyway.
  if (R->isSubClassOf("Immediate"))
    R = R->getValueAsDef("type");
  else if (R->isSubClassOf("unpromoted"))
    R = R->getValueAsDef("underlying_type");

  if (R->getName() == "Void")
    return getVoidType();
  if (R->isSubClassOf("PrimitiveType"))
    return getScalarType(R);
  if (R->isSubClassOf("ComplexType"))
    return getType(R->getValueAsDag("spec"), Param);

  PrintFatalError(R->getLoc(), "Could not convert this record into a type");
}

const Type *EmitterBase::getType(DagInit *D, const Type *Param) {
  // The meat of the getType system: types in the Tablegen are represented by a
  // dag whose operators select sub-cases of this function.

  Record *Op = cast<DefInit>(D->getOperator())->getDef();
  if (!Op->isSubClassOf("ComplexTypeOp"))
    PrintFatalError(
        "Expected ComplexTypeOp as dag operator in type expression");

  if (Op->getName() == "CTO_Parameter") {
    if (isa<VoidType>(Param))
      PrintFatalError("Parametric type in unparametrised context");
    return Param;
  }

  if (Op->getName() == "CTO_Vec") {
    const Type *Element = getType(D->getArg(0), Param);
    if (D->getNumArgs() == 1) {
      return getVectorType(cast<ScalarType>(Element));
    } else {
      const Type *ExistingVector = getType(D->getArg(1), Param);
      return getVectorType(cast<ScalarType>(Element),
                           cast<VectorType>(ExistingVector)->lanes());
    }
  }

  if (Op->getName() == "CTO_Pred") {
    const Type *Element = getType(D->getArg(0), Param);
    return getPredicateType(128 / Element->sizeInBits());
  }

  if (Op->isSubClassOf("CTO_Tuple")) {
    unsigned Registers = Op->getValueAsInt("n");
    const Type *Element = getType(D->getArg(0), Param);
    return getMultiVectorType(Registers, cast<VectorType>(Element));
  }

  if (Op->isSubClassOf("CTO_Pointer")) {
    const Type *Pointee = getType(D->getArg(0), Param);
    return getPointerType(Pointee, Op->getValueAsBit("const"));
  }

  if (Op->getName() == "CTO_CopyKind") {
    const ScalarType *STSize = cast<ScalarType>(getType(D->getArg(0), Param));
    const ScalarType *STKind = cast<ScalarType>(getType(D->getArg(1), Param));
    for (const auto &kv : ScalarTypes) {
      const ScalarType *RT = kv.second.get();
      if (RT->kind() == STKind->kind() && RT->sizeInBits() == STSize->sizeInBits())
        return RT;
    }
    PrintFatalError("Cannot find a type to satisfy CopyKind");
  }

  if (Op->isSubClassOf("CTO_ScaleSize")) {
    const ScalarType *STKind = cast<ScalarType>(getType(D->getArg(0), Param));
    int Num = Op->getValueAsInt("num"), Denom = Op->getValueAsInt("denom");
    unsigned DesiredSize = STKind->sizeInBits() * Num / Denom;
    for (const auto &kv : ScalarTypes) {
      const ScalarType *RT = kv.second.get();
      if (RT->kind() == STKind->kind() && RT->sizeInBits() == DesiredSize)
        return RT;
    }
    PrintFatalError("Cannot find a type to satisfy ScaleSize");
  }

  PrintFatalError("Bad operator in type dag expression");
}

Result::Ptr EmitterBase::getCodeForDag(DagInit *D, const Result::Scope &Scope,
                                       const Type *Param) {
  Record *Op = cast<DefInit>(D->getOperator())->getDef();

  if (Op->getName() == "seq") {
    Result::Scope SubScope = Scope;
    Result::Ptr PrevV = nullptr;
    for (unsigned i = 0, e = D->getNumArgs(); i < e; ++i) {
      // We don't use getCodeForDagArg here, because the argument name
      // has different semantics in a seq
      Result::Ptr V =
          getCodeForDag(cast<DagInit>(D->getArg(i)), SubScope, Param);
      StringRef ArgName = D->getArgNameStr(i);
      if (!ArgName.empty())
        SubScope[std::string(ArgName)] = V;
      if (PrevV)
        V->setPredecessor(PrevV);
      PrevV = V;
    }
    return PrevV;
  } else if (Op->isSubClassOf("Type")) {
    if (D->getNumArgs() != 1)
      PrintFatalError("Type casts should have exactly one argument");
    const Type *CastType = getType(Op, Param);
    Result::Ptr Arg = getCodeForDagArg(D, 0, Scope, Param);
    if (const auto *ST = dyn_cast<ScalarType>(CastType)) {
      if (!ST->requiresFloat()) {
        if (Arg->hasIntegerConstantValue())
          return std::make_shared<IntLiteralResult>(
              ST, Arg->integerConstantValue());
        else
          return std::make_shared<IntCastResult>(ST, Arg);
      }
    } else if (const auto *PT = dyn_cast<PointerType>(CastType)) {
      return std::make_shared<PointerCastResult>(PT, Arg);
    }
    PrintFatalError("Unsupported type cast");
  } else if (Op->getName() == "address") {
    if (D->getNumArgs() != 2)
      PrintFatalError("'address' should have two arguments");
    Result::Ptr Arg = getCodeForDagArg(D, 0, Scope, Param);
    unsigned Alignment;
    if (auto *II = dyn_cast<IntInit>(D->getArg(1))) {
      Alignment = II->getValue();
    } else {
      PrintFatalError("'address' alignment argument should be an integer");
    }
    return std::make_shared<AddressResult>(Arg, Alignment);
  } else if (Op->getName() == "unsignedflag") {
    if (D->getNumArgs() != 1)
      PrintFatalError("unsignedflag should have exactly one argument");
    Record *TypeRec = cast<DefInit>(D->getArg(0))->getDef();
    if (!TypeRec->isSubClassOf("Type"))
      PrintFatalError("unsignedflag's argument should be a type");
    if (const auto *ST = dyn_cast<ScalarType>(getType(TypeRec, Param))) {
      return std::make_shared<IntLiteralResult>(
        getScalarType("u32"), ST->kind() == ScalarTypeKind::UnsignedInt);
    } else {
      PrintFatalError("unsignedflag's argument should be a scalar type");
    }
  } else if (Op->getName() == "bitsize") {
    if (D->getNumArgs() != 1)
      PrintFatalError("bitsize should have exactly one argument");
    Record *TypeRec = cast<DefInit>(D->getArg(0))->getDef();
    if (!TypeRec->isSubClassOf("Type"))
      PrintFatalError("bitsize's argument should be a type");
    if (const auto *ST = dyn_cast<ScalarType>(getType(TypeRec, Param))) {
      return std::make_shared<IntLiteralResult>(getScalarType("u32"),
                                                ST->sizeInBits());
    } else {
      PrintFatalError("bitsize's argument should be a scalar type");
    }
  } else {
    std::vector<Result::Ptr> Args;
    for (unsigned i = 0, e = D->getNumArgs(); i < e; ++i)
      Args.push_back(getCodeForDagArg(D, i, Scope, Param));
    if (Op->isSubClassOf("IRBuilderBase")) {
      std::set<unsigned> AddressArgs;
      std::map<unsigned, std::string> IntegerArgs;
      for (Record *sp : Op->getValueAsListOfDefs("special_params")) {
        unsigned Index = sp->getValueAsInt("index");
        if (sp->isSubClassOf("IRBuilderAddrParam")) {
          AddressArgs.insert(Index);
        } else if (sp->isSubClassOf("IRBuilderIntParam")) {
          IntegerArgs[Index] = std::string(sp->getValueAsString("type"));
        }
      }
      return std::make_shared<IRBuilderResult>(Op->getValueAsString("prefix"),
                                               Args, AddressArgs, IntegerArgs);
    } else if (Op->isSubClassOf("IRIntBase")) {
      std::vector<const Type *> ParamTypes;
      for (Record *RParam : Op->getValueAsListOfDefs("params"))
        ParamTypes.push_back(getType(RParam, Param));
      std::string IntName = std::string(Op->getValueAsString("intname"));
      if (Op->getValueAsBit("appendKind"))
        IntName += "_" + toLetter(cast<ScalarType>(Param)->kind());
      return std::make_shared<IRIntrinsicResult>(IntName, ParamTypes, Args);
    } else {
      PrintFatalError("Unsupported dag node " + Op->getName());
    }
  }
}

Result::Ptr EmitterBase::getCodeForDagArg(DagInit *D, unsigned ArgNum,
                                          const Result::Scope &Scope,
                                          const Type *Param) {
  Init *Arg = D->getArg(ArgNum);
  StringRef Name = D->getArgNameStr(ArgNum);

  if (!Name.empty()) {
    if (!isa<UnsetInit>(Arg))
      PrintFatalError(
          "dag operator argument should not have both a value and a name");
    auto it = Scope.find(std::string(Name));
    if (it == Scope.end())
      PrintFatalError("unrecognized variable name '" + Name + "'");
    return it->second;
  }

  // Sometimes the Arg is a bit. Prior to multiclass template argument
  // checking, integers would sneak through the bit declaration,
  // but now they really are bits.
  if (auto *BI = dyn_cast<BitInit>(Arg))
    return std::make_shared<IntLiteralResult>(getScalarType("u32"),
                                              BI->getValue());

  if (auto *II = dyn_cast<IntInit>(Arg))
    return std::make_shared<IntLiteralResult>(getScalarType("u32"),
                                              II->getValue());

  if (auto *DI = dyn_cast<DagInit>(Arg))
    return getCodeForDag(DI, Scope, Param);

  if (auto *DI = dyn_cast<DefInit>(Arg)) {
    Record *Rec = DI->getDef();
    if (Rec->isSubClassOf("Type")) {
      const Type *T = getType(Rec, Param);
      return std::make_shared<TypeResult>(T);
    }
  }

  PrintError("bad DAG argument type for code generation");
  PrintNote("DAG: " + D->getAsString());
  if (TypedInit *Typed = dyn_cast<TypedInit>(Arg))
    PrintNote("argument type: " + Typed->getType()->getAsString());
  PrintFatalNote("argument number " + Twine(ArgNum) + ": " + Arg->getAsString());
}

Result::Ptr EmitterBase::getCodeForArg(unsigned ArgNum, const Type *ArgType,
                                       bool Promote, bool Immediate) {
  Result::Ptr V = std::make_shared<BuiltinArgResult>(
      ArgNum, isa<PointerType>(ArgType), Immediate);

  if (Promote) {
    if (const auto *ST = dyn_cast<ScalarType>(ArgType)) {
      if (ST->isInteger() && ST->sizeInBits() < 32)
        V = std::make_shared<IntCastResult>(getScalarType("u32"), V);
    } else if (const auto *PT = dyn_cast<PredicateType>(ArgType)) {
      V = std::make_shared<IntCastResult>(getScalarType("u32"), V);
      V = std::make_shared<IRIntrinsicResult>("arm_mve_pred_i2v",
                                              std::vector<const Type *>{PT},
                                              std::vector<Result::Ptr>{V});
    }
  }

  return V;
}

ACLEIntrinsic::ACLEIntrinsic(EmitterBase &ME, Record *R, const Type *Param)
    : ReturnType(ME.getType(R->getValueAsDef("ret"), Param)) {
  // Derive the intrinsic's full name, by taking the name of the
  // Tablegen record (or override) and appending the suffix from its
  // parameter type. (If the intrinsic is unparametrised, its
  // parameter type will be given as Void, which returns the empty
  // string for acleSuffix.)
  StringRef BaseName =
      (R->isSubClassOf("NameOverride") ? R->getValueAsString("basename")
                                       : R->getName());
  StringRef overrideLetter = R->getValueAsString("overrideKindLetter");
  FullName =
      (Twine(BaseName) + Param->acleSuffix(std::string(overrideLetter))).str();

  // Derive the intrinsic's polymorphic name, by removing components from the
  // full name as specified by its 'pnt' member ('polymorphic name type'),
  // which indicates how many type suffixes to remove, and any other piece of
  // the name that should be removed.
  Record *PolymorphicNameType = R->getValueAsDef("pnt");
  SmallVector<StringRef, 8> NameParts;
  StringRef(FullName).split(NameParts, '_');
  for (unsigned i = 0, e = PolymorphicNameType->getValueAsInt(
                           "NumTypeSuffixesToDiscard");
       i < e; ++i)
    NameParts.pop_back();
  if (!PolymorphicNameType->isValueUnset("ExtraSuffixToDiscard")) {
    StringRef ExtraSuffix =
        PolymorphicNameType->getValueAsString("ExtraSuffixToDiscard");
    auto it = NameParts.end();
    while (it != NameParts.begin()) {
      --it;
      if (*it == ExtraSuffix) {
        NameParts.erase(it);
        break;
      }
    }
  }
  ShortName = join(std::begin(NameParts), std::end(NameParts), "_");

  BuiltinExtension = R->getValueAsString("builtinExtension");

  PolymorphicOnly = R->getValueAsBit("polymorphicOnly");
  NonEvaluating = R->getValueAsBit("nonEvaluating");
  HeaderOnly = R->getValueAsBit("headerOnly");

  // Process the intrinsic's argument list.
  DagInit *ArgsDag = R->getValueAsDag("args");
  Result::Scope Scope;
  for (unsigned i = 0, e = ArgsDag->getNumArgs(); i < e; ++i) {
    Init *TypeInit = ArgsDag->getArg(i);

    bool Promote = true;
    if (auto TypeDI = dyn_cast<DefInit>(TypeInit))
      if (TypeDI->getDef()->isSubClassOf("unpromoted"))
        Promote = false;

    // Work out the type of the argument, for use in the function prototype in
    // the header file.
    const Type *ArgType = ME.getType(TypeInit, Param);
    ArgTypes.push_back(ArgType);

    // If the argument is a subclass of Immediate, record the details about
    // what values it can take, for Sema checking.
    bool Immediate = false;
    if (auto TypeDI = dyn_cast<DefInit>(TypeInit)) {
      Record *TypeRec = TypeDI->getDef();
      if (TypeRec->isSubClassOf("Immediate")) {
        Immediate = true;

        Record *Bounds = TypeRec->getValueAsDef("bounds");
        ImmediateArg &IA = ImmediateArgs[i];
        if (Bounds->isSubClassOf("IB_ConstRange")) {
          IA.boundsType = ImmediateArg::BoundsType::ExplicitRange;
          IA.i1 = Bounds->getValueAsInt("lo");
          IA.i2 = Bounds->getValueAsInt("hi");
        } else if (Bounds->getName() == "IB_UEltValue") {
          IA.boundsType = ImmediateArg::BoundsType::UInt;
          IA.i1 = Param->sizeInBits();
        } else if (Bounds->getName() == "IB_LaneIndex") {
          IA.boundsType = ImmediateArg::BoundsType::ExplicitRange;
          IA.i1 = 0;
          IA.i2 = 128 / Param->sizeInBits() - 1;
        } else if (Bounds->isSubClassOf("IB_EltBit")) {
          IA.boundsType = ImmediateArg::BoundsType::ExplicitRange;
          IA.i1 = Bounds->getValueAsInt("base");
          const Type *T = ME.getType(Bounds->getValueAsDef("type"), Param);
          IA.i2 = IA.i1 + T->sizeInBits() - 1;
        } else {
          PrintFatalError("unrecognised ImmediateBounds subclass");
        }

        IA.ArgType = ArgType;

        if (!TypeRec->isValueUnset("extra")) {
          IA.ExtraCheckType = TypeRec->getValueAsString("extra");
          if (!TypeRec->isValueUnset("extraarg"))
            IA.ExtraCheckArgs = TypeRec->getValueAsString("extraarg");
        }
      }
    }

    // The argument will usually have a name in the arguments dag, which goes
    // into the variable-name scope that the code gen will refer to.
    StringRef ArgName = ArgsDag->getArgNameStr(i);
    if (!ArgName.empty())
      Scope[std::string(ArgName)] =
          ME.getCodeForArg(i, ArgType, Promote, Immediate);
  }

  // Finally, go through the codegen dag and translate it into a Result object
  // (with an arbitrary DAG of depended-on Results hanging off it).
  DagInit *CodeDag = R->getValueAsDag("codegen");
  Record *MainOp = cast<DefInit>(CodeDag->getOperator())->getDef();
  if (MainOp->isSubClassOf("CustomCodegen")) {
    // Or, if it's the special case of CustomCodegen, just accumulate
    // a list of parameters we're going to assign to variables before
    // breaking from the loop.
    CustomCodeGenArgs["CustomCodeGenType"] =
        (Twine("CustomCodeGen::") + MainOp->getValueAsString("type")).str();
    for (unsigned i = 0, e = CodeDag->getNumArgs(); i < e; ++i) {
      StringRef Name = CodeDag->getArgNameStr(i);
      if (Name.empty()) {
        PrintFatalError("Operands to CustomCodegen should have names");
      } else if (auto *II = dyn_cast<IntInit>(CodeDag->getArg(i))) {
        CustomCodeGenArgs[std::string(Name)] = itostr(II->getValue());
      } else if (auto *SI = dyn_cast<StringInit>(CodeDag->getArg(i))) {
        CustomCodeGenArgs[std::string(Name)] = std::string(SI->getValue());
      } else {
        PrintFatalError("Operands to CustomCodegen should be integers");
      }
    }
  } else {
    Code = ME.getCodeForDag(CodeDag, Scope, Param);
  }
}

EmitterBase::EmitterBase(RecordKeeper &Records) {
  // Construct the whole EmitterBase.

  // First, look up all the instances of PrimitiveType. This gives us the list
  // of vector typedefs we have to put in arm_mve.h, and also allows us to
  // collect all the useful ScalarType instances into a big list so that we can
  // use it for operations such as 'find the unsigned version of this signed
  // integer type'.
  for (Record *R : Records.getAllDerivedDefinitions("PrimitiveType"))
    ScalarTypes[std::string(R->getName())] = std::make_unique<ScalarType>(R);

  // Now go through the instances of Intrinsic, and for each one, iterate
  // through its list of type parameters making an ACLEIntrinsic for each one.
  for (Record *R : Records.getAllDerivedDefinitions("Intrinsic")) {
    for (Record *RParam : R->getValueAsListOfDefs("params")) {
      const Type *Param = getType(RParam, getVoidType());
      auto Intrinsic = std::make_unique<ACLEIntrinsic>(*this, R, Param);
      ACLEIntrinsics[Intrinsic->fullName()] = std::move(Intrinsic);
    }
  }
}

/// A wrapper on raw_string_ostream that contains its own buffer rather than
/// having to point it at one elsewhere. (In other words, it works just like
/// std::ostringstream; also, this makes it convenient to declare a whole array
/// of them at once.)
///
/// We have to set this up using multiple inheritance, to ensure that the
/// string member has been constructed before raw_string_ostream's constructor
/// is given a pointer to it.
class string_holder {
protected:
  std::string S;
};
class raw_self_contained_string_ostream : private string_holder,
                                          public raw_string_ostream {
public:
  raw_self_contained_string_ostream()
      : string_holder(), raw_string_ostream(S) {}
};

const char LLVMLicenseHeader[] =
    " *\n"
    " *\n"
    " * Part of the LLVM Project, under the Apache License v2.0 with LLVM"
    " Exceptions.\n"
    " * See https://llvm.org/LICENSE.txt for license information.\n"
    " * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception\n"
    " *\n"
    " *===-----------------------------------------------------------------"
    "------===\n"
    " */\n"
    "\n";

// Machinery for the grouping of intrinsics by similar codegen.
//
// The general setup is that 'MergeableGroup' stores the things that a set of
// similarly shaped intrinsics have in common: the text of their code
// generation, and the number and type of their parameter variables.
// MergeableGroup is the key in a std::map whose value is a set of
// OutputIntrinsic, which stores the ways in which a particular intrinsic
// specializes the MergeableGroup's generic description: the function name and
// the _values_ of the parameter variables.

struct ComparableStringVector : std::vector<std::string> {
  // Infrastructure: a derived class of vector<string> which comes with an
  // ordering, so that it can be used as a key in maps and an element in sets.
  // There's no requirement on the ordering beyond being deterministic.
  bool operator<(const ComparableStringVector &rhs) const {
    if (size() != rhs.size())
      return size() < rhs.size();
    for (size_t i = 0, e = size(); i < e; ++i)
      if ((*this)[i] != rhs[i])
        return (*this)[i] < rhs[i];
    return false;
  }
};

struct OutputIntrinsic {
  const ACLEIntrinsic *Int;
  std::string Name;
  ComparableStringVector ParamValues;
  bool operator<(const OutputIntrinsic &rhs) const {
    if (Name != rhs.Name)
      return Name < rhs.Name;
    return ParamValues < rhs.ParamValues;
  }
};
struct MergeableGroup {
  std::string Code;
  ComparableStringVector ParamTypes;
  bool operator<(const MergeableGroup &rhs) const {
    if (Code != rhs.Code)
      return Code < rhs.Code;
    return ParamTypes < rhs.ParamTypes;
  }
};

void EmitterBase::EmitBuiltinCG(raw_ostream &OS) {
  // Pass 1: generate code for all the intrinsics as if every type or constant
  // that can possibly be abstracted out into a parameter variable will be.
  // This identifies the sets of intrinsics we'll group together into a single
  // piece of code generation.

  std::map<MergeableGroup, std::set<OutputIntrinsic>> MergeableGroupsPrelim;

  for (const auto &kv : ACLEIntrinsics) {
    const ACLEIntrinsic &Int = *kv.second;
    if (Int.headerOnly())
      continue;

    MergeableGroup MG;
    OutputIntrinsic OI;

    OI.Int = &Int;
    OI.Name = Int.fullName();
    CodeGenParamAllocator ParamAllocPrelim{&MG.ParamTypes, &OI.ParamValues};
    raw_string_ostream OS(MG.Code);
    Int.genCode(OS, ParamAllocPrelim, 1);
    OS.flush();

    MergeableGroupsPrelim[MG].insert(OI);
  }

  // Pass 2: for each of those groups, optimize the parameter variable set by
  // eliminating 'parameters' that are the same for all intrinsics in the
  // group, and merging together pairs of parameter variables that take the
  // same values as each other for all intrinsics in the group.

  std::map<MergeableGroup, std::set<OutputIntrinsic>> MergeableGroups;

  for (const auto &kv : MergeableGroupsPrelim) {
    const MergeableGroup &MG = kv.first;
    std::vector<int> ParamNumbers;
    std::map<ComparableStringVector, int> ParamNumberMap;

    // Loop over the parameters for this group.
    for (size_t i = 0, e = MG.ParamTypes.size(); i < e; ++i) {
      // Is this parameter the same for all intrinsics in the group?
      const OutputIntrinsic &OI_first = *kv.second.begin();
      bool Constant = all_of(kv.second, [&](const OutputIntrinsic &OI) {
        return OI.ParamValues[i] == OI_first.ParamValues[i];
      });

      // If so, record it as -1, meaning 'no parameter variable needed'. Then
      // the corresponding call to allocParam in pass 2 will not generate a
      // variable at all, and just use the value inline.
      if (Constant) {
        ParamNumbers.push_back(-1);
        continue;
      }

      // Otherwise, make a list of the values this parameter takes for each
      // intrinsic, and see if that value vector matches anything we already
      // have. We also record the parameter type, so that we don't accidentally
      // match up two parameter variables with different types. (Not that
      // there's much chance of them having textually equivalent values, but in
      // _principle_ it could happen.)
      ComparableStringVector key;
      key.push_back(MG.ParamTypes[i]);
      for (const auto &OI : kv.second)
        key.push_back(OI.ParamValues[i]);

      auto Found = ParamNumberMap.find(key);
      if (Found != ParamNumberMap.end()) {
        // Yes, an existing parameter variable can be reused for this.
        ParamNumbers.push_back(Found->second);
        continue;
      }

      // No, we need a new parameter variable.
      int ExistingIndex = ParamNumberMap.size();
      ParamNumberMap[key] = ExistingIndex;
      ParamNumbers.push_back(ExistingIndex);
    }

    // Now we're ready to do the pass 2 code generation, which will emit the
    // reduced set of parameter variables we've just worked out.

    for (const auto &OI_prelim : kv.second) {
      const ACLEIntrinsic *Int = OI_prelim.Int;

      MergeableGroup MG;
      OutputIntrinsic OI;

      OI.Int = OI_prelim.Int;
      OI.Name = OI_prelim.Name;
      CodeGenParamAllocator ParamAlloc{&MG.ParamTypes, &OI.ParamValues,
                                       &ParamNumbers};
      raw_string_ostream OS(MG.Code);
      Int->genCode(OS, ParamAlloc, 2);
      OS.flush();

      MergeableGroups[MG].insert(OI);
    }
  }

  // Output the actual C++ code.

  for (const auto &kv : MergeableGroups) {
    const MergeableGroup &MG = kv.first;

    // List of case statements in the main switch on BuiltinID, and an open
    // brace.
    const char *prefix = "";
    for (const auto &OI : kv.second) {
      OS << prefix << "case ARM::BI__builtin_arm_" << OI.Int->builtinExtension()
         << "_" << OI.Name << ":";

      prefix = "\n";
    }
    OS << " {\n";

    if (!MG.ParamTypes.empty()) {
      // If we've got some parameter variables, then emit their declarations...
      for (size_t i = 0, e = MG.ParamTypes.size(); i < e; ++i) {
        StringRef Type = MG.ParamTypes[i];
        OS << "  " << Type;
        if (!Type.endswith("*"))
          OS << " ";
        OS << " Param" << utostr(i) << ";\n";
      }

      // ... and an inner switch on BuiltinID that will fill them in with each
      // individual intrinsic's values.
      OS << "  switch (BuiltinID) {\n";
      for (const auto &OI : kv.second) {
        OS << "  case ARM::BI__builtin_arm_" << OI.Int->builtinExtension()
           << "_" << OI.Name << ":\n";
        for (size_t i = 0, e = MG.ParamTypes.size(); i < e; ++i)
          OS << "    Param" << utostr(i) << " = " << OI.ParamValues[i] << ";\n";
        OS << "    break;\n";
      }
      OS << "  }\n";
    }

    // And finally, output the code, and close the outer pair of braces. (The
    // code will always end with a 'return' statement, so we need not insert a
    // 'break' here.)
    OS << MG.Code << "}\n";
  }
}

void EmitterBase::EmitBuiltinAliases(raw_ostream &OS) {
  // Build a sorted table of:
  // - intrinsic id number
  // - full name
  // - polymorphic name or -1
  StringToOffsetTable StringTable;
  OS << "static const IntrinToName MapData[] = {\n";
  for (const auto &kv : ACLEIntrinsics) {
    const ACLEIntrinsic &Int = *kv.second;
    if (Int.headerOnly())
      continue;
    int32_t ShortNameOffset =
        Int.polymorphic() ? StringTable.GetOrAddStringOffset(Int.shortName())
                          : -1;
    OS << "  { ARM::BI__builtin_arm_" << Int.builtinExtension() << "_"
       << Int.fullName() << ", "
       << StringTable.GetOrAddStringOffset(Int.fullName()) << ", "
       << ShortNameOffset << "},\n";
  }
  OS << "};\n\n";

  OS << "ArrayRef<IntrinToName> Map(MapData);\n\n";

  OS << "static const char IntrinNames[] = {\n";
  StringTable.EmitString(OS);
  OS << "};\n\n";
}

void EmitterBase::GroupSemaChecks(
    std::map<std::string, std::set<std::string>> &Checks) {
  for (const auto &kv : ACLEIntrinsics) {
    const ACLEIntrinsic &Int = *kv.second;
    if (Int.headerOnly())
      continue;
    std::string Check = Int.genSema();
    if (!Check.empty())
      Checks[Check].insert(Int.fullName());
  }
}

// -----------------------------------------------------------------------------
// The class used for generating arm_mve.h and related Clang bits
//

class MveEmitter : public EmitterBase {
public:
  MveEmitter(RecordKeeper &Records) : EmitterBase(Records){};
  void EmitHeader(raw_ostream &OS) override;
  void EmitBuiltinDef(raw_ostream &OS) override;
  void EmitBuiltinSema(raw_ostream &OS) override;
};

void MveEmitter::EmitHeader(raw_ostream &OS) {
  // Accumulate pieces of the header file that will be enabled under various
  // different combinations of #ifdef. The index into parts[] is made up of
  // the following bit flags.
  constexpr unsigned Float = 1;
  constexpr unsigned UseUserNamespace = 2;

  constexpr unsigned NumParts = 4;
  raw_self_contained_string_ostream parts[NumParts];

  // Write typedefs for all the required vector types, and a few scalar
  // types that don't already have the name we want them to have.

  parts[0] << "typedef uint16_t mve_pred16_t;\n";
  parts[Float] << "typedef __fp16 float16_t;\n"
                  "typedef float float32_t;\n";
  for (const auto &kv : ScalarTypes) {
    const ScalarType *ST = kv.second.get();
    if (ST->hasNonstandardName())
      continue;
    raw_ostream &OS = parts[ST->requiresFloat() ? Float : 0];
    const VectorType *VT = getVectorType(ST);

    OS << "typedef __attribute__((__neon_vector_type__(" << VT->lanes()
       << "), __clang_arm_mve_strict_polymorphism)) " << ST->cName() << " "
       << VT->cName() << ";\n";

    // Every vector type also comes with a pair of multi-vector types for
    // the VLD2 and VLD4 instructions.
    for (unsigned n = 2; n <= 4; n += 2) {
      const MultiVectorType *MT = getMultiVectorType(n, VT);
      OS << "typedef struct { " << VT->cName() << " val[" << n << "]; } "
         << MT->cName() << ";\n";
    }
  }
  parts[0] << "\n";
  parts[Float] << "\n";

  // Write declarations for all the intrinsics.

  for (const auto &kv : ACLEIntrinsics) {
    const ACLEIntrinsic &Int = *kv.second;

    // We generate each intrinsic twice, under its full unambiguous
    // name and its shorter polymorphic name (if the latter exists).
    for (bool Polymorphic : {false, true}) {
      if (Polymorphic && !Int.polymorphic())
        continue;
      if (!Polymorphic && Int.polymorphicOnly())
        continue;

      // We also generate each intrinsic under a name like __arm_vfooq
      // (which is in C language implementation namespace, so it's
      // safe to define in any conforming user program) and a shorter
      // one like vfooq (which is in user namespace, so a user might
      // reasonably have used it for something already). If so, they
      // can #define __ARM_MVE_PRESERVE_USER_NAMESPACE before
      // including the header, which will suppress the shorter names
      // and leave only the implementation-namespace ones. Then they
      // have to write __arm_vfooq everywhere, of course.

      for (bool UserNamespace : {false, true}) {
        raw_ostream &OS = parts[(Int.requiresFloat() ? Float : 0) |
                                (UserNamespace ? UseUserNamespace : 0)];

        // Make the name of the function in this declaration.

        std::string FunctionName =
            Polymorphic ? Int.shortName() : Int.fullName();
        if (!UserNamespace)
          FunctionName = "__arm_" + FunctionName;

        // Make strings for the types involved in the function's
        // prototype.

        std::string RetTypeName = Int.returnType()->cName();
        if (!StringRef(RetTypeName).endswith("*"))
          RetTypeName += " ";

        std::vector<std::string> ArgTypeNames;
        for (const Type *ArgTypePtr : Int.argTypes())
          ArgTypeNames.push_back(ArgTypePtr->cName());
        std::string ArgTypesString =
            join(std::begin(ArgTypeNames), std::end(ArgTypeNames), ", ");

        // Emit the actual declaration. All these functions are
        // declared 'static inline' without a body, which is fine
        // provided clang recognizes them as builtins, and has the
        // effect that this type signature is used in place of the one
        // that Builtins.def didn't provide. That's how we can get
        // structure types that weren't defined until this header was
        // included to be part of the type signature of a builtin that
        // was known to clang already.
        //
        // The declarations use __attribute__(__clang_arm_builtin_alias),
        // so that each function declared will be recognized as the
        // appropriate MVE builtin in spite of its user-facing name.
        //
        // (That's better than making them all wrapper functions,
        // partly because it avoids any compiler error message citing
        // the wrapper function definition instead of the user's code,
        // and mostly because some MVE intrinsics have arguments
        // required to be compile-time constants, and that property
        // can't be propagated through a wrapper function. It can be
        // propagated through a macro, but macros can't be overloaded
        // on argument types very easily - you have to use _Generic,
        // which makes error messages very confusing when the user
        // gets it wrong.)
        //
        // Finally, the polymorphic versions of the intrinsics are
        // also defined with __attribute__(overloadable), so that when
        // the same name is defined with several type signatures, the
        // right thing happens. Each one of the overloaded
        // declarations is given a different builtin id, which
        // has exactly the effect we want: first clang resolves the
        // overload to the right function, then it knows which builtin
        // it's referring to, and then the Sema checking for that
        // builtin can check further things like the constant
        // arguments.
        //
        // One more subtlety is the newline just before the return
        // type name. That's a cosmetic tweak to make the error
        // messages legible if the user gets the types wrong in a call
        // to a polymorphic function: this way, clang will print just
        // the _final_ line of each declaration in the header, to show
        // the type signatures that would have been legal. So all the
        // confusing machinery with __attribute__ is left out of the
        // error message, and the user sees something that's more or
        // less self-documenting: "here's a list of actually readable
        // type signatures for vfooq(), and here's why each one didn't
        // match your call".

        OS << "static __inline__ __attribute__(("
           << (Polymorphic ? "__overloadable__, " : "")
           << "__clang_arm_builtin_alias(__builtin_arm_mve_" << Int.fullName()
           << ")))\n"
           << RetTypeName << FunctionName << "(" << ArgTypesString << ");\n";
      }
    }
  }
  for (auto &part : parts)
    part << "\n";

  // Now we've finished accumulating bits and pieces into the parts[] array.
  // Put it all together to write the final output file.

  OS << "/*===---- arm_mve.h - ARM MVE intrinsics "
        "-----------------------------------===\n"
     << LLVMLicenseHeader
     << "#ifndef __ARM_MVE_H\n"
        "#define __ARM_MVE_H\n"
        "\n"
        "#if !__ARM_FEATURE_MVE\n"
        "#error \"MVE support not enabled\"\n"
        "#endif\n"
        "\n"
        "#include <stdint.h>\n"
        "\n"
        "#ifdef __cplusplus\n"
        "extern \"C\" {\n"
        "#endif\n"
        "\n";

  for (size_t i = 0; i < NumParts; ++i) {
    std::vector<std::string> conditions;
    if (i & Float)
      conditions.push_back("(__ARM_FEATURE_MVE & 2)");
    if (i & UseUserNamespace)
      conditions.push_back("(!defined __ARM_MVE_PRESERVE_USER_NAMESPACE)");

    std::string condition =
        join(std::begin(conditions), std::end(conditions), " && ");
    if (!condition.empty())
      OS << "#if " << condition << "\n\n";
    OS << parts[i].str();
    if (!condition.empty())
      OS << "#endif /* " << condition << " */\n\n";
  }

  OS << "#ifdef __cplusplus\n"
        "} /* extern \"C\" */\n"
        "#endif\n"
        "\n"
        "#endif /* __ARM_MVE_H */\n";
}

void MveEmitter::EmitBuiltinDef(raw_ostream &OS) {
  for (const auto &kv : ACLEIntrinsics) {
    const ACLEIntrinsic &Int = *kv.second;
    OS << "BUILTIN(__builtin_arm_mve_" << Int.fullName()
       << ", \"\", \"n\")\n";
  }

  std::set<std::string> ShortNamesSeen;

  for (const auto &kv : ACLEIntrinsics) {
    const ACLEIntrinsic &Int = *kv.second;
    if (Int.polymorphic()) {
      StringRef Name = Int.shortName();
      if (ShortNamesSeen.find(std::string(Name)) == ShortNamesSeen.end()) {
        OS << "BUILTIN(__builtin_arm_mve_" << Name << ", \"vi.\", \"nt";
        if (Int.nonEvaluating())
          OS << "u"; // indicate that this builtin doesn't evaluate its args
        OS << "\")\n";
        ShortNamesSeen.insert(std::string(Name));
      }
    }
  }
}

void MveEmitter::EmitBuiltinSema(raw_ostream &OS) {
  std::map<std::string, std::set<std::string>> Checks;
  GroupSemaChecks(Checks);

  for (const auto &kv : Checks) {
    for (StringRef Name : kv.second)
      OS << "case ARM::BI__builtin_arm_mve_" << Name << ":\n";
    OS << "  return " << kv.first;
  }
}

// -----------------------------------------------------------------------------
// Class that describes an ACLE intrinsic implemented as a macro.
//
// This class is used when the intrinsic is polymorphic in 2 or 3 types, but we
// want to avoid a combinatorial explosion by reinterpreting the arguments to
// fixed types.

class FunctionMacro {
  std::vector<StringRef> Params;
  StringRef Definition;

public:
  FunctionMacro(const Record &R);

  const std::vector<StringRef> &getParams() const { return Params; }
  StringRef getDefinition() const { return Definition; }
};

FunctionMacro::FunctionMacro(const Record &R) {
  Params = R.getValueAsListOfStrings("params");
  Definition = R.getValueAsString("definition");
}

// -----------------------------------------------------------------------------
// The class used for generating arm_cde.h and related Clang bits
//

class CdeEmitter : public EmitterBase {
  std::map<StringRef, FunctionMacro> FunctionMacros;

public:
  CdeEmitter(RecordKeeper &Records);
  void EmitHeader(raw_ostream &OS) override;
  void EmitBuiltinDef(raw_ostream &OS) override;
  void EmitBuiltinSema(raw_ostream &OS) override;
};

CdeEmitter::CdeEmitter(RecordKeeper &Records) : EmitterBase(Records) {
  for (Record *R : Records.getAllDerivedDefinitions("FunctionMacro"))
    FunctionMacros.emplace(R->getName(), FunctionMacro(*R));
}

void CdeEmitter::EmitHeader(raw_ostream &OS) {
  // Accumulate pieces of the header file that will be enabled under various
  // different combinations of #ifdef. The index into parts[] is one of the
  // following:
  constexpr unsigned None = 0;
  constexpr unsigned MVE = 1;
  constexpr unsigned MVEFloat = 2;

  constexpr unsigned NumParts = 3;
  raw_self_contained_string_ostream parts[NumParts];

  // Write typedefs for all the required vector types, and a few scalar
  // types that don't already have the name we want them to have.

  parts[MVE] << "typedef uint16_t mve_pred16_t;\n";
  parts[MVEFloat] << "typedef __fp16 float16_t;\n"
                     "typedef float float32_t;\n";
  for (const auto &kv : ScalarTypes) {
    const ScalarType *ST = kv.second.get();
    if (ST->hasNonstandardName())
      continue;
    // We don't have float64x2_t
    if (ST->kind() == ScalarTypeKind::Float && ST->sizeInBits() == 64)
      continue;
    raw_ostream &OS = parts[ST->requiresFloat() ? MVEFloat : MVE];
    const VectorType *VT = getVectorType(ST);

    OS << "typedef __attribute__((__neon_vector_type__(" << VT->lanes()
       << "), __clang_arm_mve_strict_polymorphism)) " << ST->cName() << " "
       << VT->cName() << ";\n";
  }
  parts[MVE] << "\n";
  parts[MVEFloat] << "\n";

  // Write declarations for all the intrinsics.

  for (const auto &kv : ACLEIntrinsics) {
    const ACLEIntrinsic &Int = *kv.second;

    // We generate each intrinsic twice, under its full unambiguous
    // name and its shorter polymorphic name (if the latter exists).
    for (bool Polymorphic : {false, true}) {
      if (Polymorphic && !Int.polymorphic())
        continue;
      if (!Polymorphic && Int.polymorphicOnly())
        continue;

      raw_ostream &OS =
          parts[Int.requiresFloat() ? MVEFloat
                                    : Int.requiresMVE() ? MVE : None];

      // Make the name of the function in this declaration.
      std::string FunctionName =
          "__arm_" + (Polymorphic ? Int.shortName() : Int.fullName());

      // Make strings for the types involved in the function's
      // prototype.
      std::string RetTypeName = Int.returnType()->cName();
      if (!StringRef(RetTypeName).endswith("*"))
        RetTypeName += " ";

      std::vector<std::string> ArgTypeNames;
      for (const Type *ArgTypePtr : Int.argTypes())
        ArgTypeNames.push_back(ArgTypePtr->cName());
      std::string ArgTypesString =
          join(std::begin(ArgTypeNames), std::end(ArgTypeNames), ", ");

      // Emit the actual declaration. See MveEmitter::EmitHeader for detailed
      // comments
      OS << "static __inline__ __attribute__(("
         << (Polymorphic ? "__overloadable__, " : "")
         << "__clang_arm_builtin_alias(__builtin_arm_" << Int.builtinExtension()
         << "_" << Int.fullName() << ")))\n"
         << RetTypeName << FunctionName << "(" << ArgTypesString << ");\n";
    }
  }

  for (const auto &kv : FunctionMacros) {
    StringRef Name = kv.first;
    const FunctionMacro &FM = kv.second;

    raw_ostream &OS = parts[MVE];
    OS << "#define "
       << "__arm_" << Name << "(" << join(FM.getParams(), ", ") << ") "
       << FM.getDefinition() << "\n";
  }

  for (auto &part : parts)
    part << "\n";

  // Now we've finished accumulating bits and pieces into the parts[] array.
  // Put it all together to write the final output file.

  OS << "/*===---- arm_cde.h - ARM CDE intrinsics "
        "-----------------------------------===\n"
     << LLVMLicenseHeader
     << "#ifndef __ARM_CDE_H\n"
        "#define __ARM_CDE_H\n"
        "\n"
        "#if !__ARM_FEATURE_CDE\n"
        "#error \"CDE support not enabled\"\n"
        "#endif\n"
        "\n"
        "#include <stdint.h>\n"
        "\n"
        "#ifdef __cplusplus\n"
        "extern \"C\" {\n"
        "#endif\n"
        "\n";

  for (size_t i = 0; i < NumParts; ++i) {
    std::string condition;
    if (i == MVEFloat)
      condition = "__ARM_FEATURE_MVE & 2";
    else if (i == MVE)
      condition = "__ARM_FEATURE_MVE";

    if (!condition.empty())
      OS << "#if " << condition << "\n\n";
    OS << parts[i].str();
    if (!condition.empty())
      OS << "#endif /* " << condition << " */\n\n";
  }

  OS << "#ifdef __cplusplus\n"
        "} /* extern \"C\" */\n"
        "#endif\n"
        "\n"
        "#endif /* __ARM_CDE_H */\n";
}

void CdeEmitter::EmitBuiltinDef(raw_ostream &OS) {
  for (const auto &kv : ACLEIntrinsics) {
    if (kv.second->headerOnly())
      continue;
    const ACLEIntrinsic &Int = *kv.second;
    OS << "BUILTIN(__builtin_arm_cde_" << Int.fullName()
       << ", \"\", \"ncU\")\n";
  }
}

void CdeEmitter::EmitBuiltinSema(raw_ostream &OS) {
  std::map<std::string, std::set<std::string>> Checks;
  GroupSemaChecks(Checks);

  for (const auto &kv : Checks) {
    for (StringRef Name : kv.second)
      OS << "case ARM::BI__builtin_arm_cde_" << Name << ":\n";
    OS << "  Err = " << kv.first << "  break;\n";
  }
}

} // namespace

namespace clang {

// MVE

void EmitMveHeader(RecordKeeper &Records, raw_ostream &OS) {
  MveEmitter(Records).EmitHeader(OS);
}

void EmitMveBuiltinDef(RecordKeeper &Records, raw_ostream &OS) {
  MveEmitter(Records).EmitBuiltinDef(OS);
}

void EmitMveBuiltinSema(RecordKeeper &Records, raw_ostream &OS) {
  MveEmitter(Records).EmitBuiltinSema(OS);
}

void EmitMveBuiltinCG(RecordKeeper &Records, raw_ostream &OS) {
  MveEmitter(Records).EmitBuiltinCG(OS);
}

void EmitMveBuiltinAliases(RecordKeeper &Records, raw_ostream &OS) {
  MveEmitter(Records).EmitBuiltinAliases(OS);
}

// CDE

void EmitCdeHeader(RecordKeeper &Records, raw_ostream &OS) {
  CdeEmitter(Records).EmitHeader(OS);
}

void EmitCdeBuiltinDef(RecordKeeper &Records, raw_ostream &OS) {
  CdeEmitter(Records).EmitBuiltinDef(OS);
}

void EmitCdeBuiltinSema(RecordKeeper &Records, raw_ostream &OS) {
  CdeEmitter(Records).EmitBuiltinSema(OS);
}

void EmitCdeBuiltinCG(RecordKeeper &Records, raw_ostream &OS) {
  CdeEmitter(Records).EmitBuiltinCG(OS);
}

void EmitCdeBuiltinAliases(RecordKeeper &Records, raw_ostream &OS) {
  CdeEmitter(Records).EmitBuiltinAliases(OS);
}

} // end namespace clang
