//===- CodeGenTarget.h - Target Class Wrapper -------------------*- 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 wrappers for the Target class and related global
// functionality.  This makes it easier to access the data and provides a single
// place that needs to check it for validity.  All of these classes abort
// on error conditions.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_UTILS_TABLEGEN_CODEGENTARGET_H
#define LLVM_UTILS_TABLEGEN_CODEGENTARGET_H

#include "CodeGenHwModes.h"
#include "CodeGenRegisters.h"
#include "InfoByHwMode.h"
#include "SDNodeProperties.h"

namespace llvm {

class RecordKeeper;
class Record;
class CodeGenInstruction;
struct CodeGenRegister;
class CodeGenSchedModels;
class CodeGenTarget;

/// getValueType - Return the MVT::SimpleValueType that the specified TableGen
/// record corresponds to.
MVT::SimpleValueType getValueType(Record *Rec);

StringRef getName(MVT::SimpleValueType T);
StringRef getEnumName(MVT::SimpleValueType T);

/// getQualifiedName - Return the name of the specified record, with a
/// namespace qualifier if the record contains one.
std::string getQualifiedName(const Record *R);

/// CodeGenTarget - This class corresponds to the Target class in the .td files.
///
class CodeGenTarget {
  RecordKeeper &Records;
  Record *TargetRec;

  mutable DenseMap<const Record*,
                   std::unique_ptr<CodeGenInstruction>> Instructions;
  mutable std::unique_ptr<CodeGenRegBank> RegBank;
  mutable std::vector<Record*> RegAltNameIndices;
  mutable SmallVector<ValueTypeByHwMode, 8> LegalValueTypes;
  CodeGenHwModes CGH;
  void ReadRegAltNameIndices() const;
  void ReadInstructions() const;
  void ReadLegalValueTypes() const;

  mutable std::unique_ptr<CodeGenSchedModels> SchedModels;

  mutable StringRef InstNamespace;
  mutable std::vector<const CodeGenInstruction*> InstrsByEnum;
  mutable unsigned NumPseudoInstructions = 0;
public:
  CodeGenTarget(RecordKeeper &Records);
  ~CodeGenTarget();

  Record *getTargetRecord() const { return TargetRec; }
  StringRef getName() const;

  /// getInstNamespace - Return the target-specific instruction namespace.
  ///
  StringRef getInstNamespace() const;

  /// getRegNamespace - Return the target-specific register namespace.
  StringRef getRegNamespace() const;

  /// getInstructionSet - Return the InstructionSet object.
  ///
  Record *getInstructionSet() const;

  /// getAllowRegisterRenaming - Return the AllowRegisterRenaming flag value for
  /// this target.
  ///
  bool getAllowRegisterRenaming() const;

  /// getAsmParser - Return the AssemblyParser definition for this target.
  ///
  Record *getAsmParser() const;

  /// getAsmParserVariant - Return the AssemblyParserVariant definition for
  /// this target.
  ///
  Record *getAsmParserVariant(unsigned i) const;

  /// getAsmParserVariantCount - Return the AssemblyParserVariant definition
  /// available for this target.
  ///
  unsigned getAsmParserVariantCount() const;

  /// getAsmWriter - Return the AssemblyWriter definition for this target.
  ///
  Record *getAsmWriter() const;

  /// getRegBank - Return the register bank description.
  CodeGenRegBank &getRegBank() const;

  /// Return the largest register class on \p RegBank which supports \p Ty and
  /// covers \p SubIdx if it exists.
  Optional<CodeGenRegisterClass *>
  getSuperRegForSubReg(const ValueTypeByHwMode &Ty, CodeGenRegBank &RegBank,
                       const CodeGenSubRegIndex *SubIdx,
                       bool MustBeAllocatable = false) const;

  /// getRegisterByName - If there is a register with the specific AsmName,
  /// return it.
  const CodeGenRegister *getRegisterByName(StringRef Name) const;

  const std::vector<Record*> &getRegAltNameIndices() const {
    if (RegAltNameIndices.empty()) ReadRegAltNameIndices();
    return RegAltNameIndices;
  }

  const CodeGenRegisterClass &getRegisterClass(Record *R) const {
    return *getRegBank().getRegClass(R);
  }

  /// getRegisterVTs - Find the union of all possible SimpleValueTypes for the
  /// specified physical register.
  std::vector<ValueTypeByHwMode> getRegisterVTs(Record *R) const;

  ArrayRef<ValueTypeByHwMode> getLegalValueTypes() const {
    if (LegalValueTypes.empty())
      ReadLegalValueTypes();
    return LegalValueTypes;
  }

  CodeGenSchedModels &getSchedModels() const;

  const CodeGenHwModes &getHwModes() const { return CGH; }

private:
  DenseMap<const Record*, std::unique_ptr<CodeGenInstruction>> &
  getInstructions() const {
    if (Instructions.empty()) ReadInstructions();
    return Instructions;
  }
public:

  CodeGenInstruction &getInstruction(const Record *InstRec) const {
    if (Instructions.empty()) ReadInstructions();
    auto I = Instructions.find(InstRec);
    assert(I != Instructions.end() && "Not an instruction");
    return *I->second;
  }

  /// Returns the number of predefined instructions.
  static unsigned getNumFixedInstructions();

  /// Returns the number of pseudo instructions.
  unsigned getNumPseudoInstructions() const {
    if (InstrsByEnum.empty())
      ComputeInstrsByEnum();
    return NumPseudoInstructions;
  }

  /// Return all of the instructions defined by the target, ordered by their
  /// enum value.
  /// The following order of instructions is also guaranteed:
  /// - fixed / generic instructions as declared in TargetOpcodes.def, in order;
  /// - pseudo instructions in lexicographical order sorted by name;
  /// - other instructions in lexicographical order sorted by name.
  ArrayRef<const CodeGenInstruction *> getInstructionsByEnumValue() const {
    if (InstrsByEnum.empty())
      ComputeInstrsByEnum();
    return InstrsByEnum;
  }

  typedef ArrayRef<const CodeGenInstruction *>::const_iterator inst_iterator;
  inst_iterator inst_begin() const{return getInstructionsByEnumValue().begin();}
  inst_iterator inst_end() const { return getInstructionsByEnumValue().end(); }


  /// isLittleEndianEncoding - are instruction bit patterns defined as  [0..n]?
  ///
  bool isLittleEndianEncoding() const;

  /// reverseBitsForLittleEndianEncoding - For little-endian instruction bit
  /// encodings, reverse the bit order of all instructions.
  void reverseBitsForLittleEndianEncoding();

  /// guessInstructionProperties - should we just guess unset instruction
  /// properties?
  bool guessInstructionProperties() const;

private:
  void ComputeInstrsByEnum() const;
};

/// ComplexPattern - ComplexPattern info, corresponding to the ComplexPattern
/// tablegen class in TargetSelectionDAG.td
class ComplexPattern {
  Record *Ty;
  unsigned NumOperands;
  std::string SelectFunc;
  std::vector<Record*> RootNodes;
  unsigned Properties; // Node properties
  unsigned Complexity;
public:
  ComplexPattern(Record *R);

  Record *getValueType() const { return Ty; }
  unsigned getNumOperands() const { return NumOperands; }
  const std::string &getSelectFunc() const { return SelectFunc; }
  const std::vector<Record*> &getRootNodes() const {
    return RootNodes;
  }
  bool hasProperty(enum SDNP Prop) const { return Properties & (1 << Prop); }
  unsigned getComplexity() const { return Complexity; }
};

} // End llvm namespace

#endif
