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 Range, 133 }; 134 135 struct ArgAttribute { 136 ArgAttrKind Kind; 137 uint64_t Value; 138 uint64_t Value2; 139 ArgAttributeCodeGenIntrinsic::ArgAttribute140 ArgAttribute(ArgAttrKind K, uint64_t V, uint64_t V2) 141 : Kind(K), Value(V), Value2(V2) {} 142 143 bool operator<(const ArgAttribute &Other) const { 144 return std::tie(Kind, Value, Value2) < 145 std::tie(Other.Kind, Other.Value, Other.Value2); 146 } 147 }; 148 149 /// Vector of attributes for each argument. 150 SmallVector<SmallVector<ArgAttribute, 0>> ArgumentAttributes; 151 152 void addArgAttribute(unsigned Idx, ArgAttrKind AK, uint64_t V = 0, 153 uint64_t V2 = 0); 154 hasPropertyCodeGenIntrinsic155 bool hasProperty(enum SDNP Prop) const { return Properties & (1 << Prop); } 156 157 /// Goes through all IntrProperties that have IsDefault value set and sets 158 /// the property. 159 void setDefaultProperties(ArrayRef<const Record *> DefaultProperties); 160 161 /// Helper function to set property \p Name to true. 162 void setProperty(const Record *R); 163 164 /// Returns true if the parameter at \p ParamIdx is a pointer type. Returns 165 /// false if the parameter is not a pointer, or \p ParamIdx is greater than 166 /// the size of \p IS.ParamVTs. 167 /// 168 /// Note that this requires that \p IS.ParamVTs is available. 169 bool isParamAPointer(unsigned ParamIdx) const; 170 171 bool isParamImmArg(unsigned ParamIdx) const; 172 173 CodeGenIntrinsic(const Record *R, const CodeGenIntrinsicContext &Ctx); 174 }; 175 176 class CodeGenIntrinsicTable { 177 public: 178 struct TargetSet { 179 StringRef Name; 180 size_t Offset; 181 size_t Count; 182 }; 183 184 explicit CodeGenIntrinsicTable(const RecordKeeper &RC); 185 empty()186 bool empty() const { return Intrinsics.empty(); } size()187 size_t size() const { return Intrinsics.size(); } begin()188 auto begin() const { return Intrinsics.begin(); } end()189 auto end() const { return Intrinsics.end(); } 190 const CodeGenIntrinsic &operator[](size_t Pos) const { 191 return Intrinsics[Pos]; 192 } 193 ArrayRef<CodeGenIntrinsic> operator[](const TargetSet &Set) const { 194 return ArrayRef(&Intrinsics[Set.Offset], Set.Count); 195 } getTargets()196 ArrayRef<TargetSet> getTargets() const { return Targets; } 197 198 private: 199 void CheckDuplicateIntrinsics() const; 200 void CheckTargetIndependentIntrinsics() const; 201 void CheckOverloadSuffixConflicts() const; 202 203 std::vector<CodeGenIntrinsic> Intrinsics; 204 std::vector<TargetSet> Targets; 205 }; 206 207 // This class builds `CodeGenIntrinsic` on demand for a given Def. 208 class CodeGenIntrinsicMap { 209 DenseMap<const Record *, std::unique_ptr<CodeGenIntrinsic>> Map; 210 const CodeGenIntrinsicContext Ctx; 211 212 public: CodeGenIntrinsicMap(const RecordKeeper & RC)213 explicit CodeGenIntrinsicMap(const RecordKeeper &RC) : Ctx(RC) {} 214 const CodeGenIntrinsic &operator[](const Record *Def); 215 }; 216 217 } // namespace llvm 218 219 #endif // LLVM_UTILS_TABLEGEN_BASIC_CODEGENINTRINSICS_H 220