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