1 | //===- llvm/Attributes.h - Container for Attributes -------------*- C++ -*-===// |
2 | // |
3 | // The LLVM Compiler Infrastructure |
4 | // |
5 | // This file is distributed under the University of Illinois Open Source |
6 | // License. See LICENSE.TXT for details. |
7 | // |
8 | //===----------------------------------------------------------------------===// |
9 | // |
10 | /// \file |
11 | /// This file contains the simple types necessary to represent the |
12 | /// attributes associated with functions and their calls. |
13 | // |
14 | //===----------------------------------------------------------------------===// |
15 | |
16 | #ifndef LLVM_IR_ATTRIBUTES_H |
17 | #define LLVM_IR_ATTRIBUTES_H |
18 | |
19 | #include "llvm-c/Types.h" |
20 | #include "llvm/ADT/ArrayRef.h" |
21 | #include "llvm/ADT/FoldingSet.h" |
22 | #include "llvm/ADT/Optional.h" |
23 | #include "llvm/ADT/StringRef.h" |
24 | #include "llvm/ADT/iterator_range.h" |
25 | #include "llvm/Config/llvm-config.h" |
26 | #include "llvm/Support/PointerLikeTypeTraits.h" |
27 | #include <bitset> |
28 | #include <cassert> |
29 | #include <cstdint> |
30 | #include <map> |
31 | #include <string> |
32 | #include <utility> |
33 | |
34 | namespace llvm { |
35 | |
36 | class AttrBuilder; |
37 | class AttributeImpl; |
38 | class AttributeListImpl; |
39 | class AttributeSetNode; |
40 | template<typename T> struct DenseMapInfo; |
41 | class Function; |
42 | class LLVMContext; |
43 | class Type; |
44 | |
45 | //===----------------------------------------------------------------------===// |
46 | /// \class |
47 | /// Functions, function parameters, and return types can have attributes |
48 | /// to indicate how they should be treated by optimizations and code |
49 | /// generation. This class represents one of those attributes. It's light-weight |
50 | /// and should be passed around by-value. |
51 | class Attribute { |
52 | public: |
53 | /// This enumeration lists the attributes that can be associated with |
54 | /// parameters, function results, or the function itself. |
55 | /// |
56 | /// Note: The `uwtable' attribute is about the ABI or the user mandating an |
57 | /// entry in the unwind table. The `nounwind' attribute is about an exception |
58 | /// passing by the function. |
59 | /// |
60 | /// In a theoretical system that uses tables for profiling and SjLj for |
61 | /// exceptions, they would be fully independent. In a normal system that uses |
62 | /// tables for both, the semantics are: |
63 | /// |
64 | /// nil = Needs an entry because an exception might pass by. |
65 | /// nounwind = No need for an entry |
66 | /// uwtable = Needs an entry because the ABI says so and because |
67 | /// an exception might pass by. |
68 | /// uwtable + nounwind = Needs an entry because the ABI says so. |
69 | |
70 | enum AttrKind { |
71 | // IR-Level Attributes |
72 | None, ///< No attributes have been set |
73 | #define GET_ATTR_ENUM |
74 | #include "llvm/IR/Attributes.inc" |
75 | EndAttrKinds ///< Sentinal value useful for loops |
76 | }; |
77 | |
78 | private: |
79 | AttributeImpl *pImpl = nullptr; |
80 | |
81 | Attribute(AttributeImpl *A) : pImpl(A) {} |
82 | |
83 | public: |
84 | Attribute() = default; |
85 | |
86 | //===--------------------------------------------------------------------===// |
87 | // Attribute Construction |
88 | //===--------------------------------------------------------------------===// |
89 | |
90 | /// Return a uniquified Attribute object. |
91 | static Attribute get(LLVMContext &Context, AttrKind Kind, uint64_t Val = 0); |
92 | static Attribute get(LLVMContext &Context, StringRef Kind, |
93 | StringRef Val = StringRef()); |
94 | |
95 | /// Return a uniquified Attribute object that has the specific |
96 | /// alignment set. |
97 | static Attribute getWithAlignment(LLVMContext &Context, uint64_t Align); |
98 | static Attribute getWithStackAlignment(LLVMContext &Context, uint64_t Align); |
99 | static Attribute getWithDereferenceableBytes(LLVMContext &Context, |
100 | uint64_t Bytes); |
101 | static Attribute getWithDereferenceableOrNullBytes(LLVMContext &Context, |
102 | uint64_t Bytes); |
103 | static Attribute getWithAllocSizeArgs(LLVMContext &Context, |
104 | unsigned ElemSizeArg, |
105 | const Optional<unsigned> &NumElemsArg); |
106 | |
107 | //===--------------------------------------------------------------------===// |
108 | // Attribute Accessors |
109 | //===--------------------------------------------------------------------===// |
110 | |
111 | /// Return true if the attribute is an Attribute::AttrKind type. |
112 | bool isEnumAttribute() const; |
113 | |
114 | /// Return true if the attribute is an integer attribute. |
115 | bool isIntAttribute() const; |
116 | |
117 | /// Return true if the attribute is a string (target-dependent) |
118 | /// attribute. |
119 | bool isStringAttribute() const; |
120 | |
121 | /// Return true if the attribute is present. |
122 | bool hasAttribute(AttrKind Val) const; |
123 | |
124 | /// Return true if the target-dependent attribute is present. |
125 | bool hasAttribute(StringRef Val) const; |
126 | |
127 | /// Return the attribute's kind as an enum (Attribute::AttrKind). This |
128 | /// requires the attribute to be an enum or integer attribute. |
129 | Attribute::AttrKind getKindAsEnum() const; |
130 | |
131 | /// Return the attribute's value as an integer. This requires that the |
132 | /// attribute be an integer attribute. |
133 | uint64_t getValueAsInt() const; |
134 | |
135 | /// Return the attribute's kind as a string. This requires the |
136 | /// attribute to be a string attribute. |
137 | StringRef getKindAsString() const; |
138 | |
139 | /// Return the attribute's value as a string. This requires the |
140 | /// attribute to be a string attribute. |
141 | StringRef getValueAsString() const; |
142 | |
143 | /// Returns the alignment field of an attribute as a byte alignment |
144 | /// value. |
145 | unsigned getAlignment() const; |
146 | |
147 | /// Returns the stack alignment field of an attribute as a byte |
148 | /// alignment value. |
149 | unsigned getStackAlignment() const; |
150 | |
151 | /// Returns the number of dereferenceable bytes from the |
152 | /// dereferenceable attribute. |
153 | uint64_t getDereferenceableBytes() const; |
154 | |
155 | /// Returns the number of dereferenceable_or_null bytes from the |
156 | /// dereferenceable_or_null attribute. |
157 | uint64_t getDereferenceableOrNullBytes() const; |
158 | |
159 | /// Returns the argument numbers for the allocsize attribute (or pair(0, 0) |
160 | /// if not known). |
161 | std::pair<unsigned, Optional<unsigned>> getAllocSizeArgs() const; |
162 | |
163 | /// The Attribute is converted to a string of equivalent mnemonic. This |
164 | /// is, presumably, for writing out the mnemonics for the assembly writer. |
165 | std::string getAsString(bool InAttrGrp = false) const; |
166 | |
167 | /// Equality and non-equality operators. |
168 | bool operator==(Attribute A) const { return pImpl == A.pImpl; } |
169 | bool operator!=(Attribute A) const { return pImpl != A.pImpl; } |
170 | |
171 | /// Less-than operator. Useful for sorting the attributes list. |
172 | bool operator<(Attribute A) const; |
173 | |
174 | void Profile(FoldingSetNodeID &ID) const { |
175 | ID.AddPointer(pImpl); |
176 | } |
177 | |
178 | /// Return a raw pointer that uniquely identifies this attribute. |
179 | void *getRawPointer() const { |
180 | return pImpl; |
181 | } |
182 | |
183 | /// Get an attribute from a raw pointer created by getRawPointer. |
184 | static Attribute fromRawPointer(void *RawPtr) { |
185 | return Attribute(reinterpret_cast<AttributeImpl*>(RawPtr)); |
186 | } |
187 | }; |
188 | |
189 | // Specialized opaque value conversions. |
190 | inline LLVMAttributeRef wrap(Attribute Attr) { |
191 | return reinterpret_cast<LLVMAttributeRef>(Attr.getRawPointer()); |
192 | } |
193 | |
194 | // Specialized opaque value conversions. |
195 | inline Attribute unwrap(LLVMAttributeRef Attr) { |
196 | return Attribute::fromRawPointer(Attr); |
197 | } |
198 | |
199 | //===----------------------------------------------------------------------===// |
200 | /// \class |
201 | /// This class holds the attributes for a particular argument, parameter, |
202 | /// function, or return value. It is an immutable value type that is cheap to |
203 | /// copy. Adding and removing enum attributes is intended to be fast, but adding |
204 | /// and removing string or integer attributes involves a FoldingSet lookup. |
205 | class AttributeSet { |
206 | friend AttributeListImpl; |
207 | template <typename Ty> friend struct DenseMapInfo; |
208 | |
209 | // TODO: Extract AvailableAttrs from AttributeSetNode and store them here. |
210 | // This will allow an efficient implementation of addAttribute and |
211 | // removeAttribute for enum attrs. |
212 | |
213 | /// Private implementation pointer. |
214 | AttributeSetNode *SetNode = nullptr; |
215 | |
216 | private: |
217 | explicit AttributeSet(AttributeSetNode *ASN) : SetNode(ASN) {} |
218 | |
219 | public: |
220 | /// AttributeSet is a trivially copyable value type. |
221 | AttributeSet() = default; |
222 | AttributeSet(const AttributeSet &) = default; |
223 | ~AttributeSet() = default; |
224 | |
225 | static AttributeSet get(LLVMContext &C, const AttrBuilder &B); |
226 | static AttributeSet get(LLVMContext &C, ArrayRef<Attribute> Attrs); |
227 | |
228 | bool operator==(const AttributeSet &O) const { return SetNode == O.SetNode; } |
229 | bool operator!=(const AttributeSet &O) const { return !(*this == O); } |
230 | |
231 | /// Add an argument attribute. Returns a new set because attribute sets are |
232 | /// immutable. |
233 | LLVM_NODISCARD AttributeSet addAttribute(LLVMContext &C, |
234 | Attribute::AttrKind Kind) const; |
235 | |
236 | /// Add a target-dependent attribute. Returns a new set because attribute sets |
237 | /// are immutable. |
238 | LLVM_NODISCARD AttributeSet addAttribute(LLVMContext &C, StringRef Kind, |
239 | StringRef Value = StringRef()) const; |
240 | |
241 | /// Add attributes to the attribute set. Returns a new set because attribute |
242 | /// sets are immutable. |
243 | LLVM_NODISCARD AttributeSet addAttributes(LLVMContext &C, |
244 | AttributeSet AS) const; |
245 | |
246 | /// Remove the specified attribute from this set. Returns a new set because |
247 | /// attribute sets are immutable. |
248 | LLVM_NODISCARD AttributeSet removeAttribute(LLVMContext &C, |
249 | Attribute::AttrKind Kind) const; |
250 | |
251 | /// Remove the specified attribute from this set. Returns a new set because |
252 | /// attribute sets are immutable. |
253 | LLVM_NODISCARD AttributeSet removeAttribute(LLVMContext &C, |
254 | StringRef Kind) const; |
255 | |
256 | /// Remove the specified attributes from this set. Returns a new set because |
257 | /// attribute sets are immutable. |
258 | LLVM_NODISCARD AttributeSet |
259 | removeAttributes(LLVMContext &C, const AttrBuilder &AttrsToRemove) const; |
260 | |
261 | /// Return the number of attributes in this set. |
262 | unsigned getNumAttributes() const; |
263 | |
264 | /// Return true if attributes exists in this set. |
265 | bool hasAttributes() const { return SetNode != nullptr; } |
266 | |
267 | /// Return true if the attribute exists in this set. |
268 | bool hasAttribute(Attribute::AttrKind Kind) const; |
269 | |
270 | /// Return true if the attribute exists in this set. |
271 | bool hasAttribute(StringRef Kind) const; |
272 | |
273 | /// Return the attribute object. |
274 | Attribute getAttribute(Attribute::AttrKind Kind) const; |
275 | |
276 | /// Return the target-dependent attribute object. |
277 | Attribute getAttribute(StringRef Kind) const; |
278 | |
279 | unsigned getAlignment() const; |
280 | unsigned getStackAlignment() const; |
281 | uint64_t getDereferenceableBytes() const; |
282 | uint64_t getDereferenceableOrNullBytes() const; |
283 | std::pair<unsigned, Optional<unsigned>> getAllocSizeArgs() const; |
284 | std::string getAsString(bool InAttrGrp = false) const; |
285 | |
286 | using iterator = const Attribute *; |
287 | |
288 | iterator begin() const; |
289 | iterator end() const; |
290 | #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) |
291 | void dump() const; |
292 | #endif |
293 | }; |
294 | |
295 | //===----------------------------------------------------------------------===// |
296 | /// \class |
297 | /// Provide DenseMapInfo for AttributeSet. |
298 | template <> struct DenseMapInfo<AttributeSet> { |
299 | static AttributeSet getEmptyKey() { |
300 | auto Val = static_cast<uintptr_t>(-1); |
301 | Val <<= PointerLikeTypeTraits<void *>::NumLowBitsAvailable; |
302 | return AttributeSet(reinterpret_cast<AttributeSetNode *>(Val)); |
303 | } |
304 | |
305 | static AttributeSet getTombstoneKey() { |
306 | auto Val = static_cast<uintptr_t>(-2); |
307 | Val <<= PointerLikeTypeTraits<void *>::NumLowBitsAvailable; |
308 | return AttributeSet(reinterpret_cast<AttributeSetNode *>(Val)); |
309 | } |
310 | |
311 | static unsigned getHashValue(AttributeSet AS) { |
312 | return (unsigned((uintptr_t)AS.SetNode) >> 4) ^ |
313 | (unsigned((uintptr_t)AS.SetNode) >> 9); |
314 | } |
315 | |
316 | static bool isEqual(AttributeSet LHS, AttributeSet RHS) { return LHS == RHS; } |
317 | }; |
318 | |
319 | //===----------------------------------------------------------------------===// |
320 | /// \class |
321 | /// This class holds the attributes for a function, its return value, and |
322 | /// its parameters. You access the attributes for each of them via an index into |
323 | /// the AttributeList object. The function attributes are at index |
324 | /// `AttributeList::FunctionIndex', the return value is at index |
325 | /// `AttributeList::ReturnIndex', and the attributes for the parameters start at |
326 | /// index `AttributeList::FirstArgIndex'. |
327 | class AttributeList { |
328 | public: |
329 | enum AttrIndex : unsigned { |
330 | ReturnIndex = 0U, |
331 | FunctionIndex = ~0U, |
332 | FirstArgIndex = 1, |
333 | }; |
334 | |
335 | private: |
336 | friend class AttrBuilder; |
337 | friend class AttributeListImpl; |
338 | friend class AttributeSet; |
339 | friend class AttributeSetNode; |
340 | template <typename Ty> friend struct DenseMapInfo; |
341 | |
342 | /// The attributes that we are managing. This can be null to represent |
343 | /// the empty attributes list. |
344 | AttributeListImpl *pImpl = nullptr; |
345 | |
346 | public: |
347 | /// Create an AttributeList with the specified parameters in it. |
348 | static AttributeList get(LLVMContext &C, |
349 | ArrayRef<std::pair<unsigned, Attribute>> Attrs); |
350 | static AttributeList get(LLVMContext &C, |
351 | ArrayRef<std::pair<unsigned, AttributeSet>> Attrs); |
352 | |
353 | /// Create an AttributeList from attribute sets for a function, its |
354 | /// return value, and all of its arguments. |
355 | static AttributeList get(LLVMContext &C, AttributeSet FnAttrs, |
356 | AttributeSet RetAttrs, |
357 | ArrayRef<AttributeSet> ArgAttrs); |
358 | |
359 | private: |
360 | explicit AttributeList(AttributeListImpl *LI) : pImpl(LI) {} |
361 | |
362 | static AttributeList getImpl(LLVMContext &C, ArrayRef<AttributeSet> AttrSets); |
363 | |
364 | public: |
365 | AttributeList() = default; |
366 | |
367 | //===--------------------------------------------------------------------===// |
368 | // AttributeList Construction and Mutation |
369 | //===--------------------------------------------------------------------===// |
370 | |
371 | /// Return an AttributeList with the specified parameters in it. |
372 | static AttributeList get(LLVMContext &C, ArrayRef<AttributeList> Attrs); |
373 | static AttributeList get(LLVMContext &C, unsigned Index, |
374 | ArrayRef<Attribute::AttrKind> Kinds); |
375 | static AttributeList get(LLVMContext &C, unsigned Index, |
376 | ArrayRef<StringRef> Kind); |
377 | static AttributeList get(LLVMContext &C, unsigned Index, |
378 | const AttrBuilder &B); |
379 | |
380 | /// Add an attribute to the attribute set at the given index. |
381 | /// Returns a new list because attribute lists are immutable. |
382 | LLVM_NODISCARD AttributeList addAttribute(LLVMContext &C, unsigned Index, |
383 | Attribute::AttrKind Kind) const; |
384 | |
385 | /// Add an attribute to the attribute set at the given index. |
386 | /// Returns a new list because attribute lists are immutable. |
387 | LLVM_NODISCARD AttributeList |
388 | addAttribute(LLVMContext &C, unsigned Index, StringRef Kind, |
389 | StringRef Value = StringRef()) const; |
390 | |
391 | /// Add an attribute to the attribute set at the given index. |
392 | /// Returns a new list because attribute lists are immutable. |
393 | LLVM_NODISCARD AttributeList addAttribute(LLVMContext &C, unsigned Index, |
394 | Attribute A) const; |
395 | |
396 | /// Add attributes to the attribute set at the given index. |
397 | /// Returns a new list because attribute lists are immutable. |
398 | LLVM_NODISCARD AttributeList addAttributes(LLVMContext &C, unsigned Index, |
399 | const AttrBuilder &B) const; |
400 | |
401 | /// Add an argument attribute to the list. Returns a new list because |
402 | /// attribute lists are immutable. |
403 | LLVM_NODISCARD AttributeList addParamAttribute( |
404 | LLVMContext &C, unsigned ArgNo, Attribute::AttrKind Kind) const { |
405 | return addAttribute(C, ArgNo + FirstArgIndex, Kind); |
406 | } |
407 | |
408 | /// Add an argument attribute to the list. Returns a new list because |
409 | /// attribute lists are immutable. |
410 | LLVM_NODISCARD AttributeList |
411 | addParamAttribute(LLVMContext &C, unsigned ArgNo, StringRef Kind, |
412 | StringRef Value = StringRef()) const { |
413 | return addAttribute(C, ArgNo + FirstArgIndex, Kind, Value); |
414 | } |
415 | |
416 | /// Add an attribute to the attribute list at the given arg indices. Returns a |
417 | /// new list because attribute lists are immutable. |
418 | LLVM_NODISCARD AttributeList addParamAttribute(LLVMContext &C, |
419 | ArrayRef<unsigned> ArgNos, |
420 | Attribute A) const; |
421 | |
422 | /// Add an argument attribute to the list. Returns a new list because |
423 | /// attribute lists are immutable. |
424 | LLVM_NODISCARD AttributeList addParamAttributes(LLVMContext &C, |
425 | unsigned ArgNo, |
426 | const AttrBuilder &B) const { |
427 | return addAttributes(C, ArgNo + FirstArgIndex, B); |
428 | } |
429 | |
430 | /// Remove the specified attribute at the specified index from this |
431 | /// attribute list. Returns a new list because attribute lists are immutable. |
432 | LLVM_NODISCARD AttributeList removeAttribute(LLVMContext &C, unsigned Index, |
433 | Attribute::AttrKind Kind) const; |
434 | |
435 | /// Remove the specified attribute at the specified index from this |
436 | /// attribute list. Returns a new list because attribute lists are immutable. |
437 | LLVM_NODISCARD AttributeList removeAttribute(LLVMContext &C, unsigned Index, |
438 | StringRef Kind) const; |
439 | |
440 | /// Remove the specified attributes at the specified index from this |
441 | /// attribute list. Returns a new list because attribute lists are immutable. |
442 | LLVM_NODISCARD AttributeList removeAttributes( |
443 | LLVMContext &C, unsigned Index, const AttrBuilder &AttrsToRemove) const; |
444 | |
445 | /// Remove all attributes at the specified index from this |
446 | /// attribute list. Returns a new list because attribute lists are immutable. |
447 | LLVM_NODISCARD AttributeList removeAttributes(LLVMContext &C, |
448 | unsigned Index) const; |
449 | |
450 | /// Remove the specified attribute at the specified arg index from this |
451 | /// attribute list. Returns a new list because attribute lists are immutable. |
452 | LLVM_NODISCARD AttributeList removeParamAttribute( |
453 | LLVMContext &C, unsigned ArgNo, Attribute::AttrKind Kind) const { |
454 | return removeAttribute(C, ArgNo + FirstArgIndex, Kind); |
455 | } |
456 | |
457 | /// Remove the specified attribute at the specified arg index from this |
458 | /// attribute list. Returns a new list because attribute lists are immutable. |
459 | LLVM_NODISCARD AttributeList removeParamAttribute(LLVMContext &C, |
460 | unsigned ArgNo, |
461 | StringRef Kind) const { |
462 | return removeAttribute(C, ArgNo + FirstArgIndex, Kind); |
463 | } |
464 | |
465 | /// Remove the specified attribute at the specified arg index from this |
466 | /// attribute list. Returns a new list because attribute lists are immutable. |
467 | LLVM_NODISCARD AttributeList removeParamAttributes( |
468 | LLVMContext &C, unsigned ArgNo, const AttrBuilder &AttrsToRemove) const { |
469 | return removeAttributes(C, ArgNo + FirstArgIndex, AttrsToRemove); |
470 | } |
471 | |
472 | /// Remove all attributes at the specified arg index from this |
473 | /// attribute list. Returns a new list because attribute lists are immutable. |
474 | LLVM_NODISCARD AttributeList removeParamAttributes(LLVMContext &C, |
475 | unsigned ArgNo) const { |
476 | return removeAttributes(C, ArgNo + FirstArgIndex); |
477 | } |
478 | |
479 | /// \brief Add the dereferenceable attribute to the attribute set at the given |
480 | /// index. Returns a new list because attribute lists are immutable. |
481 | LLVM_NODISCARD AttributeList addDereferenceableAttr(LLVMContext &C, |
482 | unsigned Index, |
483 | uint64_t Bytes) const; |
484 | |
485 | /// \brief Add the dereferenceable attribute to the attribute set at the given |
486 | /// arg index. Returns a new list because attribute lists are immutable. |
487 | LLVM_NODISCARD AttributeList addDereferenceableParamAttr( |
488 | LLVMContext &C, unsigned ArgNo, uint64_t Bytes) const { |
489 | return addDereferenceableAttr(C, ArgNo + FirstArgIndex, Bytes); |
490 | } |
491 | |
492 | /// Add the dereferenceable_or_null attribute to the attribute set at |
493 | /// the given index. Returns a new list because attribute lists are immutable. |
494 | LLVM_NODISCARD AttributeList addDereferenceableOrNullAttr( |
495 | LLVMContext &C, unsigned Index, uint64_t Bytes) const; |
496 | |
497 | /// Add the dereferenceable_or_null attribute to the attribute set at |
498 | /// the given arg index. Returns a new list because attribute lists are |
499 | /// immutable. |
500 | LLVM_NODISCARD AttributeList addDereferenceableOrNullParamAttr( |
501 | LLVMContext &C, unsigned ArgNo, uint64_t Bytes) const { |
502 | return addDereferenceableOrNullAttr(C, ArgNo + FirstArgIndex, Bytes); |
503 | } |
504 | |
505 | /// Add the allocsize attribute to the attribute set at the given index. |
506 | /// Returns a new list because attribute lists are immutable. |
507 | LLVM_NODISCARD AttributeList |
508 | addAllocSizeAttr(LLVMContext &C, unsigned Index, unsigned ElemSizeArg, |
509 | const Optional<unsigned> &NumElemsArg); |
510 | |
511 | /// Add the allocsize attribute to the attribute set at the given arg index. |
512 | /// Returns a new list because attribute lists are immutable. |
513 | LLVM_NODISCARD AttributeList |
514 | addAllocSizeParamAttr(LLVMContext &C, unsigned ArgNo, unsigned ElemSizeArg, |
515 | const Optional<unsigned> &NumElemsArg) { |
516 | return addAllocSizeAttr(C, ArgNo + FirstArgIndex, ElemSizeArg, NumElemsArg); |
517 | } |
518 | |
519 | //===--------------------------------------------------------------------===// |
520 | // AttributeList Accessors |
521 | //===--------------------------------------------------------------------===// |
522 | |
523 | /// Retrieve the LLVM context. |
524 | LLVMContext &getContext() const; |
525 | |
526 | /// The attributes for the specified index are returned. |
527 | AttributeSet getAttributes(unsigned Index) const; |
528 | |
529 | /// The attributes for the argument or parameter at the given index are |
530 | /// returned. |
531 | AttributeSet getParamAttributes(unsigned ArgNo) const; |
532 | |
533 | /// The attributes for the ret value are returned. |
534 | AttributeSet getRetAttributes() const; |
535 | |
536 | /// The function attributes are returned. |
537 | AttributeSet getFnAttributes() const; |
538 | |
539 | /// Return true if the attribute exists at the given index. |
540 | bool hasAttribute(unsigned Index, Attribute::AttrKind Kind) const; |
541 | |
542 | /// Return true if the attribute exists at the given index. |
543 | bool hasAttribute(unsigned Index, StringRef Kind) const; |
544 | |
545 | /// Return true if attribute exists at the given index. |
546 | bool hasAttributes(unsigned Index) const; |
547 | |
548 | /// Return true if the attribute exists for the given argument |
549 | bool hasParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) const { |
550 | return hasAttribute(ArgNo + FirstArgIndex, Kind); |
551 | } |
552 | |
553 | /// Return true if the attribute exists for the given argument |
554 | bool hasParamAttr(unsigned ArgNo, StringRef Kind) const { |
555 | return hasAttribute(ArgNo + FirstArgIndex, Kind); |
556 | } |
557 | |
558 | /// Return true if attributes exists for the given argument |
559 | bool hasParamAttrs(unsigned ArgNo) const { |
560 | return hasAttributes(ArgNo + FirstArgIndex); |
561 | } |
562 | |
563 | /// Equivalent to hasAttribute(AttributeList::FunctionIndex, Kind) but |
564 | /// may be faster. |
565 | bool hasFnAttribute(Attribute::AttrKind Kind) const; |
566 | |
567 | /// Equivalent to hasAttribute(AttributeList::FunctionIndex, Kind) but |
568 | /// may be faster. |
569 | bool hasFnAttribute(StringRef Kind) const; |
570 | |
571 | /// Equivalent to hasAttribute(ArgNo + FirstArgIndex, Kind). |
572 | bool hasParamAttribute(unsigned ArgNo, Attribute::AttrKind Kind) const; |
573 | |
574 | /// Return true if the specified attribute is set for at least one |
575 | /// parameter or for the return value. If Index is not nullptr, the index |
576 | /// of a parameter with the specified attribute is provided. |
577 | bool hasAttrSomewhere(Attribute::AttrKind Kind, |
578 | unsigned *Index = nullptr) const; |
579 | |
580 | /// Return the attribute object that exists at the given index. |
581 | Attribute getAttribute(unsigned Index, Attribute::AttrKind Kind) const; |
582 | |
583 | /// Return the attribute object that exists at the given index. |
584 | Attribute getAttribute(unsigned Index, StringRef Kind) const; |
585 | |
586 | /// Return the attribute object that exists at the arg index. |
587 | Attribute getParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) const { |
588 | return getAttribute(ArgNo + FirstArgIndex, Kind); |
589 | } |
590 | |
591 | /// Return the attribute object that exists at the given index. |
592 | Attribute getParamAttr(unsigned ArgNo, StringRef Kind) const { |
593 | return getAttribute(ArgNo + FirstArgIndex, Kind); |
594 | } |
595 | |
596 | /// Return the alignment of the return value. |
597 | unsigned getRetAlignment() const; |
598 | |
599 | /// Return the alignment for the specified function parameter. |
600 | unsigned getParamAlignment(unsigned ArgNo) const; |
601 | |
602 | /// Get the stack alignment. |
603 | unsigned getStackAlignment(unsigned Index) const; |
604 | |
605 | /// Get the number of dereferenceable bytes (or zero if unknown). |
606 | uint64_t getDereferenceableBytes(unsigned Index) const; |
607 | |
608 | /// Get the number of dereferenceable bytes (or zero if unknown) of an |
609 | /// arg. |
610 | uint64_t getParamDereferenceableBytes(unsigned ArgNo) const { |
611 | return getDereferenceableBytes(ArgNo + FirstArgIndex); |
612 | } |
613 | |
614 | /// Get the number of dereferenceable_or_null bytes (or zero if |
615 | /// unknown). |
616 | uint64_t getDereferenceableOrNullBytes(unsigned Index) const; |
617 | |
618 | /// Get the number of dereferenceable_or_null bytes (or zero if |
619 | /// unknown) of an arg. |
620 | uint64_t getParamDereferenceableOrNullBytes(unsigned ArgNo) const { |
621 | return getDereferenceableOrNullBytes(ArgNo + FirstArgIndex); |
622 | } |
623 | |
624 | /// Get the allocsize argument numbers (or pair(0, 0) if unknown). |
625 | std::pair<unsigned, Optional<unsigned>> |
626 | getAllocSizeArgs(unsigned Index) const; |
627 | |
628 | /// Return the attributes at the index as a string. |
629 | std::string getAsString(unsigned Index, bool InAttrGrp = false) const; |
630 | |
631 | //===--------------------------------------------------------------------===// |
632 | // AttributeList Introspection |
633 | //===--------------------------------------------------------------------===// |
634 | |
635 | using iterator = const AttributeSet *; |
636 | |
637 | iterator begin() const; |
638 | iterator end() const; |
639 | |
640 | unsigned getNumAttrSets() const; |
641 | |
642 | /// Use these to iterate over the valid attribute indices. |
643 | unsigned index_begin() const { return AttributeList::FunctionIndex; } |
644 | unsigned index_end() const { return getNumAttrSets() - 1; } |
645 | |
646 | /// operator==/!= - Provide equality predicates. |
647 | bool operator==(const AttributeList &RHS) const { return pImpl == RHS.pImpl; } |
648 | bool operator!=(const AttributeList &RHS) const { return pImpl != RHS.pImpl; } |
649 | |
650 | /// Return a raw pointer that uniquely identifies this attribute list. |
651 | void *getRawPointer() const { |
652 | return pImpl; |
653 | } |
654 | |
655 | /// Return true if there are no attributes. |
656 | bool isEmpty() const { return pImpl == nullptr; } |
657 | |
658 | void dump() const; |
659 | }; |
660 | |
661 | //===----------------------------------------------------------------------===// |
662 | /// \class |
663 | /// Provide DenseMapInfo for AttributeList. |
664 | template <> struct DenseMapInfo<AttributeList> { |
665 | static AttributeList getEmptyKey() { |
666 | auto Val = static_cast<uintptr_t>(-1); |
667 | Val <<= PointerLikeTypeTraits<void*>::NumLowBitsAvailable; |
668 | return AttributeList(reinterpret_cast<AttributeListImpl *>(Val)); |
669 | } |
670 | |
671 | static AttributeList getTombstoneKey() { |
672 | auto Val = static_cast<uintptr_t>(-2); |
673 | Val <<= PointerLikeTypeTraits<void*>::NumLowBitsAvailable; |
674 | return AttributeList(reinterpret_cast<AttributeListImpl *>(Val)); |
675 | } |
676 | |
677 | static unsigned getHashValue(AttributeList AS) { |
678 | return (unsigned((uintptr_t)AS.pImpl) >> 4) ^ |
679 | (unsigned((uintptr_t)AS.pImpl) >> 9); |
680 | } |
681 | |
682 | static bool isEqual(AttributeList LHS, AttributeList RHS) { |
683 | return LHS == RHS; |
684 | } |
685 | }; |
686 | |
687 | //===----------------------------------------------------------------------===// |
688 | /// \class |
689 | /// This class is used in conjunction with the Attribute::get method to |
690 | /// create an Attribute object. The object itself is uniquified. The Builder's |
691 | /// value, however, is not. So this can be used as a quick way to test for |
692 | /// equality, presence of attributes, etc. |
693 | class AttrBuilder { |
694 | std::bitset<Attribute::EndAttrKinds> Attrs; |
695 | std::map<std::string, std::string> TargetDepAttrs; |
696 | uint64_t Alignment = 0; |
697 | uint64_t StackAlignment = 0; |
698 | uint64_t DerefBytes = 0; |
699 | uint64_t DerefOrNullBytes = 0; |
700 | uint64_t AllocSizeArgs = 0; |
701 | |
702 | public: |
703 | AttrBuilder() = default; |
704 | |
705 | AttrBuilder(const Attribute &A) { |
706 | addAttribute(A); |
707 | } |
708 | |
709 | AttrBuilder(AttributeList AS, unsigned Idx); |
710 | AttrBuilder(AttributeSet AS); |
711 | |
712 | void clear(); |
713 | |
714 | /// Add an attribute to the builder. |
715 | AttrBuilder &addAttribute(Attribute::AttrKind Val); |
716 | |
717 | /// Add the Attribute object to the builder. |
718 | AttrBuilder &addAttribute(Attribute A); |
719 | |
720 | /// Add the target-dependent attribute to the builder. |
721 | AttrBuilder &addAttribute(StringRef A, StringRef V = StringRef()); |
722 | |
723 | /// Remove an attribute from the builder. |
724 | AttrBuilder &removeAttribute(Attribute::AttrKind Val); |
725 | |
726 | /// Remove the attributes from the builder. |
727 | AttrBuilder &removeAttributes(AttributeList A, uint64_t WithoutIndex); |
728 | |
729 | /// Remove the target-dependent attribute to the builder. |
730 | AttrBuilder &removeAttribute(StringRef A); |
731 | |
732 | /// Add the attributes from the builder. |
733 | AttrBuilder &merge(const AttrBuilder &B); |
734 | |
735 | /// Remove the attributes from the builder. |
736 | AttrBuilder &remove(const AttrBuilder &B); |
737 | |
738 | /// Return true if the builder has any attribute that's in the |
739 | /// specified builder. |
740 | bool overlaps(const AttrBuilder &B) const; |
741 | |
742 | /// Return true if the builder has the specified attribute. |
743 | bool contains(Attribute::AttrKind A) const { |
744 | assert((unsigned)A < Attribute::EndAttrKinds && "Attribute out of range!" ); |
745 | return Attrs[A]; |
746 | } |
747 | |
748 | /// Return true if the builder has the specified target-dependent |
749 | /// attribute. |
750 | bool contains(StringRef A) const; |
751 | |
752 | /// Return true if the builder has IR-level attributes. |
753 | bool hasAttributes() const; |
754 | |
755 | /// Return true if the builder has any attribute that's in the |
756 | /// specified attribute. |
757 | bool hasAttributes(AttributeList A, uint64_t Index) const; |
758 | |
759 | /// Return true if the builder has an alignment attribute. |
760 | bool hasAlignmentAttr() const; |
761 | |
762 | /// Retrieve the alignment attribute, if it exists. |
763 | uint64_t getAlignment() const { return Alignment; } |
764 | |
765 | /// Retrieve the stack alignment attribute, if it exists. |
766 | uint64_t getStackAlignment() const { return StackAlignment; } |
767 | |
768 | /// Retrieve the number of dereferenceable bytes, if the |
769 | /// dereferenceable attribute exists (zero is returned otherwise). |
770 | uint64_t getDereferenceableBytes() const { return DerefBytes; } |
771 | |
772 | /// Retrieve the number of dereferenceable_or_null bytes, if the |
773 | /// dereferenceable_or_null attribute exists (zero is returned otherwise). |
774 | uint64_t getDereferenceableOrNullBytes() const { return DerefOrNullBytes; } |
775 | |
776 | /// Retrieve the allocsize args, if the allocsize attribute exists. If it |
777 | /// doesn't exist, pair(0, 0) is returned. |
778 | std::pair<unsigned, Optional<unsigned>> getAllocSizeArgs() const; |
779 | |
780 | /// This turns an int alignment (which must be a power of 2) into the |
781 | /// form used internally in Attribute. |
782 | AttrBuilder &addAlignmentAttr(unsigned Align); |
783 | |
784 | /// This turns an int stack alignment (which must be a power of 2) into |
785 | /// the form used internally in Attribute. |
786 | AttrBuilder &addStackAlignmentAttr(unsigned Align); |
787 | |
788 | /// This turns the number of dereferenceable bytes into the form used |
789 | /// internally in Attribute. |
790 | AttrBuilder &addDereferenceableAttr(uint64_t Bytes); |
791 | |
792 | /// This turns the number of dereferenceable_or_null bytes into the |
793 | /// form used internally in Attribute. |
794 | AttrBuilder &addDereferenceableOrNullAttr(uint64_t Bytes); |
795 | |
796 | /// This turns one (or two) ints into the form used internally in Attribute. |
797 | AttrBuilder &addAllocSizeAttr(unsigned ElemSizeArg, |
798 | const Optional<unsigned> &NumElemsArg); |
799 | |
800 | /// Add an allocsize attribute, using the representation returned by |
801 | /// Attribute.getIntValue(). |
802 | AttrBuilder &addAllocSizeAttrFromRawRepr(uint64_t RawAllocSizeRepr); |
803 | |
804 | /// Return true if the builder contains no target-independent |
805 | /// attributes. |
806 | bool empty() const { return Attrs.none(); } |
807 | |
808 | // Iterators for target-dependent attributes. |
809 | using td_type = std::pair<std::string, std::string>; |
810 | using td_iterator = std::map<std::string, std::string>::iterator; |
811 | using td_const_iterator = std::map<std::string, std::string>::const_iterator; |
812 | using td_range = iterator_range<td_iterator>; |
813 | using td_const_range = iterator_range<td_const_iterator>; |
814 | |
815 | td_iterator td_begin() { return TargetDepAttrs.begin(); } |
816 | td_iterator td_end() { return TargetDepAttrs.end(); } |
817 | |
818 | td_const_iterator td_begin() const { return TargetDepAttrs.begin(); } |
819 | td_const_iterator td_end() const { return TargetDepAttrs.end(); } |
820 | |
821 | td_range td_attrs() { return td_range(td_begin(), td_end()); } |
822 | |
823 | td_const_range td_attrs() const { |
824 | return td_const_range(td_begin(), td_end()); |
825 | } |
826 | |
827 | bool td_empty() const { return TargetDepAttrs.empty(); } |
828 | |
829 | bool operator==(const AttrBuilder &B); |
830 | bool operator!=(const AttrBuilder &B) { |
831 | return !(*this == B); |
832 | } |
833 | }; |
834 | |
835 | namespace AttributeFuncs { |
836 | |
837 | /// Which attributes cannot be applied to a type. |
838 | AttrBuilder typeIncompatible(Type *Ty); |
839 | |
840 | /// \returns Return true if the two functions have compatible target-independent |
841 | /// attributes for inlining purposes. |
842 | bool areInlineCompatible(const Function &Caller, const Function &Callee); |
843 | |
844 | /// Merge caller's and callee's attributes. |
845 | void mergeAttributesForInlining(Function &Caller, const Function &Callee); |
846 | |
847 | } // end namespace AttributeFuncs |
848 | |
849 | } // end namespace llvm |
850 | |
851 | #endif // LLVM_IR_ATTRIBUTES_H |
852 | |