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