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