123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410 |
- //===- CodeGenInstruction.h - Instruction 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 a wrapper class for the 'Instruction' TableGen class.
- //
- //===----------------------------------------------------------------------===//
- #ifndef LLVM_UTILS_TABLEGEN_CODEGENINSTRUCTION_H
- #define LLVM_UTILS_TABLEGEN_CODEGENINSTRUCTION_H
- #include "llvm/ADT/BitVector.h"
- #include "llvm/ADT/StringMap.h"
- #include "llvm/ADT/StringRef.h"
- #include "llvm/Support/MachineValueType.h"
- #include <cassert>
- #include <string>
- #include <utility>
- #include <vector>
- namespace llvm {
- class SMLoc;
- template <typename T> class ArrayRef;
- class Record;
- class DagInit;
- class CodeGenTarget;
- class CGIOperandList {
- public:
- class ConstraintInfo {
- enum { None, EarlyClobber, Tied } Kind = None;
- unsigned OtherTiedOperand = 0;
- public:
- ConstraintInfo() = default;
- static ConstraintInfo getEarlyClobber() {
- ConstraintInfo I;
- I.Kind = EarlyClobber;
- I.OtherTiedOperand = 0;
- return I;
- }
- static ConstraintInfo getTied(unsigned Op) {
- ConstraintInfo I;
- I.Kind = Tied;
- I.OtherTiedOperand = Op;
- return I;
- }
- bool isNone() const { return Kind == None; }
- bool isEarlyClobber() const { return Kind == EarlyClobber; }
- bool isTied() const { return Kind == Tied; }
- unsigned getTiedOperand() const {
- assert(isTied());
- return OtherTiedOperand;
- }
- bool operator==(const ConstraintInfo &RHS) const {
- if (Kind != RHS.Kind)
- return false;
- if (Kind == Tied && OtherTiedOperand != RHS.OtherTiedOperand)
- return false;
- return true;
- }
- bool operator!=(const ConstraintInfo &RHS) const {
- return !(*this == RHS);
- }
- };
- /// OperandInfo - The information we keep track of for each operand in the
- /// operand list for a tablegen instruction.
- struct OperandInfo {
- /// Rec - The definition this operand is declared as.
- ///
- Record *Rec;
- /// Name - If this operand was assigned a symbolic name, this is it,
- /// otherwise, it's empty.
- std::string Name;
- /// The names of sub-operands, if given, otherwise empty.
- std::vector<std::string> SubOpNames;
- /// PrinterMethodName - The method used to print operands of this type in
- /// the asmprinter.
- std::string PrinterMethodName;
- /// The method used to get the machine operand value for binary
- /// encoding, per sub-operand. If empty, uses "getMachineOpValue".
- std::vector<std::string> EncoderMethodNames;
- /// OperandType - A value from MCOI::OperandType representing the type of
- /// the operand.
- std::string OperandType;
- /// MIOperandNo - Currently (this is meant to be phased out), some logical
- /// operands correspond to multiple MachineInstr operands. In the X86
- /// target for example, one address operand is represented as 4
- /// MachineOperands. Because of this, the operand number in the
- /// OperandList may not match the MachineInstr operand num. Until it
- /// does, this contains the MI operand index of this operand.
- unsigned MIOperandNo;
- unsigned MINumOperands; // The number of operands.
- /// DoNotEncode - Bools are set to true in this vector for each operand in
- /// the DisableEncoding list. These should not be emitted by the code
- /// emitter.
- BitVector DoNotEncode;
- /// MIOperandInfo - Default MI operand type. Note an operand may be made
- /// up of multiple MI operands.
- DagInit *MIOperandInfo;
- /// Constraint info for this operand. This operand can have pieces, so we
- /// track constraint info for each.
- std::vector<ConstraintInfo> Constraints;
- OperandInfo(Record *R, const std::string &N, const std::string &PMN,
- const std::string &OT, unsigned MION, unsigned MINO,
- DagInit *MIOI)
- : Rec(R), Name(N), SubOpNames(MINO), PrinterMethodName(PMN),
- EncoderMethodNames(MINO), OperandType(OT), MIOperandNo(MION),
- MINumOperands(MINO), DoNotEncode(MINO), MIOperandInfo(MIOI),
- Constraints(MINO) {}
- /// getTiedOperand - If this operand is tied to another one, return the
- /// other operand number. Otherwise, return -1.
- int getTiedRegister() const {
- for (unsigned j = 0, e = Constraints.size(); j != e; ++j) {
- const CGIOperandList::ConstraintInfo &CI = Constraints[j];
- if (CI.isTied()) return CI.getTiedOperand();
- }
- return -1;
- }
- };
- CGIOperandList(Record *D);
- Record *TheDef; // The actual record containing this OperandList.
- /// NumDefs - Number of def operands declared, this is the number of
- /// elements in the instruction's (outs) list.
- ///
- unsigned NumDefs;
- /// OperandList - The list of declared operands, along with their declared
- /// type (which is a record).
- std::vector<OperandInfo> OperandList;
- /// SubOpAliases - List of alias names for suboperands.
- StringMap<std::pair<unsigned, unsigned>> SubOpAliases;
- // Information gleaned from the operand list.
- bool isPredicable;
- bool hasOptionalDef;
- bool isVariadic;
- // Provide transparent accessors to the operand list.
- bool empty() const { return OperandList.empty(); }
- unsigned size() const { return OperandList.size(); }
- const OperandInfo &operator[](unsigned i) const { return OperandList[i]; }
- OperandInfo &operator[](unsigned i) { return OperandList[i]; }
- OperandInfo &back() { return OperandList.back(); }
- const OperandInfo &back() const { return OperandList.back(); }
- typedef std::vector<OperandInfo>::iterator iterator;
- typedef std::vector<OperandInfo>::const_iterator const_iterator;
- iterator begin() { return OperandList.begin(); }
- const_iterator begin() const { return OperandList.begin(); }
- iterator end() { return OperandList.end(); }
- const_iterator end() const { return OperandList.end(); }
- /// getOperandNamed - Return the index of the operand with the specified
- /// non-empty name. If the instruction does not have an operand with the
- /// specified name, abort.
- unsigned getOperandNamed(StringRef Name) const;
- /// hasOperandNamed - Query whether the instruction has an operand of the
- /// given name. If so, return true and set OpIdx to the index of the
- /// operand. Otherwise, return false.
- bool hasOperandNamed(StringRef Name, unsigned &OpIdx) const;
- bool hasSubOperandAlias(StringRef Name,
- std::pair<unsigned, unsigned> &SubOp) const;
- /// ParseOperandName - Parse an operand name like "$foo" or "$foo.bar",
- /// where $foo is a whole operand and $foo.bar refers to a suboperand.
- /// This aborts if the name is invalid. If AllowWholeOp is true, references
- /// to operands with suboperands are allowed, otherwise not.
- std::pair<unsigned,unsigned> ParseOperandName(StringRef Op,
- bool AllowWholeOp = true);
- /// getFlattenedOperandNumber - Flatten a operand/suboperand pair into a
- /// flat machineinstr operand #.
- unsigned getFlattenedOperandNumber(std::pair<unsigned,unsigned> Op) const {
- return OperandList[Op.first].MIOperandNo + Op.second;
- }
- /// getSubOperandNumber - Unflatten a operand number into an
- /// operand/suboperand pair.
- std::pair<unsigned,unsigned> getSubOperandNumber(unsigned Op) const {
- for (unsigned i = 0; ; ++i) {
- assert(i < OperandList.size() && "Invalid flat operand #");
- if (OperandList[i].MIOperandNo+OperandList[i].MINumOperands > Op)
- return std::make_pair(i, Op-OperandList[i].MIOperandNo);
- }
- }
- /// isFlatOperandNotEmitted - Return true if the specified flat operand #
- /// should not be emitted with the code emitter.
- bool isFlatOperandNotEmitted(unsigned FlatOpNo) const {
- std::pair<unsigned,unsigned> Op = getSubOperandNumber(FlatOpNo);
- if (OperandList[Op.first].DoNotEncode.size() > Op.second)
- return OperandList[Op.first].DoNotEncode[Op.second];
- return false;
- }
- void ProcessDisableEncoding(StringRef Value);
- };
- class CodeGenInstruction {
- public:
- Record *TheDef; // The actual record defining this instruction.
- StringRef Namespace; // The namespace the instruction is in.
- /// AsmString - The format string used to emit a .s file for the
- /// instruction.
- std::string AsmString;
- /// Operands - This is information about the (ins) and (outs) list specified
- /// to the instruction.
- CGIOperandList Operands;
- /// ImplicitDefs/ImplicitUses - These are lists of registers that are
- /// implicitly defined and used by the instruction.
- std::vector<Record*> ImplicitDefs, ImplicitUses;
- // Various boolean values we track for the instruction.
- bool isPreISelOpcode : 1;
- bool isReturn : 1;
- bool isEHScopeReturn : 1;
- bool isBranch : 1;
- bool isIndirectBranch : 1;
- bool isCompare : 1;
- bool isMoveImm : 1;
- bool isMoveReg : 1;
- bool isBitcast : 1;
- bool isSelect : 1;
- bool isBarrier : 1;
- bool isCall : 1;
- bool isAdd : 1;
- bool isTrap : 1;
- bool canFoldAsLoad : 1;
- bool mayLoad : 1;
- bool mayLoad_Unset : 1;
- bool mayStore : 1;
- bool mayStore_Unset : 1;
- bool mayRaiseFPException : 1;
- bool isPredicable : 1;
- bool isConvertibleToThreeAddress : 1;
- bool isCommutable : 1;
- bool isTerminator : 1;
- bool isReMaterializable : 1;
- bool hasDelaySlot : 1;
- bool usesCustomInserter : 1;
- bool hasPostISelHook : 1;
- bool hasCtrlDep : 1;
- bool isNotDuplicable : 1;
- bool hasSideEffects : 1;
- bool hasSideEffects_Unset : 1;
- bool isAsCheapAsAMove : 1;
- bool hasExtraSrcRegAllocReq : 1;
- bool hasExtraDefRegAllocReq : 1;
- bool isCodeGenOnly : 1;
- bool isPseudo : 1;
- bool isMeta : 1;
- bool isRegSequence : 1;
- bool isExtractSubreg : 1;
- bool isInsertSubreg : 1;
- bool isConvergent : 1;
- bool hasNoSchedulingInfo : 1;
- bool FastISelShouldIgnore : 1;
- bool hasChain : 1;
- bool hasChain_Inferred : 1;
- bool variadicOpsAreDefs : 1;
- bool isAuthenticated : 1;
- std::string DeprecatedReason;
- bool HasComplexDeprecationPredicate;
- /// Are there any undefined flags?
- bool hasUndefFlags() const {
- return mayLoad_Unset || mayStore_Unset || hasSideEffects_Unset;
- }
- // The record used to infer instruction flags, or NULL if no flag values
- // have been inferred.
- Record *InferredFrom;
- CodeGenInstruction(Record *R);
- /// HasOneImplicitDefWithKnownVT - If the instruction has at least one
- /// implicit def and it has a known VT, return the VT, otherwise return
- /// MVT::Other.
- MVT::SimpleValueType
- HasOneImplicitDefWithKnownVT(const CodeGenTarget &TargetInfo) const;
- /// FlattenAsmStringVariants - Flatten the specified AsmString to only
- /// include text from the specified variant, returning the new string.
- static std::string FlattenAsmStringVariants(StringRef AsmString,
- unsigned Variant);
- // Is the specified operand in a generic instruction implicitly a pointer.
- // This can be used on intructions that use typeN or ptypeN to identify
- // operands that should be considered as pointers even though SelectionDAG
- // didn't make a distinction between integer and pointers.
- bool isInOperandAPointer(unsigned i) const {
- return isOperandImpl("InOperandList", i, "IsPointer");
- }
- bool isOutOperandAPointer(unsigned i) const {
- return isOperandImpl("OutOperandList", i, "IsPointer");
- }
- /// Check if the operand is required to be an immediate.
- bool isInOperandImmArg(unsigned i) const {
- return isOperandImpl("InOperandList", i, "IsImmediate");
- }
- private:
- bool isOperandImpl(StringRef OpListName, unsigned i,
- StringRef PropertyName) const;
- };
- /// CodeGenInstAlias - This represents an InstAlias definition.
- class CodeGenInstAlias {
- public:
- Record *TheDef; // The actual record defining this InstAlias.
- /// AsmString - The format string used to emit a .s file for the
- /// instruction.
- std::string AsmString;
- /// Result - The result instruction.
- DagInit *Result;
- /// ResultInst - The instruction generated by the alias (decoded from
- /// Result).
- CodeGenInstruction *ResultInst;
- struct ResultOperand {
- private:
- std::string Name;
- Record *R = nullptr;
- int64_t Imm = 0;
- public:
- enum {
- K_Record,
- K_Imm,
- K_Reg
- } Kind;
- ResultOperand(std::string N, Record *r)
- : Name(std::move(N)), R(r), Kind(K_Record) {}
- ResultOperand(int64_t I) : Imm(I), Kind(K_Imm) {}
- ResultOperand(Record *r) : R(r), Kind(K_Reg) {}
- bool isRecord() const { return Kind == K_Record; }
- bool isImm() const { return Kind == K_Imm; }
- bool isReg() const { return Kind == K_Reg; }
- StringRef getName() const { assert(isRecord()); return Name; }
- Record *getRecord() const { assert(isRecord()); return R; }
- int64_t getImm() const { assert(isImm()); return Imm; }
- Record *getRegister() const { assert(isReg()); return R; }
- unsigned getMINumOperands() const;
- };
- /// ResultOperands - The decoded operands for the result instruction.
- std::vector<ResultOperand> ResultOperands;
- /// ResultInstOperandIndex - For each operand, this vector holds a pair of
- /// indices to identify the corresponding operand in the result
- /// instruction. The first index specifies the operand and the second
- /// index specifies the suboperand. If there are no suboperands or if all
- /// of them are matched by the operand, the second value should be -1.
- std::vector<std::pair<unsigned, int> > ResultInstOperandIndex;
- CodeGenInstAlias(Record *R, CodeGenTarget &T);
- bool tryAliasOpMatch(DagInit *Result, unsigned AliasOpNo,
- Record *InstOpRec, bool hasSubOps, ArrayRef<SMLoc> Loc,
- CodeGenTarget &T, ResultOperand &ResOp);
- };
- }
- #endif
|