1*0fca6ea1SDimitry Andric //===- CodeGenIntrinsics.h - Intrinsic Class Wrapper -----------*- C++ -*--===// 2*0fca6ea1SDimitry Andric // 3*0fca6ea1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0fca6ea1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0fca6ea1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0fca6ea1SDimitry Andric // 7*0fca6ea1SDimitry Andric //===----------------------------------------------------------------------===// 8*0fca6ea1SDimitry Andric // 9*0fca6ea1SDimitry Andric // This file defines a wrapper class for the 'Intrinsic' TableGen class. 10*0fca6ea1SDimitry Andric // 11*0fca6ea1SDimitry Andric //===----------------------------------------------------------------------===// 12*0fca6ea1SDimitry Andric 13*0fca6ea1SDimitry Andric #ifndef LLVM_UTILS_TABLEGEN_CODEGENINTRINSICS_H 14*0fca6ea1SDimitry Andric #define LLVM_UTILS_TABLEGEN_CODEGENINTRINSICS_H 15*0fca6ea1SDimitry Andric 16*0fca6ea1SDimitry Andric #include "SDNodeProperties.h" 17*0fca6ea1SDimitry Andric #include "llvm/ADT/ArrayRef.h" 18*0fca6ea1SDimitry Andric #include "llvm/ADT/SmallVector.h" 19*0fca6ea1SDimitry Andric #include "llvm/Support/ModRef.h" 20*0fca6ea1SDimitry Andric #include <string> 21*0fca6ea1SDimitry Andric #include <tuple> 22*0fca6ea1SDimitry Andric #include <vector> 23*0fca6ea1SDimitry Andric 24*0fca6ea1SDimitry Andric namespace llvm { 25*0fca6ea1SDimitry Andric class Record; 26*0fca6ea1SDimitry Andric class RecordKeeper; 27*0fca6ea1SDimitry Andric 28*0fca6ea1SDimitry Andric struct CodeGenIntrinsic { 29*0fca6ea1SDimitry Andric Record *TheDef; // The actual record defining this intrinsic. 30*0fca6ea1SDimitry Andric std::string Name; // The name of the LLVM function "llvm.bswap.i32" 31*0fca6ea1SDimitry Andric std::string EnumName; // The name of the enum "bswap_i32" 32*0fca6ea1SDimitry Andric std::string ClangBuiltinName; // Name of the corresponding GCC builtin, or "". 33*0fca6ea1SDimitry Andric std::string MSBuiltinName; // Name of the corresponding MS builtin, or "". 34*0fca6ea1SDimitry Andric std::string TargetPrefix; // Target prefix, e.g. "ppc" for t-s intrinsics. 35*0fca6ea1SDimitry Andric 36*0fca6ea1SDimitry Andric /// This structure holds the return values and parameter values of an 37*0fca6ea1SDimitry Andric /// intrinsic. If the number of return values is > 1, then the intrinsic 38*0fca6ea1SDimitry Andric /// implicitly returns a first-class aggregate. The numbering of the types 39*0fca6ea1SDimitry Andric /// starts at 0 with the first return value and continues from there through 40*0fca6ea1SDimitry Andric /// the parameter list. This is useful for "matching" types. 41*0fca6ea1SDimitry Andric struct IntrinsicSignature { 42*0fca6ea1SDimitry Andric /// The MVT::SimpleValueType for each return type. Note that this list is 43*0fca6ea1SDimitry Andric /// only populated when in the context of a target .td file. When building 44*0fca6ea1SDimitry Andric /// Intrinsics.td, this isn't available, because we don't know the target 45*0fca6ea1SDimitry Andric /// pointer size. 46*0fca6ea1SDimitry Andric std::vector<Record *> RetTys; 47*0fca6ea1SDimitry Andric 48*0fca6ea1SDimitry Andric /// The MVT::SimpleValueType for each parameter type. Note that this list is 49*0fca6ea1SDimitry Andric /// only populated when in the context of a target .td file. When building 50*0fca6ea1SDimitry Andric /// Intrinsics.td, this isn't available, because we don't know the target 51*0fca6ea1SDimitry Andric /// pointer size. 52*0fca6ea1SDimitry Andric std::vector<Record *> ParamTys; 53*0fca6ea1SDimitry Andric }; 54*0fca6ea1SDimitry Andric 55*0fca6ea1SDimitry Andric IntrinsicSignature IS; 56*0fca6ea1SDimitry Andric 57*0fca6ea1SDimitry Andric /// Memory effects of the intrinsic. 58*0fca6ea1SDimitry Andric MemoryEffects ME = MemoryEffects::unknown(); 59*0fca6ea1SDimitry Andric 60*0fca6ea1SDimitry Andric /// SDPatternOperator Properties applied to the intrinsic. 61*0fca6ea1SDimitry Andric unsigned Properties; 62*0fca6ea1SDimitry Andric 63*0fca6ea1SDimitry Andric /// This is set to true if the intrinsic is overloaded by its argument 64*0fca6ea1SDimitry Andric /// types. 65*0fca6ea1SDimitry Andric bool isOverloaded; 66*0fca6ea1SDimitry Andric 67*0fca6ea1SDimitry Andric /// True if the intrinsic is commutative. 68*0fca6ea1SDimitry Andric bool isCommutative; 69*0fca6ea1SDimitry Andric 70*0fca6ea1SDimitry Andric /// True if the intrinsic can throw. 71*0fca6ea1SDimitry Andric bool canThrow; 72*0fca6ea1SDimitry Andric 73*0fca6ea1SDimitry Andric /// True if the intrinsic is marked as noduplicate. 74*0fca6ea1SDimitry Andric bool isNoDuplicate; 75*0fca6ea1SDimitry Andric 76*0fca6ea1SDimitry Andric /// True if the intrinsic is marked as nomerge. 77*0fca6ea1SDimitry Andric bool isNoMerge; 78*0fca6ea1SDimitry Andric 79*0fca6ea1SDimitry Andric /// True if the intrinsic is no-return. 80*0fca6ea1SDimitry Andric bool isNoReturn; 81*0fca6ea1SDimitry Andric 82*0fca6ea1SDimitry Andric /// True if the intrinsic is no-callback. 83*0fca6ea1SDimitry Andric bool isNoCallback; 84*0fca6ea1SDimitry Andric 85*0fca6ea1SDimitry Andric /// True if the intrinsic is no-sync. 86*0fca6ea1SDimitry Andric bool isNoSync; 87*0fca6ea1SDimitry Andric 88*0fca6ea1SDimitry Andric /// True if the intrinsic is no-free. 89*0fca6ea1SDimitry Andric bool isNoFree; 90*0fca6ea1SDimitry Andric 91*0fca6ea1SDimitry Andric /// True if the intrinsic is will-return. 92*0fca6ea1SDimitry Andric bool isWillReturn; 93*0fca6ea1SDimitry Andric 94*0fca6ea1SDimitry Andric /// True if the intrinsic is cold. 95*0fca6ea1SDimitry Andric bool isCold; 96*0fca6ea1SDimitry Andric 97*0fca6ea1SDimitry Andric /// True if the intrinsic is marked as convergent. 98*0fca6ea1SDimitry Andric bool isConvergent; 99*0fca6ea1SDimitry Andric 100*0fca6ea1SDimitry Andric /// True if the intrinsic has side effects that aren't captured by any 101*0fca6ea1SDimitry Andric /// of the other flags. 102*0fca6ea1SDimitry Andric bool hasSideEffects; 103*0fca6ea1SDimitry Andric 104*0fca6ea1SDimitry Andric // True if the intrinsic is marked as speculatable. 105*0fca6ea1SDimitry Andric bool isSpeculatable; 106*0fca6ea1SDimitry Andric 107*0fca6ea1SDimitry Andric // True if the intrinsic is marked as strictfp. 108*0fca6ea1SDimitry Andric bool isStrictFP; 109*0fca6ea1SDimitry Andric 110*0fca6ea1SDimitry Andric enum ArgAttrKind { 111*0fca6ea1SDimitry Andric NoCapture, 112*0fca6ea1SDimitry Andric NoAlias, 113*0fca6ea1SDimitry Andric NoUndef, 114*0fca6ea1SDimitry Andric NonNull, 115*0fca6ea1SDimitry Andric Returned, 116*0fca6ea1SDimitry Andric ReadOnly, 117*0fca6ea1SDimitry Andric WriteOnly, 118*0fca6ea1SDimitry Andric ReadNone, 119*0fca6ea1SDimitry Andric ImmArg, 120*0fca6ea1SDimitry Andric Alignment, 121*0fca6ea1SDimitry Andric Dereferenceable 122*0fca6ea1SDimitry Andric }; 123*0fca6ea1SDimitry Andric 124*0fca6ea1SDimitry Andric struct ArgAttribute { 125*0fca6ea1SDimitry Andric ArgAttrKind Kind; 126*0fca6ea1SDimitry Andric uint64_t Value; 127*0fca6ea1SDimitry Andric 128*0fca6ea1SDimitry Andric ArgAttribute(ArgAttrKind K, uint64_t V) : Kind(K), Value(V) {} 129*0fca6ea1SDimitry Andric 130*0fca6ea1SDimitry Andric bool operator<(const ArgAttribute &Other) const { 131*0fca6ea1SDimitry Andric return std::tie(Kind, Value) < std::tie(Other.Kind, Other.Value); 132*0fca6ea1SDimitry Andric } 133*0fca6ea1SDimitry Andric }; 134*0fca6ea1SDimitry Andric 135*0fca6ea1SDimitry Andric /// Vector of attributes for each argument. 136*0fca6ea1SDimitry Andric SmallVector<SmallVector<ArgAttribute, 0>> ArgumentAttributes; 137*0fca6ea1SDimitry Andric 138*0fca6ea1SDimitry Andric void addArgAttribute(unsigned Idx, ArgAttrKind AK, uint64_t V = 0); 139*0fca6ea1SDimitry Andric 140*0fca6ea1SDimitry Andric bool hasProperty(enum SDNP Prop) const { return Properties & (1 << Prop); } 141*0fca6ea1SDimitry Andric 142*0fca6ea1SDimitry Andric /// Goes through all IntrProperties that have IsDefault 143*0fca6ea1SDimitry Andric /// value set and sets the property. 144*0fca6ea1SDimitry Andric void setDefaultProperties(Record *R, ArrayRef<Record *> DefaultProperties); 145*0fca6ea1SDimitry Andric 146*0fca6ea1SDimitry Andric /// Helper function to set property \p Name to true; 147*0fca6ea1SDimitry Andric void setProperty(Record *R); 148*0fca6ea1SDimitry Andric 149*0fca6ea1SDimitry Andric /// Returns true if the parameter at \p ParamIdx is a pointer type. Returns 150*0fca6ea1SDimitry Andric /// false if the parameter is not a pointer, or \p ParamIdx is greater than 151*0fca6ea1SDimitry Andric /// the size of \p IS.ParamVTs. 152*0fca6ea1SDimitry Andric /// 153*0fca6ea1SDimitry Andric /// Note that this requires that \p IS.ParamVTs is available. 154*0fca6ea1SDimitry Andric bool isParamAPointer(unsigned ParamIdx) const; 155*0fca6ea1SDimitry Andric 156*0fca6ea1SDimitry Andric bool isParamImmArg(unsigned ParamIdx) const; 157*0fca6ea1SDimitry Andric 158*0fca6ea1SDimitry Andric CodeGenIntrinsic(Record *R, ArrayRef<Record *> DefaultProperties); 159*0fca6ea1SDimitry Andric }; 160*0fca6ea1SDimitry Andric 161*0fca6ea1SDimitry Andric class CodeGenIntrinsicTable { 162*0fca6ea1SDimitry Andric std::vector<CodeGenIntrinsic> Intrinsics; 163*0fca6ea1SDimitry Andric 164*0fca6ea1SDimitry Andric public: 165*0fca6ea1SDimitry Andric struct TargetSet { 166*0fca6ea1SDimitry Andric std::string Name; 167*0fca6ea1SDimitry Andric size_t Offset; 168*0fca6ea1SDimitry Andric size_t Count; 169*0fca6ea1SDimitry Andric }; 170*0fca6ea1SDimitry Andric std::vector<TargetSet> Targets; 171*0fca6ea1SDimitry Andric 172*0fca6ea1SDimitry Andric explicit CodeGenIntrinsicTable(const RecordKeeper &RC); 173*0fca6ea1SDimitry Andric CodeGenIntrinsicTable() = default; 174*0fca6ea1SDimitry Andric 175*0fca6ea1SDimitry Andric bool empty() const { return Intrinsics.empty(); } 176*0fca6ea1SDimitry Andric size_t size() const { return Intrinsics.size(); } 177*0fca6ea1SDimitry Andric auto begin() const { return Intrinsics.begin(); } 178*0fca6ea1SDimitry Andric auto end() const { return Intrinsics.end(); } 179*0fca6ea1SDimitry Andric CodeGenIntrinsic &operator[](size_t Pos) { return Intrinsics[Pos]; } 180*0fca6ea1SDimitry Andric const CodeGenIntrinsic &operator[](size_t Pos) const { 181*0fca6ea1SDimitry Andric return Intrinsics[Pos]; 182*0fca6ea1SDimitry Andric } 183*0fca6ea1SDimitry Andric }; 184*0fca6ea1SDimitry Andric } // namespace llvm 185*0fca6ea1SDimitry Andric 186*0fca6ea1SDimitry Andric #endif 187