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