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/Optional.h" |
21 | #include "llvm/ADT/SmallString.h" |
22 | #include "llvm/ADT/StringRef.h" |
23 | #include "llvm/ADT/iterator_range.h" |
24 | #include "llvm/Config/llvm-config.h" |
25 | #include "llvm/Support/Alignment.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 FoldingSetNodeID; |
42 | class Function; |
43 | class LLVMContext; |
44 | class Type; |
45 | |
46 | //===----------------------------------------------------------------------===// |
47 | /// \class |
48 | /// Functions, function parameters, and return types can have attributes |
49 | /// to indicate how they should be treated by optimizations and code |
50 | /// generation. This class represents one of those attributes. It's light-weight |
51 | /// and should be passed around by-value. |
52 | class Attribute { |
53 | public: |
54 | /// This enumeration lists the attributes that can be associated with |
55 | /// parameters, function results, or the function itself. |
56 | /// |
57 | /// Note: The `uwtable' attribute is about the ABI or the user mandating an |
58 | /// entry in the unwind table. The `nounwind' attribute is about an exception |
59 | /// passing by the function. |
60 | /// |
61 | /// In a theoretical system that uses tables for profiling and SjLj for |
62 | /// exceptions, they would be fully independent. In a normal system that uses |
63 | /// tables for both, the semantics are: |
64 | /// |
65 | /// nil = Needs an entry because an exception might pass by. |
66 | /// nounwind = No need for an entry |
67 | /// uwtable = Needs an entry because the ABI says so and because |
68 | /// an exception might pass by. |
69 | /// uwtable + nounwind = Needs an entry because the ABI says so. |
70 | |
71 | enum AttrKind { |
72 | // IR-Level Attributes |
73 | None, ///< No attributes have been set |
74 | #define GET_ATTR_NAMES |
75 | #define ATTRIBUTE_ENUM(ENUM_NAME, OTHER) ENUM_NAME, |
76 | #include "llvm/IR/Attributes.inc" |
77 | EndAttrKinds, ///< Sentinal value useful for loops |
78 | EmptyKey, ///< Use as Empty key for DenseMap of AttrKind |
79 | TombstoneKey, ///< Use as Tombstone key for DenseMap of AttrKind |
80 | }; |
81 | |
82 | private: |
83 | AttributeImpl *pImpl = nullptr; |
84 | |
85 | Attribute(AttributeImpl *A) : pImpl(A) {} |
86 | |
87 | public: |
88 | Attribute() = default; |
89 | |
90 | //===--------------------------------------------------------------------===// |
91 | // Attribute Construction |
92 | //===--------------------------------------------------------------------===// |
93 | |
94 | /// Return a uniquified Attribute object. |
95 | static Attribute get(LLVMContext &Context, AttrKind Kind, uint64_t Val = 0); |
96 | static Attribute get(LLVMContext &Context, StringRef Kind, |
97 | StringRef Val = StringRef()); |
98 | static Attribute get(LLVMContext &Context, AttrKind Kind, Type *Ty); |
99 | |
100 | /// Return a uniquified Attribute object that has the specific |
101 | /// alignment set. |
102 | static Attribute getWithAlignment(LLVMContext &Context, Align Alignment); |
103 | static Attribute getWithStackAlignment(LLVMContext &Context, Align Alignment); |
104 | static Attribute getWithDereferenceableBytes(LLVMContext &Context, |
105 | uint64_t Bytes); |
106 | static Attribute getWithDereferenceableOrNullBytes(LLVMContext &Context, |
107 | uint64_t Bytes); |
108 | static Attribute getWithAllocSizeArgs(LLVMContext &Context, |
109 | unsigned ElemSizeArg, |
110 | const Optional<unsigned> &NumElemsArg); |
111 | static Attribute getWithVScaleRangeArgs(LLVMContext &Context, |
112 | unsigned MinValue, unsigned MaxValue); |
113 | static Attribute getWithByValType(LLVMContext &Context, Type *Ty); |
114 | static Attribute getWithStructRetType(LLVMContext &Context, Type *Ty); |
115 | static Attribute getWithByRefType(LLVMContext &Context, Type *Ty); |
116 | static Attribute getWithPreallocatedType(LLVMContext &Context, Type *Ty); |
117 | static Attribute getWithInAllocaType(LLVMContext &Context, Type *Ty); |
118 | |
119 | /// For a typed attribute, return the equivalent attribute with the type |
120 | /// changed to \p ReplacementTy. |
121 | Attribute getWithNewType(LLVMContext &Context, Type *ReplacementTy) { |
122 | assert(isTypeAttribute() && "this requires a typed attribute" ); |
123 | return get(Context, getKindAsEnum(), ReplacementTy); |
124 | } |
125 | |
126 | static Attribute::AttrKind getAttrKindFromName(StringRef AttrName); |
127 | |
128 | static StringRef getNameFromAttrKind(Attribute::AttrKind AttrKind); |
129 | |
130 | /// Return true if and only if the attribute has an Argument. |
131 | static bool doesAttrKindHaveArgument(Attribute::AttrKind AttrKind); |
132 | |
133 | /// Return true if the provided string matches the IR name of an attribute. |
134 | /// example: "noalias" return true but not "NoAlias" |
135 | static bool isExistingAttribute(StringRef Name); |
136 | |
137 | //===--------------------------------------------------------------------===// |
138 | // Attribute Accessors |
139 | //===--------------------------------------------------------------------===// |
140 | |
141 | /// Return true if the attribute is an Attribute::AttrKind type. |
142 | bool isEnumAttribute() const; |
143 | |
144 | /// Return true if the attribute is an integer attribute. |
145 | bool isIntAttribute() const; |
146 | |
147 | /// Return true if the attribute is a string (target-dependent) |
148 | /// attribute. |
149 | bool isStringAttribute() const; |
150 | |
151 | /// Return true if the attribute is a type attribute. |
152 | bool isTypeAttribute() const; |
153 | |
154 | /// Return true if the attribute is any kind of attribute. |
155 | bool isValid() const { return pImpl; } |
156 | |
157 | /// Return true if the attribute is present. |
158 | bool hasAttribute(AttrKind Val) const; |
159 | |
160 | /// Return true if the target-dependent attribute is present. |
161 | bool hasAttribute(StringRef Val) const; |
162 | |
163 | /// Return the attribute's kind as an enum (Attribute::AttrKind). This |
164 | /// requires the attribute to be an enum, integer, or type attribute. |
165 | Attribute::AttrKind getKindAsEnum() const; |
166 | |
167 | /// Return the attribute's value as an integer. This requires that the |
168 | /// attribute be an integer attribute. |
169 | uint64_t getValueAsInt() const; |
170 | |
171 | /// Return the attribute's value as a boolean. This requires that the |
172 | /// attribute be a string attribute. |
173 | bool getValueAsBool() const; |
174 | |
175 | /// Return the attribute's kind as a string. This requires the |
176 | /// attribute to be a string attribute. |
177 | StringRef getKindAsString() const; |
178 | |
179 | /// Return the attribute's value as a string. This requires the |
180 | /// attribute to be a string attribute. |
181 | StringRef getValueAsString() const; |
182 | |
183 | /// Return the attribute's value as a Type. This requires the attribute to be |
184 | /// a type attribute. |
185 | Type *getValueAsType() const; |
186 | |
187 | /// Returns the alignment field of an attribute as a byte alignment |
188 | /// value. |
189 | MaybeAlign getAlignment() const; |
190 | |
191 | /// Returns the stack alignment field of an attribute as a byte |
192 | /// alignment value. |
193 | MaybeAlign getStackAlignment() const; |
194 | |
195 | /// Returns the number of dereferenceable bytes from the |
196 | /// dereferenceable attribute. |
197 | uint64_t getDereferenceableBytes() const; |
198 | |
199 | /// Returns the number of dereferenceable_or_null bytes from the |
200 | /// dereferenceable_or_null attribute. |
201 | uint64_t getDereferenceableOrNullBytes() const; |
202 | |
203 | /// Returns the argument numbers for the allocsize attribute (or pair(0, 0) |
204 | /// if not known). |
205 | std::pair<unsigned, Optional<unsigned>> getAllocSizeArgs() const; |
206 | |
207 | /// Returns the argument numbers for the vscale_range attribute (or pair(0, 0) |
208 | /// if not known). |
209 | std::pair<unsigned, unsigned> getVScaleRangeArgs() const; |
210 | |
211 | /// The Attribute is converted to a string of equivalent mnemonic. This |
212 | /// is, presumably, for writing out the mnemonics for the assembly writer. |
213 | std::string getAsString(bool InAttrGrp = false) const; |
214 | |
215 | /// Return true if this attribute belongs to the LLVMContext. |
216 | bool hasParentContext(LLVMContext &C) const; |
217 | |
218 | /// Equality and non-equality operators. |
219 | bool operator==(Attribute A) const { return pImpl == A.pImpl; } |
220 | bool operator!=(Attribute A) const { return pImpl != A.pImpl; } |
221 | |
222 | /// Less-than operator. Useful for sorting the attributes list. |
223 | bool operator<(Attribute A) const; |
224 | |
225 | void Profile(FoldingSetNodeID &ID) const; |
226 | |
227 | /// Return a raw pointer that uniquely identifies this attribute. |
228 | void *getRawPointer() const { |
229 | return pImpl; |
230 | } |
231 | |
232 | /// Get an attribute from a raw pointer created by getRawPointer. |
233 | static Attribute fromRawPointer(void *RawPtr) { |
234 | return Attribute(reinterpret_cast<AttributeImpl*>(RawPtr)); |
235 | } |
236 | }; |
237 | |
238 | // Specialized opaque value conversions. |
239 | inline LLVMAttributeRef wrap(Attribute Attr) { |
240 | return reinterpret_cast<LLVMAttributeRef>(Attr.getRawPointer()); |
241 | } |
242 | |
243 | // Specialized opaque value conversions. |
244 | inline Attribute unwrap(LLVMAttributeRef Attr) { |
245 | return Attribute::fromRawPointer(Attr); |
246 | } |
247 | |
248 | //===----------------------------------------------------------------------===// |
249 | /// \class |
250 | /// This class holds the attributes for a particular argument, parameter, |
251 | /// function, or return value. It is an immutable value type that is cheap to |
252 | /// copy. Adding and removing enum attributes is intended to be fast, but adding |
253 | /// and removing string or integer attributes involves a FoldingSet lookup. |
254 | class AttributeSet { |
255 | friend AttributeListImpl; |
256 | template <typename Ty> friend struct DenseMapInfo; |
257 | |
258 | // TODO: Extract AvailableAttrs from AttributeSetNode and store them here. |
259 | // This will allow an efficient implementation of addAttribute and |
260 | // removeAttribute for enum attrs. |
261 | |
262 | /// Private implementation pointer. |
263 | AttributeSetNode *SetNode = nullptr; |
264 | |
265 | private: |
266 | explicit AttributeSet(AttributeSetNode *ASN) : SetNode(ASN) {} |
267 | |
268 | public: |
269 | /// AttributeSet is a trivially copyable value type. |
270 | AttributeSet() = default; |
271 | AttributeSet(const AttributeSet &) = default; |
272 | ~AttributeSet() = default; |
273 | |
274 | static AttributeSet get(LLVMContext &C, const AttrBuilder &B); |
275 | static AttributeSet get(LLVMContext &C, ArrayRef<Attribute> Attrs); |
276 | |
277 | bool operator==(const AttributeSet &O) const { return SetNode == O.SetNode; } |
278 | bool operator!=(const AttributeSet &O) const { return !(*this == O); } |
279 | |
280 | /// Add an argument attribute. Returns a new set because attribute sets are |
281 | /// immutable. |
282 | LLVM_NODISCARD AttributeSet addAttribute(LLVMContext &C, |
283 | Attribute::AttrKind Kind) const; |
284 | |
285 | /// Add a target-dependent attribute. Returns a new set because attribute sets |
286 | /// are immutable. |
287 | LLVM_NODISCARD AttributeSet addAttribute(LLVMContext &C, StringRef Kind, |
288 | StringRef Value = StringRef()) const; |
289 | |
290 | /// Add attributes to the attribute set. Returns a new set because attribute |
291 | /// sets are immutable. |
292 | LLVM_NODISCARD AttributeSet addAttributes(LLVMContext &C, |
293 | AttributeSet AS) const; |
294 | |
295 | /// Remove the specified attribute from this set. Returns a new set because |
296 | /// attribute sets are immutable. |
297 | LLVM_NODISCARD AttributeSet removeAttribute(LLVMContext &C, |
298 | Attribute::AttrKind Kind) const; |
299 | |
300 | /// Remove the specified attribute from this set. Returns a new set because |
301 | /// attribute sets are immutable. |
302 | LLVM_NODISCARD AttributeSet removeAttribute(LLVMContext &C, |
303 | StringRef Kind) const; |
304 | |
305 | /// Remove the specified attributes from this set. Returns a new set because |
306 | /// attribute sets are immutable. |
307 | LLVM_NODISCARD AttributeSet |
308 | removeAttributes(LLVMContext &C, const AttrBuilder &AttrsToRemove) const; |
309 | |
310 | /// Return the number of attributes in this set. |
311 | unsigned getNumAttributes() const; |
312 | |
313 | /// Return true if attributes exists in this set. |
314 | bool hasAttributes() const { return SetNode != nullptr; } |
315 | |
316 | /// Return true if the attribute exists in this set. |
317 | bool hasAttribute(Attribute::AttrKind Kind) const; |
318 | |
319 | /// Return true if the attribute exists in this set. |
320 | bool hasAttribute(StringRef Kind) const; |
321 | |
322 | /// Return the attribute object. |
323 | Attribute getAttribute(Attribute::AttrKind Kind) const; |
324 | |
325 | /// Return the target-dependent attribute object. |
326 | Attribute getAttribute(StringRef Kind) const; |
327 | |
328 | MaybeAlign getAlignment() const; |
329 | MaybeAlign getStackAlignment() const; |
330 | uint64_t getDereferenceableBytes() const; |
331 | uint64_t getDereferenceableOrNullBytes() const; |
332 | Type *getByValType() const; |
333 | Type *getStructRetType() const; |
334 | Type *getByRefType() const; |
335 | Type *getPreallocatedType() const; |
336 | Type *getInAllocaType() const; |
337 | std::pair<unsigned, Optional<unsigned>> getAllocSizeArgs() const; |
338 | std::pair<unsigned, unsigned> getVScaleRangeArgs() const; |
339 | std::string getAsString(bool InAttrGrp = false) const; |
340 | |
341 | /// Return true if this attribute set belongs to the LLVMContext. |
342 | bool hasParentContext(LLVMContext &C) const; |
343 | |
344 | using iterator = const Attribute *; |
345 | |
346 | iterator begin() const; |
347 | iterator end() const; |
348 | #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) |
349 | void dump() const; |
350 | #endif |
351 | }; |
352 | |
353 | //===----------------------------------------------------------------------===// |
354 | /// \class |
355 | /// Provide DenseMapInfo for AttributeSet. |
356 | template <> struct DenseMapInfo<AttributeSet> { |
357 | static AttributeSet getEmptyKey() { |
358 | auto Val = static_cast<uintptr_t>(-1); |
359 | Val <<= PointerLikeTypeTraits<void *>::NumLowBitsAvailable; |
360 | return AttributeSet(reinterpret_cast<AttributeSetNode *>(Val)); |
361 | } |
362 | |
363 | static AttributeSet getTombstoneKey() { |
364 | auto Val = static_cast<uintptr_t>(-2); |
365 | Val <<= PointerLikeTypeTraits<void *>::NumLowBitsAvailable; |
366 | return AttributeSet(reinterpret_cast<AttributeSetNode *>(Val)); |
367 | } |
368 | |
369 | static unsigned getHashValue(AttributeSet AS) { |
370 | return (unsigned((uintptr_t)AS.SetNode) >> 4) ^ |
371 | (unsigned((uintptr_t)AS.SetNode) >> 9); |
372 | } |
373 | |
374 | static bool isEqual(AttributeSet LHS, AttributeSet RHS) { return LHS == RHS; } |
375 | }; |
376 | |
377 | //===----------------------------------------------------------------------===// |
378 | /// \class |
379 | /// This class holds the attributes for a function, its return value, and |
380 | /// its parameters. You access the attributes for each of them via an index into |
381 | /// the AttributeList object. The function attributes are at index |
382 | /// `AttributeList::FunctionIndex', the return value is at index |
383 | /// `AttributeList::ReturnIndex', and the attributes for the parameters start at |
384 | /// index `AttributeList::FirstArgIndex'. |
385 | class AttributeList { |
386 | public: |
387 | enum AttrIndex : unsigned { |
388 | ReturnIndex = 0U, |
389 | FunctionIndex = ~0U, |
390 | FirstArgIndex = 1, |
391 | }; |
392 | |
393 | private: |
394 | friend class AttrBuilder; |
395 | friend class AttributeListImpl; |
396 | friend class AttributeSet; |
397 | friend class AttributeSetNode; |
398 | template <typename Ty> friend struct DenseMapInfo; |
399 | |
400 | /// The attributes that we are managing. This can be null to represent |
401 | /// the empty attributes list. |
402 | AttributeListImpl *pImpl = nullptr; |
403 | |
404 | public: |
405 | /// Create an AttributeList with the specified parameters in it. |
406 | static AttributeList get(LLVMContext &C, |
407 | ArrayRef<std::pair<unsigned, Attribute>> Attrs); |
408 | static AttributeList get(LLVMContext &C, |
409 | ArrayRef<std::pair<unsigned, AttributeSet>> Attrs); |
410 | |
411 | /// Create an AttributeList from attribute sets for a function, its |
412 | /// return value, and all of its arguments. |
413 | static AttributeList get(LLVMContext &C, AttributeSet FnAttrs, |
414 | AttributeSet RetAttrs, |
415 | ArrayRef<AttributeSet> ArgAttrs); |
416 | |
417 | private: |
418 | explicit AttributeList(AttributeListImpl *LI) : pImpl(LI) {} |
419 | |
420 | static AttributeList getImpl(LLVMContext &C, ArrayRef<AttributeSet> AttrSets); |
421 | |
422 | AttributeList setAttributes(LLVMContext &C, unsigned Index, |
423 | AttributeSet Attrs) const; |
424 | |
425 | public: |
426 | AttributeList() = default; |
427 | |
428 | //===--------------------------------------------------------------------===// |
429 | // AttributeList Construction and Mutation |
430 | //===--------------------------------------------------------------------===// |
431 | |
432 | /// Return an AttributeList with the specified parameters in it. |
433 | static AttributeList get(LLVMContext &C, ArrayRef<AttributeList> Attrs); |
434 | static AttributeList get(LLVMContext &C, unsigned Index, |
435 | ArrayRef<Attribute::AttrKind> Kinds); |
436 | static AttributeList get(LLVMContext &C, unsigned Index, |
437 | ArrayRef<Attribute::AttrKind> Kinds, |
438 | ArrayRef<uint64_t> Values); |
439 | static AttributeList get(LLVMContext &C, unsigned Index, |
440 | ArrayRef<StringRef> Kind); |
441 | static AttributeList get(LLVMContext &C, unsigned Index, |
442 | const AttrBuilder &B); |
443 | |
444 | /// Add an attribute to the attribute set at the given index. |
445 | /// Returns a new list because attribute lists are immutable. |
446 | LLVM_NODISCARD AttributeList addAttribute(LLVMContext &C, unsigned Index, |
447 | Attribute::AttrKind Kind) const; |
448 | |
449 | /// Add an attribute to the attribute set at the given index. |
450 | /// Returns a new list because attribute lists are immutable. |
451 | LLVM_NODISCARD AttributeList |
452 | addAttribute(LLVMContext &C, unsigned Index, StringRef Kind, |
453 | StringRef Value = StringRef()) const; |
454 | |
455 | /// Add an attribute to the attribute set at the given index. |
456 | /// Returns a new list because attribute lists are immutable. |
457 | LLVM_NODISCARD AttributeList addAttribute(LLVMContext &C, unsigned Index, |
458 | Attribute A) const; |
459 | |
460 | /// Add attributes to the attribute set at the given index. |
461 | /// Returns a new list because attribute lists are immutable. |
462 | LLVM_NODISCARD AttributeList addAttributes(LLVMContext &C, unsigned Index, |
463 | const AttrBuilder &B) const; |
464 | |
465 | /// Add an argument attribute to the list. Returns a new list because |
466 | /// attribute lists are immutable. |
467 | LLVM_NODISCARD AttributeList addParamAttribute( |
468 | LLVMContext &C, unsigned ArgNo, Attribute::AttrKind Kind) const { |
469 | return addAttribute(C, ArgNo + FirstArgIndex, Kind); |
470 | } |
471 | |
472 | /// Add an argument attribute to the list. Returns a new list because |
473 | /// attribute lists are immutable. |
474 | LLVM_NODISCARD AttributeList |
475 | addParamAttribute(LLVMContext &C, unsigned ArgNo, StringRef Kind, |
476 | StringRef Value = StringRef()) const { |
477 | return addAttribute(C, ArgNo + FirstArgIndex, Kind, Value); |
478 | } |
479 | |
480 | /// Add an attribute to the attribute list at the given arg indices. Returns a |
481 | /// new list because attribute lists are immutable. |
482 | LLVM_NODISCARD AttributeList addParamAttribute(LLVMContext &C, |
483 | ArrayRef<unsigned> ArgNos, |
484 | Attribute A) const; |
485 | |
486 | /// Add an argument attribute to the list. Returns a new list because |
487 | /// attribute lists are immutable. |
488 | LLVM_NODISCARD AttributeList addParamAttributes(LLVMContext &C, |
489 | unsigned ArgNo, |
490 | const AttrBuilder &B) const { |
491 | return addAttributes(C, ArgNo + FirstArgIndex, B); |
492 | } |
493 | |
494 | /// Remove the specified attribute at the specified index from this |
495 | /// attribute list. Returns a new list because attribute lists are immutable. |
496 | LLVM_NODISCARD AttributeList removeAttribute(LLVMContext &C, unsigned Index, |
497 | Attribute::AttrKind Kind) const; |
498 | |
499 | /// Remove the specified attribute at the specified index from this |
500 | /// attribute list. Returns a new list because attribute lists are immutable. |
501 | LLVM_NODISCARD AttributeList removeAttribute(LLVMContext &C, unsigned Index, |
502 | StringRef Kind) const; |
503 | |
504 | /// Remove the specified attributes at the specified index from this |
505 | /// attribute list. Returns a new list because attribute lists are immutable. |
506 | LLVM_NODISCARD AttributeList removeAttributes( |
507 | LLVMContext &C, unsigned Index, const AttrBuilder &AttrsToRemove) const; |
508 | |
509 | /// Remove all attributes at the specified index from this |
510 | /// attribute list. Returns a new list because attribute lists are immutable. |
511 | LLVM_NODISCARD AttributeList removeAttributes(LLVMContext &C, |
512 | unsigned Index) const; |
513 | |
514 | /// Remove the specified attribute at the specified arg index from this |
515 | /// attribute list. Returns a new list because attribute lists are immutable. |
516 | LLVM_NODISCARD AttributeList removeParamAttribute( |
517 | LLVMContext &C, unsigned ArgNo, Attribute::AttrKind Kind) const { |
518 | return removeAttribute(C, ArgNo + FirstArgIndex, Kind); |
519 | } |
520 | |
521 | /// Remove the specified attribute at the specified arg index from this |
522 | /// attribute list. Returns a new list because attribute lists are immutable. |
523 | LLVM_NODISCARD AttributeList removeParamAttribute(LLVMContext &C, |
524 | unsigned ArgNo, |
525 | StringRef Kind) const { |
526 | return removeAttribute(C, ArgNo + FirstArgIndex, Kind); |
527 | } |
528 | |
529 | /// Remove the specified attribute at the specified arg index from this |
530 | /// attribute list. Returns a new list because attribute lists are immutable. |
531 | LLVM_NODISCARD AttributeList removeParamAttributes( |
532 | LLVMContext &C, unsigned ArgNo, const AttrBuilder &AttrsToRemove) const { |
533 | return removeAttributes(C, ArgNo + FirstArgIndex, AttrsToRemove); |
534 | } |
535 | |
536 | /// Remove noundef attribute and other attributes that imply undefined |
537 | /// behavior if a `undef` or `poison` value is passed from this attribute |
538 | /// list. Returns a new list because attribute lists are immutable. |
539 | LLVM_NODISCARD AttributeList |
540 | removeParamUndefImplyingAttributes(LLVMContext &C, unsigned ArgNo) const; |
541 | |
542 | /// Remove all attributes at the specified arg index from this |
543 | /// attribute list. Returns a new list because attribute lists are immutable. |
544 | LLVM_NODISCARD AttributeList removeParamAttributes(LLVMContext &C, |
545 | unsigned ArgNo) const { |
546 | return removeAttributes(C, ArgNo + FirstArgIndex); |
547 | } |
548 | |
549 | /// Replace the type contained by attribute \p AttrKind at index \p ArgNo wih |
550 | /// \p ReplacementTy, preserving all other attributes. |
551 | LLVM_NODISCARD AttributeList replaceAttributeType(LLVMContext &C, |
552 | unsigned ArgNo, |
553 | Attribute::AttrKind Kind, |
554 | Type *ReplacementTy) const { |
555 | Attribute Attr = getAttribute(ArgNo, Kind); |
556 | auto Attrs = removeAttribute(C, ArgNo, Kind); |
557 | return Attrs.addAttribute(C, ArgNo, Attr.getWithNewType(C, ReplacementTy)); |
558 | } |
559 | |
560 | /// \brief Add the dereferenceable attribute to the attribute set at the given |
561 | /// index. Returns a new list because attribute lists are immutable. |
562 | LLVM_NODISCARD AttributeList addDereferenceableAttr(LLVMContext &C, |
563 | unsigned Index, |
564 | uint64_t Bytes) const; |
565 | |
566 | /// \brief Add the dereferenceable attribute to the attribute set at the given |
567 | /// arg index. Returns a new list because attribute lists are immutable. |
568 | LLVM_NODISCARD AttributeList addDereferenceableParamAttr( |
569 | LLVMContext &C, unsigned ArgNo, uint64_t Bytes) const { |
570 | return addDereferenceableAttr(C, ArgNo + FirstArgIndex, Bytes); |
571 | } |
572 | |
573 | /// Add the dereferenceable_or_null attribute to the attribute set at |
574 | /// the given index. Returns a new list because attribute lists are immutable. |
575 | LLVM_NODISCARD AttributeList addDereferenceableOrNullAttr( |
576 | LLVMContext &C, unsigned Index, uint64_t Bytes) const; |
577 | |
578 | /// Add the dereferenceable_or_null attribute to the attribute set at |
579 | /// the given arg index. Returns a new list because attribute lists are |
580 | /// immutable. |
581 | LLVM_NODISCARD AttributeList addDereferenceableOrNullParamAttr( |
582 | LLVMContext &C, unsigned ArgNo, uint64_t Bytes) const { |
583 | return addDereferenceableOrNullAttr(C, ArgNo + FirstArgIndex, Bytes); |
584 | } |
585 | |
586 | /// Add the allocsize attribute to the attribute set at the given index. |
587 | /// Returns a new list because attribute lists are immutable. |
588 | LLVM_NODISCARD AttributeList |
589 | addAllocSizeAttr(LLVMContext &C, unsigned Index, unsigned ElemSizeArg, |
590 | const Optional<unsigned> &NumElemsArg); |
591 | |
592 | /// Add the allocsize attribute to the attribute set at the given arg index. |
593 | /// Returns a new list because attribute lists are immutable. |
594 | LLVM_NODISCARD AttributeList |
595 | addAllocSizeParamAttr(LLVMContext &C, unsigned ArgNo, unsigned ElemSizeArg, |
596 | const Optional<unsigned> &NumElemsArg) { |
597 | return addAllocSizeAttr(C, ArgNo + FirstArgIndex, ElemSizeArg, NumElemsArg); |
598 | } |
599 | |
600 | /// Add the vscale_range attribute to the attribute set at the given index. |
601 | /// Returns a new list because attribute lists are immutable. |
602 | LLVM_NODISCARD AttributeList addVScaleRangeAttr(LLVMContext &C, |
603 | unsigned Index, |
604 | unsigned MinValue, |
605 | unsigned MaxValue); |
606 | |
607 | //===--------------------------------------------------------------------===// |
608 | // AttributeList Accessors |
609 | //===--------------------------------------------------------------------===// |
610 | |
611 | /// The attributes for the specified index are returned. |
612 | AttributeSet getAttributes(unsigned Index) const; |
613 | |
614 | /// The attributes for the argument or parameter at the given index are |
615 | /// returned. |
616 | AttributeSet getParamAttributes(unsigned ArgNo) const; |
617 | |
618 | /// The attributes for the ret value are returned. |
619 | AttributeSet getRetAttributes() const; |
620 | |
621 | /// The function attributes are returned. |
622 | AttributeSet getFnAttributes() const; |
623 | |
624 | /// Return true if the attribute exists at the given index. |
625 | bool hasAttribute(unsigned Index, Attribute::AttrKind Kind) const; |
626 | |
627 | /// Return true if the attribute exists at the given index. |
628 | bool hasAttribute(unsigned Index, StringRef Kind) const; |
629 | |
630 | /// Return true if attribute exists at the given index. |
631 | bool hasAttributes(unsigned Index) const; |
632 | |
633 | /// Return true if the attribute exists for the given argument |
634 | bool hasParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) const { |
635 | return hasAttribute(ArgNo + FirstArgIndex, Kind); |
636 | } |
637 | |
638 | /// Return true if the attribute exists for the given argument |
639 | bool hasParamAttr(unsigned ArgNo, StringRef Kind) const { |
640 | return hasAttribute(ArgNo + FirstArgIndex, Kind); |
641 | } |
642 | |
643 | /// Return true if attributes exists for the given argument |
644 | bool hasParamAttrs(unsigned ArgNo) const { |
645 | return hasAttributes(ArgNo + FirstArgIndex); |
646 | } |
647 | |
648 | /// Equivalent to hasAttribute(AttributeList::FunctionIndex, Kind) but |
649 | /// may be faster. |
650 | bool hasFnAttribute(Attribute::AttrKind Kind) const; |
651 | |
652 | /// Equivalent to hasAttribute(AttributeList::FunctionIndex, Kind) but |
653 | /// may be faster. |
654 | bool hasFnAttribute(StringRef Kind) const; |
655 | |
656 | /// Equivalent to hasAttribute(ArgNo + FirstArgIndex, Kind). |
657 | bool hasParamAttribute(unsigned ArgNo, Attribute::AttrKind Kind) const; |
658 | |
659 | /// Return true if the specified attribute is set for at least one |
660 | /// parameter or for the return value. If Index is not nullptr, the index |
661 | /// of a parameter with the specified attribute is provided. |
662 | bool hasAttrSomewhere(Attribute::AttrKind Kind, |
663 | unsigned *Index = nullptr) const; |
664 | |
665 | /// Return the attribute object that exists at the given index. |
666 | Attribute getAttribute(unsigned Index, Attribute::AttrKind Kind) const; |
667 | |
668 | /// Return the attribute object that exists at the given index. |
669 | Attribute getAttribute(unsigned Index, StringRef Kind) const; |
670 | |
671 | /// Return the attribute object that exists at the arg index. |
672 | Attribute getParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) const { |
673 | return getAttribute(ArgNo + FirstArgIndex, Kind); |
674 | } |
675 | |
676 | /// Return the attribute object that exists at the given index. |
677 | Attribute getParamAttr(unsigned ArgNo, StringRef Kind) const { |
678 | return getAttribute(ArgNo + FirstArgIndex, Kind); |
679 | } |
680 | |
681 | /// Return the alignment of the return value. |
682 | MaybeAlign getRetAlignment() const; |
683 | |
684 | /// Return the alignment for the specified function parameter. |
685 | MaybeAlign getParamAlignment(unsigned ArgNo) const; |
686 | |
687 | /// Return the stack alignment for the specified function parameter. |
688 | MaybeAlign getParamStackAlignment(unsigned ArgNo) const; |
689 | |
690 | /// Return the byval type for the specified function parameter. |
691 | Type *getParamByValType(unsigned ArgNo) const; |
692 | |
693 | /// Return the sret type for the specified function parameter. |
694 | Type *getParamStructRetType(unsigned ArgNo) const; |
695 | |
696 | /// Return the byref type for the specified function parameter. |
697 | Type *getParamByRefType(unsigned ArgNo) const; |
698 | |
699 | /// Return the preallocated type for the specified function parameter. |
700 | Type *getParamPreallocatedType(unsigned ArgNo) const; |
701 | |
702 | /// Return the inalloca type for the specified function parameter. |
703 | Type *getParamInAllocaType(unsigned ArgNo) const; |
704 | |
705 | /// Get the stack alignment. |
706 | MaybeAlign getStackAlignment(unsigned Index) const; |
707 | |
708 | /// Get the number of dereferenceable bytes (or zero if unknown). |
709 | uint64_t getDereferenceableBytes(unsigned Index) const; |
710 | |
711 | /// Get the number of dereferenceable bytes (or zero if unknown) of an |
712 | /// arg. |
713 | uint64_t getParamDereferenceableBytes(unsigned ArgNo) const { |
714 | return getDereferenceableBytes(ArgNo + FirstArgIndex); |
715 | } |
716 | |
717 | /// Get the number of dereferenceable_or_null bytes (or zero if |
718 | /// unknown). |
719 | uint64_t getDereferenceableOrNullBytes(unsigned Index) const; |
720 | |
721 | /// Get the number of dereferenceable_or_null bytes (or zero if |
722 | /// unknown) of an arg. |
723 | uint64_t getParamDereferenceableOrNullBytes(unsigned ArgNo) const { |
724 | return getDereferenceableOrNullBytes(ArgNo + FirstArgIndex); |
725 | } |
726 | |
727 | /// Get the allocsize argument numbers (or pair(0, 0) if unknown). |
728 | std::pair<unsigned, Optional<unsigned>> |
729 | getAllocSizeArgs(unsigned Index) const; |
730 | |
731 | /// Get the vscale_range argument numbers (or pair(0, 0) if unknown). |
732 | std::pair<unsigned, unsigned> getVScaleRangeArgs(unsigned Index) const; |
733 | |
734 | /// Return the attributes at the index as a string. |
735 | std::string getAsString(unsigned Index, bool InAttrGrp = false) const; |
736 | |
737 | /// Return true if this attribute list belongs to the LLVMContext. |
738 | bool hasParentContext(LLVMContext &C) const; |
739 | |
740 | //===--------------------------------------------------------------------===// |
741 | // AttributeList Introspection |
742 | //===--------------------------------------------------------------------===// |
743 | |
744 | using iterator = const AttributeSet *; |
745 | |
746 | iterator begin() const; |
747 | iterator end() const; |
748 | |
749 | unsigned getNumAttrSets() const; |
750 | |
751 | /// Use these to iterate over the valid attribute indices. |
752 | unsigned index_begin() const { return AttributeList::FunctionIndex; } |
753 | unsigned index_end() const { return getNumAttrSets() - 1; } |
754 | |
755 | /// operator==/!= - Provide equality predicates. |
756 | bool operator==(const AttributeList &RHS) const { return pImpl == RHS.pImpl; } |
757 | bool operator!=(const AttributeList &RHS) const { return pImpl != RHS.pImpl; } |
758 | |
759 | /// Return a raw pointer that uniquely identifies this attribute list. |
760 | void *getRawPointer() const { |
761 | return pImpl; |
762 | } |
763 | |
764 | /// Return true if there are no attributes. |
765 | bool isEmpty() const { return pImpl == nullptr; } |
766 | |
767 | void print(raw_ostream &O) const; |
768 | |
769 | void dump() const; |
770 | }; |
771 | |
772 | //===----------------------------------------------------------------------===// |
773 | /// \class |
774 | /// Provide DenseMapInfo for AttributeList. |
775 | template <> struct DenseMapInfo<AttributeList> { |
776 | static AttributeList getEmptyKey() { |
777 | auto Val = static_cast<uintptr_t>(-1); |
778 | Val <<= PointerLikeTypeTraits<void*>::NumLowBitsAvailable; |
779 | return AttributeList(reinterpret_cast<AttributeListImpl *>(Val)); |
780 | } |
781 | |
782 | static AttributeList getTombstoneKey() { |
783 | auto Val = static_cast<uintptr_t>(-2); |
784 | Val <<= PointerLikeTypeTraits<void*>::NumLowBitsAvailable; |
785 | return AttributeList(reinterpret_cast<AttributeListImpl *>(Val)); |
786 | } |
787 | |
788 | static unsigned getHashValue(AttributeList AS) { |
789 | return (unsigned((uintptr_t)AS.pImpl) >> 4) ^ |
790 | (unsigned((uintptr_t)AS.pImpl) >> 9); |
791 | } |
792 | |
793 | static bool isEqual(AttributeList LHS, AttributeList RHS) { |
794 | return LHS == RHS; |
795 | } |
796 | }; |
797 | |
798 | //===----------------------------------------------------------------------===// |
799 | /// \class |
800 | /// This class is used in conjunction with the Attribute::get method to |
801 | /// create an Attribute object. The object itself is uniquified. The Builder's |
802 | /// value, however, is not. So this can be used as a quick way to test for |
803 | /// equality, presence of attributes, etc. |
804 | class AttrBuilder { |
805 | std::bitset<Attribute::EndAttrKinds> Attrs; |
806 | std::map<SmallString<32>, SmallString<32>, std::less<>> TargetDepAttrs; |
807 | MaybeAlign Alignment; |
808 | MaybeAlign StackAlignment; |
809 | uint64_t DerefBytes = 0; |
810 | uint64_t DerefOrNullBytes = 0; |
811 | uint64_t AllocSizeArgs = 0; |
812 | uint64_t VScaleRangeArgs = 0; |
813 | Type *ByValType = nullptr; |
814 | Type *StructRetType = nullptr; |
815 | Type *ByRefType = nullptr; |
816 | Type *PreallocatedType = nullptr; |
817 | Type *InAllocaType = nullptr; |
818 | |
819 | public: |
820 | AttrBuilder() = default; |
821 | |
822 | AttrBuilder(const Attribute &A) { |
823 | addAttribute(A); |
824 | } |
825 | |
826 | AttrBuilder(AttributeList AS, unsigned Idx); |
827 | AttrBuilder(AttributeSet AS); |
828 | |
829 | void clear(); |
830 | |
831 | /// Add an attribute to the builder. |
832 | AttrBuilder &addAttribute(Attribute::AttrKind Val) { |
833 | assert((unsigned)Val < Attribute::EndAttrKinds && |
834 | "Attribute out of range!" ); |
835 | assert(!Attribute::doesAttrKindHaveArgument(Val) && |
836 | "Adding integer attribute without adding a value!" ); |
837 | Attrs[Val] = true; |
838 | return *this; |
839 | } |
840 | |
841 | /// Add the Attribute object to the builder. |
842 | AttrBuilder &addAttribute(Attribute A); |
843 | |
844 | /// Add the target-dependent attribute to the builder. |
845 | AttrBuilder &addAttribute(StringRef A, StringRef V = StringRef()); |
846 | |
847 | /// Remove an attribute from the builder. |
848 | AttrBuilder &removeAttribute(Attribute::AttrKind Val); |
849 | |
850 | /// Remove the attributes from the builder. |
851 | AttrBuilder &removeAttributes(AttributeList A, uint64_t WithoutIndex); |
852 | |
853 | /// Remove the target-dependent attribute to the builder. |
854 | AttrBuilder &removeAttribute(StringRef A); |
855 | |
856 | /// Add the attributes from the builder. |
857 | AttrBuilder &merge(const AttrBuilder &B); |
858 | |
859 | /// Remove the attributes from the builder. |
860 | AttrBuilder &remove(const AttrBuilder &B); |
861 | |
862 | /// Return true if the builder has any attribute that's in the |
863 | /// specified builder. |
864 | bool overlaps(const AttrBuilder &B) const; |
865 | |
866 | /// Return true if the builder has the specified attribute. |
867 | bool contains(Attribute::AttrKind A) const { |
868 | assert((unsigned)A < Attribute::EndAttrKinds && "Attribute out of range!" ); |
869 | return Attrs[A]; |
870 | } |
871 | |
872 | /// Return true if the builder has the specified target-dependent |
873 | /// attribute. |
874 | bool contains(StringRef A) const; |
875 | |
876 | /// Return true if the builder has IR-level attributes. |
877 | bool hasAttributes() const; |
878 | |
879 | /// Return true if the builder has any attribute that's in the |
880 | /// specified attribute. |
881 | bool hasAttributes(AttributeList A, uint64_t Index) const; |
882 | |
883 | /// Return true if the builder has an alignment attribute. |
884 | bool hasAlignmentAttr() const; |
885 | |
886 | /// Retrieve the alignment attribute, if it exists. |
887 | MaybeAlign getAlignment() const { return Alignment; } |
888 | |
889 | /// Retrieve the stack alignment attribute, if it exists. |
890 | MaybeAlign getStackAlignment() const { return StackAlignment; } |
891 | |
892 | /// Retrieve the number of dereferenceable bytes, if the |
893 | /// dereferenceable attribute exists (zero is returned otherwise). |
894 | uint64_t getDereferenceableBytes() const { return DerefBytes; } |
895 | |
896 | /// Retrieve the number of dereferenceable_or_null bytes, if the |
897 | /// dereferenceable_or_null attribute exists (zero is returned otherwise). |
898 | uint64_t getDereferenceableOrNullBytes() const { return DerefOrNullBytes; } |
899 | |
900 | /// Retrieve the byval type. |
901 | Type *getByValType() const { return ByValType; } |
902 | |
903 | /// Retrieve the sret type. |
904 | Type *getStructRetType() const { return StructRetType; } |
905 | |
906 | /// Retrieve the byref type. |
907 | Type *getByRefType() const { return ByRefType; } |
908 | |
909 | /// Retrieve the preallocated type. |
910 | Type *getPreallocatedType() const { return PreallocatedType; } |
911 | |
912 | /// Retrieve the inalloca type. |
913 | Type *getInAllocaType() const { return InAllocaType; } |
914 | |
915 | /// Retrieve the allocsize args, if the allocsize attribute exists. If it |
916 | /// doesn't exist, pair(0, 0) is returned. |
917 | std::pair<unsigned, Optional<unsigned>> getAllocSizeArgs() const; |
918 | |
919 | /// Retrieve the vscale_range args, if the vscale_range attribute exists. If |
920 | /// it doesn't exist, pair(0, 0) is returned. |
921 | std::pair<unsigned, unsigned> getVScaleRangeArgs() const; |
922 | |
923 | /// This turns an alignment into the form used internally in Attribute. |
924 | /// This call has no effect if Align is not set. |
925 | AttrBuilder &addAlignmentAttr(MaybeAlign Align); |
926 | |
927 | /// This turns an int alignment (which must be a power of 2) into the |
928 | /// form used internally in Attribute. |
929 | /// This call has no effect if Align is 0. |
930 | /// Deprecated, use the version using a MaybeAlign. |
931 | inline AttrBuilder &addAlignmentAttr(unsigned Align) { |
932 | return addAlignmentAttr(MaybeAlign(Align)); |
933 | } |
934 | |
935 | /// This turns a stack alignment into the form used internally in Attribute. |
936 | /// This call has no effect if Align is not set. |
937 | AttrBuilder &addStackAlignmentAttr(MaybeAlign Align); |
938 | |
939 | /// This turns an int stack alignment (which must be a power of 2) into |
940 | /// the form used internally in Attribute. |
941 | /// This call has no effect if Align is 0. |
942 | /// Deprecated, use the version using a MaybeAlign. |
943 | inline AttrBuilder &addStackAlignmentAttr(unsigned Align) { |
944 | return addStackAlignmentAttr(MaybeAlign(Align)); |
945 | } |
946 | |
947 | /// This turns the number of dereferenceable bytes into the form used |
948 | /// internally in Attribute. |
949 | AttrBuilder &addDereferenceableAttr(uint64_t Bytes); |
950 | |
951 | /// This turns the number of dereferenceable_or_null bytes into the |
952 | /// form used internally in Attribute. |
953 | AttrBuilder &addDereferenceableOrNullAttr(uint64_t Bytes); |
954 | |
955 | /// This turns one (or two) ints into the form used internally in Attribute. |
956 | AttrBuilder &addAllocSizeAttr(unsigned ElemSizeArg, |
957 | const Optional<unsigned> &NumElemsArg); |
958 | |
959 | /// This turns two ints into the form used internally in Attribute. |
960 | AttrBuilder &addVScaleRangeAttr(unsigned MinValue, unsigned MaxValue); |
961 | |
962 | /// This turns a byval type into the form used internally in Attribute. |
963 | AttrBuilder &addByValAttr(Type *Ty); |
964 | |
965 | /// This turns a sret type into the form used internally in Attribute. |
966 | AttrBuilder &addStructRetAttr(Type *Ty); |
967 | |
968 | /// This turns a byref type into the form used internally in Attribute. |
969 | AttrBuilder &addByRefAttr(Type *Ty); |
970 | |
971 | /// This turns a preallocated type into the form used internally in Attribute. |
972 | AttrBuilder &addPreallocatedAttr(Type *Ty); |
973 | |
974 | /// This turns an inalloca type into the form used internally in Attribute. |
975 | AttrBuilder &addInAllocaAttr(Type *Ty); |
976 | |
977 | /// Add an allocsize attribute, using the representation returned by |
978 | /// Attribute.getIntValue(). |
979 | AttrBuilder &addAllocSizeAttrFromRawRepr(uint64_t RawAllocSizeRepr); |
980 | |
981 | /// Add a vscale_range attribute, using the representation returned by |
982 | /// Attribute.getIntValue(). |
983 | AttrBuilder &addVScaleRangeAttrFromRawRepr(uint64_t RawVScaleRangeRepr); |
984 | |
985 | /// Return true if the builder contains no target-independent |
986 | /// attributes. |
987 | bool empty() const { return Attrs.none(); } |
988 | |
989 | // Iterators for target-dependent attributes. |
990 | using td_type = decltype(TargetDepAttrs)::value_type; |
991 | using td_iterator = decltype(TargetDepAttrs)::iterator; |
992 | using td_const_iterator = decltype(TargetDepAttrs)::const_iterator; |
993 | using td_range = iterator_range<td_iterator>; |
994 | using td_const_range = iterator_range<td_const_iterator>; |
995 | |
996 | td_iterator td_begin() { return TargetDepAttrs.begin(); } |
997 | td_iterator td_end() { return TargetDepAttrs.end(); } |
998 | |
999 | td_const_iterator td_begin() const { return TargetDepAttrs.begin(); } |
1000 | td_const_iterator td_end() const { return TargetDepAttrs.end(); } |
1001 | |
1002 | td_range td_attrs() { return td_range(td_begin(), td_end()); } |
1003 | |
1004 | td_const_range td_attrs() const { |
1005 | return td_const_range(td_begin(), td_end()); |
1006 | } |
1007 | |
1008 | bool td_empty() const { return TargetDepAttrs.empty(); } |
1009 | |
1010 | bool operator==(const AttrBuilder &B) const; |
1011 | bool operator!=(const AttrBuilder &B) const { return !(*this == B); } |
1012 | }; |
1013 | |
1014 | namespace AttributeFuncs { |
1015 | |
1016 | /// Which attributes cannot be applied to a type. |
1017 | AttrBuilder typeIncompatible(Type *Ty); |
1018 | |
1019 | /// \returns Return true if the two functions have compatible target-independent |
1020 | /// attributes for inlining purposes. |
1021 | bool areInlineCompatible(const Function &Caller, const Function &Callee); |
1022 | |
1023 | |
1024 | /// Checks if there are any incompatible function attributes between |
1025 | /// \p A and \p B. |
1026 | /// |
1027 | /// \param [in] A - The first function to be compared with. |
1028 | /// \param [in] B - The second function to be compared with. |
1029 | /// \returns true if the functions have compatible attributes. |
1030 | bool areOutlineCompatible(const Function &A, const Function &B); |
1031 | |
1032 | /// Merge caller's and callee's attributes. |
1033 | void mergeAttributesForInlining(Function &Caller, const Function &Callee); |
1034 | |
1035 | /// Merges the functions attributes from \p ToMerge into function \p Base. |
1036 | /// |
1037 | /// \param [in,out] Base - The function being merged into. |
1038 | /// \param [in] ToMerge - The function to merge attributes from. |
1039 | void mergeAttributesForOutlining(Function &Base, const Function &ToMerge); |
1040 | |
1041 | } // end namespace AttributeFuncs |
1042 | |
1043 | } // end namespace llvm |
1044 | |
1045 | #endif // LLVM_IR_ATTRIBUTES_H |
1046 | |