Home | History | Annotate | Line # | Download | only in TableGen
      1 //===- CodeGenInstruction.h - Instruction Class Wrapper ---------*- C++ -*-===//
      2 //
      3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4 // See https://llvm.org/LICENSE.txt for license information.
      5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6 //
      7 //===----------------------------------------------------------------------===//
      8 //
      9 // This file defines a wrapper class for the 'Instruction' TableGen class.
     10 //
     11 //===----------------------------------------------------------------------===//
     12 
     13 #ifndef LLVM_UTILS_TABLEGEN_CODEGENINSTRUCTION_H
     14 #define LLVM_UTILS_TABLEGEN_CODEGENINSTRUCTION_H
     15 
     16 #include "llvm/ADT/StringRef.h"
     17 #include "llvm/Support/MachineValueType.h"
     18 #include "llvm/Support/SMLoc.h"
     19 #include <cassert>
     20 #include <string>
     21 #include <utility>
     22 #include <vector>
     23 
     24 namespace llvm {
     25 template <typename T> class ArrayRef;
     26   class Record;
     27   class DagInit;
     28   class CodeGenTarget;
     29 
     30   class CGIOperandList {
     31   public:
     32     class ConstraintInfo {
     33       enum { None, EarlyClobber, Tied } Kind = None;
     34       unsigned OtherTiedOperand = 0;
     35 
     36     public:
     37       ConstraintInfo() = default;
     38 
     39       static ConstraintInfo getEarlyClobber() {
     40         ConstraintInfo I;
     41         I.Kind = EarlyClobber;
     42         I.OtherTiedOperand = 0;
     43         return I;
     44       }
     45 
     46       static ConstraintInfo getTied(unsigned Op) {
     47         ConstraintInfo I;
     48         I.Kind = Tied;
     49         I.OtherTiedOperand = Op;
     50         return I;
     51       }
     52 
     53       bool isNone() const { return Kind == None; }
     54       bool isEarlyClobber() const { return Kind == EarlyClobber; }
     55       bool isTied() const { return Kind == Tied; }
     56 
     57       unsigned getTiedOperand() const {
     58         assert(isTied());
     59         return OtherTiedOperand;
     60       }
     61 
     62       bool operator==(const ConstraintInfo &RHS) const {
     63         if (Kind != RHS.Kind)
     64           return false;
     65         if (Kind == Tied && OtherTiedOperand != RHS.OtherTiedOperand)
     66           return false;
     67         return true;
     68       }
     69       bool operator!=(const ConstraintInfo &RHS) const {
     70         return !(*this == RHS);
     71       }
     72     };
     73 
     74     /// OperandInfo - The information we keep track of for each operand in the
     75     /// operand list for a tablegen instruction.
     76     struct OperandInfo {
     77       /// Rec - The definition this operand is declared as.
     78       ///
     79       Record *Rec;
     80 
     81       /// Name - If this operand was assigned a symbolic name, this is it,
     82       /// otherwise, it's empty.
     83       std::string Name;
     84 
     85       /// PrinterMethodName - The method used to print operands of this type in
     86       /// the asmprinter.
     87       std::string PrinterMethodName;
     88 
     89       /// EncoderMethodName - The method used to get the machine operand value
     90       /// for binary encoding. "getMachineOpValue" by default.
     91       std::string EncoderMethodName;
     92 
     93       /// OperandType - A value from MCOI::OperandType representing the type of
     94       /// the operand.
     95       std::string OperandType;
     96 
     97       /// MIOperandNo - Currently (this is meant to be phased out), some logical
     98       /// operands correspond to multiple MachineInstr operands.  In the X86
     99       /// target for example, one address operand is represented as 4
    100       /// MachineOperands.  Because of this, the operand number in the
    101       /// OperandList may not match the MachineInstr operand num.  Until it
    102       /// does, this contains the MI operand index of this operand.
    103       unsigned MIOperandNo;
    104       unsigned MINumOperands;   // The number of operands.
    105 
    106       /// DoNotEncode - Bools are set to true in this vector for each operand in
    107       /// the DisableEncoding list.  These should not be emitted by the code
    108       /// emitter.
    109       std::vector<bool> DoNotEncode;
    110 
    111       /// MIOperandInfo - Default MI operand type. Note an operand may be made
    112       /// up of multiple MI operands.
    113       DagInit *MIOperandInfo;
    114 
    115       /// Constraint info for this operand.  This operand can have pieces, so we
    116       /// track constraint info for each.
    117       std::vector<ConstraintInfo> Constraints;
    118 
    119       OperandInfo(Record *R, const std::string &N, const std::string &PMN,
    120                   const std::string &EMN, const std::string &OT, unsigned MION,
    121                   unsigned MINO, DagInit *MIOI)
    122       : Rec(R), Name(N), PrinterMethodName(PMN), EncoderMethodName(EMN),
    123         OperandType(OT), MIOperandNo(MION), MINumOperands(MINO),
    124         MIOperandInfo(MIOI) {}
    125 
    126 
    127       /// getTiedOperand - If this operand is tied to another one, return the
    128       /// other operand number.  Otherwise, return -1.
    129       int getTiedRegister() const {
    130         for (unsigned j = 0, e = Constraints.size(); j != e; ++j) {
    131           const CGIOperandList::ConstraintInfo &CI = Constraints[j];
    132           if (CI.isTied()) return CI.getTiedOperand();
    133         }
    134         return -1;
    135       }
    136     };
    137 
    138     CGIOperandList(Record *D);
    139 
    140     Record *TheDef;            // The actual record containing this OperandList.
    141 
    142     /// NumDefs - Number of def operands declared, this is the number of
    143     /// elements in the instruction's (outs) list.
    144     ///
    145     unsigned NumDefs;
    146 
    147     /// OperandList - The list of declared operands, along with their declared
    148     /// type (which is a record).
    149     std::vector<OperandInfo> OperandList;
    150 
    151     // Information gleaned from the operand list.
    152     bool isPredicable;
    153     bool hasOptionalDef;
    154     bool isVariadic;
    155 
    156     // Provide transparent accessors to the operand list.
    157     bool empty() const { return OperandList.empty(); }
    158     unsigned size() const { return OperandList.size(); }
    159     const OperandInfo &operator[](unsigned i) const { return OperandList[i]; }
    160     OperandInfo &operator[](unsigned i) { return OperandList[i]; }
    161     OperandInfo &back() { return OperandList.back(); }
    162     const OperandInfo &back() const { return OperandList.back(); }
    163 
    164     typedef std::vector<OperandInfo>::iterator iterator;
    165     typedef std::vector<OperandInfo>::const_iterator const_iterator;
    166     iterator begin() { return OperandList.begin(); }
    167     const_iterator begin() const { return OperandList.begin(); }
    168     iterator end() { return OperandList.end(); }
    169     const_iterator end() const { return OperandList.end(); }
    170 
    171     /// getOperandNamed - Return the index of the operand with the specified
    172     /// non-empty name.  If the instruction does not have an operand with the
    173     /// specified name, abort.
    174     unsigned getOperandNamed(StringRef Name) const;
    175 
    176     /// hasOperandNamed - Query whether the instruction has an operand of the
    177     /// given name. If so, return true and set OpIdx to the index of the
    178     /// operand. Otherwise, return false.
    179     bool hasOperandNamed(StringRef Name, unsigned &OpIdx) const;
    180 
    181     /// ParseOperandName - Parse an operand name like "$foo" or "$foo.bar",
    182     /// where $foo is a whole operand and $foo.bar refers to a suboperand.
    183     /// This aborts if the name is invalid.  If AllowWholeOp is true, references
    184     /// to operands with suboperands are allowed, otherwise not.
    185     std::pair<unsigned,unsigned> ParseOperandName(StringRef Op,
    186                                                   bool AllowWholeOp = true);
    187 
    188     /// getFlattenedOperandNumber - Flatten a operand/suboperand pair into a
    189     /// flat machineinstr operand #.
    190     unsigned getFlattenedOperandNumber(std::pair<unsigned,unsigned> Op) const {
    191       return OperandList[Op.first].MIOperandNo + Op.second;
    192     }
    193 
    194     /// getSubOperandNumber - Unflatten a operand number into an
    195     /// operand/suboperand pair.
    196     std::pair<unsigned,unsigned> getSubOperandNumber(unsigned Op) const {
    197       for (unsigned i = 0; ; ++i) {
    198         assert(i < OperandList.size() && "Invalid flat operand #");
    199         if (OperandList[i].MIOperandNo+OperandList[i].MINumOperands > Op)
    200           return std::make_pair(i, Op-OperandList[i].MIOperandNo);
    201       }
    202     }
    203 
    204 
    205     /// isFlatOperandNotEmitted - Return true if the specified flat operand #
    206     /// should not be emitted with the code emitter.
    207     bool isFlatOperandNotEmitted(unsigned FlatOpNo) const {
    208       std::pair<unsigned,unsigned> Op = getSubOperandNumber(FlatOpNo);
    209       if (OperandList[Op.first].DoNotEncode.size() > Op.second)
    210         return OperandList[Op.first].DoNotEncode[Op.second];
    211       return false;
    212     }
    213 
    214     void ProcessDisableEncoding(StringRef Value);
    215   };
    216 
    217 
    218   class CodeGenInstruction {
    219   public:
    220     Record *TheDef;            // The actual record defining this instruction.
    221     StringRef Namespace;       // The namespace the instruction is in.
    222 
    223     /// AsmString - The format string used to emit a .s file for the
    224     /// instruction.
    225     std::string AsmString;
    226 
    227     /// Operands - This is information about the (ins) and (outs) list specified
    228     /// to the instruction.
    229     CGIOperandList Operands;
    230 
    231     /// ImplicitDefs/ImplicitUses - These are lists of registers that are
    232     /// implicitly defined and used by the instruction.
    233     std::vector<Record*> ImplicitDefs, ImplicitUses;
    234 
    235     // Various boolean values we track for the instruction.
    236     bool isPreISelOpcode : 1;
    237     bool isReturn : 1;
    238     bool isEHScopeReturn : 1;
    239     bool isBranch : 1;
    240     bool isIndirectBranch : 1;
    241     bool isCompare : 1;
    242     bool isMoveImm : 1;
    243     bool isMoveReg : 1;
    244     bool isBitcast : 1;
    245     bool isSelect : 1;
    246     bool isBarrier : 1;
    247     bool isCall : 1;
    248     bool isAdd : 1;
    249     bool isTrap : 1;
    250     bool canFoldAsLoad : 1;
    251     bool mayLoad : 1;
    252     bool mayLoad_Unset : 1;
    253     bool mayStore : 1;
    254     bool mayStore_Unset : 1;
    255     bool mayRaiseFPException : 1;
    256     bool isPredicable : 1;
    257     bool isConvertibleToThreeAddress : 1;
    258     bool isCommutable : 1;
    259     bool isTerminator : 1;
    260     bool isReMaterializable : 1;
    261     bool hasDelaySlot : 1;
    262     bool usesCustomInserter : 1;
    263     bool hasPostISelHook : 1;
    264     bool hasCtrlDep : 1;
    265     bool isNotDuplicable : 1;
    266     bool hasSideEffects : 1;
    267     bool hasSideEffects_Unset : 1;
    268     bool isAsCheapAsAMove : 1;
    269     bool hasExtraSrcRegAllocReq : 1;
    270     bool hasExtraDefRegAllocReq : 1;
    271     bool isCodeGenOnly : 1;
    272     bool isPseudo : 1;
    273     bool isRegSequence : 1;
    274     bool isExtractSubreg : 1;
    275     bool isInsertSubreg : 1;
    276     bool isConvergent : 1;
    277     bool hasNoSchedulingInfo : 1;
    278     bool FastISelShouldIgnore : 1;
    279     bool hasChain : 1;
    280     bool hasChain_Inferred : 1;
    281     bool variadicOpsAreDefs : 1;
    282     bool isAuthenticated : 1;
    283 
    284     std::string DeprecatedReason;
    285     bool HasComplexDeprecationPredicate;
    286 
    287     /// Are there any undefined flags?
    288     bool hasUndefFlags() const {
    289       return mayLoad_Unset || mayStore_Unset || hasSideEffects_Unset;
    290     }
    291 
    292     // The record used to infer instruction flags, or NULL if no flag values
    293     // have been inferred.
    294     Record *InferredFrom;
    295 
    296     CodeGenInstruction(Record *R);
    297 
    298     /// HasOneImplicitDefWithKnownVT - If the instruction has at least one
    299     /// implicit def and it has a known VT, return the VT, otherwise return
    300     /// MVT::Other.
    301     MVT::SimpleValueType
    302       HasOneImplicitDefWithKnownVT(const CodeGenTarget &TargetInfo) const;
    303 
    304 
    305     /// FlattenAsmStringVariants - Flatten the specified AsmString to only
    306     /// include text from the specified variant, returning the new string.
    307     static std::string FlattenAsmStringVariants(StringRef AsmString,
    308                                                 unsigned Variant);
    309 
    310     // Is the specified operand in a generic instruction implicitly a pointer.
    311     // This can be used on intructions that use typeN or ptypeN to identify
    312     // operands that should be considered as pointers even though SelectionDAG
    313     // didn't make a distinction between integer and pointers.
    314     bool isOperandAPointer(unsigned i) const {
    315       return isOperandImpl(i, "IsPointer");
    316     }
    317 
    318     /// Check if the operand is required to be an immediate.
    319     bool isOperandImmArg(unsigned i) const {
    320       return isOperandImpl(i, "IsImmediate");
    321     }
    322 
    323   private:
    324     bool isOperandImpl(unsigned i, StringRef PropertyName) const;
    325   };
    326 
    327 
    328   /// CodeGenInstAlias - This represents an InstAlias definition.
    329   class CodeGenInstAlias {
    330   public:
    331     Record *TheDef;            // The actual record defining this InstAlias.
    332 
    333     /// AsmString - The format string used to emit a .s file for the
    334     /// instruction.
    335     std::string AsmString;
    336 
    337     /// Result - The result instruction.
    338     DagInit *Result;
    339 
    340     /// ResultInst - The instruction generated by the alias (decoded from
    341     /// Result).
    342     CodeGenInstruction *ResultInst;
    343 
    344 
    345     struct ResultOperand {
    346     private:
    347       std::string Name;
    348       Record *R = nullptr;
    349       int64_t Imm = 0;
    350 
    351     public:
    352       enum {
    353         K_Record,
    354         K_Imm,
    355         K_Reg
    356       } Kind;
    357 
    358       ResultOperand(std::string N, Record *r)
    359           : Name(std::move(N)), R(r), Kind(K_Record) {}
    360       ResultOperand(int64_t I) : Imm(I), Kind(K_Imm) {}
    361       ResultOperand(Record *r) : R(r), Kind(K_Reg) {}
    362 
    363       bool isRecord() const { return Kind == K_Record; }
    364       bool isImm() const { return Kind == K_Imm; }
    365       bool isReg() const { return Kind == K_Reg; }
    366 
    367       StringRef getName() const { assert(isRecord()); return Name; }
    368       Record *getRecord() const { assert(isRecord()); return R; }
    369       int64_t getImm() const { assert(isImm()); return Imm; }
    370       Record *getRegister() const { assert(isReg()); return R; }
    371 
    372       unsigned getMINumOperands() const;
    373     };
    374 
    375     /// ResultOperands - The decoded operands for the result instruction.
    376     std::vector<ResultOperand> ResultOperands;
    377 
    378     /// ResultInstOperandIndex - For each operand, this vector holds a pair of
    379     /// indices to identify the corresponding operand in the result
    380     /// instruction.  The first index specifies the operand and the second
    381     /// index specifies the suboperand.  If there are no suboperands or if all
    382     /// of them are matched by the operand, the second value should be -1.
    383     std::vector<std::pair<unsigned, int> > ResultInstOperandIndex;
    384 
    385     CodeGenInstAlias(Record *R, CodeGenTarget &T);
    386 
    387     bool tryAliasOpMatch(DagInit *Result, unsigned AliasOpNo,
    388                          Record *InstOpRec, bool hasSubOps, ArrayRef<SMLoc> Loc,
    389                          CodeGenTarget &T, ResultOperand &ResOp);
    390   };
    391 }
    392 
    393 #endif
    394