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 // Maximum number of values an intrinsic can return.
35 unsigned MaxNumReturn;
36};
37
38struct 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 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 bool hasProperty(enum SDNP Prop) const { return Properties & (1 << Prop); }
156
157 /// Goes through all IntrProperties that have IsDefault value set and sets
158 /// the property.
159 void setDefaultProperties(ArrayRef<const Record *> DefaultProperties);
160
161 /// Helper function to set property \p Name to true.
162 void setProperty(const Record *R);
163
164 /// Returns true if the parameter at \p ParamIdx is a pointer type. Returns
165 /// false if the parameter is not a pointer, or \p ParamIdx is greater than
166 /// the size of \p IS.ParamVTs.
167 ///
168 /// Note that this requires that \p IS.ParamVTs is available.
169 bool isParamAPointer(unsigned ParamIdx) const;
170
171 bool isParamImmArg(unsigned ParamIdx) const;
172
173 CodeGenIntrinsic(const Record *R, const CodeGenIntrinsicContext &Ctx);
174};
175
176class CodeGenIntrinsicTable {
177public:
178 struct TargetSet {
179 StringRef Name;
180 size_t Offset;
181 size_t Count;
182 };
183
184 explicit CodeGenIntrinsicTable(const RecordKeeper &RC);
185
186 bool empty() const { return Intrinsics.empty(); }
187 size_t size() const { return Intrinsics.size(); }
188 auto begin() const { return Intrinsics.begin(); }
189 auto end() const { return Intrinsics.end(); }
190 const CodeGenIntrinsic &operator[](size_t Pos) const {
191 return Intrinsics[Pos];
192 }
193 ArrayRef<CodeGenIntrinsic> operator[](const TargetSet &Set) const {
194 return ArrayRef(&Intrinsics[Set.Offset], Set.Count);
195 }
196 ArrayRef<TargetSet> getTargets() const { return Targets; }
197
198private:
199 void CheckDuplicateIntrinsics() const;
200 void CheckTargetIndependentIntrinsics() const;
201 void CheckOverloadSuffixConflicts() const;
202
203 std::vector<CodeGenIntrinsic> Intrinsics;
204 std::vector<TargetSet> Targets;
205};
206
207// This class builds `CodeGenIntrinsic` on demand for a given Def.
208class CodeGenIntrinsicMap {
209 DenseMap<const Record *, std::unique_ptr<CodeGenIntrinsic>> Map;
210 const CodeGenIntrinsicContext Ctx;
211
212public:
213 explicit CodeGenIntrinsicMap(const RecordKeeper &RC) : Ctx(RC) {}
214 const CodeGenIntrinsic &operator[](const Record *Def);
215};
216
217} // namespace llvm
218
219#endif // LLVM_UTILS_TABLEGEN_BASIC_CODEGENINTRINSICS_H
220