1 //===- Attributes.cpp - Implement AttributesList --------------------------===//
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
7 //===----------------------------------------------------------------------===//
10 // This file implements the Attribute, AttributeImpl, AttrBuilder,
11 // AttributeListImpl, and AttributeList classes.
13 //===----------------------------------------------------------------------===//
15 #include "llvm/IR/Attributes.h"
16 #include "AttributeImpl.h"
17 #include "LLVMContextImpl.h"
18 #include "llvm/ADT/ArrayRef.h"
19 #include "llvm/ADT/FoldingSet.h"
20 #include "llvm/ADT/Optional.h"
21 #include "llvm/ADT/STLExtras.h"
22 #include "llvm/ADT/SmallVector.h"
23 #include "llvm/ADT/StringExtras.h"
24 #include "llvm/ADT/StringRef.h"
25 #include "llvm/ADT/Twine.h"
26 #include "llvm/Config/llvm-config.h"
27 #include "llvm/IR/Function.h"
28 #include "llvm/IR/LLVMContext.h"
29 #include "llvm/IR/Type.h"
30 #include "llvm/Support/Compiler.h"
31 #include "llvm/Support/Debug.h"
32 #include "llvm/Support/ErrorHandling.h"
33 #include "llvm/Support/MathExtras.h"
34 #include "llvm/Support/raw_ostream.h"
47 //===----------------------------------------------------------------------===//
48 // Attribute Construction Methods
49 //===----------------------------------------------------------------------===//
51 // allocsize has two integer arguments, but because they're both 32 bits, we can
52 // pack them into one 64-bit value, at the cost of making said value
55 // In order to do this, we need to reserve one value of the second (optional)
56 // allocsize argument to signify "not present."
57 static const unsigned AllocSizeNumElemsNotPresent
= -1;
59 static uint64_t packAllocSizeArgs(unsigned ElemSizeArg
,
60 const Optional
<unsigned> &NumElemsArg
) {
61 assert((!NumElemsArg
.hasValue() ||
62 *NumElemsArg
!= AllocSizeNumElemsNotPresent
) &&
63 "Attempting to pack a reserved value");
65 return uint64_t(ElemSizeArg
) << 32 |
66 NumElemsArg
.getValueOr(AllocSizeNumElemsNotPresent
);
69 static std::pair
<unsigned, Optional
<unsigned>>
70 unpackAllocSizeArgs(uint64_t Num
) {
71 unsigned NumElems
= Num
& std::numeric_limits
<unsigned>::max();
72 unsigned ElemSizeArg
= Num
>> 32;
74 Optional
<unsigned> NumElemsArg
;
75 if (NumElems
!= AllocSizeNumElemsNotPresent
)
76 NumElemsArg
= NumElems
;
77 return std::make_pair(ElemSizeArg
, NumElemsArg
);
80 Attribute
Attribute::get(LLVMContext
&Context
, Attribute::AttrKind Kind
,
82 LLVMContextImpl
*pImpl
= Context
.pImpl
;
85 if (Val
) ID
.AddInteger(Val
);
88 AttributeImpl
*PA
= pImpl
->AttrsSet
.FindNodeOrInsertPos(ID
, InsertPoint
);
91 // If we didn't find any existing attributes of the same shape then create a
92 // new one and insert it.
94 PA
= new EnumAttributeImpl(Kind
);
96 PA
= new IntAttributeImpl(Kind
, Val
);
97 pImpl
->AttrsSet
.InsertNode(PA
, InsertPoint
);
100 // Return the Attribute that we found or created.
101 return Attribute(PA
);
104 Attribute
Attribute::get(LLVMContext
&Context
, StringRef Kind
, StringRef Val
) {
105 LLVMContextImpl
*pImpl
= Context
.pImpl
;
108 if (!Val
.empty()) ID
.AddString(Val
);
111 AttributeImpl
*PA
= pImpl
->AttrsSet
.FindNodeOrInsertPos(ID
, InsertPoint
);
114 // If we didn't find any existing attributes of the same shape then create a
115 // new one and insert it.
116 PA
= new StringAttributeImpl(Kind
, Val
);
117 pImpl
->AttrsSet
.InsertNode(PA
, InsertPoint
);
120 // Return the Attribute that we found or created.
121 return Attribute(PA
);
124 Attribute
Attribute::get(LLVMContext
&Context
, Attribute::AttrKind Kind
,
126 LLVMContextImpl
*pImpl
= Context
.pImpl
;
132 AttributeImpl
*PA
= pImpl
->AttrsSet
.FindNodeOrInsertPos(ID
, InsertPoint
);
135 // If we didn't find any existing attributes of the same shape then create a
136 // new one and insert it.
137 PA
= new TypeAttributeImpl(Kind
, Ty
);
138 pImpl
->AttrsSet
.InsertNode(PA
, InsertPoint
);
141 // Return the Attribute that we found or created.
142 return Attribute(PA
);
145 Attribute
Attribute::getWithAlignment(LLVMContext
&Context
, Align A
) {
146 assert(A
<= 0x40000000 && "Alignment too large.");
147 return get(Context
, Alignment
, A
.value());
150 Attribute
Attribute::getWithStackAlignment(LLVMContext
&Context
, Align A
) {
151 assert(A
<= 0x100 && "Alignment too large.");
152 return get(Context
, StackAlignment
, A
.value());
155 Attribute
Attribute::getWithDereferenceableBytes(LLVMContext
&Context
,
157 assert(Bytes
&& "Bytes must be non-zero.");
158 return get(Context
, Dereferenceable
, Bytes
);
161 Attribute
Attribute::getWithDereferenceableOrNullBytes(LLVMContext
&Context
,
163 assert(Bytes
&& "Bytes must be non-zero.");
164 return get(Context
, DereferenceableOrNull
, Bytes
);
167 Attribute
Attribute::getWithByValType(LLVMContext
&Context
, Type
*Ty
) {
168 return get(Context
, ByVal
, Ty
);
172 Attribute::getWithAllocSizeArgs(LLVMContext
&Context
, unsigned ElemSizeArg
,
173 const Optional
<unsigned> &NumElemsArg
) {
174 assert(!(ElemSizeArg
== 0 && NumElemsArg
&& *NumElemsArg
== 0) &&
175 "Invalid allocsize arguments -- given allocsize(0, 0)");
176 return get(Context
, AllocSize
, packAllocSizeArgs(ElemSizeArg
, NumElemsArg
));
179 //===----------------------------------------------------------------------===//
180 // Attribute Accessor Methods
181 //===----------------------------------------------------------------------===//
183 bool Attribute::isEnumAttribute() const {
184 return pImpl
&& pImpl
->isEnumAttribute();
187 bool Attribute::isIntAttribute() const {
188 return pImpl
&& pImpl
->isIntAttribute();
191 bool Attribute::isStringAttribute() const {
192 return pImpl
&& pImpl
->isStringAttribute();
195 bool Attribute::isTypeAttribute() const {
196 return pImpl
&& pImpl
->isTypeAttribute();
199 Attribute::AttrKind
Attribute::getKindAsEnum() const {
200 if (!pImpl
) return None
;
201 assert((isEnumAttribute() || isIntAttribute() || isTypeAttribute()) &&
202 "Invalid attribute type to get the kind as an enum!");
203 return pImpl
->getKindAsEnum();
206 uint64_t Attribute::getValueAsInt() const {
207 if (!pImpl
) return 0;
208 assert(isIntAttribute() &&
209 "Expected the attribute to be an integer attribute!");
210 return pImpl
->getValueAsInt();
213 StringRef
Attribute::getKindAsString() const {
214 if (!pImpl
) return {};
215 assert(isStringAttribute() &&
216 "Invalid attribute type to get the kind as a string!");
217 return pImpl
->getKindAsString();
220 StringRef
Attribute::getValueAsString() const {
221 if (!pImpl
) return {};
222 assert(isStringAttribute() &&
223 "Invalid attribute type to get the value as a string!");
224 return pImpl
->getValueAsString();
227 Type
*Attribute::getValueAsType() const {
228 if (!pImpl
) return {};
229 assert(isTypeAttribute() &&
230 "Invalid attribute type to get the value as a type!");
231 return pImpl
->getValueAsType();
235 bool Attribute::hasAttribute(AttrKind Kind
) const {
236 return (pImpl
&& pImpl
->hasAttribute(Kind
)) || (!pImpl
&& Kind
== None
);
239 bool Attribute::hasAttribute(StringRef Kind
) const {
240 if (!isStringAttribute()) return false;
241 return pImpl
&& pImpl
->hasAttribute(Kind
);
244 MaybeAlign
Attribute::getAlignment() const {
245 assert(hasAttribute(Attribute::Alignment
) &&
246 "Trying to get alignment from non-alignment attribute!");
247 return MaybeAlign(pImpl
->getValueAsInt());
250 MaybeAlign
Attribute::getStackAlignment() const {
251 assert(hasAttribute(Attribute::StackAlignment
) &&
252 "Trying to get alignment from non-alignment attribute!");
253 return MaybeAlign(pImpl
->getValueAsInt());
256 uint64_t Attribute::getDereferenceableBytes() const {
257 assert(hasAttribute(Attribute::Dereferenceable
) &&
258 "Trying to get dereferenceable bytes from "
259 "non-dereferenceable attribute!");
260 return pImpl
->getValueAsInt();
263 uint64_t Attribute::getDereferenceableOrNullBytes() const {
264 assert(hasAttribute(Attribute::DereferenceableOrNull
) &&
265 "Trying to get dereferenceable bytes from "
266 "non-dereferenceable attribute!");
267 return pImpl
->getValueAsInt();
270 std::pair
<unsigned, Optional
<unsigned>> Attribute::getAllocSizeArgs() const {
271 assert(hasAttribute(Attribute::AllocSize
) &&
272 "Trying to get allocsize args from non-allocsize attribute");
273 return unpackAllocSizeArgs(pImpl
->getValueAsInt());
276 std::string
Attribute::getAsString(bool InAttrGrp
) const {
277 if (!pImpl
) return {};
279 if (hasAttribute(Attribute::SanitizeAddress
))
280 return "sanitize_address";
281 if (hasAttribute(Attribute::SanitizeHWAddress
))
282 return "sanitize_hwaddress";
283 if (hasAttribute(Attribute::SanitizeMemTag
))
284 return "sanitize_memtag";
285 if (hasAttribute(Attribute::AlwaysInline
))
286 return "alwaysinline";
287 if (hasAttribute(Attribute::ArgMemOnly
))
289 if (hasAttribute(Attribute::Builtin
))
291 if (hasAttribute(Attribute::Convergent
))
293 if (hasAttribute(Attribute::SwiftError
))
295 if (hasAttribute(Attribute::SwiftSelf
))
297 if (hasAttribute(Attribute::InaccessibleMemOnly
))
298 return "inaccessiblememonly";
299 if (hasAttribute(Attribute::InaccessibleMemOrArgMemOnly
))
300 return "inaccessiblemem_or_argmemonly";
301 if (hasAttribute(Attribute::InAlloca
))
303 if (hasAttribute(Attribute::InlineHint
))
305 if (hasAttribute(Attribute::InReg
))
307 if (hasAttribute(Attribute::JumpTable
))
309 if (hasAttribute(Attribute::MinSize
))
311 if (hasAttribute(Attribute::Naked
))
313 if (hasAttribute(Attribute::Nest
))
315 if (hasAttribute(Attribute::NoAlias
))
317 if (hasAttribute(Attribute::NoBuiltin
))
319 if (hasAttribute(Attribute::NoCapture
))
321 if (hasAttribute(Attribute::NoDuplicate
))
322 return "noduplicate";
323 if (hasAttribute(Attribute::NoFree
))
325 if (hasAttribute(Attribute::NoImplicitFloat
))
326 return "noimplicitfloat";
327 if (hasAttribute(Attribute::NoInline
))
329 if (hasAttribute(Attribute::NonLazyBind
))
330 return "nonlazybind";
331 if (hasAttribute(Attribute::NonNull
))
333 if (hasAttribute(Attribute::NoRedZone
))
335 if (hasAttribute(Attribute::NoReturn
))
337 if (hasAttribute(Attribute::NoSync
))
339 if (hasAttribute(Attribute::WillReturn
))
341 if (hasAttribute(Attribute::NoCfCheck
))
343 if (hasAttribute(Attribute::NoRecurse
))
345 if (hasAttribute(Attribute::NoUnwind
))
347 if (hasAttribute(Attribute::OptForFuzzing
))
348 return "optforfuzzing";
349 if (hasAttribute(Attribute::OptimizeNone
))
351 if (hasAttribute(Attribute::OptimizeForSize
))
353 if (hasAttribute(Attribute::ReadNone
))
355 if (hasAttribute(Attribute::ReadOnly
))
357 if (hasAttribute(Attribute::WriteOnly
))
359 if (hasAttribute(Attribute::Returned
))
361 if (hasAttribute(Attribute::ReturnsTwice
))
362 return "returns_twice";
363 if (hasAttribute(Attribute::SExt
))
365 if (hasAttribute(Attribute::SpeculativeLoadHardening
))
366 return "speculative_load_hardening";
367 if (hasAttribute(Attribute::Speculatable
))
368 return "speculatable";
369 if (hasAttribute(Attribute::StackProtect
))
371 if (hasAttribute(Attribute::StackProtectReq
))
373 if (hasAttribute(Attribute::StackProtectStrong
))
375 if (hasAttribute(Attribute::SafeStack
))
377 if (hasAttribute(Attribute::ShadowCallStack
))
378 return "shadowcallstack";
379 if (hasAttribute(Attribute::StrictFP
))
381 if (hasAttribute(Attribute::StructRet
))
383 if (hasAttribute(Attribute::SanitizeThread
))
384 return "sanitize_thread";
385 if (hasAttribute(Attribute::SanitizeMemory
))
386 return "sanitize_memory";
387 if (hasAttribute(Attribute::UWTable
))
389 if (hasAttribute(Attribute::ZExt
))
391 if (hasAttribute(Attribute::Cold
))
393 if (hasAttribute(Attribute::ImmArg
))
396 if (hasAttribute(Attribute::ByVal
)) {
399 if (Type
*Ty
= getValueAsType()) {
400 raw_string_ostream
OS(Result
);
402 Ty
->print(OS
, false, true);
409 // FIXME: These should be output like this:
414 if (hasAttribute(Attribute::Alignment
)) {
417 Result
+= (InAttrGrp
) ? "=" : " ";
418 Result
+= utostr(getValueAsInt());
422 auto AttrWithBytesToString
= [&](const char *Name
) {
427 Result
+= utostr(getValueAsInt());
430 Result
+= utostr(getValueAsInt());
436 if (hasAttribute(Attribute::StackAlignment
))
437 return AttrWithBytesToString("alignstack");
439 if (hasAttribute(Attribute::Dereferenceable
))
440 return AttrWithBytesToString("dereferenceable");
442 if (hasAttribute(Attribute::DereferenceableOrNull
))
443 return AttrWithBytesToString("dereferenceable_or_null");
445 if (hasAttribute(Attribute::AllocSize
)) {
447 Optional
<unsigned> NumElems
;
448 std::tie(ElemSize
, NumElems
) = getAllocSizeArgs();
450 std::string Result
= "allocsize(";
451 Result
+= utostr(ElemSize
);
452 if (NumElems
.hasValue()) {
454 Result
+= utostr(*NumElems
);
460 // Convert target-dependent attributes to strings of the form:
465 if (isStringAttribute()) {
467 Result
+= (Twine('"') + getKindAsString() + Twine('"')).str();
469 std::string AttrVal
= pImpl
->getValueAsString();
470 if (AttrVal
.empty()) return Result
;
472 // Since some attribute strings contain special characters that cannot be
473 // printable, those have to be escaped to make the attribute value printable
474 // as is. e.g. "\01__gnu_mcount_nc"
476 raw_string_ostream
OS(Result
);
478 printEscapedString(AttrVal
, OS
);
484 llvm_unreachable("Unknown attribute");
487 bool Attribute::operator<(Attribute A
) const {
488 if (!pImpl
&& !A
.pImpl
) return false;
489 if (!pImpl
) return true;
490 if (!A
.pImpl
) return false;
491 return *pImpl
< *A
.pImpl
;
494 //===----------------------------------------------------------------------===//
495 // AttributeImpl Definition
496 //===----------------------------------------------------------------------===//
498 // Pin the vtables to this file.
499 AttributeImpl::~AttributeImpl() = default;
501 void EnumAttributeImpl::anchor() {}
503 void IntAttributeImpl::anchor() {}
505 void StringAttributeImpl::anchor() {}
507 void TypeAttributeImpl::anchor() {}
509 bool AttributeImpl::hasAttribute(Attribute::AttrKind A
) const {
510 if (isStringAttribute()) return false;
511 return getKindAsEnum() == A
;
514 bool AttributeImpl::hasAttribute(StringRef Kind
) const {
515 if (!isStringAttribute()) return false;
516 return getKindAsString() == Kind
;
519 Attribute::AttrKind
AttributeImpl::getKindAsEnum() const {
520 assert(isEnumAttribute() || isIntAttribute() || isTypeAttribute());
521 return static_cast<const EnumAttributeImpl
*>(this)->getEnumKind();
524 uint64_t AttributeImpl::getValueAsInt() const {
525 assert(isIntAttribute());
526 return static_cast<const IntAttributeImpl
*>(this)->getValue();
529 StringRef
AttributeImpl::getKindAsString() const {
530 assert(isStringAttribute());
531 return static_cast<const StringAttributeImpl
*>(this)->getStringKind();
534 StringRef
AttributeImpl::getValueAsString() const {
535 assert(isStringAttribute());
536 return static_cast<const StringAttributeImpl
*>(this)->getStringValue();
539 Type
*AttributeImpl::getValueAsType() const {
540 assert(isTypeAttribute());
541 return static_cast<const TypeAttributeImpl
*>(this)->getTypeValue();
544 bool AttributeImpl::operator<(const AttributeImpl
&AI
) const {
545 // This sorts the attributes with Attribute::AttrKinds coming first (sorted
546 // relative to their enum value) and then strings.
547 if (isEnumAttribute()) {
548 if (AI
.isEnumAttribute()) return getKindAsEnum() < AI
.getKindAsEnum();
549 if (AI
.isIntAttribute()) return true;
550 if (AI
.isStringAttribute()) return true;
551 if (AI
.isTypeAttribute()) return true;
554 if (isTypeAttribute()) {
555 if (AI
.isEnumAttribute()) return false;
556 if (AI
.isTypeAttribute()) {
557 assert(getKindAsEnum() != AI
.getKindAsEnum() &&
558 "Comparison of types would be unstable");
559 return getKindAsEnum() < AI
.getKindAsEnum();
561 if (AI
.isIntAttribute()) return true;
562 if (AI
.isStringAttribute()) return true;
565 if (isIntAttribute()) {
566 if (AI
.isEnumAttribute()) return false;
567 if (AI
.isTypeAttribute()) return false;
568 if (AI
.isIntAttribute()) {
569 if (getKindAsEnum() == AI
.getKindAsEnum())
570 return getValueAsInt() < AI
.getValueAsInt();
571 return getKindAsEnum() < AI
.getKindAsEnum();
573 if (AI
.isStringAttribute()) return true;
576 assert(isStringAttribute());
577 if (AI
.isEnumAttribute()) return false;
578 if (AI
.isTypeAttribute()) return false;
579 if (AI
.isIntAttribute()) return false;
580 if (getKindAsString() == AI
.getKindAsString())
581 return getValueAsString() < AI
.getValueAsString();
582 return getKindAsString() < AI
.getKindAsString();
585 //===----------------------------------------------------------------------===//
586 // AttributeSet Definition
587 //===----------------------------------------------------------------------===//
589 AttributeSet
AttributeSet::get(LLVMContext
&C
, const AttrBuilder
&B
) {
590 return AttributeSet(AttributeSetNode::get(C
, B
));
593 AttributeSet
AttributeSet::get(LLVMContext
&C
, ArrayRef
<Attribute
> Attrs
) {
594 return AttributeSet(AttributeSetNode::get(C
, Attrs
));
597 AttributeSet
AttributeSet::addAttribute(LLVMContext
&C
,
598 Attribute::AttrKind Kind
) const {
599 if (hasAttribute(Kind
)) return *this;
601 B
.addAttribute(Kind
);
602 return addAttributes(C
, AttributeSet::get(C
, B
));
605 AttributeSet
AttributeSet::addAttribute(LLVMContext
&C
, StringRef Kind
,
606 StringRef Value
) const {
608 B
.addAttribute(Kind
, Value
);
609 return addAttributes(C
, AttributeSet::get(C
, B
));
612 AttributeSet
AttributeSet::addAttributes(LLVMContext
&C
,
613 const AttributeSet AS
) const {
614 if (!hasAttributes())
617 if (!AS
.hasAttributes())
621 for (const auto I
: *this)
627 AttributeSet
AttributeSet::removeAttribute(LLVMContext
&C
,
628 Attribute::AttrKind Kind
) const {
629 if (!hasAttribute(Kind
)) return *this;
630 AttrBuilder
B(*this);
631 B
.removeAttribute(Kind
);
635 AttributeSet
AttributeSet::removeAttribute(LLVMContext
&C
,
636 StringRef Kind
) const {
637 if (!hasAttribute(Kind
)) return *this;
638 AttrBuilder
B(*this);
639 B
.removeAttribute(Kind
);
643 AttributeSet
AttributeSet::removeAttributes(LLVMContext
&C
,
644 const AttrBuilder
&Attrs
) const {
645 AttrBuilder
B(*this);
650 unsigned AttributeSet::getNumAttributes() const {
651 return SetNode
? SetNode
->getNumAttributes() : 0;
654 bool AttributeSet::hasAttribute(Attribute::AttrKind Kind
) const {
655 return SetNode
? SetNode
->hasAttribute(Kind
) : false;
658 bool AttributeSet::hasAttribute(StringRef Kind
) const {
659 return SetNode
? SetNode
->hasAttribute(Kind
) : false;
662 Attribute
AttributeSet::getAttribute(Attribute::AttrKind Kind
) const {
663 return SetNode
? SetNode
->getAttribute(Kind
) : Attribute();
666 Attribute
AttributeSet::getAttribute(StringRef Kind
) const {
667 return SetNode
? SetNode
->getAttribute(Kind
) : Attribute();
670 MaybeAlign
AttributeSet::getAlignment() const {
671 return SetNode
? SetNode
->getAlignment() : None
;
674 MaybeAlign
AttributeSet::getStackAlignment() const {
675 return SetNode
? SetNode
->getStackAlignment() : None
;
678 uint64_t AttributeSet::getDereferenceableBytes() const {
679 return SetNode
? SetNode
->getDereferenceableBytes() : 0;
682 uint64_t AttributeSet::getDereferenceableOrNullBytes() const {
683 return SetNode
? SetNode
->getDereferenceableOrNullBytes() : 0;
686 Type
*AttributeSet::getByValType() const {
687 return SetNode
? SetNode
->getByValType() : nullptr;
690 std::pair
<unsigned, Optional
<unsigned>> AttributeSet::getAllocSizeArgs() const {
691 return SetNode
? SetNode
->getAllocSizeArgs()
692 : std::pair
<unsigned, Optional
<unsigned>>(0, 0);
695 std::string
AttributeSet::getAsString(bool InAttrGrp
) const {
696 return SetNode
? SetNode
->getAsString(InAttrGrp
) : "";
699 AttributeSet::iterator
AttributeSet::begin() const {
700 return SetNode
? SetNode
->begin() : nullptr;
703 AttributeSet::iterator
AttributeSet::end() const {
704 return SetNode
? SetNode
->end() : nullptr;
707 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
708 LLVM_DUMP_METHOD
void AttributeSet::dump() const {
711 dbgs() << getAsString(true) << " }\n";
715 //===----------------------------------------------------------------------===//
716 // AttributeSetNode Definition
717 //===----------------------------------------------------------------------===//
719 AttributeSetNode::AttributeSetNode(ArrayRef
<Attribute
> Attrs
)
720 : NumAttrs(Attrs
.size()) {
721 // There's memory after the node where we can store the entries in.
722 llvm::copy(Attrs
, getTrailingObjects
<Attribute
>());
724 static_assert(Attribute::EndAttrKinds
<=
725 sizeof(AvailableAttrs
) * CHAR_BIT
,
726 "Too many attributes");
728 for (const auto I
: *this) {
729 if (!I
.isStringAttribute()) {
730 Attribute::AttrKind Kind
= I
.getKindAsEnum();
731 AvailableAttrs
[Kind
/ 8] |= 1ULL << (Kind
% 8);
736 AttributeSetNode
*AttributeSetNode::get(LLVMContext
&C
,
737 ArrayRef
<Attribute
> Attrs
) {
741 // Otherwise, build a key to look up the existing attributes.
742 LLVMContextImpl
*pImpl
= C
.pImpl
;
745 SmallVector
<Attribute
, 8> SortedAttrs(Attrs
.begin(), Attrs
.end());
746 llvm::sort(SortedAttrs
);
748 for (const auto Attr
: SortedAttrs
)
752 AttributeSetNode
*PA
=
753 pImpl
->AttrsSetNodes
.FindNodeOrInsertPos(ID
, InsertPoint
);
755 // If we didn't find any existing attributes of the same shape then create a
756 // new one and insert it.
758 // Coallocate entries after the AttributeSetNode itself.
759 void *Mem
= ::operator new(totalSizeToAlloc
<Attribute
>(SortedAttrs
.size()));
760 PA
= new (Mem
) AttributeSetNode(SortedAttrs
);
761 pImpl
->AttrsSetNodes
.InsertNode(PA
, InsertPoint
);
764 // Return the AttributeSetNode that we found or created.
768 AttributeSetNode
*AttributeSetNode::get(LLVMContext
&C
, const AttrBuilder
&B
) {
769 // Add target-independent attributes.
770 SmallVector
<Attribute
, 8> Attrs
;
771 for (Attribute::AttrKind Kind
= Attribute::None
;
772 Kind
!= Attribute::EndAttrKinds
; Kind
= Attribute::AttrKind(Kind
+ 1)) {
773 if (!B
.contains(Kind
))
778 case Attribute::ByVal
:
779 Attr
= Attribute::getWithByValType(C
, B
.getByValType());
781 case Attribute::Alignment
:
782 assert(B
.getAlignment() && "Alignment must be set");
783 Attr
= Attribute::getWithAlignment(C
, *B
.getAlignment());
785 case Attribute::StackAlignment
:
786 assert(B
.getStackAlignment() && "StackAlignment must be set");
787 Attr
= Attribute::getWithStackAlignment(C
, *B
.getStackAlignment());
789 case Attribute::Dereferenceable
:
790 Attr
= Attribute::getWithDereferenceableBytes(
791 C
, B
.getDereferenceableBytes());
793 case Attribute::DereferenceableOrNull
:
794 Attr
= Attribute::getWithDereferenceableOrNullBytes(
795 C
, B
.getDereferenceableOrNullBytes());
797 case Attribute::AllocSize
: {
798 auto A
= B
.getAllocSizeArgs();
799 Attr
= Attribute::getWithAllocSizeArgs(C
, A
.first
, A
.second
);
803 Attr
= Attribute::get(C
, Kind
);
805 Attrs
.push_back(Attr
);
808 // Add target-dependent (string) attributes.
809 for (const auto &TDA
: B
.td_attrs())
810 Attrs
.emplace_back(Attribute::get(C
, TDA
.first
, TDA
.second
));
812 return get(C
, Attrs
);
815 bool AttributeSetNode::hasAttribute(StringRef Kind
) const {
816 for (const auto I
: *this)
817 if (I
.hasAttribute(Kind
))
822 Attribute
AttributeSetNode::getAttribute(Attribute::AttrKind Kind
) const {
823 if (hasAttribute(Kind
)) {
824 for (const auto I
: *this)
825 if (I
.hasAttribute(Kind
))
831 Attribute
AttributeSetNode::getAttribute(StringRef Kind
) const {
832 for (const auto I
: *this)
833 if (I
.hasAttribute(Kind
))
838 MaybeAlign
AttributeSetNode::getAlignment() const {
839 for (const auto I
: *this)
840 if (I
.hasAttribute(Attribute::Alignment
))
841 return I
.getAlignment();
845 MaybeAlign
AttributeSetNode::getStackAlignment() const {
846 for (const auto I
: *this)
847 if (I
.hasAttribute(Attribute::StackAlignment
))
848 return I
.getStackAlignment();
852 Type
*AttributeSetNode::getByValType() const {
853 for (const auto I
: *this)
854 if (I
.hasAttribute(Attribute::ByVal
))
855 return I
.getValueAsType();
859 uint64_t AttributeSetNode::getDereferenceableBytes() const {
860 for (const auto I
: *this)
861 if (I
.hasAttribute(Attribute::Dereferenceable
))
862 return I
.getDereferenceableBytes();
866 uint64_t AttributeSetNode::getDereferenceableOrNullBytes() const {
867 for (const auto I
: *this)
868 if (I
.hasAttribute(Attribute::DereferenceableOrNull
))
869 return I
.getDereferenceableOrNullBytes();
873 std::pair
<unsigned, Optional
<unsigned>>
874 AttributeSetNode::getAllocSizeArgs() const {
875 for (const auto I
: *this)
876 if (I
.hasAttribute(Attribute::AllocSize
))
877 return I
.getAllocSizeArgs();
878 return std::make_pair(0, 0);
881 std::string
AttributeSetNode::getAsString(bool InAttrGrp
) const {
883 for (iterator I
= begin(), E
= end(); I
!= E
; ++I
) {
886 Str
+= I
->getAsString(InAttrGrp
);
891 //===----------------------------------------------------------------------===//
892 // AttributeListImpl Definition
893 //===----------------------------------------------------------------------===//
895 /// Map from AttributeList index to the internal array index. Adding one happens
896 /// to work, but it relies on unsigned integer wrapping. MSVC warns about
897 /// unsigned wrapping in constexpr functions, so write out the conditional. LLVM
898 /// folds it to add anyway.
899 static constexpr unsigned attrIdxToArrayIdx(unsigned Index
) {
900 return Index
== AttributeList::FunctionIndex
? 0 : Index
+ 1;
903 AttributeListImpl::AttributeListImpl(LLVMContext
&C
,
904 ArrayRef
<AttributeSet
> Sets
)
905 : Context(C
), NumAttrSets(Sets
.size()) {
906 assert(!Sets
.empty() && "pointless AttributeListImpl");
908 // There's memory after the node where we can store the entries in.
909 llvm::copy(Sets
, getTrailingObjects
<AttributeSet
>());
911 // Initialize AvailableFunctionAttrs summary bitset.
912 static_assert(Attribute::EndAttrKinds
<=
913 sizeof(AvailableFunctionAttrs
) * CHAR_BIT
,
914 "Too many attributes");
915 static_assert(attrIdxToArrayIdx(AttributeList::FunctionIndex
) == 0U,
916 "function should be stored in slot 0");
917 for (const auto I
: Sets
[0]) {
918 if (!I
.isStringAttribute()) {
919 Attribute::AttrKind Kind
= I
.getKindAsEnum();
920 AvailableFunctionAttrs
[Kind
/ 8] |= 1ULL << (Kind
% 8);
925 void AttributeListImpl::Profile(FoldingSetNodeID
&ID
) const {
926 Profile(ID
, makeArrayRef(begin(), end()));
929 void AttributeListImpl::Profile(FoldingSetNodeID
&ID
,
930 ArrayRef
<AttributeSet
> Sets
) {
931 for (const auto &Set
: Sets
)
932 ID
.AddPointer(Set
.SetNode
);
935 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
936 LLVM_DUMP_METHOD
void AttributeListImpl::dump() const {
937 AttributeList(const_cast<AttributeListImpl
*>(this)).dump();
941 //===----------------------------------------------------------------------===//
942 // AttributeList Construction and Mutation Methods
943 //===----------------------------------------------------------------------===//
945 AttributeList
AttributeList::getImpl(LLVMContext
&C
,
946 ArrayRef
<AttributeSet
> AttrSets
) {
947 assert(!AttrSets
.empty() && "pointless AttributeListImpl");
949 LLVMContextImpl
*pImpl
= C
.pImpl
;
951 AttributeListImpl::Profile(ID
, AttrSets
);
954 AttributeListImpl
*PA
=
955 pImpl
->AttrsLists
.FindNodeOrInsertPos(ID
, InsertPoint
);
957 // If we didn't find any existing attributes of the same shape then
958 // create a new one and insert it.
960 // Coallocate entries after the AttributeListImpl itself.
961 void *Mem
= ::operator new(
962 AttributeListImpl::totalSizeToAlloc
<AttributeSet
>(AttrSets
.size()));
963 PA
= new (Mem
) AttributeListImpl(C
, AttrSets
);
964 pImpl
->AttrsLists
.InsertNode(PA
, InsertPoint
);
967 // Return the AttributesList that we found or created.
968 return AttributeList(PA
);
972 AttributeList::get(LLVMContext
&C
,
973 ArrayRef
<std::pair
<unsigned, Attribute
>> Attrs
) {
974 // If there are no attributes then return a null AttributesList pointer.
978 assert(std::is_sorted(Attrs
.begin(), Attrs
.end(),
979 [](const std::pair
<unsigned, Attribute
> &LHS
,
980 const std::pair
<unsigned, Attribute
> &RHS
) {
981 return LHS
.first
< RHS
.first
;
982 }) && "Misordered Attributes list!");
983 assert(llvm::none_of(Attrs
,
984 [](const std::pair
<unsigned, Attribute
> &Pair
) {
985 return Pair
.second
.hasAttribute(Attribute::None
);
987 "Pointless attribute!");
989 // Create a vector if (unsigned, AttributeSetNode*) pairs from the attributes
991 SmallVector
<std::pair
<unsigned, AttributeSet
>, 8> AttrPairVec
;
992 for (ArrayRef
<std::pair
<unsigned, Attribute
>>::iterator I
= Attrs
.begin(),
993 E
= Attrs
.end(); I
!= E
; ) {
994 unsigned Index
= I
->first
;
995 SmallVector
<Attribute
, 4> AttrVec
;
996 while (I
!= E
&& I
->first
== Index
) {
997 AttrVec
.push_back(I
->second
);
1001 AttrPairVec
.emplace_back(Index
, AttributeSet::get(C
, AttrVec
));
1004 return get(C
, AttrPairVec
);
1008 AttributeList::get(LLVMContext
&C
,
1009 ArrayRef
<std::pair
<unsigned, AttributeSet
>> Attrs
) {
1010 // If there are no attributes then return a null AttributesList pointer.
1014 assert(std::is_sorted(Attrs
.begin(), Attrs
.end(),
1015 [](const std::pair
<unsigned, AttributeSet
> &LHS
,
1016 const std::pair
<unsigned, AttributeSet
> &RHS
) {
1017 return LHS
.first
< RHS
.first
;
1019 "Misordered Attributes list!");
1020 assert(llvm::none_of(Attrs
,
1021 [](const std::pair
<unsigned, AttributeSet
> &Pair
) {
1022 return !Pair
.second
.hasAttributes();
1024 "Pointless attribute!");
1026 unsigned MaxIndex
= Attrs
.back().first
;
1027 // If the MaxIndex is FunctionIndex and there are other indices in front
1028 // of it, we need to use the largest of those to get the right size.
1029 if (MaxIndex
== FunctionIndex
&& Attrs
.size() > 1)
1030 MaxIndex
= Attrs
[Attrs
.size() - 2].first
;
1032 SmallVector
<AttributeSet
, 4> AttrVec(attrIdxToArrayIdx(MaxIndex
) + 1);
1033 for (const auto Pair
: Attrs
)
1034 AttrVec
[attrIdxToArrayIdx(Pair
.first
)] = Pair
.second
;
1036 return getImpl(C
, AttrVec
);
1039 AttributeList
AttributeList::get(LLVMContext
&C
, AttributeSet FnAttrs
,
1040 AttributeSet RetAttrs
,
1041 ArrayRef
<AttributeSet
> ArgAttrs
) {
1042 // Scan from the end to find the last argument with attributes. Most
1043 // arguments don't have attributes, so it's nice if we can have fewer unique
1044 // AttributeListImpls by dropping empty attribute sets at the end of the list.
1045 unsigned NumSets
= 0;
1046 for (size_t I
= ArgAttrs
.size(); I
!= 0; --I
) {
1047 if (ArgAttrs
[I
- 1].hasAttributes()) {
1053 // Check function and return attributes if we didn't have argument
1055 if (RetAttrs
.hasAttributes())
1057 else if (FnAttrs
.hasAttributes())
1061 // If all attribute sets were empty, we can use the empty attribute list.
1065 SmallVector
<AttributeSet
, 8> AttrSets
;
1066 AttrSets
.reserve(NumSets
);
1067 // If we have any attributes, we always have function attributes.
1068 AttrSets
.push_back(FnAttrs
);
1070 AttrSets
.push_back(RetAttrs
);
1072 // Drop the empty argument attribute sets at the end.
1073 ArgAttrs
= ArgAttrs
.take_front(NumSets
- 2);
1074 AttrSets
.insert(AttrSets
.end(), ArgAttrs
.begin(), ArgAttrs
.end());
1077 return getImpl(C
, AttrSets
);
1080 AttributeList
AttributeList::get(LLVMContext
&C
, unsigned Index
,
1081 const AttrBuilder
&B
) {
1082 if (!B
.hasAttributes())
1084 Index
= attrIdxToArrayIdx(Index
);
1085 SmallVector
<AttributeSet
, 8> AttrSets(Index
+ 1);
1086 AttrSets
[Index
] = AttributeSet::get(C
, B
);
1087 return getImpl(C
, AttrSets
);
1090 AttributeList
AttributeList::get(LLVMContext
&C
, unsigned Index
,
1091 ArrayRef
<Attribute::AttrKind
> Kinds
) {
1092 SmallVector
<std::pair
<unsigned, Attribute
>, 8> Attrs
;
1093 for (const auto K
: Kinds
)
1094 Attrs
.emplace_back(Index
, Attribute::get(C
, K
));
1095 return get(C
, Attrs
);
1098 AttributeList
AttributeList::get(LLVMContext
&C
, unsigned Index
,
1099 ArrayRef
<StringRef
> Kinds
) {
1100 SmallVector
<std::pair
<unsigned, Attribute
>, 8> Attrs
;
1101 for (const auto K
: Kinds
)
1102 Attrs
.emplace_back(Index
, Attribute::get(C
, K
));
1103 return get(C
, Attrs
);
1106 AttributeList
AttributeList::get(LLVMContext
&C
,
1107 ArrayRef
<AttributeList
> Attrs
) {
1110 if (Attrs
.size() == 1)
1113 unsigned MaxSize
= 0;
1114 for (const auto List
: Attrs
)
1115 MaxSize
= std::max(MaxSize
, List
.getNumAttrSets());
1117 // If every list was empty, there is no point in merging the lists.
1121 SmallVector
<AttributeSet
, 8> NewAttrSets(MaxSize
);
1122 for (unsigned I
= 0; I
< MaxSize
; ++I
) {
1123 AttrBuilder CurBuilder
;
1124 for (const auto List
: Attrs
)
1125 CurBuilder
.merge(List
.getAttributes(I
- 1));
1126 NewAttrSets
[I
] = AttributeSet::get(C
, CurBuilder
);
1129 return getImpl(C
, NewAttrSets
);
1132 AttributeList
AttributeList::addAttribute(LLVMContext
&C
, unsigned Index
,
1133 Attribute::AttrKind Kind
) const {
1134 if (hasAttribute(Index
, Kind
)) return *this;
1136 B
.addAttribute(Kind
);
1137 return addAttributes(C
, Index
, B
);
1140 AttributeList
AttributeList::addAttribute(LLVMContext
&C
, unsigned Index
,
1142 StringRef Value
) const {
1144 B
.addAttribute(Kind
, Value
);
1145 return addAttributes(C
, Index
, B
);
1148 AttributeList
AttributeList::addAttribute(LLVMContext
&C
, unsigned Index
,
1149 Attribute A
) const {
1152 return addAttributes(C
, Index
, B
);
1155 AttributeList
AttributeList::addAttributes(LLVMContext
&C
, unsigned Index
,
1156 const AttrBuilder
&B
) const {
1157 if (!B
.hasAttributes())
1161 return AttributeList::get(C
, {{Index
, AttributeSet::get(C
, B
)}});
1164 // FIXME it is not obvious how this should work for alignment. For now, say
1165 // we can't change a known alignment.
1166 const MaybeAlign OldAlign
= getAttributes(Index
).getAlignment();
1167 const MaybeAlign NewAlign
= B
.getAlignment();
1168 assert((!OldAlign
|| !NewAlign
|| OldAlign
== NewAlign
) &&
1169 "Attempt to change alignment!");
1172 Index
= attrIdxToArrayIdx(Index
);
1173 SmallVector
<AttributeSet
, 4> AttrSets(this->begin(), this->end());
1174 if (Index
>= AttrSets
.size())
1175 AttrSets
.resize(Index
+ 1);
1177 AttrBuilder
Merged(AttrSets
[Index
]);
1179 AttrSets
[Index
] = AttributeSet::get(C
, Merged
);
1181 return getImpl(C
, AttrSets
);
1184 AttributeList
AttributeList::addParamAttribute(LLVMContext
&C
,
1185 ArrayRef
<unsigned> ArgNos
,
1186 Attribute A
) const {
1187 assert(std::is_sorted(ArgNos
.begin(), ArgNos
.end()));
1189 SmallVector
<AttributeSet
, 4> AttrSets(this->begin(), this->end());
1190 unsigned MaxIndex
= attrIdxToArrayIdx(ArgNos
.back() + FirstArgIndex
);
1191 if (MaxIndex
>= AttrSets
.size())
1192 AttrSets
.resize(MaxIndex
+ 1);
1194 for (unsigned ArgNo
: ArgNos
) {
1195 unsigned Index
= attrIdxToArrayIdx(ArgNo
+ FirstArgIndex
);
1196 AttrBuilder
B(AttrSets
[Index
]);
1198 AttrSets
[Index
] = AttributeSet::get(C
, B
);
1201 return getImpl(C
, AttrSets
);
1204 AttributeList
AttributeList::removeAttribute(LLVMContext
&C
, unsigned Index
,
1205 Attribute::AttrKind Kind
) const {
1206 if (!hasAttribute(Index
, Kind
)) return *this;
1208 Index
= attrIdxToArrayIdx(Index
);
1209 SmallVector
<AttributeSet
, 4> AttrSets(this->begin(), this->end());
1210 assert(Index
< AttrSets
.size());
1212 AttrSets
[Index
] = AttrSets
[Index
].removeAttribute(C
, Kind
);
1214 return getImpl(C
, AttrSets
);
1217 AttributeList
AttributeList::removeAttribute(LLVMContext
&C
, unsigned Index
,
1218 StringRef Kind
) const {
1219 if (!hasAttribute(Index
, Kind
)) return *this;
1221 Index
= attrIdxToArrayIdx(Index
);
1222 SmallVector
<AttributeSet
, 4> AttrSets(this->begin(), this->end());
1223 assert(Index
< AttrSets
.size());
1225 AttrSets
[Index
] = AttrSets
[Index
].removeAttribute(C
, Kind
);
1227 return getImpl(C
, AttrSets
);
1231 AttributeList::removeAttributes(LLVMContext
&C
, unsigned Index
,
1232 const AttrBuilder
&AttrsToRemove
) const {
1236 Index
= attrIdxToArrayIdx(Index
);
1237 SmallVector
<AttributeSet
, 4> AttrSets(this->begin(), this->end());
1238 if (Index
>= AttrSets
.size())
1239 AttrSets
.resize(Index
+ 1);
1241 AttrSets
[Index
] = AttrSets
[Index
].removeAttributes(C
, AttrsToRemove
);
1243 return getImpl(C
, AttrSets
);
1246 AttributeList
AttributeList::removeAttributes(LLVMContext
&C
,
1247 unsigned WithoutIndex
) const {
1250 WithoutIndex
= attrIdxToArrayIdx(WithoutIndex
);
1251 if (WithoutIndex
>= getNumAttrSets())
1253 SmallVector
<AttributeSet
, 4> AttrSets(this->begin(), this->end());
1254 AttrSets
[WithoutIndex
] = AttributeSet();
1255 return getImpl(C
, AttrSets
);
1258 AttributeList
AttributeList::addDereferenceableAttr(LLVMContext
&C
,
1260 uint64_t Bytes
) const {
1262 B
.addDereferenceableAttr(Bytes
);
1263 return addAttributes(C
, Index
, B
);
1267 AttributeList::addDereferenceableOrNullAttr(LLVMContext
&C
, unsigned Index
,
1268 uint64_t Bytes
) const {
1270 B
.addDereferenceableOrNullAttr(Bytes
);
1271 return addAttributes(C
, Index
, B
);
1275 AttributeList::addAllocSizeAttr(LLVMContext
&C
, unsigned Index
,
1276 unsigned ElemSizeArg
,
1277 const Optional
<unsigned> &NumElemsArg
) {
1279 B
.addAllocSizeAttr(ElemSizeArg
, NumElemsArg
);
1280 return addAttributes(C
, Index
, B
);
1283 //===----------------------------------------------------------------------===//
1284 // AttributeList Accessor Methods
1285 //===----------------------------------------------------------------------===//
1287 LLVMContext
&AttributeList::getContext() const { return pImpl
->getContext(); }
1289 AttributeSet
AttributeList::getParamAttributes(unsigned ArgNo
) const {
1290 return getAttributes(ArgNo
+ FirstArgIndex
);
1293 AttributeSet
AttributeList::getRetAttributes() const {
1294 return getAttributes(ReturnIndex
);
1297 AttributeSet
AttributeList::getFnAttributes() const {
1298 return getAttributes(FunctionIndex
);
1301 bool AttributeList::hasAttribute(unsigned Index
,
1302 Attribute::AttrKind Kind
) const {
1303 return getAttributes(Index
).hasAttribute(Kind
);
1306 bool AttributeList::hasAttribute(unsigned Index
, StringRef Kind
) const {
1307 return getAttributes(Index
).hasAttribute(Kind
);
1310 bool AttributeList::hasAttributes(unsigned Index
) const {
1311 return getAttributes(Index
).hasAttributes();
1314 bool AttributeList::hasFnAttribute(Attribute::AttrKind Kind
) const {
1315 return pImpl
&& pImpl
->hasFnAttribute(Kind
);
1318 bool AttributeList::hasFnAttribute(StringRef Kind
) const {
1319 return hasAttribute(AttributeList::FunctionIndex
, Kind
);
1322 bool AttributeList::hasParamAttribute(unsigned ArgNo
,
1323 Attribute::AttrKind Kind
) const {
1324 return hasAttribute(ArgNo
+ FirstArgIndex
, Kind
);
1327 bool AttributeList::hasAttrSomewhere(Attribute::AttrKind Attr
,
1328 unsigned *Index
) const {
1329 if (!pImpl
) return false;
1331 for (unsigned I
= index_begin(), E
= index_end(); I
!= E
; ++I
) {
1332 if (hasAttribute(I
, Attr
)) {
1342 Attribute
AttributeList::getAttribute(unsigned Index
,
1343 Attribute::AttrKind Kind
) const {
1344 return getAttributes(Index
).getAttribute(Kind
);
1347 Attribute
AttributeList::getAttribute(unsigned Index
, StringRef Kind
) const {
1348 return getAttributes(Index
).getAttribute(Kind
);
1351 MaybeAlign
AttributeList::getRetAlignment() const {
1352 return getAttributes(ReturnIndex
).getAlignment();
1355 MaybeAlign
AttributeList::getParamAlignment(unsigned ArgNo
) const {
1356 return getAttributes(ArgNo
+ FirstArgIndex
).getAlignment();
1359 Type
*AttributeList::getParamByValType(unsigned Index
) const {
1360 return getAttributes(Index
+FirstArgIndex
).getByValType();
1363 MaybeAlign
AttributeList::getStackAlignment(unsigned Index
) const {
1364 return getAttributes(Index
).getStackAlignment();
1367 uint64_t AttributeList::getDereferenceableBytes(unsigned Index
) const {
1368 return getAttributes(Index
).getDereferenceableBytes();
1371 uint64_t AttributeList::getDereferenceableOrNullBytes(unsigned Index
) const {
1372 return getAttributes(Index
).getDereferenceableOrNullBytes();
1375 std::pair
<unsigned, Optional
<unsigned>>
1376 AttributeList::getAllocSizeArgs(unsigned Index
) const {
1377 return getAttributes(Index
).getAllocSizeArgs();
1380 std::string
AttributeList::getAsString(unsigned Index
, bool InAttrGrp
) const {
1381 return getAttributes(Index
).getAsString(InAttrGrp
);
1384 AttributeSet
AttributeList::getAttributes(unsigned Index
) const {
1385 Index
= attrIdxToArrayIdx(Index
);
1386 if (!pImpl
|| Index
>= getNumAttrSets())
1388 return pImpl
->begin()[Index
];
1391 AttributeList::iterator
AttributeList::begin() const {
1392 return pImpl
? pImpl
->begin() : nullptr;
1395 AttributeList::iterator
AttributeList::end() const {
1396 return pImpl
? pImpl
->end() : nullptr;
1399 //===----------------------------------------------------------------------===//
1400 // AttributeList Introspection Methods
1401 //===----------------------------------------------------------------------===//
1403 unsigned AttributeList::getNumAttrSets() const {
1404 return pImpl
? pImpl
->NumAttrSets
: 0;
1407 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1408 LLVM_DUMP_METHOD
void AttributeList::dump() const {
1411 for (unsigned i
= index_begin(), e
= index_end(); i
!= e
; ++i
) {
1412 if (getAttributes(i
).hasAttributes())
1413 dbgs() << " { " << i
<< " => " << getAsString(i
) << " }\n";
1420 //===----------------------------------------------------------------------===//
1421 // AttrBuilder Method Implementations
1422 //===----------------------------------------------------------------------===//
1424 // FIXME: Remove this ctor, use AttributeSet.
1425 AttrBuilder::AttrBuilder(AttributeList AL
, unsigned Index
) {
1426 AttributeSet AS
= AL
.getAttributes(Index
);
1427 for (const auto &A
: AS
)
1431 AttrBuilder::AttrBuilder(AttributeSet AS
) {
1432 for (const auto &A
: AS
)
1436 void AttrBuilder::clear() {
1438 TargetDepAttrs
.clear();
1440 StackAlignment
.reset();
1441 DerefBytes
= DerefOrNullBytes
= 0;
1443 ByValType
= nullptr;
1446 AttrBuilder
&AttrBuilder::addAttribute(Attribute::AttrKind Val
) {
1447 assert((unsigned)Val
< Attribute::EndAttrKinds
&& "Attribute out of range!");
1448 assert(Val
!= Attribute::Alignment
&& Val
!= Attribute::StackAlignment
&&
1449 Val
!= Attribute::Dereferenceable
&& Val
!= Attribute::AllocSize
&&
1450 "Adding integer attribute without adding a value!");
1455 AttrBuilder
&AttrBuilder::addAttribute(Attribute Attr
) {
1456 if (Attr
.isStringAttribute()) {
1457 addAttribute(Attr
.getKindAsString(), Attr
.getValueAsString());
1461 Attribute::AttrKind Kind
= Attr
.getKindAsEnum();
1464 if (Kind
== Attribute::Alignment
)
1465 Alignment
= Attr
.getAlignment();
1466 else if (Kind
== Attribute::StackAlignment
)
1467 StackAlignment
= Attr
.getStackAlignment();
1468 else if (Kind
== Attribute::ByVal
)
1469 ByValType
= Attr
.getValueAsType();
1470 else if (Kind
== Attribute::Dereferenceable
)
1471 DerefBytes
= Attr
.getDereferenceableBytes();
1472 else if (Kind
== Attribute::DereferenceableOrNull
)
1473 DerefOrNullBytes
= Attr
.getDereferenceableOrNullBytes();
1474 else if (Kind
== Attribute::AllocSize
)
1475 AllocSizeArgs
= Attr
.getValueAsInt();
1479 AttrBuilder
&AttrBuilder::addAttribute(StringRef A
, StringRef V
) {
1480 TargetDepAttrs
[A
] = V
;
1484 AttrBuilder
&AttrBuilder::removeAttribute(Attribute::AttrKind Val
) {
1485 assert((unsigned)Val
< Attribute::EndAttrKinds
&& "Attribute out of range!");
1488 if (Val
== Attribute::Alignment
)
1490 else if (Val
== Attribute::StackAlignment
)
1491 StackAlignment
.reset();
1492 else if (Val
== Attribute::ByVal
)
1493 ByValType
= nullptr;
1494 else if (Val
== Attribute::Dereferenceable
)
1496 else if (Val
== Attribute::DereferenceableOrNull
)
1497 DerefOrNullBytes
= 0;
1498 else if (Val
== Attribute::AllocSize
)
1504 AttrBuilder
&AttrBuilder::removeAttributes(AttributeList A
, uint64_t Index
) {
1505 remove(A
.getAttributes(Index
));
1509 AttrBuilder
&AttrBuilder::removeAttribute(StringRef A
) {
1510 auto I
= TargetDepAttrs
.find(A
);
1511 if (I
!= TargetDepAttrs
.end())
1512 TargetDepAttrs
.erase(I
);
1516 std::pair
<unsigned, Optional
<unsigned>> AttrBuilder::getAllocSizeArgs() const {
1517 return unpackAllocSizeArgs(AllocSizeArgs
);
1520 AttrBuilder
&AttrBuilder::addAlignmentAttr(MaybeAlign Align
) {
1524 assert(*Align
<= 0x40000000 && "Alignment too large.");
1526 Attrs
[Attribute::Alignment
] = true;
1531 AttrBuilder
&AttrBuilder::addStackAlignmentAttr(MaybeAlign Align
) {
1532 // Default alignment, allow the target to define how to align it.
1536 assert(*Align
<= 0x100 && "Alignment too large.");
1538 Attrs
[Attribute::StackAlignment
] = true;
1539 StackAlignment
= Align
;
1543 AttrBuilder
&AttrBuilder::addDereferenceableAttr(uint64_t Bytes
) {
1544 if (Bytes
== 0) return *this;
1546 Attrs
[Attribute::Dereferenceable
] = true;
1551 AttrBuilder
&AttrBuilder::addDereferenceableOrNullAttr(uint64_t Bytes
) {
1555 Attrs
[Attribute::DereferenceableOrNull
] = true;
1556 DerefOrNullBytes
= Bytes
;
1560 AttrBuilder
&AttrBuilder::addAllocSizeAttr(unsigned ElemSize
,
1561 const Optional
<unsigned> &NumElems
) {
1562 return addAllocSizeAttrFromRawRepr(packAllocSizeArgs(ElemSize
, NumElems
));
1565 AttrBuilder
&AttrBuilder::addAllocSizeAttrFromRawRepr(uint64_t RawArgs
) {
1566 // (0, 0) is our "not present" value, so we need to check for it here.
1567 assert(RawArgs
&& "Invalid allocsize arguments -- given allocsize(0, 0)");
1569 Attrs
[Attribute::AllocSize
] = true;
1570 // Reuse existing machinery to store this as a single 64-bit integer so we can
1571 // save a few bytes over using a pair<unsigned, Optional<unsigned>>.
1572 AllocSizeArgs
= RawArgs
;
1576 AttrBuilder
&AttrBuilder::addByValAttr(Type
*Ty
) {
1577 Attrs
[Attribute::ByVal
] = true;
1582 AttrBuilder
&AttrBuilder::merge(const AttrBuilder
&B
) {
1583 // FIXME: What if both have alignments, but they don't match?!
1585 Alignment
= B
.Alignment
;
1587 if (!StackAlignment
)
1588 StackAlignment
= B
.StackAlignment
;
1591 DerefBytes
= B
.DerefBytes
;
1593 if (!DerefOrNullBytes
)
1594 DerefOrNullBytes
= B
.DerefOrNullBytes
;
1597 AllocSizeArgs
= B
.AllocSizeArgs
;
1600 ByValType
= B
.ByValType
;
1604 for (auto I
: B
.td_attrs())
1605 TargetDepAttrs
[I
.first
] = I
.second
;
1610 AttrBuilder
&AttrBuilder::remove(const AttrBuilder
&B
) {
1611 // FIXME: What if both have alignments, but they don't match?!
1615 if (B
.StackAlignment
)
1616 StackAlignment
.reset();
1621 if (B
.DerefOrNullBytes
)
1622 DerefOrNullBytes
= 0;
1624 if (B
.AllocSizeArgs
)
1628 ByValType
= nullptr;
1632 for (auto I
: B
.td_attrs())
1633 TargetDepAttrs
.erase(I
.first
);
1638 bool AttrBuilder::overlaps(const AttrBuilder
&B
) const {
1639 // First check if any of the target independent attributes overlap.
1640 if ((Attrs
& B
.Attrs
).any())
1643 // Then check if any target dependent ones do.
1644 for (const auto &I
: td_attrs())
1645 if (B
.contains(I
.first
))
1651 bool AttrBuilder::contains(StringRef A
) const {
1652 return TargetDepAttrs
.find(A
) != TargetDepAttrs
.end();
1655 bool AttrBuilder::hasAttributes() const {
1656 return !Attrs
.none() || !TargetDepAttrs
.empty();
1659 bool AttrBuilder::hasAttributes(AttributeList AL
, uint64_t Index
) const {
1660 AttributeSet AS
= AL
.getAttributes(Index
);
1662 for (const auto Attr
: AS
) {
1663 if (Attr
.isEnumAttribute() || Attr
.isIntAttribute()) {
1664 if (contains(Attr
.getKindAsEnum()))
1667 assert(Attr
.isStringAttribute() && "Invalid attribute kind!");
1668 return contains(Attr
.getKindAsString());
1675 bool AttrBuilder::hasAlignmentAttr() const {
1676 return Alignment
!= 0;
1679 bool AttrBuilder::operator==(const AttrBuilder
&B
) {
1680 if (Attrs
!= B
.Attrs
)
1683 for (td_const_iterator I
= TargetDepAttrs
.begin(),
1684 E
= TargetDepAttrs
.end(); I
!= E
; ++I
)
1685 if (B
.TargetDepAttrs
.find(I
->first
) == B
.TargetDepAttrs
.end())
1688 return Alignment
== B
.Alignment
&& StackAlignment
== B
.StackAlignment
&&
1689 DerefBytes
== B
.DerefBytes
&& ByValType
== B
.ByValType
;
1692 //===----------------------------------------------------------------------===//
1693 // AttributeFuncs Function Defintions
1694 //===----------------------------------------------------------------------===//
1696 /// Which attributes cannot be applied to a type.
1697 AttrBuilder
AttributeFuncs::typeIncompatible(Type
*Ty
) {
1698 AttrBuilder Incompatible
;
1700 if (!Ty
->isIntegerTy())
1701 // Attribute that only apply to integers.
1702 Incompatible
.addAttribute(Attribute::SExt
)
1703 .addAttribute(Attribute::ZExt
);
1705 if (!Ty
->isPointerTy())
1706 // Attribute that only apply to pointers.
1707 Incompatible
.addAttribute(Attribute::ByVal
)
1708 .addAttribute(Attribute::Nest
)
1709 .addAttribute(Attribute::NoAlias
)
1710 .addAttribute(Attribute::NoCapture
)
1711 .addAttribute(Attribute::NonNull
)
1712 .addDereferenceableAttr(1) // the int here is ignored
1713 .addDereferenceableOrNullAttr(1) // the int here is ignored
1714 .addAttribute(Attribute::ReadNone
)
1715 .addAttribute(Attribute::ReadOnly
)
1716 .addAttribute(Attribute::StructRet
)
1717 .addAttribute(Attribute::InAlloca
);
1719 return Incompatible
;
1722 template<typename AttrClass
>
1723 static bool isEqual(const Function
&Caller
, const Function
&Callee
) {
1724 return Caller
.getFnAttribute(AttrClass::getKind()) ==
1725 Callee
.getFnAttribute(AttrClass::getKind());
1728 /// Compute the logical AND of the attributes of the caller and the
1731 /// This function sets the caller's attribute to false if the callee's attribute
1733 template<typename AttrClass
>
1734 static void setAND(Function
&Caller
, const Function
&Callee
) {
1735 if (AttrClass::isSet(Caller
, AttrClass::getKind()) &&
1736 !AttrClass::isSet(Callee
, AttrClass::getKind()))
1737 AttrClass::set(Caller
, AttrClass::getKind(), false);
1740 /// Compute the logical OR of the attributes of the caller and the
1743 /// This function sets the caller's attribute to true if the callee's attribute
1745 template<typename AttrClass
>
1746 static void setOR(Function
&Caller
, const Function
&Callee
) {
1747 if (!AttrClass::isSet(Caller
, AttrClass::getKind()) &&
1748 AttrClass::isSet(Callee
, AttrClass::getKind()))
1749 AttrClass::set(Caller
, AttrClass::getKind(), true);
1752 /// If the inlined function had a higher stack protection level than the
1753 /// calling function, then bump up the caller's stack protection level.
1754 static void adjustCallerSSPLevel(Function
&Caller
, const Function
&Callee
) {
1755 // If upgrading the SSP attribute, clear out the old SSP Attributes first.
1756 // Having multiple SSP attributes doesn't actually hurt, but it adds useless
1757 // clutter to the IR.
1758 AttrBuilder OldSSPAttr
;
1759 OldSSPAttr
.addAttribute(Attribute::StackProtect
)
1760 .addAttribute(Attribute::StackProtectStrong
)
1761 .addAttribute(Attribute::StackProtectReq
);
1763 if (Callee
.hasFnAttribute(Attribute::StackProtectReq
)) {
1764 Caller
.removeAttributes(AttributeList::FunctionIndex
, OldSSPAttr
);
1765 Caller
.addFnAttr(Attribute::StackProtectReq
);
1766 } else if (Callee
.hasFnAttribute(Attribute::StackProtectStrong
) &&
1767 !Caller
.hasFnAttribute(Attribute::StackProtectReq
)) {
1768 Caller
.removeAttributes(AttributeList::FunctionIndex
, OldSSPAttr
);
1769 Caller
.addFnAttr(Attribute::StackProtectStrong
);
1770 } else if (Callee
.hasFnAttribute(Attribute::StackProtect
) &&
1771 !Caller
.hasFnAttribute(Attribute::StackProtectReq
) &&
1772 !Caller
.hasFnAttribute(Attribute::StackProtectStrong
))
1773 Caller
.addFnAttr(Attribute::StackProtect
);
1776 /// If the inlined function required stack probes, then ensure that
1777 /// the calling function has those too.
1778 static void adjustCallerStackProbes(Function
&Caller
, const Function
&Callee
) {
1779 if (!Caller
.hasFnAttribute("probe-stack") &&
1780 Callee
.hasFnAttribute("probe-stack")) {
1781 Caller
.addFnAttr(Callee
.getFnAttribute("probe-stack"));
1785 /// If the inlined function defines the size of guard region
1786 /// on the stack, then ensure that the calling function defines a guard region
1787 /// that is no larger.
1789 adjustCallerStackProbeSize(Function
&Caller
, const Function
&Callee
) {
1790 if (Callee
.hasFnAttribute("stack-probe-size")) {
1791 uint64_t CalleeStackProbeSize
;
1792 Callee
.getFnAttribute("stack-probe-size")
1794 .getAsInteger(0, CalleeStackProbeSize
);
1795 if (Caller
.hasFnAttribute("stack-probe-size")) {
1796 uint64_t CallerStackProbeSize
;
1797 Caller
.getFnAttribute("stack-probe-size")
1799 .getAsInteger(0, CallerStackProbeSize
);
1800 if (CallerStackProbeSize
> CalleeStackProbeSize
) {
1801 Caller
.addFnAttr(Callee
.getFnAttribute("stack-probe-size"));
1804 Caller
.addFnAttr(Callee
.getFnAttribute("stack-probe-size"));
1809 /// If the inlined function defines a min legal vector width, then ensure
1810 /// the calling function has the same or larger min legal vector width. If the
1811 /// caller has the attribute, but the callee doesn't, we need to remove the
1812 /// attribute from the caller since we can't make any guarantees about the
1813 /// caller's requirements.
1814 /// This function is called after the inlining decision has been made so we have
1815 /// to merge the attribute this way. Heuristics that would use
1816 /// min-legal-vector-width to determine inline compatibility would need to be
1817 /// handled as part of inline cost analysis.
1819 adjustMinLegalVectorWidth(Function
&Caller
, const Function
&Callee
) {
1820 if (Caller
.hasFnAttribute("min-legal-vector-width")) {
1821 if (Callee
.hasFnAttribute("min-legal-vector-width")) {
1822 uint64_t CallerVectorWidth
;
1823 Caller
.getFnAttribute("min-legal-vector-width")
1825 .getAsInteger(0, CallerVectorWidth
);
1826 uint64_t CalleeVectorWidth
;
1827 Callee
.getFnAttribute("min-legal-vector-width")
1829 .getAsInteger(0, CalleeVectorWidth
);
1830 if (CallerVectorWidth
< CalleeVectorWidth
)
1831 Caller
.addFnAttr(Callee
.getFnAttribute("min-legal-vector-width"));
1833 // If the callee doesn't have the attribute then we don't know anything
1834 // and must drop the attribute from the caller.
1835 Caller
.removeFnAttr("min-legal-vector-width");
1840 /// If the inlined function has "null-pointer-is-valid=true" attribute,
1841 /// set this attribute in the caller post inlining.
1843 adjustNullPointerValidAttr(Function
&Caller
, const Function
&Callee
) {
1844 if (Callee
.nullPointerIsDefined() && !Caller
.nullPointerIsDefined()) {
1845 Caller
.addFnAttr(Callee
.getFnAttribute("null-pointer-is-valid"));
1849 #define GET_ATTR_COMPAT_FUNC
1850 #include "AttributesCompatFunc.inc"
1852 bool AttributeFuncs::areInlineCompatible(const Function
&Caller
,
1853 const Function
&Callee
) {
1854 return hasCompatibleFnAttrs(Caller
, Callee
);
1857 void AttributeFuncs::mergeAttributesForInlining(Function
&Caller
,
1858 const Function
&Callee
) {
1859 mergeFnAttrs(Caller
, Callee
);