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