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
, uint64_t Align
) {
146 assert(isPowerOf2_32(Align
) && "Alignment must be a power of two.");
147 assert(Align
<= 0x40000000 && "Alignment too large.");
148 return get(Context
, Alignment
, Align
);
151 Attribute
Attribute::getWithStackAlignment(LLVMContext
&Context
,
153 assert(isPowerOf2_32(Align
) && "Alignment must be a power of two.");
154 assert(Align
<= 0x100 && "Alignment too large.");
155 return get(Context
, StackAlignment
, Align
);
158 Attribute
Attribute::getWithDereferenceableBytes(LLVMContext
&Context
,
160 assert(Bytes
&& "Bytes must be non-zero.");
161 return get(Context
, Dereferenceable
, Bytes
);
164 Attribute
Attribute::getWithDereferenceableOrNullBytes(LLVMContext
&Context
,
166 assert(Bytes
&& "Bytes must be non-zero.");
167 return get(Context
, DereferenceableOrNull
, Bytes
);
170 Attribute
Attribute::getWithByValType(LLVMContext
&Context
, Type
*Ty
) {
171 return get(Context
, ByVal
, Ty
);
175 Attribute::getWithAllocSizeArgs(LLVMContext
&Context
, unsigned ElemSizeArg
,
176 const Optional
<unsigned> &NumElemsArg
) {
177 assert(!(ElemSizeArg
== 0 && NumElemsArg
&& *NumElemsArg
== 0) &&
178 "Invalid allocsize arguments -- given allocsize(0, 0)");
179 return get(Context
, AllocSize
, packAllocSizeArgs(ElemSizeArg
, NumElemsArg
));
182 //===----------------------------------------------------------------------===//
183 // Attribute Accessor Methods
184 //===----------------------------------------------------------------------===//
186 bool Attribute::isEnumAttribute() const {
187 return pImpl
&& pImpl
->isEnumAttribute();
190 bool Attribute::isIntAttribute() const {
191 return pImpl
&& pImpl
->isIntAttribute();
194 bool Attribute::isStringAttribute() const {
195 return pImpl
&& pImpl
->isStringAttribute();
198 bool Attribute::isTypeAttribute() const {
199 return pImpl
&& pImpl
->isTypeAttribute();
202 Attribute::AttrKind
Attribute::getKindAsEnum() const {
203 if (!pImpl
) return None
;
204 assert((isEnumAttribute() || isIntAttribute() || isTypeAttribute()) &&
205 "Invalid attribute type to get the kind as an enum!");
206 return pImpl
->getKindAsEnum();
209 uint64_t Attribute::getValueAsInt() const {
210 if (!pImpl
) return 0;
211 assert(isIntAttribute() &&
212 "Expected the attribute to be an integer attribute!");
213 return pImpl
->getValueAsInt();
216 StringRef
Attribute::getKindAsString() const {
217 if (!pImpl
) return {};
218 assert(isStringAttribute() &&
219 "Invalid attribute type to get the kind as a string!");
220 return pImpl
->getKindAsString();
223 StringRef
Attribute::getValueAsString() const {
224 if (!pImpl
) return {};
225 assert(isStringAttribute() &&
226 "Invalid attribute type to get the value as a string!");
227 return pImpl
->getValueAsString();
230 Type
*Attribute::getValueAsType() const {
231 if (!pImpl
) return {};
232 assert(isTypeAttribute() &&
233 "Invalid attribute type to get the value as a type!");
234 return pImpl
->getValueAsType();
238 bool Attribute::hasAttribute(AttrKind Kind
) const {
239 return (pImpl
&& pImpl
->hasAttribute(Kind
)) || (!pImpl
&& Kind
== None
);
242 bool Attribute::hasAttribute(StringRef Kind
) const {
243 if (!isStringAttribute()) return false;
244 return pImpl
&& pImpl
->hasAttribute(Kind
);
247 unsigned Attribute::getAlignment() const {
248 assert(hasAttribute(Attribute::Alignment
) &&
249 "Trying to get alignment from non-alignment attribute!");
250 return pImpl
->getValueAsInt();
253 unsigned Attribute::getStackAlignment() const {
254 assert(hasAttribute(Attribute::StackAlignment
) &&
255 "Trying to get alignment from non-alignment attribute!");
256 return pImpl
->getValueAsInt();
259 uint64_t Attribute::getDereferenceableBytes() const {
260 assert(hasAttribute(Attribute::Dereferenceable
) &&
261 "Trying to get dereferenceable bytes from "
262 "non-dereferenceable attribute!");
263 return pImpl
->getValueAsInt();
266 uint64_t Attribute::getDereferenceableOrNullBytes() const {
267 assert(hasAttribute(Attribute::DereferenceableOrNull
) &&
268 "Trying to get dereferenceable bytes from "
269 "non-dereferenceable attribute!");
270 return pImpl
->getValueAsInt();
273 std::pair
<unsigned, Optional
<unsigned>> Attribute::getAllocSizeArgs() const {
274 assert(hasAttribute(Attribute::AllocSize
) &&
275 "Trying to get allocsize args from non-allocsize attribute");
276 return unpackAllocSizeArgs(pImpl
->getValueAsInt());
279 std::string
Attribute::getAsString(bool InAttrGrp
) const {
280 if (!pImpl
) return {};
282 if (hasAttribute(Attribute::SanitizeAddress
))
283 return "sanitize_address";
284 if (hasAttribute(Attribute::SanitizeHWAddress
))
285 return "sanitize_hwaddress";
286 if (hasAttribute(Attribute::AlwaysInline
))
287 return "alwaysinline";
288 if (hasAttribute(Attribute::ArgMemOnly
))
290 if (hasAttribute(Attribute::Builtin
))
292 if (hasAttribute(Attribute::Convergent
))
294 if (hasAttribute(Attribute::SwiftError
))
296 if (hasAttribute(Attribute::SwiftSelf
))
298 if (hasAttribute(Attribute::InaccessibleMemOnly
))
299 return "inaccessiblememonly";
300 if (hasAttribute(Attribute::InaccessibleMemOrArgMemOnly
))
301 return "inaccessiblemem_or_argmemonly";
302 if (hasAttribute(Attribute::InAlloca
))
304 if (hasAttribute(Attribute::InlineHint
))
306 if (hasAttribute(Attribute::InReg
))
308 if (hasAttribute(Attribute::JumpTable
))
310 if (hasAttribute(Attribute::MinSize
))
312 if (hasAttribute(Attribute::Naked
))
314 if (hasAttribute(Attribute::Nest
))
316 if (hasAttribute(Attribute::NoAlias
))
318 if (hasAttribute(Attribute::NoBuiltin
))
320 if (hasAttribute(Attribute::NoCapture
))
322 if (hasAttribute(Attribute::NoDuplicate
))
323 return "noduplicate";
324 if (hasAttribute(Attribute::NoFree
))
326 if (hasAttribute(Attribute::NoImplicitFloat
))
327 return "noimplicitfloat";
328 if (hasAttribute(Attribute::NoInline
))
330 if (hasAttribute(Attribute::NonLazyBind
))
331 return "nonlazybind";
332 if (hasAttribute(Attribute::NonNull
))
334 if (hasAttribute(Attribute::NoRedZone
))
336 if (hasAttribute(Attribute::NoReturn
))
338 if (hasAttribute(Attribute::NoSync
))
340 if (hasAttribute(Attribute::WillReturn
))
342 if (hasAttribute(Attribute::NoCfCheck
))
344 if (hasAttribute(Attribute::NoRecurse
))
346 if (hasAttribute(Attribute::NoUnwind
))
348 if (hasAttribute(Attribute::OptForFuzzing
))
349 return "optforfuzzing";
350 if (hasAttribute(Attribute::OptimizeNone
))
352 if (hasAttribute(Attribute::OptimizeForSize
))
354 if (hasAttribute(Attribute::ReadNone
))
356 if (hasAttribute(Attribute::ReadOnly
))
358 if (hasAttribute(Attribute::WriteOnly
))
360 if (hasAttribute(Attribute::Returned
))
362 if (hasAttribute(Attribute::ReturnsTwice
))
363 return "returns_twice";
364 if (hasAttribute(Attribute::SExt
))
366 if (hasAttribute(Attribute::SpeculativeLoadHardening
))
367 return "speculative_load_hardening";
368 if (hasAttribute(Attribute::Speculatable
))
369 return "speculatable";
370 if (hasAttribute(Attribute::StackProtect
))
372 if (hasAttribute(Attribute::StackProtectReq
))
374 if (hasAttribute(Attribute::StackProtectStrong
))
376 if (hasAttribute(Attribute::SafeStack
))
378 if (hasAttribute(Attribute::ShadowCallStack
))
379 return "shadowcallstack";
380 if (hasAttribute(Attribute::StrictFP
))
382 if (hasAttribute(Attribute::StructRet
))
384 if (hasAttribute(Attribute::SanitizeThread
))
385 return "sanitize_thread";
386 if (hasAttribute(Attribute::SanitizeMemory
))
387 return "sanitize_memory";
388 if (hasAttribute(Attribute::UWTable
))
390 if (hasAttribute(Attribute::ZExt
))
392 if (hasAttribute(Attribute::Cold
))
394 if (hasAttribute(Attribute::ImmArg
))
397 if (hasAttribute(Attribute::ByVal
)) {
400 if (Type
*Ty
= getValueAsType()) {
401 raw_string_ostream
OS(Result
);
403 Ty
->print(OS
, false, true);
410 // FIXME: These should be output like this:
415 if (hasAttribute(Attribute::Alignment
)) {
418 Result
+= (InAttrGrp
) ? "=" : " ";
419 Result
+= utostr(getValueAsInt());
423 auto AttrWithBytesToString
= [&](const char *Name
) {
428 Result
+= utostr(getValueAsInt());
431 Result
+= utostr(getValueAsInt());
437 if (hasAttribute(Attribute::StackAlignment
))
438 return AttrWithBytesToString("alignstack");
440 if (hasAttribute(Attribute::Dereferenceable
))
441 return AttrWithBytesToString("dereferenceable");
443 if (hasAttribute(Attribute::DereferenceableOrNull
))
444 return AttrWithBytesToString("dereferenceable_or_null");
446 if (hasAttribute(Attribute::AllocSize
)) {
448 Optional
<unsigned> NumElems
;
449 std::tie(ElemSize
, NumElems
) = getAllocSizeArgs();
451 std::string Result
= "allocsize(";
452 Result
+= utostr(ElemSize
);
453 if (NumElems
.hasValue()) {
455 Result
+= utostr(*NumElems
);
461 // Convert target-dependent attributes to strings of the form:
466 if (isStringAttribute()) {
468 Result
+= (Twine('"') + getKindAsString() + Twine('"')).str();
470 std::string AttrVal
= pImpl
->getValueAsString();
471 if (AttrVal
.empty()) return Result
;
473 // Since some attribute strings contain special characters that cannot be
474 // printable, those have to be escaped to make the attribute value printable
475 // as is. e.g. "\01__gnu_mcount_nc"
477 raw_string_ostream
OS(Result
);
479 printEscapedString(AttrVal
, OS
);
485 llvm_unreachable("Unknown attribute");
488 bool Attribute::operator<(Attribute A
) const {
489 if (!pImpl
&& !A
.pImpl
) return false;
490 if (!pImpl
) return true;
491 if (!A
.pImpl
) return false;
492 return *pImpl
< *A
.pImpl
;
495 //===----------------------------------------------------------------------===//
496 // AttributeImpl Definition
497 //===----------------------------------------------------------------------===//
499 // Pin the vtables to this file.
500 AttributeImpl::~AttributeImpl() = default;
502 void EnumAttributeImpl::anchor() {}
504 void IntAttributeImpl::anchor() {}
506 void StringAttributeImpl::anchor() {}
508 void TypeAttributeImpl::anchor() {}
510 bool AttributeImpl::hasAttribute(Attribute::AttrKind A
) const {
511 if (isStringAttribute()) return false;
512 return getKindAsEnum() == A
;
515 bool AttributeImpl::hasAttribute(StringRef Kind
) const {
516 if (!isStringAttribute()) return false;
517 return getKindAsString() == Kind
;
520 Attribute::AttrKind
AttributeImpl::getKindAsEnum() const {
521 assert(isEnumAttribute() || isIntAttribute() || isTypeAttribute());
522 return static_cast<const EnumAttributeImpl
*>(this)->getEnumKind();
525 uint64_t AttributeImpl::getValueAsInt() const {
526 assert(isIntAttribute());
527 return static_cast<const IntAttributeImpl
*>(this)->getValue();
530 StringRef
AttributeImpl::getKindAsString() const {
531 assert(isStringAttribute());
532 return static_cast<const StringAttributeImpl
*>(this)->getStringKind();
535 StringRef
AttributeImpl::getValueAsString() const {
536 assert(isStringAttribute());
537 return static_cast<const StringAttributeImpl
*>(this)->getStringValue();
540 Type
*AttributeImpl::getValueAsType() const {
541 assert(isTypeAttribute());
542 return static_cast<const TypeAttributeImpl
*>(this)->getTypeValue();
545 bool AttributeImpl::operator<(const AttributeImpl
&AI
) const {
546 // This sorts the attributes with Attribute::AttrKinds coming first (sorted
547 // relative to their enum value) and then strings.
548 if (isEnumAttribute()) {
549 if (AI
.isEnumAttribute()) return getKindAsEnum() < AI
.getKindAsEnum();
550 if (AI
.isIntAttribute()) return true;
551 if (AI
.isStringAttribute()) return true;
552 if (AI
.isTypeAttribute()) return true;
555 if (isTypeAttribute()) {
556 if (AI
.isEnumAttribute()) return false;
557 if (AI
.isTypeAttribute()) {
558 assert(getKindAsEnum() != AI
.getKindAsEnum() &&
559 "Comparison of types would be unstable");
560 return getKindAsEnum() < AI
.getKindAsEnum();
562 if (AI
.isIntAttribute()) return true;
563 if (AI
.isStringAttribute()) return true;
566 if (isIntAttribute()) {
567 if (AI
.isEnumAttribute()) return false;
568 if (AI
.isTypeAttribute()) return false;
569 if (AI
.isIntAttribute()) {
570 if (getKindAsEnum() == AI
.getKindAsEnum())
571 return getValueAsInt() < AI
.getValueAsInt();
572 return getKindAsEnum() < AI
.getKindAsEnum();
574 if (AI
.isStringAttribute()) return true;
577 assert(isStringAttribute());
578 if (AI
.isEnumAttribute()) return false;
579 if (AI
.isTypeAttribute()) return false;
580 if (AI
.isIntAttribute()) return false;
581 if (getKindAsString() == AI
.getKindAsString())
582 return getValueAsString() < AI
.getValueAsString();
583 return getKindAsString() < AI
.getKindAsString();
586 //===----------------------------------------------------------------------===//
587 // AttributeSet Definition
588 //===----------------------------------------------------------------------===//
590 AttributeSet
AttributeSet::get(LLVMContext
&C
, const AttrBuilder
&B
) {
591 return AttributeSet(AttributeSetNode::get(C
, B
));
594 AttributeSet
AttributeSet::get(LLVMContext
&C
, ArrayRef
<Attribute
> Attrs
) {
595 return AttributeSet(AttributeSetNode::get(C
, Attrs
));
598 AttributeSet
AttributeSet::addAttribute(LLVMContext
&C
,
599 Attribute::AttrKind Kind
) const {
600 if (hasAttribute(Kind
)) return *this;
602 B
.addAttribute(Kind
);
603 return addAttributes(C
, AttributeSet::get(C
, B
));
606 AttributeSet
AttributeSet::addAttribute(LLVMContext
&C
, StringRef Kind
,
607 StringRef Value
) const {
609 B
.addAttribute(Kind
, Value
);
610 return addAttributes(C
, AttributeSet::get(C
, B
));
613 AttributeSet
AttributeSet::addAttributes(LLVMContext
&C
,
614 const AttributeSet AS
) const {
615 if (!hasAttributes())
618 if (!AS
.hasAttributes())
622 for (const auto I
: *this)
628 AttributeSet
AttributeSet::removeAttribute(LLVMContext
&C
,
629 Attribute::AttrKind Kind
) const {
630 if (!hasAttribute(Kind
)) return *this;
631 AttrBuilder
B(*this);
632 B
.removeAttribute(Kind
);
636 AttributeSet
AttributeSet::removeAttribute(LLVMContext
&C
,
637 StringRef Kind
) const {
638 if (!hasAttribute(Kind
)) return *this;
639 AttrBuilder
B(*this);
640 B
.removeAttribute(Kind
);
644 AttributeSet
AttributeSet::removeAttributes(LLVMContext
&C
,
645 const AttrBuilder
&Attrs
) const {
646 AttrBuilder
B(*this);
651 unsigned AttributeSet::getNumAttributes() const {
652 return SetNode
? SetNode
->getNumAttributes() : 0;
655 bool AttributeSet::hasAttribute(Attribute::AttrKind Kind
) const {
656 return SetNode
? SetNode
->hasAttribute(Kind
) : false;
659 bool AttributeSet::hasAttribute(StringRef Kind
) const {
660 return SetNode
? SetNode
->hasAttribute(Kind
) : false;
663 Attribute
AttributeSet::getAttribute(Attribute::AttrKind Kind
) const {
664 return SetNode
? SetNode
->getAttribute(Kind
) : Attribute();
667 Attribute
AttributeSet::getAttribute(StringRef Kind
) const {
668 return SetNode
? SetNode
->getAttribute(Kind
) : Attribute();
671 unsigned AttributeSet::getAlignment() const {
672 return SetNode
? SetNode
->getAlignment() : 0;
675 unsigned AttributeSet::getStackAlignment() const {
676 return SetNode
? SetNode
->getStackAlignment() : 0;
679 uint64_t AttributeSet::getDereferenceableBytes() const {
680 return SetNode
? SetNode
->getDereferenceableBytes() : 0;
683 uint64_t AttributeSet::getDereferenceableOrNullBytes() const {
684 return SetNode
? SetNode
->getDereferenceableOrNullBytes() : 0;
687 Type
*AttributeSet::getByValType() const {
688 return SetNode
? SetNode
->getByValType() : nullptr;
691 std::pair
<unsigned, Optional
<unsigned>> AttributeSet::getAllocSizeArgs() const {
692 return SetNode
? SetNode
->getAllocSizeArgs()
693 : std::pair
<unsigned, Optional
<unsigned>>(0, 0);
696 std::string
AttributeSet::getAsString(bool InAttrGrp
) const {
697 return SetNode
? SetNode
->getAsString(InAttrGrp
) : "";
700 AttributeSet::iterator
AttributeSet::begin() const {
701 return SetNode
? SetNode
->begin() : nullptr;
704 AttributeSet::iterator
AttributeSet::end() const {
705 return SetNode
? SetNode
->end() : nullptr;
708 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
709 LLVM_DUMP_METHOD
void AttributeSet::dump() const {
712 dbgs() << getAsString(true) << " }\n";
716 //===----------------------------------------------------------------------===//
717 // AttributeSetNode Definition
718 //===----------------------------------------------------------------------===//
720 AttributeSetNode::AttributeSetNode(ArrayRef
<Attribute
> Attrs
)
721 : NumAttrs(Attrs
.size()) {
722 // There's memory after the node where we can store the entries in.
723 llvm::copy(Attrs
, getTrailingObjects
<Attribute
>());
725 static_assert(Attribute::EndAttrKinds
<=
726 sizeof(AvailableAttrs
) * CHAR_BIT
,
727 "Too many attributes");
729 for (const auto I
: *this) {
730 if (!I
.isStringAttribute()) {
731 Attribute::AttrKind Kind
= I
.getKindAsEnum();
732 AvailableAttrs
[Kind
/ 8] |= 1ULL << (Kind
% 8);
737 AttributeSetNode
*AttributeSetNode::get(LLVMContext
&C
,
738 ArrayRef
<Attribute
> Attrs
) {
742 // Otherwise, build a key to look up the existing attributes.
743 LLVMContextImpl
*pImpl
= C
.pImpl
;
746 SmallVector
<Attribute
, 8> SortedAttrs(Attrs
.begin(), Attrs
.end());
747 llvm::sort(SortedAttrs
);
749 for (const auto Attr
: SortedAttrs
)
753 AttributeSetNode
*PA
=
754 pImpl
->AttrsSetNodes
.FindNodeOrInsertPos(ID
, InsertPoint
);
756 // If we didn't find any existing attributes of the same shape then create a
757 // new one and insert it.
759 // Coallocate entries after the AttributeSetNode itself.
760 void *Mem
= ::operator new(totalSizeToAlloc
<Attribute
>(SortedAttrs
.size()));
761 PA
= new (Mem
) AttributeSetNode(SortedAttrs
);
762 pImpl
->AttrsSetNodes
.InsertNode(PA
, InsertPoint
);
765 // Return the AttributeSetNode that we found or created.
769 AttributeSetNode
*AttributeSetNode::get(LLVMContext
&C
, const AttrBuilder
&B
) {
770 // Add target-independent attributes.
771 SmallVector
<Attribute
, 8> Attrs
;
772 for (Attribute::AttrKind Kind
= Attribute::None
;
773 Kind
!= Attribute::EndAttrKinds
; Kind
= Attribute::AttrKind(Kind
+ 1)) {
774 if (!B
.contains(Kind
))
779 case Attribute::ByVal
:
780 Attr
= Attribute::getWithByValType(C
, B
.getByValType());
782 case Attribute::Alignment
:
783 Attr
= Attribute::getWithAlignment(C
, B
.getAlignment());
785 case Attribute::StackAlignment
:
786 Attr
= Attribute::getWithStackAlignment(C
, B
.getStackAlignment());
788 case Attribute::Dereferenceable
:
789 Attr
= Attribute::getWithDereferenceableBytes(
790 C
, B
.getDereferenceableBytes());
792 case Attribute::DereferenceableOrNull
:
793 Attr
= Attribute::getWithDereferenceableOrNullBytes(
794 C
, B
.getDereferenceableOrNullBytes());
796 case Attribute::AllocSize
: {
797 auto A
= B
.getAllocSizeArgs();
798 Attr
= Attribute::getWithAllocSizeArgs(C
, A
.first
, A
.second
);
802 Attr
= Attribute::get(C
, Kind
);
804 Attrs
.push_back(Attr
);
807 // Add target-dependent (string) attributes.
808 for (const auto &TDA
: B
.td_attrs())
809 Attrs
.emplace_back(Attribute::get(C
, TDA
.first
, TDA
.second
));
811 return get(C
, Attrs
);
814 bool AttributeSetNode::hasAttribute(StringRef Kind
) const {
815 for (const auto I
: *this)
816 if (I
.hasAttribute(Kind
))
821 Attribute
AttributeSetNode::getAttribute(Attribute::AttrKind Kind
) const {
822 if (hasAttribute(Kind
)) {
823 for (const auto I
: *this)
824 if (I
.hasAttribute(Kind
))
830 Attribute
AttributeSetNode::getAttribute(StringRef Kind
) const {
831 for (const auto I
: *this)
832 if (I
.hasAttribute(Kind
))
837 unsigned AttributeSetNode::getAlignment() const {
838 for (const auto I
: *this)
839 if (I
.hasAttribute(Attribute::Alignment
))
840 return I
.getAlignment();
844 unsigned AttributeSetNode::getStackAlignment() const {
845 for (const auto I
: *this)
846 if (I
.hasAttribute(Attribute::StackAlignment
))
847 return I
.getStackAlignment();
851 Type
*AttributeSetNode::getByValType() const {
852 for (const auto I
: *this)
853 if (I
.hasAttribute(Attribute::ByVal
))
854 return I
.getValueAsType();
858 uint64_t AttributeSetNode::getDereferenceableBytes() const {
859 for (const auto I
: *this)
860 if (I
.hasAttribute(Attribute::Dereferenceable
))
861 return I
.getDereferenceableBytes();
865 uint64_t AttributeSetNode::getDereferenceableOrNullBytes() const {
866 for (const auto I
: *this)
867 if (I
.hasAttribute(Attribute::DereferenceableOrNull
))
868 return I
.getDereferenceableOrNullBytes();
872 std::pair
<unsigned, Optional
<unsigned>>
873 AttributeSetNode::getAllocSizeArgs() const {
874 for (const auto I
: *this)
875 if (I
.hasAttribute(Attribute::AllocSize
))
876 return I
.getAllocSizeArgs();
877 return std::make_pair(0, 0);
880 std::string
AttributeSetNode::getAsString(bool InAttrGrp
) const {
882 for (iterator I
= begin(), E
= end(); I
!= E
; ++I
) {
885 Str
+= I
->getAsString(InAttrGrp
);
890 //===----------------------------------------------------------------------===//
891 // AttributeListImpl Definition
892 //===----------------------------------------------------------------------===//
894 /// Map from AttributeList index to the internal array index. Adding one happens
895 /// to work, but it relies on unsigned integer wrapping. MSVC warns about
896 /// unsigned wrapping in constexpr functions, so write out the conditional. LLVM
897 /// folds it to add anyway.
898 static constexpr unsigned attrIdxToArrayIdx(unsigned Index
) {
899 return Index
== AttributeList::FunctionIndex
? 0 : Index
+ 1;
902 AttributeListImpl::AttributeListImpl(LLVMContext
&C
,
903 ArrayRef
<AttributeSet
> Sets
)
904 : Context(C
), NumAttrSets(Sets
.size()) {
905 assert(!Sets
.empty() && "pointless AttributeListImpl");
907 // There's memory after the node where we can store the entries in.
908 llvm::copy(Sets
, getTrailingObjects
<AttributeSet
>());
910 // Initialize AvailableFunctionAttrs summary bitset.
911 static_assert(Attribute::EndAttrKinds
<=
912 sizeof(AvailableFunctionAttrs
) * CHAR_BIT
,
913 "Too many attributes");
914 static_assert(attrIdxToArrayIdx(AttributeList::FunctionIndex
) == 0U,
915 "function should be stored in slot 0");
916 for (const auto I
: Sets
[0]) {
917 if (!I
.isStringAttribute()) {
918 Attribute::AttrKind Kind
= I
.getKindAsEnum();
919 AvailableFunctionAttrs
[Kind
/ 8] |= 1ULL << (Kind
% 8);
924 void AttributeListImpl::Profile(FoldingSetNodeID
&ID
) const {
925 Profile(ID
, makeArrayRef(begin(), end()));
928 void AttributeListImpl::Profile(FoldingSetNodeID
&ID
,
929 ArrayRef
<AttributeSet
> Sets
) {
930 for (const auto &Set
: Sets
)
931 ID
.AddPointer(Set
.SetNode
);
934 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
935 LLVM_DUMP_METHOD
void AttributeListImpl::dump() const {
936 AttributeList(const_cast<AttributeListImpl
*>(this)).dump();
940 //===----------------------------------------------------------------------===//
941 // AttributeList Construction and Mutation Methods
942 //===----------------------------------------------------------------------===//
944 AttributeList
AttributeList::getImpl(LLVMContext
&C
,
945 ArrayRef
<AttributeSet
> AttrSets
) {
946 assert(!AttrSets
.empty() && "pointless AttributeListImpl");
948 LLVMContextImpl
*pImpl
= C
.pImpl
;
950 AttributeListImpl::Profile(ID
, AttrSets
);
953 AttributeListImpl
*PA
=
954 pImpl
->AttrsLists
.FindNodeOrInsertPos(ID
, InsertPoint
);
956 // If we didn't find any existing attributes of the same shape then
957 // create a new one and insert it.
959 // Coallocate entries after the AttributeListImpl itself.
960 void *Mem
= ::operator new(
961 AttributeListImpl::totalSizeToAlloc
<AttributeSet
>(AttrSets
.size()));
962 PA
= new (Mem
) AttributeListImpl(C
, AttrSets
);
963 pImpl
->AttrsLists
.InsertNode(PA
, InsertPoint
);
966 // Return the AttributesList that we found or created.
967 return AttributeList(PA
);
971 AttributeList::get(LLVMContext
&C
,
972 ArrayRef
<std::pair
<unsigned, Attribute
>> Attrs
) {
973 // If there are no attributes then return a null AttributesList pointer.
977 assert(std::is_sorted(Attrs
.begin(), Attrs
.end(),
978 [](const std::pair
<unsigned, Attribute
> &LHS
,
979 const std::pair
<unsigned, Attribute
> &RHS
) {
980 return LHS
.first
< RHS
.first
;
981 }) && "Misordered Attributes list!");
982 assert(llvm::none_of(Attrs
,
983 [](const std::pair
<unsigned, Attribute
> &Pair
) {
984 return Pair
.second
.hasAttribute(Attribute::None
);
986 "Pointless attribute!");
988 // Create a vector if (unsigned, AttributeSetNode*) pairs from the attributes
990 SmallVector
<std::pair
<unsigned, AttributeSet
>, 8> AttrPairVec
;
991 for (ArrayRef
<std::pair
<unsigned, Attribute
>>::iterator I
= Attrs
.begin(),
992 E
= Attrs
.end(); I
!= E
; ) {
993 unsigned Index
= I
->first
;
994 SmallVector
<Attribute
, 4> AttrVec
;
995 while (I
!= E
&& I
->first
== Index
) {
996 AttrVec
.push_back(I
->second
);
1000 AttrPairVec
.emplace_back(Index
, AttributeSet::get(C
, AttrVec
));
1003 return get(C
, AttrPairVec
);
1007 AttributeList::get(LLVMContext
&C
,
1008 ArrayRef
<std::pair
<unsigned, AttributeSet
>> Attrs
) {
1009 // If there are no attributes then return a null AttributesList pointer.
1013 assert(std::is_sorted(Attrs
.begin(), Attrs
.end(),
1014 [](const std::pair
<unsigned, AttributeSet
> &LHS
,
1015 const std::pair
<unsigned, AttributeSet
> &RHS
) {
1016 return LHS
.first
< RHS
.first
;
1018 "Misordered Attributes list!");
1019 assert(llvm::none_of(Attrs
,
1020 [](const std::pair
<unsigned, AttributeSet
> &Pair
) {
1021 return !Pair
.second
.hasAttributes();
1023 "Pointless attribute!");
1025 unsigned MaxIndex
= Attrs
.back().first
;
1026 // If the MaxIndex is FunctionIndex and there are other indices in front
1027 // of it, we need to use the largest of those to get the right size.
1028 if (MaxIndex
== FunctionIndex
&& Attrs
.size() > 1)
1029 MaxIndex
= Attrs
[Attrs
.size() - 2].first
;
1031 SmallVector
<AttributeSet
, 4> AttrVec(attrIdxToArrayIdx(MaxIndex
) + 1);
1032 for (const auto Pair
: Attrs
)
1033 AttrVec
[attrIdxToArrayIdx(Pair
.first
)] = Pair
.second
;
1035 return getImpl(C
, AttrVec
);
1038 AttributeList
AttributeList::get(LLVMContext
&C
, AttributeSet FnAttrs
,
1039 AttributeSet RetAttrs
,
1040 ArrayRef
<AttributeSet
> ArgAttrs
) {
1041 // Scan from the end to find the last argument with attributes. Most
1042 // arguments don't have attributes, so it's nice if we can have fewer unique
1043 // AttributeListImpls by dropping empty attribute sets at the end of the list.
1044 unsigned NumSets
= 0;
1045 for (size_t I
= ArgAttrs
.size(); I
!= 0; --I
) {
1046 if (ArgAttrs
[I
- 1].hasAttributes()) {
1052 // Check function and return attributes if we didn't have argument
1054 if (RetAttrs
.hasAttributes())
1056 else if (FnAttrs
.hasAttributes())
1060 // If all attribute sets were empty, we can use the empty attribute list.
1064 SmallVector
<AttributeSet
, 8> AttrSets
;
1065 AttrSets
.reserve(NumSets
);
1066 // If we have any attributes, we always have function attributes.
1067 AttrSets
.push_back(FnAttrs
);
1069 AttrSets
.push_back(RetAttrs
);
1071 // Drop the empty argument attribute sets at the end.
1072 ArgAttrs
= ArgAttrs
.take_front(NumSets
- 2);
1073 AttrSets
.insert(AttrSets
.end(), ArgAttrs
.begin(), ArgAttrs
.end());
1076 return getImpl(C
, AttrSets
);
1079 AttributeList
AttributeList::get(LLVMContext
&C
, unsigned Index
,
1080 const AttrBuilder
&B
) {
1081 if (!B
.hasAttributes())
1083 Index
= attrIdxToArrayIdx(Index
);
1084 SmallVector
<AttributeSet
, 8> AttrSets(Index
+ 1);
1085 AttrSets
[Index
] = AttributeSet::get(C
, B
);
1086 return getImpl(C
, AttrSets
);
1089 AttributeList
AttributeList::get(LLVMContext
&C
, unsigned Index
,
1090 ArrayRef
<Attribute::AttrKind
> Kinds
) {
1091 SmallVector
<std::pair
<unsigned, Attribute
>, 8> Attrs
;
1092 for (const auto K
: Kinds
)
1093 Attrs
.emplace_back(Index
, Attribute::get(C
, K
));
1094 return get(C
, Attrs
);
1097 AttributeList
AttributeList::get(LLVMContext
&C
, unsigned Index
,
1098 ArrayRef
<StringRef
> Kinds
) {
1099 SmallVector
<std::pair
<unsigned, Attribute
>, 8> Attrs
;
1100 for (const auto K
: Kinds
)
1101 Attrs
.emplace_back(Index
, Attribute::get(C
, K
));
1102 return get(C
, Attrs
);
1105 AttributeList
AttributeList::get(LLVMContext
&C
,
1106 ArrayRef
<AttributeList
> Attrs
) {
1109 if (Attrs
.size() == 1)
1112 unsigned MaxSize
= 0;
1113 for (const auto List
: Attrs
)
1114 MaxSize
= std::max(MaxSize
, List
.getNumAttrSets());
1116 // If every list was empty, there is no point in merging the lists.
1120 SmallVector
<AttributeSet
, 8> NewAttrSets(MaxSize
);
1121 for (unsigned I
= 0; I
< MaxSize
; ++I
) {
1122 AttrBuilder CurBuilder
;
1123 for (const auto List
: Attrs
)
1124 CurBuilder
.merge(List
.getAttributes(I
- 1));
1125 NewAttrSets
[I
] = AttributeSet::get(C
, CurBuilder
);
1128 return getImpl(C
, NewAttrSets
);
1131 AttributeList
AttributeList::addAttribute(LLVMContext
&C
, unsigned Index
,
1132 Attribute::AttrKind Kind
) const {
1133 if (hasAttribute(Index
, Kind
)) return *this;
1135 B
.addAttribute(Kind
);
1136 return addAttributes(C
, Index
, B
);
1139 AttributeList
AttributeList::addAttribute(LLVMContext
&C
, unsigned Index
,
1141 StringRef Value
) const {
1143 B
.addAttribute(Kind
, Value
);
1144 return addAttributes(C
, Index
, B
);
1147 AttributeList
AttributeList::addAttribute(LLVMContext
&C
, unsigned Index
,
1148 Attribute A
) const {
1151 return addAttributes(C
, Index
, B
);
1154 AttributeList
AttributeList::addAttributes(LLVMContext
&C
, unsigned Index
,
1155 const AttrBuilder
&B
) const {
1156 if (!B
.hasAttributes())
1160 return AttributeList::get(C
, {{Index
, AttributeSet::get(C
, B
)}});
1163 // FIXME it is not obvious how this should work for alignment. For now, say
1164 // we can't change a known alignment.
1165 unsigned OldAlign
= getAttributes(Index
).getAlignment();
1166 unsigned NewAlign
= B
.getAlignment();
1167 assert((!OldAlign
|| !NewAlign
|| OldAlign
== NewAlign
) &&
1168 "Attempt to change alignment!");
1171 Index
= attrIdxToArrayIdx(Index
);
1172 SmallVector
<AttributeSet
, 4> AttrSets(this->begin(), this->end());
1173 if (Index
>= AttrSets
.size())
1174 AttrSets
.resize(Index
+ 1);
1176 AttrBuilder
Merged(AttrSets
[Index
]);
1178 AttrSets
[Index
] = AttributeSet::get(C
, Merged
);
1180 return getImpl(C
, AttrSets
);
1183 AttributeList
AttributeList::addParamAttribute(LLVMContext
&C
,
1184 ArrayRef
<unsigned> ArgNos
,
1185 Attribute A
) const {
1186 assert(std::is_sorted(ArgNos
.begin(), ArgNos
.end()));
1188 SmallVector
<AttributeSet
, 4> AttrSets(this->begin(), this->end());
1189 unsigned MaxIndex
= attrIdxToArrayIdx(ArgNos
.back() + FirstArgIndex
);
1190 if (MaxIndex
>= AttrSets
.size())
1191 AttrSets
.resize(MaxIndex
+ 1);
1193 for (unsigned ArgNo
: ArgNos
) {
1194 unsigned Index
= attrIdxToArrayIdx(ArgNo
+ FirstArgIndex
);
1195 AttrBuilder
B(AttrSets
[Index
]);
1197 AttrSets
[Index
] = AttributeSet::get(C
, B
);
1200 return getImpl(C
, AttrSets
);
1203 AttributeList
AttributeList::removeAttribute(LLVMContext
&C
, unsigned Index
,
1204 Attribute::AttrKind Kind
) const {
1205 if (!hasAttribute(Index
, Kind
)) return *this;
1207 Index
= attrIdxToArrayIdx(Index
);
1208 SmallVector
<AttributeSet
, 4> AttrSets(this->begin(), this->end());
1209 assert(Index
< AttrSets
.size());
1211 AttrSets
[Index
] = AttrSets
[Index
].removeAttribute(C
, Kind
);
1213 return getImpl(C
, AttrSets
);
1216 AttributeList
AttributeList::removeAttribute(LLVMContext
&C
, unsigned Index
,
1217 StringRef Kind
) const {
1218 if (!hasAttribute(Index
, Kind
)) return *this;
1220 Index
= attrIdxToArrayIdx(Index
);
1221 SmallVector
<AttributeSet
, 4> AttrSets(this->begin(), this->end());
1222 assert(Index
< AttrSets
.size());
1224 AttrSets
[Index
] = AttrSets
[Index
].removeAttribute(C
, Kind
);
1226 return getImpl(C
, AttrSets
);
1230 AttributeList::removeAttributes(LLVMContext
&C
, unsigned Index
,
1231 const AttrBuilder
&AttrsToRemove
) const {
1235 Index
= attrIdxToArrayIdx(Index
);
1236 SmallVector
<AttributeSet
, 4> AttrSets(this->begin(), this->end());
1237 if (Index
>= AttrSets
.size())
1238 AttrSets
.resize(Index
+ 1);
1240 AttrSets
[Index
] = AttrSets
[Index
].removeAttributes(C
, AttrsToRemove
);
1242 return getImpl(C
, AttrSets
);
1245 AttributeList
AttributeList::removeAttributes(LLVMContext
&C
,
1246 unsigned WithoutIndex
) const {
1249 WithoutIndex
= attrIdxToArrayIdx(WithoutIndex
);
1250 if (WithoutIndex
>= getNumAttrSets())
1252 SmallVector
<AttributeSet
, 4> AttrSets(this->begin(), this->end());
1253 AttrSets
[WithoutIndex
] = AttributeSet();
1254 return getImpl(C
, AttrSets
);
1257 AttributeList
AttributeList::addDereferenceableAttr(LLVMContext
&C
,
1259 uint64_t Bytes
) const {
1261 B
.addDereferenceableAttr(Bytes
);
1262 return addAttributes(C
, Index
, B
);
1266 AttributeList::addDereferenceableOrNullAttr(LLVMContext
&C
, unsigned Index
,
1267 uint64_t Bytes
) const {
1269 B
.addDereferenceableOrNullAttr(Bytes
);
1270 return addAttributes(C
, Index
, B
);
1274 AttributeList::addAllocSizeAttr(LLVMContext
&C
, unsigned Index
,
1275 unsigned ElemSizeArg
,
1276 const Optional
<unsigned> &NumElemsArg
) {
1278 B
.addAllocSizeAttr(ElemSizeArg
, NumElemsArg
);
1279 return addAttributes(C
, Index
, B
);
1282 //===----------------------------------------------------------------------===//
1283 // AttributeList Accessor Methods
1284 //===----------------------------------------------------------------------===//
1286 LLVMContext
&AttributeList::getContext() const { return pImpl
->getContext(); }
1288 AttributeSet
AttributeList::getParamAttributes(unsigned ArgNo
) const {
1289 return getAttributes(ArgNo
+ FirstArgIndex
);
1292 AttributeSet
AttributeList::getRetAttributes() const {
1293 return getAttributes(ReturnIndex
);
1296 AttributeSet
AttributeList::getFnAttributes() const {
1297 return getAttributes(FunctionIndex
);
1300 bool AttributeList::hasAttribute(unsigned Index
,
1301 Attribute::AttrKind Kind
) const {
1302 return getAttributes(Index
).hasAttribute(Kind
);
1305 bool AttributeList::hasAttribute(unsigned Index
, StringRef Kind
) const {
1306 return getAttributes(Index
).hasAttribute(Kind
);
1309 bool AttributeList::hasAttributes(unsigned Index
) const {
1310 return getAttributes(Index
).hasAttributes();
1313 bool AttributeList::hasFnAttribute(Attribute::AttrKind Kind
) const {
1314 return pImpl
&& pImpl
->hasFnAttribute(Kind
);
1317 bool AttributeList::hasFnAttribute(StringRef Kind
) const {
1318 return hasAttribute(AttributeList::FunctionIndex
, Kind
);
1321 bool AttributeList::hasParamAttribute(unsigned ArgNo
,
1322 Attribute::AttrKind Kind
) const {
1323 return hasAttribute(ArgNo
+ FirstArgIndex
, Kind
);
1326 bool AttributeList::hasAttrSomewhere(Attribute::AttrKind Attr
,
1327 unsigned *Index
) const {
1328 if (!pImpl
) return false;
1330 for (unsigned I
= index_begin(), E
= index_end(); I
!= E
; ++I
) {
1331 if (hasAttribute(I
, Attr
)) {
1341 Attribute
AttributeList::getAttribute(unsigned Index
,
1342 Attribute::AttrKind Kind
) const {
1343 return getAttributes(Index
).getAttribute(Kind
);
1346 Attribute
AttributeList::getAttribute(unsigned Index
, StringRef Kind
) const {
1347 return getAttributes(Index
).getAttribute(Kind
);
1350 unsigned AttributeList::getRetAlignment() const {
1351 return getAttributes(ReturnIndex
).getAlignment();
1354 unsigned AttributeList::getParamAlignment(unsigned ArgNo
) const {
1355 return getAttributes(ArgNo
+ FirstArgIndex
).getAlignment();
1358 Type
*AttributeList::getParamByValType(unsigned Index
) const {
1359 return getAttributes(Index
+FirstArgIndex
).getByValType();
1363 unsigned 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();
1439 Alignment
= StackAlignment
= DerefBytes
= DerefOrNullBytes
= 0;
1441 ByValType
= nullptr;
1444 AttrBuilder
&AttrBuilder::addAttribute(Attribute::AttrKind Val
) {
1445 assert((unsigned)Val
< Attribute::EndAttrKinds
&& "Attribute out of range!");
1446 assert(Val
!= Attribute::Alignment
&& Val
!= Attribute::StackAlignment
&&
1447 Val
!= Attribute::Dereferenceable
&& Val
!= Attribute::AllocSize
&&
1448 "Adding integer attribute without adding a value!");
1453 AttrBuilder
&AttrBuilder::addAttribute(Attribute Attr
) {
1454 if (Attr
.isStringAttribute()) {
1455 addAttribute(Attr
.getKindAsString(), Attr
.getValueAsString());
1459 Attribute::AttrKind Kind
= Attr
.getKindAsEnum();
1462 if (Kind
== Attribute::Alignment
)
1463 Alignment
= Attr
.getAlignment();
1464 else if (Kind
== Attribute::StackAlignment
)
1465 StackAlignment
= Attr
.getStackAlignment();
1466 else if (Kind
== Attribute::ByVal
)
1467 ByValType
= Attr
.getValueAsType();
1468 else if (Kind
== Attribute::Dereferenceable
)
1469 DerefBytes
= Attr
.getDereferenceableBytes();
1470 else if (Kind
== Attribute::DereferenceableOrNull
)
1471 DerefOrNullBytes
= Attr
.getDereferenceableOrNullBytes();
1472 else if (Kind
== Attribute::AllocSize
)
1473 AllocSizeArgs
= Attr
.getValueAsInt();
1477 AttrBuilder
&AttrBuilder::addAttribute(StringRef A
, StringRef V
) {
1478 TargetDepAttrs
[A
] = V
;
1482 AttrBuilder
&AttrBuilder::removeAttribute(Attribute::AttrKind Val
) {
1483 assert((unsigned)Val
< Attribute::EndAttrKinds
&& "Attribute out of range!");
1486 if (Val
== Attribute::Alignment
)
1488 else if (Val
== Attribute::StackAlignment
)
1490 else if (Val
== Attribute::ByVal
)
1491 ByValType
= nullptr;
1492 else if (Val
== Attribute::Dereferenceable
)
1494 else if (Val
== Attribute::DereferenceableOrNull
)
1495 DerefOrNullBytes
= 0;
1496 else if (Val
== Attribute::AllocSize
)
1502 AttrBuilder
&AttrBuilder::removeAttributes(AttributeList A
, uint64_t Index
) {
1503 remove(A
.getAttributes(Index
));
1507 AttrBuilder
&AttrBuilder::removeAttribute(StringRef A
) {
1508 auto I
= TargetDepAttrs
.find(A
);
1509 if (I
!= TargetDepAttrs
.end())
1510 TargetDepAttrs
.erase(I
);
1514 std::pair
<unsigned, Optional
<unsigned>> AttrBuilder::getAllocSizeArgs() const {
1515 return unpackAllocSizeArgs(AllocSizeArgs
);
1518 AttrBuilder
&AttrBuilder::addAlignmentAttr(unsigned Align
) {
1519 if (Align
== 0) return *this;
1521 assert(isPowerOf2_32(Align
) && "Alignment must be a power of two.");
1522 assert(Align
<= 0x40000000 && "Alignment too large.");
1524 Attrs
[Attribute::Alignment
] = true;
1529 AttrBuilder
&AttrBuilder::addStackAlignmentAttr(unsigned Align
) {
1530 // Default alignment, allow the target to define how to align it.
1531 if (Align
== 0) return *this;
1533 assert(isPowerOf2_32(Align
) && "Alignment must be a power of two.");
1534 assert(Align
<= 0x100 && "Alignment too large.");
1536 Attrs
[Attribute::StackAlignment
] = true;
1537 StackAlignment
= Align
;
1541 AttrBuilder
&AttrBuilder::addDereferenceableAttr(uint64_t Bytes
) {
1542 if (Bytes
== 0) return *this;
1544 Attrs
[Attribute::Dereferenceable
] = true;
1549 AttrBuilder
&AttrBuilder::addDereferenceableOrNullAttr(uint64_t Bytes
) {
1553 Attrs
[Attribute::DereferenceableOrNull
] = true;
1554 DerefOrNullBytes
= Bytes
;
1558 AttrBuilder
&AttrBuilder::addAllocSizeAttr(unsigned ElemSize
,
1559 const Optional
<unsigned> &NumElems
) {
1560 return addAllocSizeAttrFromRawRepr(packAllocSizeArgs(ElemSize
, NumElems
));
1563 AttrBuilder
&AttrBuilder::addAllocSizeAttrFromRawRepr(uint64_t RawArgs
) {
1564 // (0, 0) is our "not present" value, so we need to check for it here.
1565 assert(RawArgs
&& "Invalid allocsize arguments -- given allocsize(0, 0)");
1567 Attrs
[Attribute::AllocSize
] = true;
1568 // Reuse existing machinery to store this as a single 64-bit integer so we can
1569 // save a few bytes over using a pair<unsigned, Optional<unsigned>>.
1570 AllocSizeArgs
= RawArgs
;
1574 AttrBuilder
&AttrBuilder::addByValAttr(Type
*Ty
) {
1575 Attrs
[Attribute::ByVal
] = true;
1580 AttrBuilder
&AttrBuilder::merge(const AttrBuilder
&B
) {
1581 // FIXME: What if both have alignments, but they don't match?!
1583 Alignment
= B
.Alignment
;
1585 if (!StackAlignment
)
1586 StackAlignment
= B
.StackAlignment
;
1589 DerefBytes
= B
.DerefBytes
;
1591 if (!DerefOrNullBytes
)
1592 DerefOrNullBytes
= B
.DerefOrNullBytes
;
1595 AllocSizeArgs
= B
.AllocSizeArgs
;
1598 ByValType
= B
.ByValType
;
1602 for (auto I
: B
.td_attrs())
1603 TargetDepAttrs
[I
.first
] = I
.second
;
1608 AttrBuilder
&AttrBuilder::remove(const AttrBuilder
&B
) {
1609 // FIXME: What if both have alignments, but they don't match?!
1613 if (B
.StackAlignment
)
1619 if (B
.DerefOrNullBytes
)
1620 DerefOrNullBytes
= 0;
1622 if (B
.AllocSizeArgs
)
1626 ByValType
= nullptr;
1630 for (auto I
: B
.td_attrs())
1631 TargetDepAttrs
.erase(I
.first
);
1636 bool AttrBuilder::overlaps(const AttrBuilder
&B
) const {
1637 // First check if any of the target independent attributes overlap.
1638 if ((Attrs
& B
.Attrs
).any())
1641 // Then check if any target dependent ones do.
1642 for (const auto &I
: td_attrs())
1643 if (B
.contains(I
.first
))
1649 bool AttrBuilder::contains(StringRef A
) const {
1650 return TargetDepAttrs
.find(A
) != TargetDepAttrs
.end();
1653 bool AttrBuilder::hasAttributes() const {
1654 return !Attrs
.none() || !TargetDepAttrs
.empty();
1657 bool AttrBuilder::hasAttributes(AttributeList AL
, uint64_t Index
) const {
1658 AttributeSet AS
= AL
.getAttributes(Index
);
1660 for (const auto Attr
: AS
) {
1661 if (Attr
.isEnumAttribute() || Attr
.isIntAttribute()) {
1662 if (contains(Attr
.getKindAsEnum()))
1665 assert(Attr
.isStringAttribute() && "Invalid attribute kind!");
1666 return contains(Attr
.getKindAsString());
1673 bool AttrBuilder::hasAlignmentAttr() const {
1674 return Alignment
!= 0;
1677 bool AttrBuilder::operator==(const AttrBuilder
&B
) {
1678 if (Attrs
!= B
.Attrs
)
1681 for (td_const_iterator I
= TargetDepAttrs
.begin(),
1682 E
= TargetDepAttrs
.end(); I
!= E
; ++I
)
1683 if (B
.TargetDepAttrs
.find(I
->first
) == B
.TargetDepAttrs
.end())
1686 return Alignment
== B
.Alignment
&& StackAlignment
== B
.StackAlignment
&&
1687 DerefBytes
== B
.DerefBytes
&& ByValType
== B
.ByValType
;
1690 //===----------------------------------------------------------------------===//
1691 // AttributeFuncs Function Defintions
1692 //===----------------------------------------------------------------------===//
1694 /// Which attributes cannot be applied to a type.
1695 AttrBuilder
AttributeFuncs::typeIncompatible(Type
*Ty
) {
1696 AttrBuilder Incompatible
;
1698 if (!Ty
->isIntegerTy())
1699 // Attribute that only apply to integers.
1700 Incompatible
.addAttribute(Attribute::SExt
)
1701 .addAttribute(Attribute::ZExt
);
1703 if (!Ty
->isPointerTy())
1704 // Attribute that only apply to pointers.
1705 Incompatible
.addAttribute(Attribute::ByVal
)
1706 .addAttribute(Attribute::Nest
)
1707 .addAttribute(Attribute::NoAlias
)
1708 .addAttribute(Attribute::NoCapture
)
1709 .addAttribute(Attribute::NonNull
)
1710 .addDereferenceableAttr(1) // the int here is ignored
1711 .addDereferenceableOrNullAttr(1) // the int here is ignored
1712 .addAttribute(Attribute::ReadNone
)
1713 .addAttribute(Attribute::ReadOnly
)
1714 .addAttribute(Attribute::StructRet
)
1715 .addAttribute(Attribute::InAlloca
);
1717 return Incompatible
;
1720 template<typename AttrClass
>
1721 static bool isEqual(const Function
&Caller
, const Function
&Callee
) {
1722 return Caller
.getFnAttribute(AttrClass::getKind()) ==
1723 Callee
.getFnAttribute(AttrClass::getKind());
1726 /// Compute the logical AND of the attributes of the caller and the
1729 /// This function sets the caller's attribute to false if the callee's attribute
1731 template<typename AttrClass
>
1732 static void setAND(Function
&Caller
, const Function
&Callee
) {
1733 if (AttrClass::isSet(Caller
, AttrClass::getKind()) &&
1734 !AttrClass::isSet(Callee
, AttrClass::getKind()))
1735 AttrClass::set(Caller
, AttrClass::getKind(), false);
1738 /// Compute the logical OR of the attributes of the caller and the
1741 /// This function sets the caller's attribute to true if the callee's attribute
1743 template<typename AttrClass
>
1744 static void setOR(Function
&Caller
, const Function
&Callee
) {
1745 if (!AttrClass::isSet(Caller
, AttrClass::getKind()) &&
1746 AttrClass::isSet(Callee
, AttrClass::getKind()))
1747 AttrClass::set(Caller
, AttrClass::getKind(), true);
1750 /// If the inlined function had a higher stack protection level than the
1751 /// calling function, then bump up the caller's stack protection level.
1752 static void adjustCallerSSPLevel(Function
&Caller
, const Function
&Callee
) {
1753 // If upgrading the SSP attribute, clear out the old SSP Attributes first.
1754 // Having multiple SSP attributes doesn't actually hurt, but it adds useless
1755 // clutter to the IR.
1756 AttrBuilder OldSSPAttr
;
1757 OldSSPAttr
.addAttribute(Attribute::StackProtect
)
1758 .addAttribute(Attribute::StackProtectStrong
)
1759 .addAttribute(Attribute::StackProtectReq
);
1761 if (Callee
.hasFnAttribute(Attribute::StackProtectReq
)) {
1762 Caller
.removeAttributes(AttributeList::FunctionIndex
, OldSSPAttr
);
1763 Caller
.addFnAttr(Attribute::StackProtectReq
);
1764 } else if (Callee
.hasFnAttribute(Attribute::StackProtectStrong
) &&
1765 !Caller
.hasFnAttribute(Attribute::StackProtectReq
)) {
1766 Caller
.removeAttributes(AttributeList::FunctionIndex
, OldSSPAttr
);
1767 Caller
.addFnAttr(Attribute::StackProtectStrong
);
1768 } else if (Callee
.hasFnAttribute(Attribute::StackProtect
) &&
1769 !Caller
.hasFnAttribute(Attribute::StackProtectReq
) &&
1770 !Caller
.hasFnAttribute(Attribute::StackProtectStrong
))
1771 Caller
.addFnAttr(Attribute::StackProtect
);
1774 /// If the inlined function required stack probes, then ensure that
1775 /// the calling function has those too.
1776 static void adjustCallerStackProbes(Function
&Caller
, const Function
&Callee
) {
1777 if (!Caller
.hasFnAttribute("probe-stack") &&
1778 Callee
.hasFnAttribute("probe-stack")) {
1779 Caller
.addFnAttr(Callee
.getFnAttribute("probe-stack"));
1783 /// If the inlined function defines the size of guard region
1784 /// on the stack, then ensure that the calling function defines a guard region
1785 /// that is no larger.
1787 adjustCallerStackProbeSize(Function
&Caller
, const Function
&Callee
) {
1788 if (Callee
.hasFnAttribute("stack-probe-size")) {
1789 uint64_t CalleeStackProbeSize
;
1790 Callee
.getFnAttribute("stack-probe-size")
1792 .getAsInteger(0, CalleeStackProbeSize
);
1793 if (Caller
.hasFnAttribute("stack-probe-size")) {
1794 uint64_t CallerStackProbeSize
;
1795 Caller
.getFnAttribute("stack-probe-size")
1797 .getAsInteger(0, CallerStackProbeSize
);
1798 if (CallerStackProbeSize
> CalleeStackProbeSize
) {
1799 Caller
.addFnAttr(Callee
.getFnAttribute("stack-probe-size"));
1802 Caller
.addFnAttr(Callee
.getFnAttribute("stack-probe-size"));
1807 /// If the inlined function defines a min legal vector width, then ensure
1808 /// the calling function has the same or larger min legal vector width. If the
1809 /// caller has the attribute, but the callee doesn't, we need to remove the
1810 /// attribute from the caller since we can't make any guarantees about the
1811 /// caller's requirements.
1812 /// This function is called after the inlining decision has been made so we have
1813 /// to merge the attribute this way. Heuristics that would use
1814 /// min-legal-vector-width to determine inline compatibility would need to be
1815 /// handled as part of inline cost analysis.
1817 adjustMinLegalVectorWidth(Function
&Caller
, const Function
&Callee
) {
1818 if (Caller
.hasFnAttribute("min-legal-vector-width")) {
1819 if (Callee
.hasFnAttribute("min-legal-vector-width")) {
1820 uint64_t CallerVectorWidth
;
1821 Caller
.getFnAttribute("min-legal-vector-width")
1823 .getAsInteger(0, CallerVectorWidth
);
1824 uint64_t CalleeVectorWidth
;
1825 Callee
.getFnAttribute("min-legal-vector-width")
1827 .getAsInteger(0, CalleeVectorWidth
);
1828 if (CallerVectorWidth
< CalleeVectorWidth
)
1829 Caller
.addFnAttr(Callee
.getFnAttribute("min-legal-vector-width"));
1831 // If the callee doesn't have the attribute then we don't know anything
1832 // and must drop the attribute from the caller.
1833 Caller
.removeFnAttr("min-legal-vector-width");
1838 /// If the inlined function has "null-pointer-is-valid=true" attribute,
1839 /// set this attribute in the caller post inlining.
1841 adjustNullPointerValidAttr(Function
&Caller
, const Function
&Callee
) {
1842 if (Callee
.nullPointerIsDefined() && !Caller
.nullPointerIsDefined()) {
1843 Caller
.addFnAttr(Callee
.getFnAttribute("null-pointer-is-valid"));
1847 #define GET_ATTR_COMPAT_FUNC
1848 #include "AttributesCompatFunc.inc"
1850 bool AttributeFuncs::areInlineCompatible(const Function
&Caller
,
1851 const Function
&Callee
) {
1852 return hasCompatibleFnAttrs(Caller
, Callee
);
1855 void AttributeFuncs::mergeAttributesForInlining(Function
&Caller
,
1856 const Function
&Callee
) {
1857 mergeFnAttrs(Caller
, Callee
);