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