Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
14 | pmbaty | 1 | //===- llvm/Attributes.h - Container for Attributes -------------*- 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 | /// \file |
||
10 | /// This file contains the simple types necessary to represent the |
||
11 | /// attributes associated with functions and their calls. |
||
12 | // |
||
13 | //===----------------------------------------------------------------------===// |
||
14 | |||
15 | #ifndef LLVM_IR_ATTRIBUTES_H |
||
16 | #define LLVM_IR_ATTRIBUTES_H |
||
17 | |||
18 | #include "llvm-c/Types.h" |
||
19 | #include "llvm/ADT/ArrayRef.h" |
||
20 | #include "llvm/ADT/BitmaskEnum.h" |
||
21 | #include "llvm/ADT/SmallString.h" |
||
22 | #include "llvm/ADT/StringRef.h" |
||
23 | #include "llvm/Config/llvm-config.h" |
||
24 | #include "llvm/Support/Alignment.h" |
||
25 | #include "llvm/Support/CodeGen.h" |
||
26 | #include "llvm/Support/PointerLikeTypeTraits.h" |
||
27 | #include <bitset> |
||
28 | #include <cassert> |
||
29 | #include <cstdint> |
||
30 | #include <optional> |
||
31 | #include <set> |
||
32 | #include <string> |
||
33 | #include <utility> |
||
34 | |||
35 | namespace llvm { |
||
36 | |||
37 | class AttrBuilder; |
||
38 | class AttributeMask; |
||
39 | class AttributeImpl; |
||
40 | class AttributeListImpl; |
||
41 | class AttributeSetNode; |
||
42 | class FoldingSetNodeID; |
||
43 | class Function; |
||
44 | class LLVMContext; |
||
45 | class MemoryEffects; |
||
46 | class Type; |
||
47 | class raw_ostream; |
||
48 | |||
49 | enum class AllocFnKind : uint64_t { |
||
50 | Unknown = 0, |
||
51 | Alloc = 1 << 0, // Allocator function returns a new allocation |
||
52 | Realloc = 1 << 1, // Allocator function resizes the `allocptr` argument |
||
53 | Free = 1 << 2, // Allocator function frees the `allocptr` argument |
||
54 | Uninitialized = 1 << 3, // Allocator function returns uninitialized memory |
||
55 | Zeroed = 1 << 4, // Allocator function returns zeroed memory |
||
56 | Aligned = 1 << 5, // Allocator function aligns allocations per the |
||
57 | // `allocalign` argument |
||
58 | LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ Aligned) |
||
59 | }; |
||
60 | |||
61 | //===----------------------------------------------------------------------===// |
||
62 | /// \class |
||
63 | /// Functions, function parameters, and return types can have attributes |
||
64 | /// to indicate how they should be treated by optimizations and code |
||
65 | /// generation. This class represents one of those attributes. It's light-weight |
||
66 | /// and should be passed around by-value. |
||
67 | class Attribute { |
||
68 | public: |
||
69 | /// This enumeration lists the attributes that can be associated with |
||
70 | /// parameters, function results, or the function itself. |
||
71 | /// |
||
72 | /// Note: The `uwtable' attribute is about the ABI or the user mandating an |
||
73 | /// entry in the unwind table. The `nounwind' attribute is about an exception |
||
74 | /// passing by the function. |
||
75 | /// |
||
76 | /// In a theoretical system that uses tables for profiling and SjLj for |
||
77 | /// exceptions, they would be fully independent. In a normal system that uses |
||
78 | /// tables for both, the semantics are: |
||
79 | /// |
||
80 | /// nil = Needs an entry because an exception might pass by. |
||
81 | /// nounwind = No need for an entry |
||
82 | /// uwtable = Needs an entry because the ABI says so and because |
||
83 | /// an exception might pass by. |
||
84 | /// uwtable + nounwind = Needs an entry because the ABI says so. |
||
85 | |||
86 | enum AttrKind { |
||
87 | // IR-Level Attributes |
||
88 | None, ///< No attributes have been set |
||
89 | #define GET_ATTR_ENUM |
||
90 | #include "llvm/IR/Attributes.inc" |
||
91 | EndAttrKinds, ///< Sentinal value useful for loops |
||
92 | EmptyKey, ///< Use as Empty key for DenseMap of AttrKind |
||
93 | TombstoneKey, ///< Use as Tombstone key for DenseMap of AttrKind |
||
94 | }; |
||
95 | |||
96 | static const unsigned NumIntAttrKinds = LastIntAttr - FirstIntAttr + 1; |
||
97 | static const unsigned NumTypeAttrKinds = LastTypeAttr - FirstTypeAttr + 1; |
||
98 | |||
99 | static bool isEnumAttrKind(AttrKind Kind) { |
||
100 | return Kind >= FirstEnumAttr && Kind <= LastEnumAttr; |
||
101 | } |
||
102 | static bool isIntAttrKind(AttrKind Kind) { |
||
103 | return Kind >= FirstIntAttr && Kind <= LastIntAttr; |
||
104 | } |
||
105 | static bool isTypeAttrKind(AttrKind Kind) { |
||
106 | return Kind >= FirstTypeAttr && Kind <= LastTypeAttr; |
||
107 | } |
||
108 | |||
109 | static bool canUseAsFnAttr(AttrKind Kind); |
||
110 | static bool canUseAsParamAttr(AttrKind Kind); |
||
111 | static bool canUseAsRetAttr(AttrKind Kind); |
||
112 | |||
113 | private: |
||
114 | AttributeImpl *pImpl = nullptr; |
||
115 | |||
116 | Attribute(AttributeImpl *A) : pImpl(A) {} |
||
117 | |||
118 | public: |
||
119 | Attribute() = default; |
||
120 | |||
121 | //===--------------------------------------------------------------------===// |
||
122 | // Attribute Construction |
||
123 | //===--------------------------------------------------------------------===// |
||
124 | |||
125 | /// Return a uniquified Attribute object. |
||
126 | static Attribute get(LLVMContext &Context, AttrKind Kind, uint64_t Val = 0); |
||
127 | static Attribute get(LLVMContext &Context, StringRef Kind, |
||
128 | StringRef Val = StringRef()); |
||
129 | static Attribute get(LLVMContext &Context, AttrKind Kind, Type *Ty); |
||
130 | |||
131 | /// Return a uniquified Attribute object that has the specific |
||
132 | /// alignment set. |
||
133 | static Attribute getWithAlignment(LLVMContext &Context, Align Alignment); |
||
134 | static Attribute getWithStackAlignment(LLVMContext &Context, Align Alignment); |
||
135 | static Attribute getWithDereferenceableBytes(LLVMContext &Context, |
||
136 | uint64_t Bytes); |
||
137 | static Attribute getWithDereferenceableOrNullBytes(LLVMContext &Context, |
||
138 | uint64_t Bytes); |
||
139 | static Attribute getWithAllocSizeArgs( |
||
140 | LLVMContext &Context, unsigned ElemSizeArg, |
||
141 | const std::optional<unsigned> &NumElemsArg); |
||
142 | static Attribute getWithVScaleRangeArgs(LLVMContext &Context, |
||
143 | unsigned MinValue, unsigned MaxValue); |
||
144 | static Attribute getWithByValType(LLVMContext &Context, Type *Ty); |
||
145 | static Attribute getWithStructRetType(LLVMContext &Context, Type *Ty); |
||
146 | static Attribute getWithByRefType(LLVMContext &Context, Type *Ty); |
||
147 | static Attribute getWithPreallocatedType(LLVMContext &Context, Type *Ty); |
||
148 | static Attribute getWithInAllocaType(LLVMContext &Context, Type *Ty); |
||
149 | static Attribute getWithUWTableKind(LLVMContext &Context, UWTableKind Kind); |
||
150 | static Attribute getWithMemoryEffects(LLVMContext &Context, MemoryEffects ME); |
||
151 | |||
152 | /// For a typed attribute, return the equivalent attribute with the type |
||
153 | /// changed to \p ReplacementTy. |
||
154 | Attribute getWithNewType(LLVMContext &Context, Type *ReplacementTy) { |
||
155 | assert(isTypeAttribute() && "this requires a typed attribute"); |
||
156 | return get(Context, getKindAsEnum(), ReplacementTy); |
||
157 | } |
||
158 | |||
159 | static Attribute::AttrKind getAttrKindFromName(StringRef AttrName); |
||
160 | |||
161 | static StringRef getNameFromAttrKind(Attribute::AttrKind AttrKind); |
||
162 | |||
163 | /// Return true if the provided string matches the IR name of an attribute. |
||
164 | /// example: "noalias" return true but not "NoAlias" |
||
165 | static bool isExistingAttribute(StringRef Name); |
||
166 | |||
167 | //===--------------------------------------------------------------------===// |
||
168 | // Attribute Accessors |
||
169 | //===--------------------------------------------------------------------===// |
||
170 | |||
171 | /// Return true if the attribute is an Attribute::AttrKind type. |
||
172 | bool isEnumAttribute() const; |
||
173 | |||
174 | /// Return true if the attribute is an integer attribute. |
||
175 | bool isIntAttribute() const; |
||
176 | |||
177 | /// Return true if the attribute is a string (target-dependent) |
||
178 | /// attribute. |
||
179 | bool isStringAttribute() const; |
||
180 | |||
181 | /// Return true if the attribute is a type attribute. |
||
182 | bool isTypeAttribute() const; |
||
183 | |||
184 | /// Return true if the attribute is any kind of attribute. |
||
185 | bool isValid() const { return pImpl; } |
||
186 | |||
187 | /// Return true if the attribute is present. |
||
188 | bool hasAttribute(AttrKind Val) const; |
||
189 | |||
190 | /// Return true if the target-dependent attribute is present. |
||
191 | bool hasAttribute(StringRef Val) const; |
||
192 | |||
193 | /// Return the attribute's kind as an enum (Attribute::AttrKind). This |
||
194 | /// requires the attribute to be an enum, integer, or type attribute. |
||
195 | Attribute::AttrKind getKindAsEnum() const; |
||
196 | |||
197 | /// Return the attribute's value as an integer. This requires that the |
||
198 | /// attribute be an integer attribute. |
||
199 | uint64_t getValueAsInt() const; |
||
200 | |||
201 | /// Return the attribute's value as a boolean. This requires that the |
||
202 | /// attribute be a string attribute. |
||
203 | bool getValueAsBool() const; |
||
204 | |||
205 | /// Return the attribute's kind as a string. This requires the |
||
206 | /// attribute to be a string attribute. |
||
207 | StringRef getKindAsString() const; |
||
208 | |||
209 | /// Return the attribute's value as a string. This requires the |
||
210 | /// attribute to be a string attribute. |
||
211 | StringRef getValueAsString() const; |
||
212 | |||
213 | /// Return the attribute's value as a Type. This requires the attribute to be |
||
214 | /// a type attribute. |
||
215 | Type *getValueAsType() const; |
||
216 | |||
217 | /// Returns the alignment field of an attribute as a byte alignment |
||
218 | /// value. |
||
219 | MaybeAlign getAlignment() const; |
||
220 | |||
221 | /// Returns the stack alignment field of an attribute as a byte |
||
222 | /// alignment value. |
||
223 | MaybeAlign getStackAlignment() const; |
||
224 | |||
225 | /// Returns the number of dereferenceable bytes from the |
||
226 | /// dereferenceable attribute. |
||
227 | uint64_t getDereferenceableBytes() const; |
||
228 | |||
229 | /// Returns the number of dereferenceable_or_null bytes from the |
||
230 | /// dereferenceable_or_null attribute. |
||
231 | uint64_t getDereferenceableOrNullBytes() const; |
||
232 | |||
233 | /// Returns the argument numbers for the allocsize attribute. |
||
234 | std::pair<unsigned, std::optional<unsigned>> getAllocSizeArgs() const; |
||
235 | |||
236 | /// Returns the minimum value for the vscale_range attribute. |
||
237 | unsigned getVScaleRangeMin() const; |
||
238 | |||
239 | /// Returns the maximum value for the vscale_range attribute or std::nullopt |
||
240 | /// when unknown. |
||
241 | std::optional<unsigned> getVScaleRangeMax() const; |
||
242 | |||
243 | // Returns the unwind table kind. |
||
244 | UWTableKind getUWTableKind() const; |
||
245 | |||
246 | // Returns the allocator function kind. |
||
247 | AllocFnKind getAllocKind() const; |
||
248 | |||
249 | /// Returns memory effects. |
||
250 | MemoryEffects getMemoryEffects() const; |
||
251 | |||
252 | /// The Attribute is converted to a string of equivalent mnemonic. This |
||
253 | /// is, presumably, for writing out the mnemonics for the assembly writer. |
||
254 | std::string getAsString(bool InAttrGrp = false) const; |
||
255 | |||
256 | /// Return true if this attribute belongs to the LLVMContext. |
||
257 | bool hasParentContext(LLVMContext &C) const; |
||
258 | |||
259 | /// Equality and non-equality operators. |
||
260 | bool operator==(Attribute A) const { return pImpl == A.pImpl; } |
||
261 | bool operator!=(Attribute A) const { return pImpl != A.pImpl; } |
||
262 | |||
263 | /// Less-than operator. Useful for sorting the attributes list. |
||
264 | bool operator<(Attribute A) const; |
||
265 | |||
266 | void Profile(FoldingSetNodeID &ID) const; |
||
267 | |||
268 | /// Return a raw pointer that uniquely identifies this attribute. |
||
269 | void *getRawPointer() const { |
||
270 | return pImpl; |
||
271 | } |
||
272 | |||
273 | /// Get an attribute from a raw pointer created by getRawPointer. |
||
274 | static Attribute fromRawPointer(void *RawPtr) { |
||
275 | return Attribute(reinterpret_cast<AttributeImpl*>(RawPtr)); |
||
276 | } |
||
277 | }; |
||
278 | |||
279 | // Specialized opaque value conversions. |
||
280 | inline LLVMAttributeRef wrap(Attribute Attr) { |
||
281 | return reinterpret_cast<LLVMAttributeRef>(Attr.getRawPointer()); |
||
282 | } |
||
283 | |||
284 | // Specialized opaque value conversions. |
||
285 | inline Attribute unwrap(LLVMAttributeRef Attr) { |
||
286 | return Attribute::fromRawPointer(Attr); |
||
287 | } |
||
288 | |||
289 | //===----------------------------------------------------------------------===// |
||
290 | /// \class |
||
291 | /// This class holds the attributes for a particular argument, parameter, |
||
292 | /// function, or return value. It is an immutable value type that is cheap to |
||
293 | /// copy. Adding and removing enum attributes is intended to be fast, but adding |
||
294 | /// and removing string or integer attributes involves a FoldingSet lookup. |
||
295 | class AttributeSet { |
||
296 | friend AttributeListImpl; |
||
297 | template <typename Ty, typename Enable> friend struct DenseMapInfo; |
||
298 | |||
299 | // TODO: Extract AvailableAttrs from AttributeSetNode and store them here. |
||
300 | // This will allow an efficient implementation of addAttribute and |
||
301 | // removeAttribute for enum attrs. |
||
302 | |||
303 | /// Private implementation pointer. |
||
304 | AttributeSetNode *SetNode = nullptr; |
||
305 | |||
306 | private: |
||
307 | explicit AttributeSet(AttributeSetNode *ASN) : SetNode(ASN) {} |
||
308 | |||
309 | public: |
||
310 | /// AttributeSet is a trivially copyable value type. |
||
311 | AttributeSet() = default; |
||
312 | AttributeSet(const AttributeSet &) = default; |
||
313 | ~AttributeSet() = default; |
||
314 | |||
315 | static AttributeSet get(LLVMContext &C, const AttrBuilder &B); |
||
316 | static AttributeSet get(LLVMContext &C, ArrayRef<Attribute> Attrs); |
||
317 | |||
318 | bool operator==(const AttributeSet &O) const { return SetNode == O.SetNode; } |
||
319 | bool operator!=(const AttributeSet &O) const { return !(*this == O); } |
||
320 | |||
321 | /// Add an argument attribute. Returns a new set because attribute sets are |
||
322 | /// immutable. |
||
323 | [[nodiscard]] AttributeSet addAttribute(LLVMContext &C, |
||
324 | Attribute::AttrKind Kind) const; |
||
325 | |||
326 | /// Add a target-dependent attribute. Returns a new set because attribute sets |
||
327 | /// are immutable. |
||
328 | [[nodiscard]] AttributeSet addAttribute(LLVMContext &C, StringRef Kind, |
||
329 | StringRef Value = StringRef()) const; |
||
330 | |||
331 | /// Add attributes to the attribute set. Returns a new set because attribute |
||
332 | /// sets are immutable. |
||
333 | [[nodiscard]] AttributeSet addAttributes(LLVMContext &C, |
||
334 | AttributeSet AS) const; |
||
335 | |||
336 | /// Remove the specified attribute from this set. Returns a new set because |
||
337 | /// attribute sets are immutable. |
||
338 | [[nodiscard]] AttributeSet removeAttribute(LLVMContext &C, |
||
339 | Attribute::AttrKind Kind) const; |
||
340 | |||
341 | /// Remove the specified attribute from this set. Returns a new set because |
||
342 | /// attribute sets are immutable. |
||
343 | [[nodiscard]] AttributeSet removeAttribute(LLVMContext &C, |
||
344 | StringRef Kind) const; |
||
345 | |||
346 | /// Remove the specified attributes from this set. Returns a new set because |
||
347 | /// attribute sets are immutable. |
||
348 | [[nodiscard]] AttributeSet |
||
349 | removeAttributes(LLVMContext &C, const AttributeMask &AttrsToRemove) const; |
||
350 | |||
351 | /// Return the number of attributes in this set. |
||
352 | unsigned getNumAttributes() const; |
||
353 | |||
354 | /// Return true if attributes exists in this set. |
||
355 | bool hasAttributes() const { return SetNode != nullptr; } |
||
356 | |||
357 | /// Return true if the attribute exists in this set. |
||
358 | bool hasAttribute(Attribute::AttrKind Kind) const; |
||
359 | |||
360 | /// Return true if the attribute exists in this set. |
||
361 | bool hasAttribute(StringRef Kind) const; |
||
362 | |||
363 | /// Return the attribute object. |
||
364 | Attribute getAttribute(Attribute::AttrKind Kind) const; |
||
365 | |||
366 | /// Return the target-dependent attribute object. |
||
367 | Attribute getAttribute(StringRef Kind) const; |
||
368 | |||
369 | MaybeAlign getAlignment() const; |
||
370 | MaybeAlign getStackAlignment() const; |
||
371 | uint64_t getDereferenceableBytes() const; |
||
372 | uint64_t getDereferenceableOrNullBytes() const; |
||
373 | Type *getByValType() const; |
||
374 | Type *getStructRetType() const; |
||
375 | Type *getByRefType() const; |
||
376 | Type *getPreallocatedType() const; |
||
377 | Type *getInAllocaType() const; |
||
378 | Type *getElementType() const; |
||
379 | std::optional<std::pair<unsigned, std::optional<unsigned>>> getAllocSizeArgs() |
||
380 | const; |
||
381 | unsigned getVScaleRangeMin() const; |
||
382 | std::optional<unsigned> getVScaleRangeMax() const; |
||
383 | UWTableKind getUWTableKind() const; |
||
384 | AllocFnKind getAllocKind() const; |
||
385 | MemoryEffects getMemoryEffects() const; |
||
386 | std::string getAsString(bool InAttrGrp = false) const; |
||
387 | |||
388 | /// Return true if this attribute set belongs to the LLVMContext. |
||
389 | bool hasParentContext(LLVMContext &C) const; |
||
390 | |||
391 | using iterator = const Attribute *; |
||
392 | |||
393 | iterator begin() const; |
||
394 | iterator end() const; |
||
395 | #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) |
||
396 | void dump() const; |
||
397 | #endif |
||
398 | }; |
||
399 | |||
400 | //===----------------------------------------------------------------------===// |
||
401 | /// \class |
||
402 | /// Provide DenseMapInfo for AttributeSet. |
||
403 | template <> struct DenseMapInfo<AttributeSet, void> { |
||
404 | static AttributeSet getEmptyKey() { |
||
405 | auto Val = static_cast<uintptr_t>(-1); |
||
406 | Val <<= PointerLikeTypeTraits<void *>::NumLowBitsAvailable; |
||
407 | return AttributeSet(reinterpret_cast<AttributeSetNode *>(Val)); |
||
408 | } |
||
409 | |||
410 | static AttributeSet getTombstoneKey() { |
||
411 | auto Val = static_cast<uintptr_t>(-2); |
||
412 | Val <<= PointerLikeTypeTraits<void *>::NumLowBitsAvailable; |
||
413 | return AttributeSet(reinterpret_cast<AttributeSetNode *>(Val)); |
||
414 | } |
||
415 | |||
416 | static unsigned getHashValue(AttributeSet AS) { |
||
417 | return (unsigned((uintptr_t)AS.SetNode) >> 4) ^ |
||
418 | (unsigned((uintptr_t)AS.SetNode) >> 9); |
||
419 | } |
||
420 | |||
421 | static bool isEqual(AttributeSet LHS, AttributeSet RHS) { return LHS == RHS; } |
||
422 | }; |
||
423 | |||
424 | //===----------------------------------------------------------------------===// |
||
425 | /// \class |
||
426 | /// This class holds the attributes for a function, its return value, and |
||
427 | /// its parameters. You access the attributes for each of them via an index into |
||
428 | /// the AttributeList object. The function attributes are at index |
||
429 | /// `AttributeList::FunctionIndex', the return value is at index |
||
430 | /// `AttributeList::ReturnIndex', and the attributes for the parameters start at |
||
431 | /// index `AttributeList::FirstArgIndex'. |
||
432 | class AttributeList { |
||
433 | public: |
||
434 | enum AttrIndex : unsigned { |
||
435 | ReturnIndex = 0U, |
||
436 | FunctionIndex = ~0U, |
||
437 | FirstArgIndex = 1, |
||
438 | }; |
||
439 | |||
440 | private: |
||
441 | friend class AttrBuilder; |
||
442 | friend class AttributeListImpl; |
||
443 | friend class AttributeSet; |
||
444 | friend class AttributeSetNode; |
||
445 | template <typename Ty, typename Enable> friend struct DenseMapInfo; |
||
446 | |||
447 | /// The attributes that we are managing. This can be null to represent |
||
448 | /// the empty attributes list. |
||
449 | AttributeListImpl *pImpl = nullptr; |
||
450 | |||
451 | public: |
||
452 | /// Create an AttributeList with the specified parameters in it. |
||
453 | static AttributeList get(LLVMContext &C, |
||
454 | ArrayRef<std::pair<unsigned, Attribute>> Attrs); |
||
455 | static AttributeList get(LLVMContext &C, |
||
456 | ArrayRef<std::pair<unsigned, AttributeSet>> Attrs); |
||
457 | |||
458 | /// Create an AttributeList from attribute sets for a function, its |
||
459 | /// return value, and all of its arguments. |
||
460 | static AttributeList get(LLVMContext &C, AttributeSet FnAttrs, |
||
461 | AttributeSet RetAttrs, |
||
462 | ArrayRef<AttributeSet> ArgAttrs); |
||
463 | |||
464 | private: |
||
465 | explicit AttributeList(AttributeListImpl *LI) : pImpl(LI) {} |
||
466 | |||
467 | static AttributeList getImpl(LLVMContext &C, ArrayRef<AttributeSet> AttrSets); |
||
468 | |||
469 | AttributeList setAttributesAtIndex(LLVMContext &C, unsigned Index, |
||
470 | AttributeSet Attrs) const; |
||
471 | |||
472 | public: |
||
473 | AttributeList() = default; |
||
474 | |||
475 | //===--------------------------------------------------------------------===// |
||
476 | // AttributeList Construction and Mutation |
||
477 | //===--------------------------------------------------------------------===// |
||
478 | |||
479 | /// Return an AttributeList with the specified parameters in it. |
||
480 | static AttributeList get(LLVMContext &C, ArrayRef<AttributeList> Attrs); |
||
481 | static AttributeList get(LLVMContext &C, unsigned Index, |
||
482 | ArrayRef<Attribute::AttrKind> Kinds); |
||
483 | static AttributeList get(LLVMContext &C, unsigned Index, |
||
484 | ArrayRef<Attribute::AttrKind> Kinds, |
||
485 | ArrayRef<uint64_t> Values); |
||
486 | static AttributeList get(LLVMContext &C, unsigned Index, |
||
487 | ArrayRef<StringRef> Kind); |
||
488 | static AttributeList get(LLVMContext &C, unsigned Index, |
||
489 | AttributeSet Attrs); |
||
490 | static AttributeList get(LLVMContext &C, unsigned Index, |
||
491 | const AttrBuilder &B); |
||
492 | |||
493 | // TODO: remove non-AtIndex versions of these methods. |
||
494 | /// Add an attribute to the attribute set at the given index. |
||
495 | /// Returns a new list because attribute lists are immutable. |
||
496 | [[nodiscard]] AttributeList |
||
497 | addAttributeAtIndex(LLVMContext &C, unsigned Index, |
||
498 | Attribute::AttrKind Kind) const; |
||
499 | |||
500 | /// Add an attribute to the attribute set at the given index. |
||
501 | /// Returns a new list because attribute lists are immutable. |
||
502 | [[nodiscard]] AttributeList |
||
503 | addAttributeAtIndex(LLVMContext &C, unsigned Index, StringRef Kind, |
||
504 | StringRef Value = StringRef()) const; |
||
505 | |||
506 | /// Add an attribute to the attribute set at the given index. |
||
507 | /// Returns a new list because attribute lists are immutable. |
||
508 | [[nodiscard]] AttributeList |
||
509 | addAttributeAtIndex(LLVMContext &C, unsigned Index, Attribute A) const; |
||
510 | |||
511 | /// Add attributes to the attribute set at the given index. |
||
512 | /// Returns a new list because attribute lists are immutable. |
||
513 | [[nodiscard]] AttributeList addAttributesAtIndex(LLVMContext &C, |
||
514 | unsigned Index, |
||
515 | const AttrBuilder &B) const; |
||
516 | |||
517 | /// Add a function attribute to the list. Returns a new list because |
||
518 | /// attribute lists are immutable. |
||
519 | [[nodiscard]] AttributeList addFnAttribute(LLVMContext &C, |
||
520 | Attribute::AttrKind Kind) const { |
||
521 | return addAttributeAtIndex(C, FunctionIndex, Kind); |
||
522 | } |
||
523 | |||
524 | /// Add a function attribute to the list. Returns a new list because |
||
525 | /// attribute lists are immutable. |
||
526 | [[nodiscard]] AttributeList addFnAttribute(LLVMContext &C, |
||
527 | Attribute Attr) const { |
||
528 | return addAttributeAtIndex(C, FunctionIndex, Attr); |
||
529 | } |
||
530 | |||
531 | /// Add a function attribute to the list. Returns a new list because |
||
532 | /// attribute lists are immutable. |
||
533 | [[nodiscard]] AttributeList |
||
534 | addFnAttribute(LLVMContext &C, StringRef Kind, |
||
535 | StringRef Value = StringRef()) const { |
||
536 | return addAttributeAtIndex(C, FunctionIndex, Kind, Value); |
||
537 | } |
||
538 | |||
539 | /// Add function attribute to the list. Returns a new list because |
||
540 | /// attribute lists are immutable. |
||
541 | [[nodiscard]] AttributeList addFnAttributes(LLVMContext &C, |
||
542 | const AttrBuilder &B) const { |
||
543 | return addAttributesAtIndex(C, FunctionIndex, B); |
||
544 | } |
||
545 | |||
546 | /// Add a return value attribute to the list. Returns a new list because |
||
547 | /// attribute lists are immutable. |
||
548 | [[nodiscard]] AttributeList addRetAttribute(LLVMContext &C, |
||
549 | Attribute::AttrKind Kind) const { |
||
550 | return addAttributeAtIndex(C, ReturnIndex, Kind); |
||
551 | } |
||
552 | |||
553 | /// Add a return value attribute to the list. Returns a new list because |
||
554 | /// attribute lists are immutable. |
||
555 | [[nodiscard]] AttributeList addRetAttribute(LLVMContext &C, |
||
556 | Attribute Attr) const { |
||
557 | return addAttributeAtIndex(C, ReturnIndex, Attr); |
||
558 | } |
||
559 | |||
560 | /// Add a return value attribute to the list. Returns a new list because |
||
561 | /// attribute lists are immutable. |
||
562 | [[nodiscard]] AttributeList addRetAttributes(LLVMContext &C, |
||
563 | const AttrBuilder &B) const { |
||
564 | return addAttributesAtIndex(C, ReturnIndex, B); |
||
565 | } |
||
566 | |||
567 | /// Add an argument attribute to the list. Returns a new list because |
||
568 | /// attribute lists are immutable. |
||
569 | [[nodiscard]] AttributeList |
||
570 | addParamAttribute(LLVMContext &C, unsigned ArgNo, |
||
571 | Attribute::AttrKind Kind) const { |
||
572 | return addAttributeAtIndex(C, ArgNo + FirstArgIndex, Kind); |
||
573 | } |
||
574 | |||
575 | /// Add an argument attribute to the list. Returns a new list because |
||
576 | /// attribute lists are immutable. |
||
577 | [[nodiscard]] AttributeList |
||
578 | addParamAttribute(LLVMContext &C, unsigned ArgNo, StringRef Kind, |
||
579 | StringRef Value = StringRef()) const { |
||
580 | return addAttributeAtIndex(C, ArgNo + FirstArgIndex, Kind, Value); |
||
581 | } |
||
582 | |||
583 | /// Add an attribute to the attribute list at the given arg indices. Returns a |
||
584 | /// new list because attribute lists are immutable. |
||
585 | [[nodiscard]] AttributeList addParamAttribute(LLVMContext &C, |
||
586 | ArrayRef<unsigned> ArgNos, |
||
587 | Attribute A) const; |
||
588 | |||
589 | /// Add an argument attribute to the list. Returns a new list because |
||
590 | /// attribute lists are immutable. |
||
591 | [[nodiscard]] AttributeList addParamAttributes(LLVMContext &C, unsigned ArgNo, |
||
592 | const AttrBuilder &B) const { |
||
593 | return addAttributesAtIndex(C, ArgNo + FirstArgIndex, B); |
||
594 | } |
||
595 | |||
596 | /// Remove the specified attribute at the specified index from this |
||
597 | /// attribute list. Returns a new list because attribute lists are immutable. |
||
598 | [[nodiscard]] AttributeList |
||
599 | removeAttributeAtIndex(LLVMContext &C, unsigned Index, |
||
600 | Attribute::AttrKind Kind) const; |
||
601 | |||
602 | /// Remove the specified attribute at the specified index from this |
||
603 | /// attribute list. Returns a new list because attribute lists are immutable. |
||
604 | [[nodiscard]] AttributeList |
||
605 | removeAttributeAtIndex(LLVMContext &C, unsigned Index, StringRef Kind) const; |
||
606 | [[nodiscard]] AttributeList removeAttribute(LLVMContext &C, unsigned Index, |
||
607 | StringRef Kind) const { |
||
608 | return removeAttributeAtIndex(C, Index, Kind); |
||
609 | } |
||
610 | |||
611 | /// Remove the specified attributes at the specified index from this |
||
612 | /// attribute list. Returns a new list because attribute lists are immutable. |
||
613 | [[nodiscard]] AttributeList |
||
614 | removeAttributesAtIndex(LLVMContext &C, unsigned Index, |
||
615 | const AttributeMask &AttrsToRemove) const; |
||
616 | |||
617 | /// Remove all attributes at the specified index from this |
||
618 | /// attribute list. Returns a new list because attribute lists are immutable. |
||
619 | [[nodiscard]] AttributeList removeAttributesAtIndex(LLVMContext &C, |
||
620 | unsigned Index) const; |
||
621 | |||
622 | /// Remove the specified attribute at the function index from this |
||
623 | /// attribute list. Returns a new list because attribute lists are immutable. |
||
624 | [[nodiscard]] AttributeList |
||
625 | removeFnAttribute(LLVMContext &C, Attribute::AttrKind Kind) const { |
||
626 | return removeAttributeAtIndex(C, FunctionIndex, Kind); |
||
627 | } |
||
628 | |||
629 | /// Remove the specified attribute at the function index from this |
||
630 | /// attribute list. Returns a new list because attribute lists are immutable. |
||
631 | [[nodiscard]] AttributeList removeFnAttribute(LLVMContext &C, |
||
632 | StringRef Kind) const { |
||
633 | return removeAttributeAtIndex(C, FunctionIndex, Kind); |
||
634 | } |
||
635 | |||
636 | /// Remove the specified attribute at the function index from this |
||
637 | /// attribute list. Returns a new list because attribute lists are immutable. |
||
638 | [[nodiscard]] AttributeList |
||
639 | removeFnAttributes(LLVMContext &C, const AttributeMask &AttrsToRemove) const { |
||
640 | return removeAttributesAtIndex(C, FunctionIndex, AttrsToRemove); |
||
641 | } |
||
642 | |||
643 | /// Remove the attributes at the function index from this |
||
644 | /// attribute list. Returns a new list because attribute lists are immutable. |
||
645 | [[nodiscard]] AttributeList removeFnAttributes(LLVMContext &C) const { |
||
646 | return removeAttributesAtIndex(C, FunctionIndex); |
||
647 | } |
||
648 | |||
649 | /// Remove the specified attribute at the return value index from this |
||
650 | /// attribute list. Returns a new list because attribute lists are immutable. |
||
651 | [[nodiscard]] AttributeList |
||
652 | removeRetAttribute(LLVMContext &C, Attribute::AttrKind Kind) const { |
||
653 | return removeAttributeAtIndex(C, ReturnIndex, Kind); |
||
654 | } |
||
655 | |||
656 | /// Remove the specified attribute at the return value index from this |
||
657 | /// attribute list. Returns a new list because attribute lists are immutable. |
||
658 | [[nodiscard]] AttributeList removeRetAttribute(LLVMContext &C, |
||
659 | StringRef Kind) const { |
||
660 | return removeAttributeAtIndex(C, ReturnIndex, Kind); |
||
661 | } |
||
662 | |||
663 | /// Remove the specified attribute at the return value index from this |
||
664 | /// attribute list. Returns a new list because attribute lists are immutable. |
||
665 | [[nodiscard]] AttributeList |
||
666 | removeRetAttributes(LLVMContext &C, |
||
667 | const AttributeMask &AttrsToRemove) const { |
||
668 | return removeAttributesAtIndex(C, ReturnIndex, AttrsToRemove); |
||
669 | } |
||
670 | |||
671 | /// Remove the specified attribute at the specified arg index from this |
||
672 | /// attribute list. Returns a new list because attribute lists are immutable. |
||
673 | [[nodiscard]] AttributeList |
||
674 | removeParamAttribute(LLVMContext &C, unsigned ArgNo, |
||
675 | Attribute::AttrKind Kind) const { |
||
676 | return removeAttributeAtIndex(C, ArgNo + FirstArgIndex, Kind); |
||
677 | } |
||
678 | |||
679 | /// Remove the specified attribute at the specified arg index from this |
||
680 | /// attribute list. Returns a new list because attribute lists are immutable. |
||
681 | [[nodiscard]] AttributeList |
||
682 | removeParamAttribute(LLVMContext &C, unsigned ArgNo, StringRef Kind) const { |
||
683 | return removeAttributeAtIndex(C, ArgNo + FirstArgIndex, Kind); |
||
684 | } |
||
685 | |||
686 | /// Remove the specified attribute at the specified arg index from this |
||
687 | /// attribute list. Returns a new list because attribute lists are immutable. |
||
688 | [[nodiscard]] AttributeList |
||
689 | removeParamAttributes(LLVMContext &C, unsigned ArgNo, |
||
690 | const AttributeMask &AttrsToRemove) const { |
||
691 | return removeAttributesAtIndex(C, ArgNo + FirstArgIndex, AttrsToRemove); |
||
692 | } |
||
693 | |||
694 | /// Remove all attributes at the specified arg index from this |
||
695 | /// attribute list. Returns a new list because attribute lists are immutable. |
||
696 | [[nodiscard]] AttributeList removeParamAttributes(LLVMContext &C, |
||
697 | unsigned ArgNo) const { |
||
698 | return removeAttributesAtIndex(C, ArgNo + FirstArgIndex); |
||
699 | } |
||
700 | |||
701 | /// Replace the type contained by attribute \p AttrKind at index \p ArgNo wih |
||
702 | /// \p ReplacementTy, preserving all other attributes. |
||
703 | [[nodiscard]] AttributeList |
||
704 | replaceAttributeTypeAtIndex(LLVMContext &C, unsigned ArgNo, |
||
705 | Attribute::AttrKind Kind, |
||
706 | Type *ReplacementTy) const { |
||
707 | Attribute Attr = getAttributeAtIndex(ArgNo, Kind); |
||
708 | auto Attrs = removeAttributeAtIndex(C, ArgNo, Kind); |
||
709 | return Attrs.addAttributeAtIndex(C, ArgNo, |
||
710 | Attr.getWithNewType(C, ReplacementTy)); |
||
711 | } |
||
712 | |||
713 | /// \brief Add the dereferenceable attribute to the attribute set at the given |
||
714 | /// index. Returns a new list because attribute lists are immutable. |
||
715 | [[nodiscard]] AttributeList addDereferenceableRetAttr(LLVMContext &C, |
||
716 | uint64_t Bytes) const; |
||
717 | |||
718 | /// \brief Add the dereferenceable attribute to the attribute set at the given |
||
719 | /// arg index. Returns a new list because attribute lists are immutable. |
||
720 | [[nodiscard]] AttributeList addDereferenceableParamAttr(LLVMContext &C, |
||
721 | unsigned ArgNo, |
||
722 | uint64_t Bytes) const; |
||
723 | |||
724 | /// Add the dereferenceable_or_null attribute to the attribute set at |
||
725 | /// the given arg index. Returns a new list because attribute lists are |
||
726 | /// immutable. |
||
727 | [[nodiscard]] AttributeList |
||
728 | addDereferenceableOrNullParamAttr(LLVMContext &C, unsigned ArgNo, |
||
729 | uint64_t Bytes) const; |
||
730 | |||
731 | /// Add the allocsize attribute to the attribute set at the given arg index. |
||
732 | /// Returns a new list because attribute lists are immutable. |
||
733 | [[nodiscard]] AttributeList |
||
734 | addAllocSizeParamAttr(LLVMContext &C, unsigned ArgNo, unsigned ElemSizeArg, |
||
735 | const std::optional<unsigned> &NumElemsArg); |
||
736 | |||
737 | //===--------------------------------------------------------------------===// |
||
738 | // AttributeList Accessors |
||
739 | //===--------------------------------------------------------------------===// |
||
740 | |||
741 | /// The attributes for the specified index are returned. |
||
742 | AttributeSet getAttributes(unsigned Index) const; |
||
743 | |||
744 | /// The attributes for the argument or parameter at the given index are |
||
745 | /// returned. |
||
746 | AttributeSet getParamAttrs(unsigned ArgNo) const; |
||
747 | |||
748 | /// The attributes for the ret value are returned. |
||
749 | AttributeSet getRetAttrs() const; |
||
750 | |||
751 | /// The function attributes are returned. |
||
752 | AttributeSet getFnAttrs() const; |
||
753 | |||
754 | /// Return true if the attribute exists at the given index. |
||
755 | bool hasAttributeAtIndex(unsigned Index, Attribute::AttrKind Kind) const; |
||
756 | |||
757 | /// Return true if the attribute exists at the given index. |
||
758 | bool hasAttributeAtIndex(unsigned Index, StringRef Kind) const; |
||
759 | |||
760 | /// Return true if attribute exists at the given index. |
||
761 | bool hasAttributesAtIndex(unsigned Index) const; |
||
762 | |||
763 | /// Return true if the attribute exists for the given argument |
||
764 | bool hasParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) const { |
||
765 | return hasAttributeAtIndex(ArgNo + FirstArgIndex, Kind); |
||
766 | } |
||
767 | |||
768 | /// Return true if the attribute exists for the given argument |
||
769 | bool hasParamAttr(unsigned ArgNo, StringRef Kind) const { |
||
770 | return hasAttributeAtIndex(ArgNo + FirstArgIndex, Kind); |
||
771 | } |
||
772 | |||
773 | /// Return true if attributes exists for the given argument |
||
774 | bool hasParamAttrs(unsigned ArgNo) const { |
||
775 | return hasAttributesAtIndex(ArgNo + FirstArgIndex); |
||
776 | } |
||
777 | |||
778 | /// Return true if the attribute exists for the return value. |
||
779 | bool hasRetAttr(Attribute::AttrKind Kind) const { |
||
780 | return hasAttributeAtIndex(ReturnIndex, Kind); |
||
781 | } |
||
782 | |||
783 | /// Return true if the attribute exists for the return value. |
||
784 | bool hasRetAttr(StringRef Kind) const { |
||
785 | return hasAttributeAtIndex(ReturnIndex, Kind); |
||
786 | } |
||
787 | |||
788 | /// Return true if attributes exist for the return value. |
||
789 | bool hasRetAttrs() const { return hasAttributesAtIndex(ReturnIndex); } |
||
790 | |||
791 | /// Return true if the attribute exists for the function. |
||
792 | bool hasFnAttr(Attribute::AttrKind Kind) const; |
||
793 | |||
794 | /// Return true if the attribute exists for the function. |
||
795 | bool hasFnAttr(StringRef Kind) const; |
||
796 | |||
797 | /// Return true the attributes exist for the function. |
||
798 | bool hasFnAttrs() const { return hasAttributesAtIndex(FunctionIndex); } |
||
799 | |||
800 | /// Return true if the specified attribute is set for at least one |
||
801 | /// parameter or for the return value. If Index is not nullptr, the index |
||
802 | /// of a parameter with the specified attribute is provided. |
||
803 | bool hasAttrSomewhere(Attribute::AttrKind Kind, |
||
804 | unsigned *Index = nullptr) const; |
||
805 | |||
806 | /// Return the attribute object that exists at the given index. |
||
807 | Attribute getAttributeAtIndex(unsigned Index, Attribute::AttrKind Kind) const; |
||
808 | |||
809 | /// Return the attribute object that exists at the given index. |
||
810 | Attribute getAttributeAtIndex(unsigned Index, StringRef Kind) const; |
||
811 | |||
812 | /// Return the attribute object that exists at the arg index. |
||
813 | Attribute getParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) const { |
||
814 | return getAttributeAtIndex(ArgNo + FirstArgIndex, Kind); |
||
815 | } |
||
816 | |||
817 | /// Return the attribute object that exists at the given index. |
||
818 | Attribute getParamAttr(unsigned ArgNo, StringRef Kind) const { |
||
819 | return getAttributeAtIndex(ArgNo + FirstArgIndex, Kind); |
||
820 | } |
||
821 | |||
822 | /// Return the attribute object that exists for the function. |
||
823 | Attribute getFnAttr(Attribute::AttrKind Kind) const { |
||
824 | return getAttributeAtIndex(FunctionIndex, Kind); |
||
825 | } |
||
826 | |||
827 | /// Return the attribute object that exists for the function. |
||
828 | Attribute getFnAttr(StringRef Kind) const { |
||
829 | return getAttributeAtIndex(FunctionIndex, Kind); |
||
830 | } |
||
831 | |||
832 | /// Return the alignment of the return value. |
||
833 | MaybeAlign getRetAlignment() const; |
||
834 | |||
835 | /// Return the alignment for the specified function parameter. |
||
836 | MaybeAlign getParamAlignment(unsigned ArgNo) const; |
||
837 | |||
838 | /// Return the stack alignment for the specified function parameter. |
||
839 | MaybeAlign getParamStackAlignment(unsigned ArgNo) const; |
||
840 | |||
841 | /// Return the byval type for the specified function parameter. |
||
842 | Type *getParamByValType(unsigned ArgNo) const; |
||
843 | |||
844 | /// Return the sret type for the specified function parameter. |
||
845 | Type *getParamStructRetType(unsigned ArgNo) const; |
||
846 | |||
847 | /// Return the byref type for the specified function parameter. |
||
848 | Type *getParamByRefType(unsigned ArgNo) const; |
||
849 | |||
850 | /// Return the preallocated type for the specified function parameter. |
||
851 | Type *getParamPreallocatedType(unsigned ArgNo) const; |
||
852 | |||
853 | /// Return the inalloca type for the specified function parameter. |
||
854 | Type *getParamInAllocaType(unsigned ArgNo) const; |
||
855 | |||
856 | /// Return the elementtype type for the specified function parameter. |
||
857 | Type *getParamElementType(unsigned ArgNo) const; |
||
858 | |||
859 | /// Get the stack alignment of the function. |
||
860 | MaybeAlign getFnStackAlignment() const; |
||
861 | |||
862 | /// Get the stack alignment of the return value. |
||
863 | MaybeAlign getRetStackAlignment() const; |
||
864 | |||
865 | /// Get the number of dereferenceable bytes (or zero if unknown) of the return |
||
866 | /// value. |
||
867 | uint64_t getRetDereferenceableBytes() const; |
||
868 | |||
869 | /// Get the number of dereferenceable bytes (or zero if unknown) of an arg. |
||
870 | uint64_t getParamDereferenceableBytes(unsigned Index) const; |
||
871 | |||
872 | /// Get the number of dereferenceable_or_null bytes (or zero if unknown) of |
||
873 | /// the return value. |
||
874 | uint64_t getRetDereferenceableOrNullBytes() const; |
||
875 | |||
876 | /// Get the number of dereferenceable_or_null bytes (or zero if unknown) of an |
||
877 | /// arg. |
||
878 | uint64_t getParamDereferenceableOrNullBytes(unsigned ArgNo) const; |
||
879 | |||
880 | /// Get the unwind table kind requested for the function. |
||
881 | UWTableKind getUWTableKind() const; |
||
882 | |||
883 | AllocFnKind getAllocKind() const; |
||
884 | |||
885 | /// Returns memory effects of the function. |
||
886 | MemoryEffects getMemoryEffects() const; |
||
887 | |||
888 | /// Return the attributes at the index as a string. |
||
889 | std::string getAsString(unsigned Index, bool InAttrGrp = false) const; |
||
890 | |||
891 | /// Return true if this attribute list belongs to the LLVMContext. |
||
892 | bool hasParentContext(LLVMContext &C) const; |
||
893 | |||
894 | //===--------------------------------------------------------------------===// |
||
895 | // AttributeList Introspection |
||
896 | //===--------------------------------------------------------------------===// |
||
897 | |||
898 | using iterator = const AttributeSet *; |
||
899 | |||
900 | iterator begin() const; |
||
901 | iterator end() const; |
||
902 | |||
903 | unsigned getNumAttrSets() const; |
||
904 | |||
905 | // Implementation of indexes(). Produces iterators that wrap an index. Mostly |
||
906 | // to hide the awkwardness of unsigned wrapping when iterating over valid |
||
907 | // indexes. |
||
908 | struct index_iterator { |
||
909 | unsigned NumAttrSets; |
||
910 | index_iterator(int NumAttrSets) : NumAttrSets(NumAttrSets) {} |
||
911 | struct int_wrapper { |
||
912 | int_wrapper(unsigned i) : i(i) {} |
||
913 | unsigned i; |
||
914 | unsigned operator*() { return i; } |
||
915 | bool operator!=(const int_wrapper &Other) { return i != Other.i; } |
||
916 | int_wrapper &operator++() { |
||
917 | // This is expected to undergo unsigned wrapping since FunctionIndex is |
||
918 | // ~0 and that's where we start. |
||
919 | ++i; |
||
920 | return *this; |
||
921 | } |
||
922 | }; |
||
923 | |||
924 | int_wrapper begin() { return int_wrapper(AttributeList::FunctionIndex); } |
||
925 | |||
926 | int_wrapper end() { return int_wrapper(NumAttrSets - 1); } |
||
927 | }; |
||
928 | |||
929 | /// Use this to iterate over the valid attribute indexes. |
||
930 | index_iterator indexes() const { return index_iterator(getNumAttrSets()); } |
||
931 | |||
932 | /// operator==/!= - Provide equality predicates. |
||
933 | bool operator==(const AttributeList &RHS) const { return pImpl == RHS.pImpl; } |
||
934 | bool operator!=(const AttributeList &RHS) const { return pImpl != RHS.pImpl; } |
||
935 | |||
936 | /// Return a raw pointer that uniquely identifies this attribute list. |
||
937 | void *getRawPointer() const { |
||
938 | return pImpl; |
||
939 | } |
||
940 | |||
941 | /// Return true if there are no attributes. |
||
942 | bool isEmpty() const { return pImpl == nullptr; } |
||
943 | |||
944 | void print(raw_ostream &O) const; |
||
945 | |||
946 | void dump() const; |
||
947 | }; |
||
948 | |||
949 | //===----------------------------------------------------------------------===// |
||
950 | /// \class |
||
951 | /// Provide DenseMapInfo for AttributeList. |
||
952 | template <> struct DenseMapInfo<AttributeList, void> { |
||
953 | static AttributeList getEmptyKey() { |
||
954 | auto Val = static_cast<uintptr_t>(-1); |
||
955 | Val <<= PointerLikeTypeTraits<void*>::NumLowBitsAvailable; |
||
956 | return AttributeList(reinterpret_cast<AttributeListImpl *>(Val)); |
||
957 | } |
||
958 | |||
959 | static AttributeList getTombstoneKey() { |
||
960 | auto Val = static_cast<uintptr_t>(-2); |
||
961 | Val <<= PointerLikeTypeTraits<void*>::NumLowBitsAvailable; |
||
962 | return AttributeList(reinterpret_cast<AttributeListImpl *>(Val)); |
||
963 | } |
||
964 | |||
965 | static unsigned getHashValue(AttributeList AS) { |
||
966 | return (unsigned((uintptr_t)AS.pImpl) >> 4) ^ |
||
967 | (unsigned((uintptr_t)AS.pImpl) >> 9); |
||
968 | } |
||
969 | |||
970 | static bool isEqual(AttributeList LHS, AttributeList RHS) { |
||
971 | return LHS == RHS; |
||
972 | } |
||
973 | }; |
||
974 | |||
975 | //===----------------------------------------------------------------------===// |
||
976 | /// \class |
||
977 | /// This class stores enough information to efficiently remove some attributes |
||
978 | /// from an existing AttrBuilder, AttributeSet or AttributeList. |
||
979 | class AttributeMask { |
||
980 | std::bitset<Attribute::EndAttrKinds> Attrs; |
||
981 | std::set<SmallString<32>, std::less<>> TargetDepAttrs; |
||
982 | |||
983 | public: |
||
984 | AttributeMask() = default; |
||
985 | AttributeMask(const AttributeMask &) = delete; |
||
986 | AttributeMask(AttributeMask &&) = default; |
||
987 | |||
988 | AttributeMask(AttributeSet AS) { |
||
989 | for (Attribute A : AS) |
||
990 | addAttribute(A); |
||
991 | } |
||
992 | |||
993 | /// Add an attribute to the mask. |
||
994 | AttributeMask &addAttribute(Attribute::AttrKind Val) { |
||
995 | assert((unsigned)Val < Attribute::EndAttrKinds && |
||
996 | "Attribute out of range!"); |
||
997 | Attrs[Val] = true; |
||
998 | return *this; |
||
999 | } |
||
1000 | |||
1001 | /// Add the Attribute object to the builder. |
||
1002 | AttributeMask &addAttribute(Attribute A) { |
||
1003 | if (A.isStringAttribute()) |
||
1004 | addAttribute(A.getKindAsString()); |
||
1005 | else |
||
1006 | addAttribute(A.getKindAsEnum()); |
||
1007 | return *this; |
||
1008 | } |
||
1009 | |||
1010 | /// Add the target-dependent attribute to the builder. |
||
1011 | AttributeMask &addAttribute(StringRef A) { |
||
1012 | TargetDepAttrs.insert(A); |
||
1013 | return *this; |
||
1014 | } |
||
1015 | |||
1016 | /// Return true if the builder has the specified attribute. |
||
1017 | bool contains(Attribute::AttrKind A) const { |
||
1018 | assert((unsigned)A < Attribute::EndAttrKinds && "Attribute out of range!"); |
||
1019 | return Attrs[A]; |
||
1020 | } |
||
1021 | |||
1022 | /// Return true if the builder has the specified target-dependent |
||
1023 | /// attribute. |
||
1024 | bool contains(StringRef A) const { return TargetDepAttrs.count(A); } |
||
1025 | |||
1026 | /// Return true if the mask contains the specified attribute. |
||
1027 | bool contains(Attribute A) const { |
||
1028 | if (A.isStringAttribute()) |
||
1029 | return contains(A.getKindAsString()); |
||
1030 | return contains(A.getKindAsEnum()); |
||
1031 | } |
||
1032 | }; |
||
1033 | |||
1034 | //===----------------------------------------------------------------------===// |
||
1035 | /// \class |
||
1036 | /// This class is used in conjunction with the Attribute::get method to |
||
1037 | /// create an Attribute object. The object itself is uniquified. The Builder's |
||
1038 | /// value, however, is not. So this can be used as a quick way to test for |
||
1039 | /// equality, presence of attributes, etc. |
||
1040 | class AttrBuilder { |
||
1041 | LLVMContext &Ctx; |
||
1042 | SmallVector<Attribute, 8> Attrs; |
||
1043 | |||
1044 | public: |
||
1045 | AttrBuilder(LLVMContext &Ctx) : Ctx(Ctx) {} |
||
1046 | AttrBuilder(const AttrBuilder &) = delete; |
||
1047 | AttrBuilder(AttrBuilder &&) = default; |
||
1048 | |||
1049 | AttrBuilder(LLVMContext &Ctx, const Attribute &A) : Ctx(Ctx) { |
||
1050 | addAttribute(A); |
||
1051 | } |
||
1052 | |||
1053 | AttrBuilder(LLVMContext &Ctx, AttributeSet AS); |
||
1054 | |||
1055 | void clear(); |
||
1056 | |||
1057 | /// Add an attribute to the builder. |
||
1058 | AttrBuilder &addAttribute(Attribute::AttrKind Val); |
||
1059 | |||
1060 | /// Add the Attribute object to the builder. |
||
1061 | AttrBuilder &addAttribute(Attribute A); |
||
1062 | |||
1063 | /// Add the target-dependent attribute to the builder. |
||
1064 | AttrBuilder &addAttribute(StringRef A, StringRef V = StringRef()); |
||
1065 | |||
1066 | /// Remove an attribute from the builder. |
||
1067 | AttrBuilder &removeAttribute(Attribute::AttrKind Val); |
||
1068 | |||
1069 | /// Remove the target-dependent attribute from the builder. |
||
1070 | AttrBuilder &removeAttribute(StringRef A); |
||
1071 | |||
1072 | /// Remove the target-dependent attribute from the builder. |
||
1073 | AttrBuilder &removeAttribute(Attribute A) { |
||
1074 | if (A.isStringAttribute()) |
||
1075 | return removeAttribute(A.getKindAsString()); |
||
1076 | else |
||
1077 | return removeAttribute(A.getKindAsEnum()); |
||
1078 | } |
||
1079 | |||
1080 | /// Add the attributes from the builder. Attributes in the passed builder |
||
1081 | /// overwrite attributes in this builder if they have the same key. |
||
1082 | AttrBuilder &merge(const AttrBuilder &B); |
||
1083 | |||
1084 | /// Remove the attributes from the builder. |
||
1085 | AttrBuilder &remove(const AttributeMask &AM); |
||
1086 | |||
1087 | /// Return true if the builder has any attribute that's in the |
||
1088 | /// specified builder. |
||
1089 | bool overlaps(const AttributeMask &AM) const; |
||
1090 | |||
1091 | /// Return true if the builder has the specified attribute. |
||
1092 | bool contains(Attribute::AttrKind A) const; |
||
1093 | |||
1094 | /// Return true if the builder has the specified target-dependent |
||
1095 | /// attribute. |
||
1096 | bool contains(StringRef A) const; |
||
1097 | |||
1098 | /// Return true if the builder has IR-level attributes. |
||
1099 | bool hasAttributes() const { return !Attrs.empty(); } |
||
1100 | |||
1101 | /// Return Attribute with the given Kind. The returned attribute will be |
||
1102 | /// invalid if the Kind is not present in the builder. |
||
1103 | Attribute getAttribute(Attribute::AttrKind Kind) const; |
||
1104 | |||
1105 | /// Return Attribute with the given Kind. The returned attribute will be |
||
1106 | /// invalid if the Kind is not present in the builder. |
||
1107 | Attribute getAttribute(StringRef Kind) const; |
||
1108 | |||
1109 | /// Return raw (possibly packed/encoded) value of integer attribute or |
||
1110 | /// std::nullopt if not set. |
||
1111 | std::optional<uint64_t> getRawIntAttr(Attribute::AttrKind Kind) const; |
||
1112 | |||
1113 | /// Retrieve the alignment attribute, if it exists. |
||
1114 | MaybeAlign getAlignment() const { |
||
1115 | return MaybeAlign(getRawIntAttr(Attribute::Alignment).value_or(0)); |
||
1116 | } |
||
1117 | |||
1118 | /// Retrieve the stack alignment attribute, if it exists. |
||
1119 | MaybeAlign getStackAlignment() const { |
||
1120 | return MaybeAlign(getRawIntAttr(Attribute::StackAlignment).value_or(0)); |
||
1121 | } |
||
1122 | |||
1123 | /// Retrieve the number of dereferenceable bytes, if the |
||
1124 | /// dereferenceable attribute exists (zero is returned otherwise). |
||
1125 | uint64_t getDereferenceableBytes() const { |
||
1126 | return getRawIntAttr(Attribute::Dereferenceable).value_or(0); |
||
1127 | } |
||
1128 | |||
1129 | /// Retrieve the number of dereferenceable_or_null bytes, if the |
||
1130 | /// dereferenceable_or_null attribute exists (zero is returned otherwise). |
||
1131 | uint64_t getDereferenceableOrNullBytes() const { |
||
1132 | return getRawIntAttr(Attribute::DereferenceableOrNull).value_or(0); |
||
1133 | } |
||
1134 | |||
1135 | /// Retrieve type for the given type attribute. |
||
1136 | Type *getTypeAttr(Attribute::AttrKind Kind) const; |
||
1137 | |||
1138 | /// Retrieve the byval type. |
||
1139 | Type *getByValType() const { return getTypeAttr(Attribute::ByVal); } |
||
1140 | |||
1141 | /// Retrieve the sret type. |
||
1142 | Type *getStructRetType() const { return getTypeAttr(Attribute::StructRet); } |
||
1143 | |||
1144 | /// Retrieve the byref type. |
||
1145 | Type *getByRefType() const { return getTypeAttr(Attribute::ByRef); } |
||
1146 | |||
1147 | /// Retrieve the preallocated type. |
||
1148 | Type *getPreallocatedType() const { |
||
1149 | return getTypeAttr(Attribute::Preallocated); |
||
1150 | } |
||
1151 | |||
1152 | /// Retrieve the inalloca type. |
||
1153 | Type *getInAllocaType() const { return getTypeAttr(Attribute::InAlloca); } |
||
1154 | |||
1155 | /// Retrieve the allocsize args, or std::nullopt if the attribute does not |
||
1156 | /// exist. |
||
1157 | std::optional<std::pair<unsigned, std::optional<unsigned>>> getAllocSizeArgs() |
||
1158 | const; |
||
1159 | |||
1160 | /// Add integer attribute with raw value (packed/encoded if necessary). |
||
1161 | AttrBuilder &addRawIntAttr(Attribute::AttrKind Kind, uint64_t Value); |
||
1162 | |||
1163 | /// This turns an alignment into the form used internally in Attribute. |
||
1164 | /// This call has no effect if Align is not set. |
||
1165 | AttrBuilder &addAlignmentAttr(MaybeAlign Align); |
||
1166 | |||
1167 | /// This turns an int alignment (which must be a power of 2) into the |
||
1168 | /// form used internally in Attribute. |
||
1169 | /// This call has no effect if Align is 0. |
||
1170 | /// Deprecated, use the version using a MaybeAlign. |
||
1171 | inline AttrBuilder &addAlignmentAttr(unsigned Align) { |
||
1172 | return addAlignmentAttr(MaybeAlign(Align)); |
||
1173 | } |
||
1174 | |||
1175 | /// This turns a stack alignment into the form used internally in Attribute. |
||
1176 | /// This call has no effect if Align is not set. |
||
1177 | AttrBuilder &addStackAlignmentAttr(MaybeAlign Align); |
||
1178 | |||
1179 | /// This turns an int stack alignment (which must be a power of 2) into |
||
1180 | /// the form used internally in Attribute. |
||
1181 | /// This call has no effect if Align is 0. |
||
1182 | /// Deprecated, use the version using a MaybeAlign. |
||
1183 | inline AttrBuilder &addStackAlignmentAttr(unsigned Align) { |
||
1184 | return addStackAlignmentAttr(MaybeAlign(Align)); |
||
1185 | } |
||
1186 | |||
1187 | /// This turns the number of dereferenceable bytes into the form used |
||
1188 | /// internally in Attribute. |
||
1189 | AttrBuilder &addDereferenceableAttr(uint64_t Bytes); |
||
1190 | |||
1191 | /// This turns the number of dereferenceable_or_null bytes into the |
||
1192 | /// form used internally in Attribute. |
||
1193 | AttrBuilder &addDereferenceableOrNullAttr(uint64_t Bytes); |
||
1194 | |||
1195 | /// This turns one (or two) ints into the form used internally in Attribute. |
||
1196 | AttrBuilder &addAllocSizeAttr(unsigned ElemSizeArg, |
||
1197 | const std::optional<unsigned> &NumElemsArg); |
||
1198 | |||
1199 | /// This turns two ints into the form used internally in Attribute. |
||
1200 | AttrBuilder &addVScaleRangeAttr(unsigned MinValue, |
||
1201 | std::optional<unsigned> MaxValue); |
||
1202 | |||
1203 | /// Add a type attribute with the given type. |
||
1204 | AttrBuilder &addTypeAttr(Attribute::AttrKind Kind, Type *Ty); |
||
1205 | |||
1206 | /// This turns a byval type into the form used internally in Attribute. |
||
1207 | AttrBuilder &addByValAttr(Type *Ty); |
||
1208 | |||
1209 | /// This turns a sret type into the form used internally in Attribute. |
||
1210 | AttrBuilder &addStructRetAttr(Type *Ty); |
||
1211 | |||
1212 | /// This turns a byref type into the form used internally in Attribute. |
||
1213 | AttrBuilder &addByRefAttr(Type *Ty); |
||
1214 | |||
1215 | /// This turns a preallocated type into the form used internally in Attribute. |
||
1216 | AttrBuilder &addPreallocatedAttr(Type *Ty); |
||
1217 | |||
1218 | /// This turns an inalloca type into the form used internally in Attribute. |
||
1219 | AttrBuilder &addInAllocaAttr(Type *Ty); |
||
1220 | |||
1221 | /// Add an allocsize attribute, using the representation returned by |
||
1222 | /// Attribute.getIntValue(). |
||
1223 | AttrBuilder &addAllocSizeAttrFromRawRepr(uint64_t RawAllocSizeRepr); |
||
1224 | |||
1225 | /// Add a vscale_range attribute, using the representation returned by |
||
1226 | /// Attribute.getIntValue(). |
||
1227 | AttrBuilder &addVScaleRangeAttrFromRawRepr(uint64_t RawVScaleRangeRepr); |
||
1228 | |||
1229 | /// This turns the unwind table kind into the form used internally in |
||
1230 | /// Attribute. |
||
1231 | AttrBuilder &addUWTableAttr(UWTableKind Kind); |
||
1232 | |||
1233 | // This turns the allocator kind into the form used internally in Attribute. |
||
1234 | AttrBuilder &addAllocKindAttr(AllocFnKind Kind); |
||
1235 | |||
1236 | /// Add memory effect attribute. |
||
1237 | AttrBuilder &addMemoryAttr(MemoryEffects ME); |
||
1238 | |||
1239 | ArrayRef<Attribute> attrs() const { return Attrs; } |
||
1240 | |||
1241 | bool operator==(const AttrBuilder &B) const; |
||
1242 | bool operator!=(const AttrBuilder &B) const { return !(*this == B); } |
||
1243 | }; |
||
1244 | |||
1245 | namespace AttributeFuncs { |
||
1246 | |||
1247 | enum AttributeSafetyKind : uint8_t { |
||
1248 | ASK_SAFE_TO_DROP = 1, |
||
1249 | ASK_UNSAFE_TO_DROP = 2, |
||
1250 | ASK_ALL = ASK_SAFE_TO_DROP | ASK_UNSAFE_TO_DROP, |
||
1251 | }; |
||
1252 | |||
1253 | /// Which attributes cannot be applied to a type. The argument \p ASK indicates, |
||
1254 | /// if only attributes that are known to be safely droppable are contained in |
||
1255 | /// the mask; only attributes that might be unsafe to drop (e.g., ABI-related |
||
1256 | /// attributes) are in the mask; or both. |
||
1257 | AttributeMask typeIncompatible(Type *Ty, AttributeSafetyKind ASK = ASK_ALL); |
||
1258 | |||
1259 | /// Get param/return attributes which imply immediate undefined behavior if an |
||
1260 | /// invalid value is passed. For example, this includes noundef (where undef |
||
1261 | /// implies UB), but not nonnull (where null implies poison). It also does not |
||
1262 | /// include attributes like nocapture, which constrain the function |
||
1263 | /// implementation rather than the passed value. |
||
1264 | AttributeMask getUBImplyingAttributes(); |
||
1265 | |||
1266 | /// \returns Return true if the two functions have compatible target-independent |
||
1267 | /// attributes for inlining purposes. |
||
1268 | bool areInlineCompatible(const Function &Caller, const Function &Callee); |
||
1269 | |||
1270 | |||
1271 | /// Checks if there are any incompatible function attributes between |
||
1272 | /// \p A and \p B. |
||
1273 | /// |
||
1274 | /// \param [in] A - The first function to be compared with. |
||
1275 | /// \param [in] B - The second function to be compared with. |
||
1276 | /// \returns true if the functions have compatible attributes. |
||
1277 | bool areOutlineCompatible(const Function &A, const Function &B); |
||
1278 | |||
1279 | /// Merge caller's and callee's attributes. |
||
1280 | void mergeAttributesForInlining(Function &Caller, const Function &Callee); |
||
1281 | |||
1282 | /// Merges the functions attributes from \p ToMerge into function \p Base. |
||
1283 | /// |
||
1284 | /// \param [in,out] Base - The function being merged into. |
||
1285 | /// \param [in] ToMerge - The function to merge attributes from. |
||
1286 | void mergeAttributesForOutlining(Function &Base, const Function &ToMerge); |
||
1287 | |||
1288 | /// Update min-legal-vector-width if it is in Attribute and less than Width. |
||
1289 | void updateMinLegalVectorWidthAttr(Function &Fn, uint64_t Width); |
||
1290 | |||
1291 | } // end namespace AttributeFuncs |
||
1292 | |||
1293 | } // end namespace llvm |
||
1294 | |||
1295 | #endif // LLVM_IR_ATTRIBUTES_H |