1 //===- Attributes.cpp - Implement AttributesList --------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
11 // \brief This file implements the Attribute, AttributeImpl, AttrBuilder,
12 // AttributeListImpl, and AttributeList classes.
14 //===----------------------------------------------------------------------===//
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/SmallVector.h"
22 #include "llvm/ADT/STLExtras.h"
23 #include "llvm/ADT/StringExtras.h"
24 #include "llvm/ADT/StringRef.h"
25 #include "llvm/ADT/Twine.h"
26 #include "llvm/IR/Attributes.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"
46 //===----------------------------------------------------------------------===//
47 // Attribute Construction Methods
48 //===----------------------------------------------------------------------===//
50 // allocsize has two integer arguments, but because they're both 32 bits, we can
51 // pack them into one 64-bit value, at the cost of making said value
54 // In order to do this, we need to reserve one value of the second (optional)
55 // allocsize argument to signify "not present."
56 static const unsigned AllocSizeNumElemsNotPresent = -1;
58 static uint64_t packAllocSizeArgs(unsigned ElemSizeArg,
59 const Optional<unsigned> &NumElemsArg) {
60 assert((!NumElemsArg.hasValue() ||
61 *NumElemsArg != AllocSizeNumElemsNotPresent) &&
62 "Attempting to pack a reserved value");
64 return uint64_t(ElemSizeArg) << 32 |
65 NumElemsArg.getValueOr(AllocSizeNumElemsNotPresent);
68 static std::pair<unsigned, Optional<unsigned>>
69 unpackAllocSizeArgs(uint64_t Num) {
70 unsigned NumElems = Num & std::numeric_limits<unsigned>::max();
71 unsigned ElemSizeArg = Num >> 32;
73 Optional<unsigned> NumElemsArg;
74 if (NumElems != AllocSizeNumElemsNotPresent)
75 NumElemsArg = NumElems;
76 return std::make_pair(ElemSizeArg, NumElemsArg);
79 Attribute Attribute::get(LLVMContext &Context, Attribute::AttrKind Kind,
81 LLVMContextImpl *pImpl = Context.pImpl;
84 if (Val) ID.AddInteger(Val);
87 AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);
90 // If we didn't find any existing attributes of the same shape then create a
91 // new one and insert it.
93 PA = new EnumAttributeImpl(Kind);
95 PA = new IntAttributeImpl(Kind, Val);
96 pImpl->AttrsSet.InsertNode(PA, InsertPoint);
99 // Return the Attribute that we found or created.
100 return Attribute(PA);
103 Attribute Attribute::get(LLVMContext &Context, StringRef Kind, StringRef Val) {
104 LLVMContextImpl *pImpl = Context.pImpl;
107 if (!Val.empty()) ID.AddString(Val);
110 AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);
113 // If we didn't find any existing attributes of the same shape then create a
114 // new one and insert it.
115 PA = new StringAttributeImpl(Kind, Val);
116 pImpl->AttrsSet.InsertNode(PA, InsertPoint);
119 // Return the Attribute that we found or created.
120 return Attribute(PA);
123 Attribute Attribute::getWithAlignment(LLVMContext &Context, uint64_t Align) {
124 assert(isPowerOf2_32(Align) && "Alignment must be a power of two.");
125 assert(Align <= 0x40000000 && "Alignment too large.");
126 return get(Context, Alignment, Align);
129 Attribute Attribute::getWithStackAlignment(LLVMContext &Context,
131 assert(isPowerOf2_32(Align) && "Alignment must be a power of two.");
132 assert(Align <= 0x100 && "Alignment too large.");
133 return get(Context, StackAlignment, Align);
136 Attribute Attribute::getWithDereferenceableBytes(LLVMContext &Context,
138 assert(Bytes && "Bytes must be non-zero.");
139 return get(Context, Dereferenceable, Bytes);
142 Attribute Attribute::getWithDereferenceableOrNullBytes(LLVMContext &Context,
144 assert(Bytes && "Bytes must be non-zero.");
145 return get(Context, DereferenceableOrNull, Bytes);
149 Attribute::getWithAllocSizeArgs(LLVMContext &Context, unsigned ElemSizeArg,
150 const Optional<unsigned> &NumElemsArg) {
151 assert(!(ElemSizeArg == 0 && NumElemsArg && *NumElemsArg == 0) &&
152 "Invalid allocsize arguments -- given allocsize(0, 0)");
153 return get(Context, AllocSize, packAllocSizeArgs(ElemSizeArg, NumElemsArg));
156 //===----------------------------------------------------------------------===//
157 // Attribute Accessor Methods
158 //===----------------------------------------------------------------------===//
160 bool Attribute::isEnumAttribute() const {
161 return pImpl && pImpl->isEnumAttribute();
164 bool Attribute::isIntAttribute() const {
165 return pImpl && pImpl->isIntAttribute();
168 bool Attribute::isStringAttribute() const {
169 return pImpl && pImpl->isStringAttribute();
172 Attribute::AttrKind Attribute::getKindAsEnum() const {
173 if (!pImpl) return None;
174 assert((isEnumAttribute() || isIntAttribute()) &&
175 "Invalid attribute type to get the kind as an enum!");
176 return pImpl->getKindAsEnum();
179 uint64_t Attribute::getValueAsInt() const {
180 if (!pImpl) return 0;
181 assert(isIntAttribute() &&
182 "Expected the attribute to be an integer attribute!");
183 return pImpl->getValueAsInt();
186 StringRef Attribute::getKindAsString() const {
187 if (!pImpl) return StringRef();
188 assert(isStringAttribute() &&
189 "Invalid attribute type to get the kind as a string!");
190 return pImpl->getKindAsString();
193 StringRef Attribute::getValueAsString() const {
194 if (!pImpl) return StringRef();
195 assert(isStringAttribute() &&
196 "Invalid attribute type to get the value as a string!");
197 return pImpl->getValueAsString();
200 bool Attribute::hasAttribute(AttrKind Kind) const {
201 return (pImpl && pImpl->hasAttribute(Kind)) || (!pImpl && Kind == None);
204 bool Attribute::hasAttribute(StringRef Kind) const {
205 if (!isStringAttribute()) return false;
206 return pImpl && pImpl->hasAttribute(Kind);
209 unsigned Attribute::getAlignment() const {
210 assert(hasAttribute(Attribute::Alignment) &&
211 "Trying to get alignment from non-alignment attribute!");
212 return pImpl->getValueAsInt();
215 unsigned Attribute::getStackAlignment() const {
216 assert(hasAttribute(Attribute::StackAlignment) &&
217 "Trying to get alignment from non-alignment attribute!");
218 return pImpl->getValueAsInt();
221 uint64_t Attribute::getDereferenceableBytes() const {
222 assert(hasAttribute(Attribute::Dereferenceable) &&
223 "Trying to get dereferenceable bytes from "
224 "non-dereferenceable attribute!");
225 return pImpl->getValueAsInt();
228 uint64_t Attribute::getDereferenceableOrNullBytes() const {
229 assert(hasAttribute(Attribute::DereferenceableOrNull) &&
230 "Trying to get dereferenceable bytes from "
231 "non-dereferenceable attribute!");
232 return pImpl->getValueAsInt();
235 std::pair<unsigned, Optional<unsigned>> Attribute::getAllocSizeArgs() const {
236 assert(hasAttribute(Attribute::AllocSize) &&
237 "Trying to get allocsize args from non-allocsize attribute");
238 return unpackAllocSizeArgs(pImpl->getValueAsInt());
241 std::string Attribute::getAsString(bool InAttrGrp) const {
242 if (!pImpl) return "";
244 if (hasAttribute(Attribute::SanitizeAddress))
245 return "sanitize_address";
246 if (hasAttribute(Attribute::AlwaysInline))
247 return "alwaysinline";
248 if (hasAttribute(Attribute::ArgMemOnly))
250 if (hasAttribute(Attribute::Builtin))
252 if (hasAttribute(Attribute::ByVal))
254 if (hasAttribute(Attribute::Convergent))
256 if (hasAttribute(Attribute::SwiftError))
258 if (hasAttribute(Attribute::SwiftSelf))
260 if (hasAttribute(Attribute::InaccessibleMemOnly))
261 return "inaccessiblememonly";
262 if (hasAttribute(Attribute::InaccessibleMemOrArgMemOnly))
263 return "inaccessiblemem_or_argmemonly";
264 if (hasAttribute(Attribute::InAlloca))
266 if (hasAttribute(Attribute::InlineHint))
268 if (hasAttribute(Attribute::InReg))
270 if (hasAttribute(Attribute::JumpTable))
272 if (hasAttribute(Attribute::MinSize))
274 if (hasAttribute(Attribute::Naked))
276 if (hasAttribute(Attribute::Nest))
278 if (hasAttribute(Attribute::NoAlias))
280 if (hasAttribute(Attribute::NoBuiltin))
282 if (hasAttribute(Attribute::NoCapture))
284 if (hasAttribute(Attribute::NoDuplicate))
285 return "noduplicate";
286 if (hasAttribute(Attribute::NoImplicitFloat))
287 return "noimplicitfloat";
288 if (hasAttribute(Attribute::NoInline))
290 if (hasAttribute(Attribute::NonLazyBind))
291 return "nonlazybind";
292 if (hasAttribute(Attribute::NonNull))
294 if (hasAttribute(Attribute::NoRedZone))
296 if (hasAttribute(Attribute::NoReturn))
298 if (hasAttribute(Attribute::NoRecurse))
300 if (hasAttribute(Attribute::NoUnwind))
302 if (hasAttribute(Attribute::OptimizeNone))
304 if (hasAttribute(Attribute::OptimizeForSize))
306 if (hasAttribute(Attribute::ReadNone))
308 if (hasAttribute(Attribute::ReadOnly))
310 if (hasAttribute(Attribute::WriteOnly))
312 if (hasAttribute(Attribute::Returned))
314 if (hasAttribute(Attribute::ReturnsTwice))
315 return "returns_twice";
316 if (hasAttribute(Attribute::SExt))
318 if (hasAttribute(Attribute::StackProtect))
320 if (hasAttribute(Attribute::StackProtectReq))
322 if (hasAttribute(Attribute::StackProtectStrong))
324 if (hasAttribute(Attribute::SafeStack))
326 if (hasAttribute(Attribute::StructRet))
328 if (hasAttribute(Attribute::SanitizeThread))
329 return "sanitize_thread";
330 if (hasAttribute(Attribute::SanitizeMemory))
331 return "sanitize_memory";
332 if (hasAttribute(Attribute::UWTable))
334 if (hasAttribute(Attribute::ZExt))
336 if (hasAttribute(Attribute::Cold))
339 // FIXME: These should be output like this:
344 if (hasAttribute(Attribute::Alignment)) {
347 Result += (InAttrGrp) ? "=" : " ";
348 Result += utostr(getValueAsInt());
352 auto AttrWithBytesToString = [&](const char *Name) {
357 Result += utostr(getValueAsInt());
360 Result += utostr(getValueAsInt());
366 if (hasAttribute(Attribute::StackAlignment))
367 return AttrWithBytesToString("alignstack");
369 if (hasAttribute(Attribute::Dereferenceable))
370 return AttrWithBytesToString("dereferenceable");
372 if (hasAttribute(Attribute::DereferenceableOrNull))
373 return AttrWithBytesToString("dereferenceable_or_null");
375 if (hasAttribute(Attribute::AllocSize)) {
377 Optional<unsigned> NumElems;
378 std::tie(ElemSize, NumElems) = getAllocSizeArgs();
380 std::string Result = "allocsize(";
381 Result += utostr(ElemSize);
382 if (NumElems.hasValue()) {
384 Result += utostr(*NumElems);
390 // Convert target-dependent attributes to strings of the form:
395 if (isStringAttribute()) {
397 Result += (Twine('"') + getKindAsString() + Twine('"')).str();
399 std::string AttrVal = pImpl->getValueAsString();
400 if (AttrVal.empty()) return Result;
402 // Since some attribute strings contain special characters that cannot be
403 // printable, those have to be escaped to make the attribute value printable
404 // as is. e.g. "\01__gnu_mcount_nc"
406 raw_string_ostream OS(Result);
408 PrintEscapedString(AttrVal, OS);
414 llvm_unreachable("Unknown attribute");
417 bool Attribute::operator<(Attribute A) const {
418 if (!pImpl && !A.pImpl) return false;
419 if (!pImpl) return true;
420 if (!A.pImpl) return false;
421 return *pImpl < *A.pImpl;
424 //===----------------------------------------------------------------------===//
425 // AttributeImpl Definition
426 //===----------------------------------------------------------------------===//
428 // Pin the vtables to this file.
429 AttributeImpl::~AttributeImpl() = default;
431 void EnumAttributeImpl::anchor() {}
433 void IntAttributeImpl::anchor() {}
435 void StringAttributeImpl::anchor() {}
437 bool AttributeImpl::hasAttribute(Attribute::AttrKind A) const {
438 if (isStringAttribute()) return false;
439 return getKindAsEnum() == A;
442 bool AttributeImpl::hasAttribute(StringRef Kind) const {
443 if (!isStringAttribute()) return false;
444 return getKindAsString() == Kind;
447 Attribute::AttrKind AttributeImpl::getKindAsEnum() const {
448 assert(isEnumAttribute() || isIntAttribute());
449 return static_cast<const EnumAttributeImpl *>(this)->getEnumKind();
452 uint64_t AttributeImpl::getValueAsInt() const {
453 assert(isIntAttribute());
454 return static_cast<const IntAttributeImpl *>(this)->getValue();
457 StringRef AttributeImpl::getKindAsString() const {
458 assert(isStringAttribute());
459 return static_cast<const StringAttributeImpl *>(this)->getStringKind();
462 StringRef AttributeImpl::getValueAsString() const {
463 assert(isStringAttribute());
464 return static_cast<const StringAttributeImpl *>(this)->getStringValue();
467 bool AttributeImpl::operator<(const AttributeImpl &AI) const {
468 // This sorts the attributes with Attribute::AttrKinds coming first (sorted
469 // relative to their enum value) and then strings.
470 if (isEnumAttribute()) {
471 if (AI.isEnumAttribute()) return getKindAsEnum() < AI.getKindAsEnum();
472 if (AI.isIntAttribute()) return true;
473 if (AI.isStringAttribute()) return true;
476 if (isIntAttribute()) {
477 if (AI.isEnumAttribute()) return false;
478 if (AI.isIntAttribute()) {
479 if (getKindAsEnum() == AI.getKindAsEnum())
480 return getValueAsInt() < AI.getValueAsInt();
481 return getKindAsEnum() < AI.getKindAsEnum();
483 if (AI.isStringAttribute()) return true;
486 if (AI.isEnumAttribute()) return false;
487 if (AI.isIntAttribute()) return false;
488 if (getKindAsString() == AI.getKindAsString())
489 return getValueAsString() < AI.getValueAsString();
490 return getKindAsString() < AI.getKindAsString();
493 //===----------------------------------------------------------------------===//
494 // AttributeSet Definition
495 //===----------------------------------------------------------------------===//
497 AttributeSet AttributeSet::get(LLVMContext &C, const AttrBuilder &B) {
498 return AttributeSet(AttributeSetNode::get(C, B));
501 AttributeSet AttributeSet::get(LLVMContext &C, ArrayRef<Attribute> Attrs) {
502 return AttributeSet(AttributeSetNode::get(C, Attrs));
505 unsigned AttributeSet::getNumAttributes() const {
506 return SetNode ? SetNode->getNumAttributes() : 0;
509 bool AttributeSet::hasAttribute(Attribute::AttrKind Kind) const {
510 return SetNode ? SetNode->hasAttribute(Kind) : 0;
513 bool AttributeSet::hasAttribute(StringRef Kind) const {
514 return SetNode ? SetNode->hasAttribute(Kind) : 0;
517 Attribute AttributeSet::getAttribute(Attribute::AttrKind Kind) const {
518 return SetNode ? SetNode->getAttribute(Kind) : Attribute();
521 Attribute AttributeSet::getAttribute(StringRef Kind) const {
522 return SetNode ? SetNode->getAttribute(Kind) : Attribute();
525 unsigned AttributeSet::getAlignment() const {
526 return SetNode ? SetNode->getAlignment() : 0;
529 unsigned AttributeSet::getStackAlignment() const {
530 return SetNode ? SetNode->getStackAlignment() : 0;
533 uint64_t AttributeSet::getDereferenceableBytes() const {
534 return SetNode ? SetNode->getDereferenceableBytes() : 0;
537 uint64_t AttributeSet::getDereferenceableOrNullBytes() const {
538 return SetNode ? SetNode->getDereferenceableOrNullBytes() : 0;
541 std::pair<unsigned, Optional<unsigned>> AttributeSet::getAllocSizeArgs() const {
542 return SetNode ? SetNode->getAllocSizeArgs()
543 : std::pair<unsigned, Optional<unsigned>>(0, 0);
546 std::string AttributeSet::getAsString(bool InAttrGrp) const {
547 return SetNode ? SetNode->getAsString(InAttrGrp) : "";
550 AttributeSet::iterator AttributeSet::begin() const {
551 return SetNode ? SetNode->begin() : nullptr;
554 AttributeSet::iterator AttributeSet::end() const {
555 return SetNode ? SetNode->end() : nullptr;
558 //===----------------------------------------------------------------------===//
559 // AttributeSetNode Definition
560 //===----------------------------------------------------------------------===//
562 AttributeSetNode::AttributeSetNode(ArrayRef<Attribute> Attrs)
563 : AvailableAttrs(0), NumAttrs(Attrs.size()) {
564 // There's memory after the node where we can store the entries in.
565 std::copy(Attrs.begin(), Attrs.end(), getTrailingObjects<Attribute>());
567 for (Attribute I : *this) {
568 if (!I.isStringAttribute()) {
569 AvailableAttrs |= ((uint64_t)1) << I.getKindAsEnum();
574 AttributeSetNode *AttributeSetNode::get(LLVMContext &C,
575 ArrayRef<Attribute> Attrs) {
579 // Otherwise, build a key to look up the existing attributes.
580 LLVMContextImpl *pImpl = C.pImpl;
583 SmallVector<Attribute, 8> SortedAttrs(Attrs.begin(), Attrs.end());
584 std::sort(SortedAttrs.begin(), SortedAttrs.end());
586 for (Attribute Attr : SortedAttrs)
590 AttributeSetNode *PA =
591 pImpl->AttrsSetNodes.FindNodeOrInsertPos(ID, InsertPoint);
593 // If we didn't find any existing attributes of the same shape then create a
594 // new one and insert it.
596 // Coallocate entries after the AttributeSetNode itself.
597 void *Mem = ::operator new(totalSizeToAlloc<Attribute>(SortedAttrs.size()));
598 PA = new (Mem) AttributeSetNode(SortedAttrs);
599 pImpl->AttrsSetNodes.InsertNode(PA, InsertPoint);
602 // Return the AttributeSetNode that we found or created.
606 AttributeSetNode *AttributeSetNode::get(LLVMContext &C, const AttrBuilder &B) {
607 // Add target-independent attributes.
608 SmallVector<Attribute, 8> Attrs;
609 for (Attribute::AttrKind Kind = Attribute::None;
610 Kind != Attribute::EndAttrKinds; Kind = Attribute::AttrKind(Kind + 1)) {
611 if (!B.contains(Kind))
616 case Attribute::Alignment:
617 Attr = Attribute::getWithAlignment(C, B.getAlignment());
619 case Attribute::StackAlignment:
620 Attr = Attribute::getWithStackAlignment(C, B.getStackAlignment());
622 case Attribute::Dereferenceable:
623 Attr = Attribute::getWithDereferenceableBytes(
624 C, B.getDereferenceableBytes());
626 case Attribute::DereferenceableOrNull:
627 Attr = Attribute::getWithDereferenceableOrNullBytes(
628 C, B.getDereferenceableOrNullBytes());
630 case Attribute::AllocSize: {
631 auto A = B.getAllocSizeArgs();
632 Attr = Attribute::getWithAllocSizeArgs(C, A.first, A.second);
636 Attr = Attribute::get(C, Kind);
638 Attrs.push_back(Attr);
641 // Add target-dependent (string) attributes.
642 for (const auto &TDA : B.td_attrs())
643 Attrs.emplace_back(Attribute::get(C, TDA.first, TDA.second));
645 return get(C, Attrs);
648 bool AttributeSetNode::hasAttribute(StringRef Kind) const {
649 for (Attribute I : *this)
650 if (I.hasAttribute(Kind))
655 Attribute AttributeSetNode::getAttribute(Attribute::AttrKind Kind) const {
656 if (hasAttribute(Kind)) {
657 for (Attribute I : *this)
658 if (I.hasAttribute(Kind))
664 Attribute AttributeSetNode::getAttribute(StringRef Kind) const {
665 for (Attribute I : *this)
666 if (I.hasAttribute(Kind))
671 unsigned AttributeSetNode::getAlignment() const {
672 for (Attribute I : *this)
673 if (I.hasAttribute(Attribute::Alignment))
674 return I.getAlignment();
678 unsigned AttributeSetNode::getStackAlignment() const {
679 for (Attribute I : *this)
680 if (I.hasAttribute(Attribute::StackAlignment))
681 return I.getStackAlignment();
685 uint64_t AttributeSetNode::getDereferenceableBytes() const {
686 for (Attribute I : *this)
687 if (I.hasAttribute(Attribute::Dereferenceable))
688 return I.getDereferenceableBytes();
692 uint64_t AttributeSetNode::getDereferenceableOrNullBytes() const {
693 for (Attribute I : *this)
694 if (I.hasAttribute(Attribute::DereferenceableOrNull))
695 return I.getDereferenceableOrNullBytes();
699 std::pair<unsigned, Optional<unsigned>>
700 AttributeSetNode::getAllocSizeArgs() const {
701 for (Attribute I : *this)
702 if (I.hasAttribute(Attribute::AllocSize))
703 return I.getAllocSizeArgs();
704 return std::make_pair(0, 0);
707 std::string AttributeSetNode::getAsString(bool InAttrGrp) const {
709 for (iterator I = begin(), E = end(); I != E; ++I) {
712 Str += I->getAsString(InAttrGrp);
717 //===----------------------------------------------------------------------===//
718 // AttributeListImpl Definition
719 //===----------------------------------------------------------------------===//
721 AttributeListImpl::AttributeListImpl(
722 LLVMContext &C, ArrayRef<std::pair<unsigned, AttributeSet>> Slots)
723 : Context(C), NumSlots(Slots.size()), AvailableFunctionAttrs(0) {
725 assert(!Slots.empty() && "pointless AttributeListImpl");
726 if (Slots.size() >= 2) {
727 auto &PrevPair = Slots.front();
728 for (auto &CurPair : Slots.drop_front()) {
729 assert(PrevPair.first <= CurPair.first && "Attribute set not ordered!");
734 // There's memory after the node where we can store the entries in.
735 std::copy(Slots.begin(), Slots.end(), getTrailingObjects<IndexAttrPair>());
737 // Initialize AvailableFunctionAttrs summary bitset.
738 static_assert(Attribute::EndAttrKinds <=
739 sizeof(AvailableFunctionAttrs) * CHAR_BIT,
740 "Too many attributes");
741 static_assert(AttributeList::FunctionIndex == ~0u,
742 "FunctionIndex should be biggest possible index");
743 const auto &Last = Slots.back();
744 if (Last.first == AttributeList::FunctionIndex) {
745 AttributeSet Node = Last.second;
746 for (Attribute I : Node) {
747 if (!I.isStringAttribute())
748 AvailableFunctionAttrs |= ((uint64_t)1) << I.getKindAsEnum();
753 void AttributeListImpl::Profile(FoldingSetNodeID &ID) const {
754 Profile(ID, makeArrayRef(getSlotPair(0), getNumSlots()));
757 void AttributeListImpl::Profile(
758 FoldingSetNodeID &ID, ArrayRef<std::pair<unsigned, AttributeSet>> Nodes) {
759 for (const auto &Node : Nodes) {
760 ID.AddInteger(Node.first);
761 ID.AddPointer(Node.second.SetNode);
765 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
766 LLVM_DUMP_METHOD void AttributeListImpl::dump() const {
767 AttributeList(const_cast<AttributeListImpl *>(this)).dump();
771 //===----------------------------------------------------------------------===//
772 // AttributeList Construction and Mutation Methods
773 //===----------------------------------------------------------------------===//
775 AttributeList AttributeList::getImpl(
776 LLVMContext &C, ArrayRef<std::pair<unsigned, AttributeSet>> Attrs) {
777 assert(!Attrs.empty() && "creating pointless AttributeList");
779 unsigned LastIndex = 0;
781 for (auto &&AttrPair : Attrs) {
782 assert((IsFirst || LastIndex < AttrPair.first) &&
783 "unsorted or duplicate AttributeList indices");
784 assert(AttrPair.second.hasAttributes() && "pointless AttributeList slot");
785 LastIndex = AttrPair.first;
790 LLVMContextImpl *pImpl = C.pImpl;
792 AttributeListImpl::Profile(ID, Attrs);
795 AttributeListImpl *PA =
796 pImpl->AttrsLists.FindNodeOrInsertPos(ID, InsertPoint);
798 // If we didn't find any existing attributes of the same shape then
799 // create a new one and insert it.
801 // Coallocate entries after the AttributeListImpl itself.
802 void *Mem = ::operator new(
803 AttributeListImpl::totalSizeToAlloc<IndexAttrPair>(Attrs.size()));
804 PA = new (Mem) AttributeListImpl(C, Attrs);
805 pImpl->AttrsLists.InsertNode(PA, InsertPoint);
808 // Return the AttributesList that we found or created.
809 return AttributeList(PA);
813 AttributeList::get(LLVMContext &C,
814 ArrayRef<std::pair<unsigned, Attribute>> Attrs) {
815 // If there are no attributes then return a null AttributesList pointer.
817 return AttributeList();
819 assert(std::is_sorted(Attrs.begin(), Attrs.end(),
820 [](const std::pair<unsigned, Attribute> &LHS,
821 const std::pair<unsigned, Attribute> &RHS) {
822 return LHS.first < RHS.first;
823 }) && "Misordered Attributes list!");
824 assert(none_of(Attrs,
825 [](const std::pair<unsigned, Attribute> &Pair) {
826 return Pair.second.hasAttribute(Attribute::None);
828 "Pointless attribute!");
830 // Create a vector if (unsigned, AttributeSetNode*) pairs from the attributes
832 SmallVector<std::pair<unsigned, AttributeSet>, 8> AttrPairVec;
833 for (ArrayRef<std::pair<unsigned, Attribute>>::iterator I = Attrs.begin(),
834 E = Attrs.end(); I != E; ) {
835 unsigned Index = I->first;
836 SmallVector<Attribute, 4> AttrVec;
837 while (I != E && I->first == Index) {
838 AttrVec.push_back(I->second);
842 AttrPairVec.emplace_back(Index, AttributeSet::get(C, AttrVec));
845 return getImpl(C, AttrPairVec);
849 AttributeList::get(LLVMContext &C,
850 ArrayRef<std::pair<unsigned, AttributeSet>> Attrs) {
851 // If there are no attributes then return a null AttributesList pointer.
853 return AttributeList();
855 return getImpl(C, Attrs);
858 AttributeList AttributeList::get(LLVMContext &C, AttributeSet FnAttrs,
859 AttributeSet RetAttrs,
860 ArrayRef<AttributeSet> ArgAttrs) {
861 SmallVector<std::pair<unsigned, AttributeSet>, 8> AttrPairs;
862 if (RetAttrs.hasAttributes())
863 AttrPairs.emplace_back(ReturnIndex, RetAttrs);
865 for (AttributeSet AS : ArgAttrs) {
866 if (AS.hasAttributes())
867 AttrPairs.emplace_back(Index, AS);
870 if (FnAttrs.hasAttributes())
871 AttrPairs.emplace_back(FunctionIndex, FnAttrs);
872 if (AttrPairs.empty())
873 return AttributeList();
874 return getImpl(C, AttrPairs);
877 AttributeList AttributeList::get(LLVMContext &C, unsigned Index,
878 const AttrBuilder &B) {
879 if (!B.hasAttributes())
880 return AttributeList();
881 AttributeSet AS = AttributeSet::get(C, B);
882 std::pair<unsigned, AttributeSet> Arr[1] = {{Index, AS}};
883 return getImpl(C, Arr);
886 AttributeList AttributeList::get(LLVMContext &C, unsigned Index,
887 ArrayRef<Attribute::AttrKind> Kinds) {
888 SmallVector<std::pair<unsigned, Attribute>, 8> Attrs;
889 for (Attribute::AttrKind K : Kinds)
890 Attrs.emplace_back(Index, Attribute::get(C, K));
891 return get(C, Attrs);
894 AttributeList AttributeList::get(LLVMContext &C, unsigned Index,
895 ArrayRef<StringRef> Kinds) {
896 SmallVector<std::pair<unsigned, Attribute>, 8> Attrs;
897 for (StringRef K : Kinds)
898 Attrs.emplace_back(Index, Attribute::get(C, K));
899 return get(C, Attrs);
902 AttributeList AttributeList::get(LLVMContext &C,
903 ArrayRef<AttributeList> Attrs) {
905 return AttributeList();
906 if (Attrs.size() == 1) return Attrs[0];
908 SmallVector<std::pair<unsigned, AttributeSet>, 8> AttrNodeVec;
909 AttributeListImpl *A0 = Attrs[0].pImpl;
911 AttrNodeVec.append(A0->getSlotPair(0), A0->getSlotPair(A0->getNumSlots()));
912 // Copy all attributes from Attrs into AttrNodeVec while keeping AttrNodeVec
913 // ordered by index. Because we know that each list in Attrs is ordered by
914 // index we only need to merge each successive list in rather than doing a
916 for (unsigned I = 1, E = Attrs.size(); I != E; ++I) {
917 AttributeListImpl *ALI = Attrs[I].pImpl;
919 SmallVector<std::pair<unsigned, AttributeSet>, 8>::iterator
920 ANVI = AttrNodeVec.begin(), ANVE;
921 for (const IndexAttrPair *AI = ALI->getSlotPair(0),
922 *AE = ALI->getSlotPair(ALI->getNumSlots());
924 ANVE = AttrNodeVec.end();
925 while (ANVI != ANVE && ANVI->first <= AI->first)
927 ANVI = AttrNodeVec.insert(ANVI, *AI) + 1;
931 return getImpl(C, AttrNodeVec);
934 AttributeList AttributeList::addAttribute(LLVMContext &C, unsigned Index,
935 Attribute::AttrKind Kind) const {
936 if (hasAttribute(Index, Kind)) return *this;
937 return addAttributes(C, Index, AttributeList::get(C, Index, Kind));
940 AttributeList AttributeList::addAttribute(LLVMContext &C, unsigned Index,
942 StringRef Value) const {
944 B.addAttribute(Kind, Value);
945 return addAttributes(C, Index, AttributeList::get(C, Index, B));
948 AttributeList AttributeList::addAttribute(LLVMContext &C,
949 ArrayRef<unsigned> Indices,
951 assert(std::is_sorted(Indices.begin(), Indices.end()));
953 unsigned I = 0, E = pImpl ? pImpl->getNumSlots() : 0;
954 SmallVector<IndexAttrPair, 4> AttrVec;
955 for (unsigned Index : Indices) {
956 // Add all attribute slots before the current index.
957 for (; I < E && getSlotIndex(I) < Index; ++I)
958 AttrVec.emplace_back(getSlotIndex(I), pImpl->getSlotAttributes(I));
960 // Add the attribute at this index. If we already have attributes at this
961 // index, merge them into a new set.
963 if (I < E && getSlotIndex(I) == Index) {
964 B.merge(AttrBuilder(pImpl->getSlotAttributes(I)));
968 AttrVec.emplace_back(Index, AttributeSet::get(C, B));
971 // Add remaining attributes.
973 AttrVec.emplace_back(getSlotIndex(I), pImpl->getSlotAttributes(I));
975 return get(C, AttrVec);
978 AttributeList AttributeList::addAttributes(LLVMContext &C, unsigned Index,
979 AttributeList Attrs) const {
980 if (!pImpl) return Attrs;
981 if (!Attrs.pImpl) return *this;
983 return addAttributes(C, Index, Attrs.getAttributes(Index));
986 AttributeList AttributeList::addAttributes(LLVMContext &C, unsigned Index,
987 const AttrBuilder &B) const {
988 if (!B.hasAttributes())
992 return AttributeList::get(C, {{Index, AttributeSet::get(C, B)}});
995 // FIXME it is not obvious how this should work for alignment. For now, say
996 // we can't change a known alignment.
997 unsigned OldAlign = getParamAlignment(Index);
998 unsigned NewAlign = B.getAlignment();
999 assert((!OldAlign || !NewAlign || OldAlign == NewAlign) &&
1000 "Attempt to change alignment!");
1003 SmallVector<IndexAttrPair, 4> AttrVec;
1004 uint64_t NumAttrs = pImpl->getNumSlots();
1007 // Add all the attribute slots before the one we need to merge.
1008 for (I = 0; I < NumAttrs; ++I) {
1009 if (getSlotIndex(I) >= Index)
1011 AttrVec.emplace_back(getSlotIndex(I), pImpl->getSlotAttributes(I));
1014 AttrBuilder NewAttrs;
1015 if (I < NumAttrs && getSlotIndex(I) == Index) {
1016 // We need to merge the attribute sets.
1017 NewAttrs.merge(pImpl->getSlotAttributes(I));
1022 // Add the new or merged attribute set at this index.
1023 AttrVec.emplace_back(Index, AttributeSet::get(C, NewAttrs));
1025 // Add the remaining entries.
1026 for (; I < NumAttrs; ++I)
1027 AttrVec.emplace_back(getSlotIndex(I), pImpl->getSlotAttributes(I));
1029 return get(C, AttrVec);
1032 AttributeList AttributeList::removeAttribute(LLVMContext &C, unsigned Index,
1033 Attribute::AttrKind Kind) const {
1034 if (!hasAttribute(Index, Kind)) return *this;
1035 return removeAttributes(C, Index, AttributeList::get(C, Index, Kind));
1038 AttributeList AttributeList::removeAttribute(LLVMContext &C, unsigned Index,
1039 StringRef Kind) const {
1040 if (!hasAttribute(Index, Kind)) return *this;
1041 return removeAttributes(C, Index, AttributeList::get(C, Index, Kind));
1044 AttributeList AttributeList::removeAttributes(LLVMContext &C, unsigned Index,
1045 AttributeList Attrs) const {
1046 return removeAttributes(C, Index, AttrBuilder(Attrs.getAttributes(Index)));
1049 AttributeList AttributeList::removeAttributes(LLVMContext &C, unsigned Index,
1050 const AttrBuilder &Attrs) const {
1052 return AttributeList();
1054 // FIXME it is not obvious how this should work for alignment.
1055 // For now, say we can't pass in alignment, which no current use does.
1056 assert(!Attrs.hasAlignmentAttr() && "Attempt to change alignment!");
1058 // Add the attribute slots before the one we're trying to add.
1059 SmallVector<IndexAttrPair, 4> AttrSets;
1060 uint64_t NumAttrs = pImpl->getNumSlots();
1062 uint64_t LastIndex = 0;
1063 for (unsigned I = 0, E = NumAttrs; I != E; ++I) {
1064 if (getSlotIndex(I) >= Index) {
1065 if (getSlotIndex(I) == Index)
1066 B = AttrBuilder(getSlotAttributes(LastIndex++));
1070 AttrSets.push_back({getSlotIndex(I), getSlotAttributes(I)});
1073 // Remove the attributes from the existing set and add them.
1075 if (B.hasAttributes())
1076 AttrSets.push_back({Index, AttributeSet::get(C, B)});
1078 // Add the remaining attribute slots.
1079 for (unsigned I = LastIndex, E = NumAttrs; I < E; ++I)
1080 AttrSets.push_back({getSlotIndex(I), getSlotAttributes(I)});
1082 return get(C, AttrSets);
1085 AttributeList AttributeList::removeAttributes(LLVMContext &C,
1086 unsigned WithoutIndex) const {
1088 return AttributeList();
1090 SmallVector<std::pair<unsigned, AttributeSet>, 4> AttrSet;
1091 for (unsigned I = 0, E = pImpl->getNumSlots(); I != E; ++I) {
1092 unsigned Index = getSlotIndex(I);
1093 if (Index != WithoutIndex)
1094 AttrSet.push_back({Index, pImpl->getSlotAttributes(I)});
1096 return get(C, AttrSet);
1099 AttributeList AttributeList::addDereferenceableAttr(LLVMContext &C,
1101 uint64_t Bytes) const {
1103 B.addDereferenceableAttr(Bytes);
1104 return addAttributes(C, Index, AttributeList::get(C, Index, B));
1108 AttributeList::addDereferenceableOrNullAttr(LLVMContext &C, unsigned Index,
1109 uint64_t Bytes) const {
1111 B.addDereferenceableOrNullAttr(Bytes);
1112 return addAttributes(C, Index, AttributeList::get(C, Index, B));
1116 AttributeList::addAllocSizeAttr(LLVMContext &C, unsigned Index,
1117 unsigned ElemSizeArg,
1118 const Optional<unsigned> &NumElemsArg) {
1120 B.addAllocSizeAttr(ElemSizeArg, NumElemsArg);
1121 return addAttributes(C, Index, AttributeList::get(C, Index, B));
1124 //===----------------------------------------------------------------------===//
1125 // AttributeList Accessor Methods
1126 //===----------------------------------------------------------------------===//
1128 LLVMContext &AttributeList::getContext() const { return pImpl->getContext(); }
1130 AttributeSet AttributeList::getParamAttributes(unsigned ArgNo) const {
1131 return getAttributes(ArgNo + 1);
1134 AttributeSet AttributeList::getRetAttributes() const {
1135 return getAttributes(ReturnIndex);
1138 AttributeSet AttributeList::getFnAttributes() const {
1139 return getAttributes(FunctionIndex);
1142 bool AttributeList::hasAttribute(unsigned Index,
1143 Attribute::AttrKind Kind) const {
1144 return getAttributes(Index).hasAttribute(Kind);
1147 bool AttributeList::hasAttribute(unsigned Index, StringRef Kind) const {
1148 return getAttributes(Index).hasAttribute(Kind);
1151 bool AttributeList::hasAttributes(unsigned Index) const {
1152 return getAttributes(Index).hasAttributes();
1155 bool AttributeList::hasFnAttribute(Attribute::AttrKind Kind) const {
1156 return pImpl && pImpl->hasFnAttribute(Kind);
1159 bool AttributeList::hasFnAttribute(StringRef Kind) const {
1160 return hasAttribute(AttributeList::FunctionIndex, Kind);
1163 bool AttributeList::hasParamAttribute(unsigned ArgNo,
1164 Attribute::AttrKind Kind) const {
1165 return hasAttribute(ArgNo + 1, Kind);
1168 bool AttributeList::hasAttrSomewhere(Attribute::AttrKind Attr,
1169 unsigned *Index) const {
1170 if (!pImpl) return false;
1172 for (unsigned I = 0, E = pImpl->getNumSlots(); I != E; ++I)
1173 for (AttributeListImpl::iterator II = pImpl->begin(I), IE = pImpl->end(I);
1175 if (II->hasAttribute(Attr)) {
1176 if (Index) *Index = pImpl->getSlotIndex(I);
1183 Attribute AttributeList::getAttribute(unsigned Index,
1184 Attribute::AttrKind Kind) const {
1185 return getAttributes(Index).getAttribute(Kind);
1188 Attribute AttributeList::getAttribute(unsigned Index, StringRef Kind) const {
1189 return getAttributes(Index).getAttribute(Kind);
1192 unsigned AttributeList::getParamAlignment(unsigned Index) const {
1193 return getAttributes(Index).getAlignment();
1196 unsigned AttributeList::getStackAlignment(unsigned Index) const {
1197 return getAttributes(Index).getStackAlignment();
1200 uint64_t AttributeList::getDereferenceableBytes(unsigned Index) const {
1201 return getAttributes(Index).getDereferenceableBytes();
1204 uint64_t AttributeList::getDereferenceableOrNullBytes(unsigned Index) const {
1205 return getAttributes(Index).getDereferenceableOrNullBytes();
1208 std::pair<unsigned, Optional<unsigned>>
1209 AttributeList::getAllocSizeArgs(unsigned Index) const {
1210 return getAttributes(Index).getAllocSizeArgs();
1213 std::string AttributeList::getAsString(unsigned Index, bool InAttrGrp) const {
1214 return getAttributes(Index).getAsString(InAttrGrp);
1217 AttributeSet AttributeList::getAttributes(unsigned Index) const {
1218 if (!pImpl) return AttributeSet();
1220 // Loop through to find the attribute node we want.
1221 for (unsigned I = 0, E = pImpl->getNumSlots(); I != E; ++I)
1222 if (pImpl->getSlotIndex(I) == Index)
1223 return pImpl->getSlotAttributes(I);
1225 return AttributeSet();
1228 AttributeList::iterator AttributeList::begin(unsigned Slot) const {
1230 return ArrayRef<Attribute>().begin();
1231 return pImpl->begin(Slot);
1234 AttributeList::iterator AttributeList::end(unsigned Slot) const {
1236 return ArrayRef<Attribute>().end();
1237 return pImpl->end(Slot);
1240 //===----------------------------------------------------------------------===//
1241 // AttributeList Introspection Methods
1242 //===----------------------------------------------------------------------===//
1244 unsigned AttributeList::getNumSlots() const {
1245 return pImpl ? pImpl->getNumSlots() : 0;
1248 unsigned AttributeList::getSlotIndex(unsigned Slot) const {
1249 assert(pImpl && Slot < pImpl->getNumSlots() &&
1250 "Slot # out of range!");
1251 return pImpl->getSlotIndex(Slot);
1254 AttributeSet AttributeList::getSlotAttributes(unsigned Slot) const {
1255 assert(pImpl && Slot < pImpl->getNumSlots() &&
1256 "Slot # out of range!");
1257 return pImpl->getSlotAttributes(Slot);
1260 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1261 LLVM_DUMP_METHOD void AttributeList::dump() const {
1264 for (unsigned i = 0, e = getNumSlots(); i < e; ++i) {
1265 uint64_t Index = getSlotIndex(i);
1271 dbgs() << " => " << getAsString(Index) << " }\n";
1278 //===----------------------------------------------------------------------===//
1279 // AttrBuilder Method Implementations
1280 //===----------------------------------------------------------------------===//
1282 AttrBuilder::AttrBuilder(AttributeList AL, unsigned Index) {
1283 AttributeListImpl *pImpl = AL.pImpl;
1286 for (unsigned I = 0, E = pImpl->getNumSlots(); I != E; ++I) {
1287 if (pImpl->getSlotIndex(I) != Index) continue;
1289 for (AttributeListImpl::iterator II = pImpl->begin(I), IE = pImpl->end(I);
1297 AttrBuilder::AttrBuilder(AttributeSet AS) {
1298 if (AS.hasAttributes()) {
1299 for (const Attribute &A : AS)
1304 void AttrBuilder::clear() {
1306 TargetDepAttrs.clear();
1307 Alignment = StackAlignment = DerefBytes = DerefOrNullBytes = 0;
1311 AttrBuilder &AttrBuilder::addAttribute(Attribute::AttrKind Val) {
1312 assert((unsigned)Val < Attribute::EndAttrKinds && "Attribute out of range!");
1313 assert(Val != Attribute::Alignment && Val != Attribute::StackAlignment &&
1314 Val != Attribute::Dereferenceable && Val != Attribute::AllocSize &&
1315 "Adding integer attribute without adding a value!");
1320 AttrBuilder &AttrBuilder::addAttribute(Attribute Attr) {
1321 if (Attr.isStringAttribute()) {
1322 addAttribute(Attr.getKindAsString(), Attr.getValueAsString());
1326 Attribute::AttrKind Kind = Attr.getKindAsEnum();
1329 if (Kind == Attribute::Alignment)
1330 Alignment = Attr.getAlignment();
1331 else if (Kind == Attribute::StackAlignment)
1332 StackAlignment = Attr.getStackAlignment();
1333 else if (Kind == Attribute::Dereferenceable)
1334 DerefBytes = Attr.getDereferenceableBytes();
1335 else if (Kind == Attribute::DereferenceableOrNull)
1336 DerefOrNullBytes = Attr.getDereferenceableOrNullBytes();
1337 else if (Kind == Attribute::AllocSize)
1338 AllocSizeArgs = Attr.getValueAsInt();
1342 AttrBuilder &AttrBuilder::addAttribute(StringRef A, StringRef V) {
1343 TargetDepAttrs[A] = V;
1347 AttrBuilder &AttrBuilder::removeAttribute(Attribute::AttrKind Val) {
1348 assert((unsigned)Val < Attribute::EndAttrKinds && "Attribute out of range!");
1351 if (Val == Attribute::Alignment)
1353 else if (Val == Attribute::StackAlignment)
1355 else if (Val == Attribute::Dereferenceable)
1357 else if (Val == Attribute::DereferenceableOrNull)
1358 DerefOrNullBytes = 0;
1359 else if (Val == Attribute::AllocSize)
1365 AttrBuilder &AttrBuilder::removeAttributes(AttributeList A, uint64_t Index) {
1366 for (Attribute Attr : A.getAttributes(Index)) {
1367 if (Attr.isEnumAttribute() || Attr.isIntAttribute()) {
1368 removeAttribute(Attr.getKindAsEnum());
1370 assert(Attr.isStringAttribute() && "Invalid attribute type!");
1371 removeAttribute(Attr.getKindAsString());
1378 AttrBuilder &AttrBuilder::removeAttribute(StringRef A) {
1379 std::map<std::string, std::string>::iterator I = TargetDepAttrs.find(A);
1380 if (I != TargetDepAttrs.end())
1381 TargetDepAttrs.erase(I);
1385 std::pair<unsigned, Optional<unsigned>> AttrBuilder::getAllocSizeArgs() const {
1386 return unpackAllocSizeArgs(AllocSizeArgs);
1389 AttrBuilder &AttrBuilder::addAlignmentAttr(unsigned Align) {
1390 if (Align == 0) return *this;
1392 assert(isPowerOf2_32(Align) && "Alignment must be a power of two.");
1393 assert(Align <= 0x40000000 && "Alignment too large.");
1395 Attrs[Attribute::Alignment] = true;
1400 AttrBuilder &AttrBuilder::addStackAlignmentAttr(unsigned Align) {
1401 // Default alignment, allow the target to define how to align it.
1402 if (Align == 0) return *this;
1404 assert(isPowerOf2_32(Align) && "Alignment must be a power of two.");
1405 assert(Align <= 0x100 && "Alignment too large.");
1407 Attrs[Attribute::StackAlignment] = true;
1408 StackAlignment = Align;
1412 AttrBuilder &AttrBuilder::addDereferenceableAttr(uint64_t Bytes) {
1413 if (Bytes == 0) return *this;
1415 Attrs[Attribute::Dereferenceable] = true;
1420 AttrBuilder &AttrBuilder::addDereferenceableOrNullAttr(uint64_t Bytes) {
1424 Attrs[Attribute::DereferenceableOrNull] = true;
1425 DerefOrNullBytes = Bytes;
1429 AttrBuilder &AttrBuilder::addAllocSizeAttr(unsigned ElemSize,
1430 const Optional<unsigned> &NumElems) {
1431 return addAllocSizeAttrFromRawRepr(packAllocSizeArgs(ElemSize, NumElems));
1434 AttrBuilder &AttrBuilder::addAllocSizeAttrFromRawRepr(uint64_t RawArgs) {
1435 // (0, 0) is our "not present" value, so we need to check for it here.
1436 assert(RawArgs && "Invalid allocsize arguments -- given allocsize(0, 0)");
1438 Attrs[Attribute::AllocSize] = true;
1439 // Reuse existing machinery to store this as a single 64-bit integer so we can
1440 // save a few bytes over using a pair<unsigned, Optional<unsigned>>.
1441 AllocSizeArgs = RawArgs;
1445 AttrBuilder &AttrBuilder::merge(const AttrBuilder &B) {
1446 // FIXME: What if both have alignments, but they don't match?!
1448 Alignment = B.Alignment;
1450 if (!StackAlignment)
1451 StackAlignment = B.StackAlignment;
1454 DerefBytes = B.DerefBytes;
1456 if (!DerefOrNullBytes)
1457 DerefOrNullBytes = B.DerefOrNullBytes;
1460 AllocSizeArgs = B.AllocSizeArgs;
1464 for (auto I : B.td_attrs())
1465 TargetDepAttrs[I.first] = I.second;
1470 AttrBuilder &AttrBuilder::remove(const AttrBuilder &B) {
1471 // FIXME: What if both have alignments, but they don't match?!
1475 if (B.StackAlignment)
1481 if (B.DerefOrNullBytes)
1482 DerefOrNullBytes = 0;
1484 if (B.AllocSizeArgs)
1489 for (auto I : B.td_attrs())
1490 TargetDepAttrs.erase(I.first);
1495 bool AttrBuilder::overlaps(const AttrBuilder &B) const {
1496 // First check if any of the target independent attributes overlap.
1497 if ((Attrs & B.Attrs).any())
1500 // Then check if any target dependent ones do.
1501 for (const auto &I : td_attrs())
1502 if (B.contains(I.first))
1508 bool AttrBuilder::contains(StringRef A) const {
1509 return TargetDepAttrs.find(A) != TargetDepAttrs.end();
1512 bool AttrBuilder::hasAttributes() const {
1513 return !Attrs.none() || !TargetDepAttrs.empty();
1516 bool AttrBuilder::hasAttributes(AttributeList A, uint64_t Index) const {
1517 unsigned Slot = ~0U;
1518 for (unsigned I = 0, E = A.getNumSlots(); I != E; ++I)
1519 if (A.getSlotIndex(I) == Index) {
1524 assert(Slot != ~0U && "Couldn't find the index!");
1526 for (AttributeList::iterator I = A.begin(Slot), E = A.end(Slot); I != E;
1528 Attribute Attr = *I;
1529 if (Attr.isEnumAttribute() || Attr.isIntAttribute()) {
1530 if (Attrs[I->getKindAsEnum()])
1533 assert(Attr.isStringAttribute() && "Invalid attribute kind!");
1534 return TargetDepAttrs.find(Attr.getKindAsString())!=TargetDepAttrs.end();
1541 bool AttrBuilder::hasAlignmentAttr() const {
1542 return Alignment != 0;
1545 bool AttrBuilder::operator==(const AttrBuilder &B) {
1546 if (Attrs != B.Attrs)
1549 for (td_const_iterator I = TargetDepAttrs.begin(),
1550 E = TargetDepAttrs.end(); I != E; ++I)
1551 if (B.TargetDepAttrs.find(I->first) == B.TargetDepAttrs.end())
1554 return Alignment == B.Alignment && StackAlignment == B.StackAlignment &&
1555 DerefBytes == B.DerefBytes;
1558 //===----------------------------------------------------------------------===//
1559 // AttributeFuncs Function Defintions
1560 //===----------------------------------------------------------------------===//
1562 /// \brief Which attributes cannot be applied to a type.
1563 AttrBuilder AttributeFuncs::typeIncompatible(Type *Ty) {
1564 AttrBuilder Incompatible;
1566 if (!Ty->isIntegerTy())
1567 // Attribute that only apply to integers.
1568 Incompatible.addAttribute(Attribute::SExt)
1569 .addAttribute(Attribute::ZExt);
1571 if (!Ty->isPointerTy())
1572 // Attribute that only apply to pointers.
1573 Incompatible.addAttribute(Attribute::ByVal)
1574 .addAttribute(Attribute::Nest)
1575 .addAttribute(Attribute::NoAlias)
1576 .addAttribute(Attribute::NoCapture)
1577 .addAttribute(Attribute::NonNull)
1578 .addDereferenceableAttr(1) // the int here is ignored
1579 .addDereferenceableOrNullAttr(1) // the int here is ignored
1580 .addAttribute(Attribute::ReadNone)
1581 .addAttribute(Attribute::ReadOnly)
1582 .addAttribute(Attribute::StructRet)
1583 .addAttribute(Attribute::InAlloca);
1585 return Incompatible;
1588 template<typename AttrClass>
1589 static bool isEqual(const Function &Caller, const Function &Callee) {
1590 return Caller.getFnAttribute(AttrClass::getKind()) ==
1591 Callee.getFnAttribute(AttrClass::getKind());
1594 /// \brief Compute the logical AND of the attributes of the caller and the
1597 /// This function sets the caller's attribute to false if the callee's attribute
1599 template<typename AttrClass>
1600 static void setAND(Function &Caller, const Function &Callee) {
1601 if (AttrClass::isSet(Caller, AttrClass::getKind()) &&
1602 !AttrClass::isSet(Callee, AttrClass::getKind()))
1603 AttrClass::set(Caller, AttrClass::getKind(), false);
1606 /// \brief Compute the logical OR of the attributes of the caller and the
1609 /// This function sets the caller's attribute to true if the callee's attribute
1611 template<typename AttrClass>
1612 static void setOR(Function &Caller, const Function &Callee) {
1613 if (!AttrClass::isSet(Caller, AttrClass::getKind()) &&
1614 AttrClass::isSet(Callee, AttrClass::getKind()))
1615 AttrClass::set(Caller, AttrClass::getKind(), true);
1618 /// \brief If the inlined function had a higher stack protection level than the
1619 /// calling function, then bump up the caller's stack protection level.
1620 static void adjustCallerSSPLevel(Function &Caller, const Function &Callee) {
1621 // If upgrading the SSP attribute, clear out the old SSP Attributes first.
1622 // Having multiple SSP attributes doesn't actually hurt, but it adds useless
1623 // clutter to the IR.
1625 B.addAttribute(Attribute::StackProtect)
1626 .addAttribute(Attribute::StackProtectStrong)
1627 .addAttribute(Attribute::StackProtectReq);
1628 AttributeList OldSSPAttr =
1629 AttributeList::get(Caller.getContext(), AttributeList::FunctionIndex, B);
1631 if (Callee.hasFnAttribute(Attribute::StackProtectReq)) {
1632 Caller.removeAttributes(AttributeList::FunctionIndex, OldSSPAttr);
1633 Caller.addFnAttr(Attribute::StackProtectReq);
1634 } else if (Callee.hasFnAttribute(Attribute::StackProtectStrong) &&
1635 !Caller.hasFnAttribute(Attribute::StackProtectReq)) {
1636 Caller.removeAttributes(AttributeList::FunctionIndex, OldSSPAttr);
1637 Caller.addFnAttr(Attribute::StackProtectStrong);
1638 } else if (Callee.hasFnAttribute(Attribute::StackProtect) &&
1639 !Caller.hasFnAttribute(Attribute::StackProtectReq) &&
1640 !Caller.hasFnAttribute(Attribute::StackProtectStrong))
1641 Caller.addFnAttr(Attribute::StackProtect);
1644 #define GET_ATTR_COMPAT_FUNC
1645 #include "AttributesCompatFunc.inc"
1647 bool AttributeFuncs::areInlineCompatible(const Function &Caller,
1648 const Function &Callee) {
1649 return hasCompatibleFnAttrs(Caller, Callee);
1652 void AttributeFuncs::mergeAttributesForInlining(Function &Caller,
1653 const Function &Callee) {
1654 mergeFnAttrs(Caller, Callee);