xref: /llvm-project/llvm/utils/TableGen/Basic/CodeGenIntrinsics.h (revision 2a0073f6b50e8ae8f08dcf9c29d90503ac7816ae)
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