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 NoFreeObj,
138 };
139
140 struct ArgAttribute {
141 ArgAttrKind Kind;
142 uint64_t Value;
143 uint64_t Value2;
144
145 ArgAttribute(ArgAttrKind K, uint64_t V, uint64_t V2)
146 : Kind(K), Value(V), Value2(V2) {}
147
148 bool operator<(const ArgAttribute &Other) const {
149 return std::tie(args: Kind, args: Value, args: Value2) <
150 std::tie(args: Other.Kind, args: Other.Value, args: Other.Value2);
151 }
152 };
153
154 struct ImmArgRangeSet {
155 using Range = std::pair<int64_t, int64_t>;
156 using RangeList = SmallVector<Range, 4>;
157
158 unsigned ArgNo;
159 RangeList Ranges;
160 };
161
162 /// Vector of attributes for each argument.
163 SmallVector<SmallVector<ArgAttribute, 0>> ArgumentAttributes;
164
165 /// Range-set constraints for immediate arguments, indexed by argument number.
166 SmallVector<ImmArgRangeSet> ImmArgRangeSets;
167
168 void addArgAttribute(unsigned Idx, ArgAttrKind AK, uint64_t V = 0,
169 uint64_t V2 = 0);
170 void addImmArgRangeSet(unsigned ArgNo, ImmArgRangeSet::RangeList Ranges);
171
172 /// Structure to store pretty print and argument information.
173 struct PrettyPrintArgInfo {
174 unsigned ArgIdx;
175 StringRef ArgName;
176 StringRef FuncName;
177
178 PrettyPrintArgInfo(unsigned Idx, StringRef Name, StringRef Func)
179 : ArgIdx(Idx), ArgName(Name), FuncName(Func) {}
180 };
181
182 /// Vector that stores ArgInfo (ArgIndex, ArgName, FunctionName).
183 SmallVector<PrettyPrintArgInfo> PrettyPrintFunctions;
184
185 /// Default values for parameters. Index = param index.
186 SmallVector<std::optional<uint64_t>> ParamDefaultValues;
187
188 void addPrettyPrintFunction(unsigned ArgIdx, StringRef ArgName,
189 StringRef FuncName);
190
191 void addDefaultArgValue(unsigned ArgIdx, uint64_t Value);
192
193 bool hasProperty(enum SDNP Prop) const { return Properties & (1 << Prop); }
194
195 /// Goes through all IntrProperties that have IsDefault value set and sets
196 /// the property.
197 void setDefaultProperties(ArrayRef<const Record *> DefaultProperties);
198
199 /// Helper function to set property \p Name to true.
200 void setProperty(const Record *R);
201
202 /// Returns true if the parameter at \p ParamIdx is a pointer type. Returns
203 /// false if the parameter is not a pointer, or \p ParamIdx is greater than
204 /// the size of \p IS.ParamVTs.
205 ///
206 /// Note that this requires that \p IS.ParamVTs is available.
207 bool isParamAPointer(unsigned ParamIdx) const;
208
209 bool isParamImmArg(unsigned ParamIdx) const;
210
211 llvm::IRMemLocation getValueAsIRMemLocation(const Record *R) const;
212
213 CodeGenIntrinsic(const Record *R, const CodeGenIntrinsicContext &Ctx);
214};
215
216class CodeGenIntrinsicTable {
217public:
218 struct TargetSet {
219 StringRef Name;
220 size_t Offset;
221 size_t Count;
222 };
223
224 explicit CodeGenIntrinsicTable(const RecordKeeper &RC);
225
226 bool empty() const { return Intrinsics.empty(); }
227 size_t size() const { return Intrinsics.size(); }
228 auto begin() const { return Intrinsics.begin(); }
229 auto end() const { return Intrinsics.end(); }
230 const CodeGenIntrinsic &operator[](size_t Pos) const {
231 return Intrinsics[Pos];
232 }
233 ArrayRef<CodeGenIntrinsic> operator[](const TargetSet &Set) const {
234 return ArrayRef(&Intrinsics[Set.Offset], Set.Count);
235 }
236 ArrayRef<TargetSet> getTargets() const { return Targets; }
237
238private:
239 void CheckDuplicateIntrinsics() const;
240 void CheckTargetIndependentIntrinsics() const;
241 void CheckOverloadSuffixConflicts() const;
242
243 std::vector<CodeGenIntrinsic> Intrinsics;
244 std::vector<TargetSet> Targets;
245};
246
247// This class builds `CodeGenIntrinsic` on demand for a given Def.
248class CodeGenIntrinsicMap {
249 DenseMap<const Record *, std::unique_ptr<CodeGenIntrinsic>> Map;
250 const CodeGenIntrinsicContext Ctx;
251
252public:
253 explicit CodeGenIntrinsicMap(const RecordKeeper &RC) : Ctx(RC) {}
254 const CodeGenIntrinsic &operator[](const Record *Def);
255};
256
257} // namespace llvm
258
259#endif // LLVM_UTILS_TABLEGEN_BASIC_CODEGENINTRINSICS_H
260