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