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