Home | History | Annotate | Line # | Download | only in TableGen
      1 //===- CodeGenIntrinsic.h - Intrinsic 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 'Intrinsic' TableGen class.
     10 //
     11 //===----------------------------------------------------------------------===//
     12 
     13 #ifndef LLVM_UTILS_TABLEGEN_CODEGENINTRINSICS_H
     14 #define LLVM_UTILS_TABLEGEN_CODEGENINTRINSICS_H
     15 
     16 #include "SDNodeProperties.h"
     17 #include "llvm/Support/MachineValueType.h"
     18 #include <string>
     19 #include <vector>
     20 
     21 namespace llvm {
     22 class Record;
     23 class RecordKeeper;
     24 class CodeGenTarget;
     25 
     26 struct CodeGenIntrinsic {
     27   Record *TheDef;             // The actual record defining this intrinsic.
     28   std::string Name;           // The name of the LLVM function "llvm.bswap.i32"
     29   std::string EnumName;       // The name of the enum "bswap_i32"
     30   std::string GCCBuiltinName; // Name of the corresponding GCC builtin, or "".
     31   std::string MSBuiltinName;  // Name of the corresponding MS builtin, or "".
     32   std::string TargetPrefix;   // Target prefix, e.g. "ppc" for t-s intrinsics.
     33 
     34   /// This structure holds the return values and parameter values of an
     35   /// intrinsic. If the number of return values is > 1, then the intrinsic
     36   /// implicitly returns a first-class aggregate. The numbering of the types
     37   /// starts at 0 with the first return value and continues from there through
     38   /// the parameter list. This is useful for "matching" types.
     39   struct IntrinsicSignature {
     40     /// The MVT::SimpleValueType for each return type. Note that this list is
     41     /// only populated when in the context of a target .td file. When building
     42     /// Intrinsics.td, this isn't available, because we don't know the target
     43     /// pointer size.
     44     std::vector<MVT::SimpleValueType> RetVTs;
     45 
     46     /// The records for each return type.
     47     std::vector<Record *> RetTypeDefs;
     48 
     49     /// The MVT::SimpleValueType for each parameter type. Note that this list is
     50     /// only populated when in the context of a target .td file.  When building
     51     /// Intrinsics.td, this isn't available, because we don't know the target
     52     /// pointer size.
     53     std::vector<MVT::SimpleValueType> ParamVTs;
     54 
     55     /// The records for each parameter type.
     56     std::vector<Record *> ParamTypeDefs;
     57   };
     58 
     59   IntrinsicSignature IS;
     60 
     61   /// Bit flags describing the type (ref/mod) and location of memory
     62   /// accesses that may be performed by the intrinsics. Analogous to
     63   /// \c FunctionModRefBehaviour.
     64   enum ModRefBits {
     65     /// The intrinsic may access memory that is otherwise inaccessible via
     66     /// LLVM IR.
     67     MR_InaccessibleMem = 1,
     68 
     69     /// The intrinsic may access memory through pointer arguments.
     70     /// LLVM IR.
     71     MR_ArgMem = 2,
     72 
     73     /// The intrinsic may access memory anywhere, i.e. it is not restricted
     74     /// to access through pointer arguments.
     75     MR_Anywhere = 4 | MR_ArgMem | MR_InaccessibleMem,
     76 
     77     /// The intrinsic may read memory.
     78     MR_Ref = 8,
     79 
     80     /// The intrinsic may write memory.
     81     MR_Mod = 16,
     82 
     83     /// The intrinsic may both read and write memory.
     84     MR_ModRef = MR_Ref | MR_Mod,
     85   };
     86 
     87   /// Memory mod/ref behavior of this intrinsic, corresponding to intrinsic
     88   /// properties (IntrReadMem, IntrArgMemOnly, etc.).
     89   enum ModRefBehavior {
     90     NoMem = 0,
     91     ReadArgMem = MR_Ref | MR_ArgMem,
     92     ReadInaccessibleMem = MR_Ref | MR_InaccessibleMem,
     93     ReadInaccessibleMemOrArgMem = MR_Ref | MR_ArgMem | MR_InaccessibleMem,
     94     ReadMem = MR_Ref | MR_Anywhere,
     95     WriteArgMem = MR_Mod | MR_ArgMem,
     96     WriteInaccessibleMem = MR_Mod | MR_InaccessibleMem,
     97     WriteInaccessibleMemOrArgMem = MR_Mod | MR_ArgMem | MR_InaccessibleMem,
     98     WriteMem = MR_Mod | MR_Anywhere,
     99     ReadWriteArgMem = MR_ModRef | MR_ArgMem,
    100     ReadWriteInaccessibleMem = MR_ModRef | MR_InaccessibleMem,
    101     ReadWriteInaccessibleMemOrArgMem = MR_ModRef | MR_ArgMem |
    102                                        MR_InaccessibleMem,
    103     ReadWriteMem = MR_ModRef | MR_Anywhere,
    104   };
    105   ModRefBehavior ModRef;
    106 
    107   /// SDPatternOperator Properties applied to the intrinsic.
    108   unsigned Properties;
    109 
    110   /// This is set to true if the intrinsic is overloaded by its argument
    111   /// types.
    112   bool isOverloaded;
    113 
    114   /// True if the intrinsic is commutative.
    115   bool isCommutative;
    116 
    117   /// True if the intrinsic can throw.
    118   bool canThrow;
    119 
    120   /// True if the intrinsic is marked as noduplicate.
    121   bool isNoDuplicate;
    122 
    123   /// True if the intrinsic is marked as nomerge.
    124   bool isNoMerge;
    125 
    126   /// True if the intrinsic is no-return.
    127   bool isNoReturn;
    128 
    129   /// True if the intrinsic is no-sync.
    130   bool isNoSync;
    131 
    132   /// True if the intrinsic is no-free.
    133   bool isNoFree;
    134 
    135   /// True if the intrinsic is will-return.
    136   bool isWillReturn;
    137 
    138   /// True if the intrinsic is cold.
    139   bool isCold;
    140 
    141   /// True if the intrinsic is marked as convergent.
    142   bool isConvergent;
    143 
    144   /// True if the intrinsic has side effects that aren't captured by any
    145   /// of the other flags.
    146   bool hasSideEffects;
    147 
    148   // True if the intrinsic is marked as speculatable.
    149   bool isSpeculatable;
    150 
    151   enum ArgAttrKind {
    152     NoCapture,
    153     NoAlias,
    154     NoUndef,
    155     Returned,
    156     ReadOnly,
    157     WriteOnly,
    158     ReadNone,
    159     ImmArg,
    160     Alignment
    161   };
    162 
    163   struct ArgAttribute {
    164     unsigned Index;
    165     ArgAttrKind Kind;
    166     uint64_t Value;
    167 
    168     ArgAttribute(unsigned Idx, ArgAttrKind K, uint64_t V)
    169         : Index(Idx), Kind(K), Value(V) {}
    170 
    171     bool operator<(const ArgAttribute &Other) const {
    172       return std::tie(Index, Kind, Value) <
    173              std::tie(Other.Index, Other.Kind, Other.Value);
    174     }
    175   };
    176 
    177   std::vector<ArgAttribute> ArgumentAttributes;
    178 
    179   bool hasProperty(enum SDNP Prop) const {
    180     return Properties & (1 << Prop);
    181   }
    182 
    183   /// Goes through all IntrProperties that have IsDefault
    184   /// value set and sets the property.
    185   void setDefaultProperties(Record *R, std::vector<Record *> DefaultProperties);
    186 
    187   /// Helper function to set property \p Name to true;
    188   void setProperty(Record *R);
    189 
    190   /// Returns true if the parameter at \p ParamIdx is a pointer type. Returns
    191   /// false if the parameter is not a pointer, or \p ParamIdx is greater than
    192   /// the size of \p IS.ParamVTs.
    193   ///
    194   /// Note that this requires that \p IS.ParamVTs is available.
    195   bool isParamAPointer(unsigned ParamIdx) const;
    196 
    197   bool isParamImmArg(unsigned ParamIdx) const;
    198 
    199   CodeGenIntrinsic(Record *R, std::vector<Record *> DefaultProperties);
    200 };
    201 
    202 class CodeGenIntrinsicTable {
    203   std::vector<CodeGenIntrinsic> Intrinsics;
    204 
    205 public:
    206   struct TargetSet {
    207     std::string Name;
    208     size_t Offset;
    209     size_t Count;
    210   };
    211   std::vector<TargetSet> Targets;
    212 
    213   explicit CodeGenIntrinsicTable(const RecordKeeper &RC);
    214   CodeGenIntrinsicTable() = default;
    215 
    216   bool empty() const { return Intrinsics.empty(); }
    217   size_t size() const { return Intrinsics.size(); }
    218   CodeGenIntrinsic &operator[](size_t Pos) { return Intrinsics[Pos]; }
    219   const CodeGenIntrinsic &operator[](size_t Pos) const {
    220     return Intrinsics[Pos];
    221   }
    222 };
    223 }
    224 
    225 #endif
    226