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/StringSwitch.h"
26 #include "llvm/ADT/Twine.h"
27 #include "llvm/Config/llvm-config.h"
28 #include "llvm/IR/Function.h"
29 #include "llvm/IR/LLVMContext.h"
30 #include "llvm/IR/Type.h"
31 #include "llvm/Support/Compiler.h"
32 #include "llvm/Support/Debug.h"
33 #include "llvm/Support/ErrorHandling.h"
34 #include "llvm/Support/MathExtras.h"
35 #include "llvm/Support/raw_ostream.h"
48 //===----------------------------------------------------------------------===//
49 // Attribute Construction Methods
50 //===----------------------------------------------------------------------===//
52 // allocsize has two integer arguments, but because they're both 32 bits, we can
53 // pack them into one 64-bit value, at the cost of making said value
56 // In order to do this, we need to reserve one value of the second (optional)
57 // allocsize argument to signify "not present."
58 static const unsigned AllocSizeNumElemsNotPresent
= -1;
60 static uint64_t packAllocSizeArgs(unsigned ElemSizeArg
,
61 const Optional
<unsigned> &NumElemsArg
) {
62 assert((!NumElemsArg
.hasValue() ||
63 *NumElemsArg
!= AllocSizeNumElemsNotPresent
) &&
64 "Attempting to pack a reserved value");
66 return uint64_t(ElemSizeArg
) << 32 |
67 NumElemsArg
.getValueOr(AllocSizeNumElemsNotPresent
);
70 static std::pair
<unsigned, Optional
<unsigned>>
71 unpackAllocSizeArgs(uint64_t Num
) {
72 unsigned NumElems
= Num
& std::numeric_limits
<unsigned>::max();
73 unsigned ElemSizeArg
= Num
>> 32;
75 Optional
<unsigned> NumElemsArg
;
76 if (NumElems
!= AllocSizeNumElemsNotPresent
)
77 NumElemsArg
= NumElems
;
78 return std::make_pair(ElemSizeArg
, NumElemsArg
);
81 static uint64_t packVScaleRangeArgs(unsigned MinValue
, unsigned MaxValue
) {
82 return uint64_t(MinValue
) << 32 | MaxValue
;
85 static std::pair
<unsigned, unsigned> unpackVScaleRangeArgs(uint64_t Value
) {
86 unsigned MaxValue
= Value
& std::numeric_limits
<unsigned>::max();
87 unsigned MinValue
= Value
>> 32;
89 return std::make_pair(MinValue
, MaxValue
);
92 Attribute
Attribute::get(LLVMContext
&Context
, Attribute::AttrKind Kind
,
95 assert(Attribute::isIntAttrKind(Kind
) && "Not an int attribute");
97 assert(Attribute::isEnumAttrKind(Kind
) && "Not an enum attribute");
99 LLVMContextImpl
*pImpl
= Context
.pImpl
;
102 if (Val
) ID
.AddInteger(Val
);
105 AttributeImpl
*PA
= pImpl
->AttrsSet
.FindNodeOrInsertPos(ID
, InsertPoint
);
108 // If we didn't find any existing attributes of the same shape then create a
109 // new one and insert it.
111 PA
= new (pImpl
->Alloc
) EnumAttributeImpl(Kind
);
113 PA
= new (pImpl
->Alloc
) IntAttributeImpl(Kind
, Val
);
114 pImpl
->AttrsSet
.InsertNode(PA
, InsertPoint
);
117 // Return the Attribute that we found or created.
118 return Attribute(PA
);
121 Attribute
Attribute::get(LLVMContext
&Context
, StringRef Kind
, StringRef Val
) {
122 LLVMContextImpl
*pImpl
= Context
.pImpl
;
125 if (!Val
.empty()) ID
.AddString(Val
);
128 AttributeImpl
*PA
= pImpl
->AttrsSet
.FindNodeOrInsertPos(ID
, InsertPoint
);
131 // If we didn't find any existing attributes of the same shape then create a
132 // new one and insert it.
134 pImpl
->Alloc
.Allocate(StringAttributeImpl::totalSizeToAlloc(Kind
, Val
),
135 alignof(StringAttributeImpl
));
136 PA
= new (Mem
) StringAttributeImpl(Kind
, Val
);
137 pImpl
->AttrsSet
.InsertNode(PA
, InsertPoint
);
140 // Return the Attribute that we found or created.
141 return Attribute(PA
);
144 Attribute
Attribute::get(LLVMContext
&Context
, Attribute::AttrKind Kind
,
146 assert(Attribute::isTypeAttrKind(Kind
) && "Not a type attribute");
147 LLVMContextImpl
*pImpl
= Context
.pImpl
;
153 AttributeImpl
*PA
= pImpl
->AttrsSet
.FindNodeOrInsertPos(ID
, InsertPoint
);
156 // If we didn't find any existing attributes of the same shape then create a
157 // new one and insert it.
158 PA
= new (pImpl
->Alloc
) TypeAttributeImpl(Kind
, Ty
);
159 pImpl
->AttrsSet
.InsertNode(PA
, InsertPoint
);
162 // Return the Attribute that we found or created.
163 return Attribute(PA
);
166 Attribute
Attribute::getWithAlignment(LLVMContext
&Context
, Align A
) {
167 assert(A
<= llvm::Value::MaximumAlignment
&& "Alignment too large.");
168 return get(Context
, Alignment
, A
.value());
171 Attribute
Attribute::getWithStackAlignment(LLVMContext
&Context
, Align A
) {
172 assert(A
<= 0x100 && "Alignment too large.");
173 return get(Context
, StackAlignment
, A
.value());
176 Attribute
Attribute::getWithDereferenceableBytes(LLVMContext
&Context
,
178 assert(Bytes
&& "Bytes must be non-zero.");
179 return get(Context
, Dereferenceable
, Bytes
);
182 Attribute
Attribute::getWithDereferenceableOrNullBytes(LLVMContext
&Context
,
184 assert(Bytes
&& "Bytes must be non-zero.");
185 return get(Context
, DereferenceableOrNull
, Bytes
);
188 Attribute
Attribute::getWithByValType(LLVMContext
&Context
, Type
*Ty
) {
189 return get(Context
, ByVal
, Ty
);
192 Attribute
Attribute::getWithStructRetType(LLVMContext
&Context
, Type
*Ty
) {
193 return get(Context
, StructRet
, Ty
);
196 Attribute
Attribute::getWithByRefType(LLVMContext
&Context
, Type
*Ty
) {
197 return get(Context
, ByRef
, Ty
);
200 Attribute
Attribute::getWithPreallocatedType(LLVMContext
&Context
, Type
*Ty
) {
201 return get(Context
, Preallocated
, Ty
);
204 Attribute
Attribute::getWithInAllocaType(LLVMContext
&Context
, Type
*Ty
) {
205 return get(Context
, InAlloca
, Ty
);
209 Attribute::getWithAllocSizeArgs(LLVMContext
&Context
, unsigned ElemSizeArg
,
210 const Optional
<unsigned> &NumElemsArg
) {
211 assert(!(ElemSizeArg
== 0 && NumElemsArg
&& *NumElemsArg
== 0) &&
212 "Invalid allocsize arguments -- given allocsize(0, 0)");
213 return get(Context
, AllocSize
, packAllocSizeArgs(ElemSizeArg
, NumElemsArg
));
216 Attribute
Attribute::getWithVScaleRangeArgs(LLVMContext
&Context
,
219 return get(Context
, VScaleRange
, packVScaleRangeArgs(MinValue
, MaxValue
));
222 Attribute::AttrKind
Attribute::getAttrKindFromName(StringRef AttrName
) {
223 return StringSwitch
<Attribute::AttrKind
>(AttrName
)
224 #define GET_ATTR_NAMES
225 #define ATTRIBUTE_ENUM(ENUM_NAME, DISPLAY_NAME) \
226 .Case(#DISPLAY_NAME, Attribute::ENUM_NAME)
227 #include "llvm/IR/Attributes.inc"
228 .Default(Attribute::None
);
231 StringRef
Attribute::getNameFromAttrKind(Attribute::AttrKind AttrKind
) {
233 #define GET_ATTR_NAMES
234 #define ATTRIBUTE_ENUM(ENUM_NAME, DISPLAY_NAME) \
235 case Attribute::ENUM_NAME: \
236 return #DISPLAY_NAME;
237 #include "llvm/IR/Attributes.inc"
238 case Attribute::None
:
241 llvm_unreachable("invalid Kind");
245 bool Attribute::isExistingAttribute(StringRef Name
) {
246 return StringSwitch
<bool>(Name
)
247 #define GET_ATTR_NAMES
248 #define ATTRIBUTE_ALL(ENUM_NAME, DISPLAY_NAME) .Case(#DISPLAY_NAME, true)
249 #include "llvm/IR/Attributes.inc"
253 //===----------------------------------------------------------------------===//
254 // Attribute Accessor Methods
255 //===----------------------------------------------------------------------===//
257 bool Attribute::isEnumAttribute() const {
258 return pImpl
&& pImpl
->isEnumAttribute();
261 bool Attribute::isIntAttribute() const {
262 return pImpl
&& pImpl
->isIntAttribute();
265 bool Attribute::isStringAttribute() const {
266 return pImpl
&& pImpl
->isStringAttribute();
269 bool Attribute::isTypeAttribute() const {
270 return pImpl
&& pImpl
->isTypeAttribute();
273 Attribute::AttrKind
Attribute::getKindAsEnum() const {
274 if (!pImpl
) return None
;
275 assert((isEnumAttribute() || isIntAttribute() || isTypeAttribute()) &&
276 "Invalid attribute type to get the kind as an enum!");
277 return pImpl
->getKindAsEnum();
280 uint64_t Attribute::getValueAsInt() const {
281 if (!pImpl
) return 0;
282 assert(isIntAttribute() &&
283 "Expected the attribute to be an integer attribute!");
284 return pImpl
->getValueAsInt();
287 bool Attribute::getValueAsBool() const {
288 if (!pImpl
) return false;
289 assert(isStringAttribute() &&
290 "Expected the attribute to be a string attribute!");
291 return pImpl
->getValueAsBool();
294 StringRef
Attribute::getKindAsString() const {
295 if (!pImpl
) return {};
296 assert(isStringAttribute() &&
297 "Invalid attribute type to get the kind as a string!");
298 return pImpl
->getKindAsString();
301 StringRef
Attribute::getValueAsString() const {
302 if (!pImpl
) return {};
303 assert(isStringAttribute() &&
304 "Invalid attribute type to get the value as a string!");
305 return pImpl
->getValueAsString();
308 Type
*Attribute::getValueAsType() const {
309 if (!pImpl
) return {};
310 assert(isTypeAttribute() &&
311 "Invalid attribute type to get the value as a type!");
312 return pImpl
->getValueAsType();
316 bool Attribute::hasAttribute(AttrKind Kind
) const {
317 return (pImpl
&& pImpl
->hasAttribute(Kind
)) || (!pImpl
&& Kind
== None
);
320 bool Attribute::hasAttribute(StringRef Kind
) const {
321 if (!isStringAttribute()) return false;
322 return pImpl
&& pImpl
->hasAttribute(Kind
);
325 MaybeAlign
Attribute::getAlignment() const {
326 assert(hasAttribute(Attribute::Alignment
) &&
327 "Trying to get alignment from non-alignment attribute!");
328 return MaybeAlign(pImpl
->getValueAsInt());
331 MaybeAlign
Attribute::getStackAlignment() const {
332 assert(hasAttribute(Attribute::StackAlignment
) &&
333 "Trying to get alignment from non-alignment attribute!");
334 return MaybeAlign(pImpl
->getValueAsInt());
337 uint64_t Attribute::getDereferenceableBytes() const {
338 assert(hasAttribute(Attribute::Dereferenceable
) &&
339 "Trying to get dereferenceable bytes from "
340 "non-dereferenceable attribute!");
341 return pImpl
->getValueAsInt();
344 uint64_t Attribute::getDereferenceableOrNullBytes() const {
345 assert(hasAttribute(Attribute::DereferenceableOrNull
) &&
346 "Trying to get dereferenceable bytes from "
347 "non-dereferenceable attribute!");
348 return pImpl
->getValueAsInt();
351 std::pair
<unsigned, Optional
<unsigned>> Attribute::getAllocSizeArgs() const {
352 assert(hasAttribute(Attribute::AllocSize
) &&
353 "Trying to get allocsize args from non-allocsize attribute");
354 return unpackAllocSizeArgs(pImpl
->getValueAsInt());
357 std::pair
<unsigned, unsigned> Attribute::getVScaleRangeArgs() const {
358 assert(hasAttribute(Attribute::VScaleRange
) &&
359 "Trying to get vscale args from non-vscale attribute");
360 return unpackVScaleRangeArgs(pImpl
->getValueAsInt());
363 std::string
Attribute::getAsString(bool InAttrGrp
) const {
364 if (!pImpl
) return {};
366 if (isEnumAttribute())
367 return getNameFromAttrKind(getKindAsEnum()).str();
369 if (isTypeAttribute()) {
370 std::string Result
= getNameFromAttrKind(getKindAsEnum()).str();
372 raw_string_ostream
OS(Result
);
373 getValueAsType()->print(OS
, false, true);
379 // FIXME: These should be output like this:
384 if (hasAttribute(Attribute::Alignment
)) {
387 Result
+= (InAttrGrp
) ? "=" : " ";
388 Result
+= utostr(getValueAsInt());
392 auto AttrWithBytesToString
= [&](const char *Name
) {
397 Result
+= utostr(getValueAsInt());
400 Result
+= utostr(getValueAsInt());
406 if (hasAttribute(Attribute::StackAlignment
))
407 return AttrWithBytesToString("alignstack");
409 if (hasAttribute(Attribute::Dereferenceable
))
410 return AttrWithBytesToString("dereferenceable");
412 if (hasAttribute(Attribute::DereferenceableOrNull
))
413 return AttrWithBytesToString("dereferenceable_or_null");
415 if (hasAttribute(Attribute::AllocSize
)) {
417 Optional
<unsigned> NumElems
;
418 std::tie(ElemSize
, NumElems
) = getAllocSizeArgs();
420 std::string Result
= "allocsize(";
421 Result
+= utostr(ElemSize
);
422 if (NumElems
.hasValue()) {
424 Result
+= utostr(*NumElems
);
430 if (hasAttribute(Attribute::VScaleRange
)) {
431 unsigned MinValue
, MaxValue
;
432 std::tie(MinValue
, MaxValue
) = getVScaleRangeArgs();
434 std::string Result
= "vscale_range(";
435 Result
+= utostr(MinValue
);
437 Result
+= utostr(MaxValue
);
442 // Convert target-dependent attributes to strings of the form:
447 if (isStringAttribute()) {
450 raw_string_ostream
OS(Result
);
451 OS
<< '"' << getKindAsString() << '"';
453 // Since some attribute strings contain special characters that cannot be
454 // printable, those have to be escaped to make the attribute value
455 // printable as is. e.g. "\01__gnu_mcount_nc"
456 const auto &AttrVal
= pImpl
->getValueAsString();
457 if (!AttrVal
.empty()) {
459 printEscapedString(AttrVal
, OS
);
466 llvm_unreachable("Unknown attribute");
469 bool Attribute::hasParentContext(LLVMContext
&C
) const {
470 assert(isValid() && "invalid Attribute doesn't refer to any context");
474 return C
.pImpl
->AttrsSet
.FindNodeOrInsertPos(ID
, Unused
) == pImpl
;
477 bool Attribute::operator<(Attribute A
) const {
478 if (!pImpl
&& !A
.pImpl
) return false;
479 if (!pImpl
) return true;
480 if (!A
.pImpl
) return false;
481 return *pImpl
< *A
.pImpl
;
484 void Attribute::Profile(FoldingSetNodeID
&ID
) const {
485 ID
.AddPointer(pImpl
);
488 enum AttributeProperty
{
490 ParamAttr
= (1 << 1),
494 #define GET_ATTR_PROP_TABLE
495 #include "llvm/IR/Attributes.inc"
497 static bool hasAttributeProperty(Attribute::AttrKind Kind
,
498 AttributeProperty Prop
) {
499 unsigned Index
= Kind
- 1;
500 assert(Index
< sizeof(AttrPropTable
) / sizeof(AttrPropTable
[0]) &&
501 "Invalid attribute kind");
502 return AttrPropTable
[Index
] & Prop
;
505 bool Attribute::canUseAsFnAttr(AttrKind Kind
) {
506 return hasAttributeProperty(Kind
, AttributeProperty::FnAttr
);
509 bool Attribute::canUseAsParamAttr(AttrKind Kind
) {
510 return hasAttributeProperty(Kind
, AttributeProperty::ParamAttr
);
513 bool Attribute::canUseAsRetAttr(AttrKind Kind
) {
514 return hasAttributeProperty(Kind
, AttributeProperty::RetAttr
);
517 //===----------------------------------------------------------------------===//
518 // AttributeImpl Definition
519 //===----------------------------------------------------------------------===//
521 bool AttributeImpl::hasAttribute(Attribute::AttrKind A
) const {
522 if (isStringAttribute()) return false;
523 return getKindAsEnum() == A
;
526 bool AttributeImpl::hasAttribute(StringRef Kind
) const {
527 if (!isStringAttribute()) return false;
528 return getKindAsString() == Kind
;
531 Attribute::AttrKind
AttributeImpl::getKindAsEnum() const {
532 assert(isEnumAttribute() || isIntAttribute() || isTypeAttribute());
533 return static_cast<const EnumAttributeImpl
*>(this)->getEnumKind();
536 uint64_t AttributeImpl::getValueAsInt() const {
537 assert(isIntAttribute());
538 return static_cast<const IntAttributeImpl
*>(this)->getValue();
541 bool AttributeImpl::getValueAsBool() const {
542 assert(getValueAsString().empty() || getValueAsString() == "false" || getValueAsString() == "true");
543 return getValueAsString() == "true";
546 StringRef
AttributeImpl::getKindAsString() const {
547 assert(isStringAttribute());
548 return static_cast<const StringAttributeImpl
*>(this)->getStringKind();
551 StringRef
AttributeImpl::getValueAsString() const {
552 assert(isStringAttribute());
553 return static_cast<const StringAttributeImpl
*>(this)->getStringValue();
556 Type
*AttributeImpl::getValueAsType() const {
557 assert(isTypeAttribute());
558 return static_cast<const TypeAttributeImpl
*>(this)->getTypeValue();
561 bool AttributeImpl::operator<(const AttributeImpl
&AI
) const {
565 // This sorts the attributes with Attribute::AttrKinds coming first (sorted
566 // relative to their enum value) and then strings.
567 if (!isStringAttribute()) {
568 if (AI
.isStringAttribute())
570 if (getKindAsEnum() != AI
.getKindAsEnum())
571 return getKindAsEnum() < AI
.getKindAsEnum();
572 assert(!AI
.isEnumAttribute() && "Non-unique attribute");
573 assert(!AI
.isTypeAttribute() && "Comparison of types would be unstable");
574 // TODO: Is this actually needed?
575 assert(AI
.isIntAttribute() && "Only possibility left");
576 return getValueAsInt() < AI
.getValueAsInt();
579 if (!AI
.isStringAttribute())
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);
647 // If there is nothing to remove, directly return the original set.
648 if (!B
.overlaps(Attrs
))
655 unsigned AttributeSet::getNumAttributes() const {
656 return SetNode
? SetNode
->getNumAttributes() : 0;
659 bool AttributeSet::hasAttribute(Attribute::AttrKind Kind
) const {
660 return SetNode
? SetNode
->hasAttribute(Kind
) : false;
663 bool AttributeSet::hasAttribute(StringRef Kind
) const {
664 return SetNode
? SetNode
->hasAttribute(Kind
) : false;
667 Attribute
AttributeSet::getAttribute(Attribute::AttrKind Kind
) const {
668 return SetNode
? SetNode
->getAttribute(Kind
) : Attribute();
671 Attribute
AttributeSet::getAttribute(StringRef Kind
) const {
672 return SetNode
? SetNode
->getAttribute(Kind
) : Attribute();
675 MaybeAlign
AttributeSet::getAlignment() const {
676 return SetNode
? SetNode
->getAlignment() : None
;
679 MaybeAlign
AttributeSet::getStackAlignment() const {
680 return SetNode
? SetNode
->getStackAlignment() : None
;
683 uint64_t AttributeSet::getDereferenceableBytes() const {
684 return SetNode
? SetNode
->getDereferenceableBytes() : 0;
687 uint64_t AttributeSet::getDereferenceableOrNullBytes() const {
688 return SetNode
? SetNode
->getDereferenceableOrNullBytes() : 0;
691 Type
*AttributeSet::getByRefType() const {
692 return SetNode
? SetNode
->getAttributeType(Attribute::ByRef
) : nullptr;
695 Type
*AttributeSet::getByValType() const {
696 return SetNode
? SetNode
->getAttributeType(Attribute::ByVal
) : nullptr;
699 Type
*AttributeSet::getStructRetType() const {
700 return SetNode
? SetNode
->getAttributeType(Attribute::StructRet
) : nullptr;
703 Type
*AttributeSet::getPreallocatedType() const {
704 return SetNode
? SetNode
->getAttributeType(Attribute::Preallocated
) : nullptr;
707 Type
*AttributeSet::getInAllocaType() const {
708 return SetNode
? SetNode
->getAttributeType(Attribute::InAlloca
) : nullptr;
711 Type
*AttributeSet::getElementType() const {
712 return SetNode
? SetNode
->getAttributeType(Attribute::ElementType
) : nullptr;
715 std::pair
<unsigned, Optional
<unsigned>> AttributeSet::getAllocSizeArgs() const {
716 return SetNode
? SetNode
->getAllocSizeArgs()
717 : std::pair
<unsigned, Optional
<unsigned>>(0, 0);
720 std::pair
<unsigned, unsigned> AttributeSet::getVScaleRangeArgs() const {
721 return SetNode
? SetNode
->getVScaleRangeArgs()
722 : std::pair
<unsigned, unsigned>(0, 0);
725 std::string
AttributeSet::getAsString(bool InAttrGrp
) const {
726 return SetNode
? SetNode
->getAsString(InAttrGrp
) : "";
729 bool AttributeSet::hasParentContext(LLVMContext
&C
) const {
730 assert(hasAttributes() && "empty AttributeSet doesn't refer to any context");
732 SetNode
->Profile(ID
);
734 return C
.pImpl
->AttrsSetNodes
.FindNodeOrInsertPos(ID
, Unused
) == SetNode
;
737 AttributeSet::iterator
AttributeSet::begin() const {
738 return SetNode
? SetNode
->begin() : nullptr;
741 AttributeSet::iterator
AttributeSet::end() const {
742 return SetNode
? SetNode
->end() : nullptr;
745 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
746 LLVM_DUMP_METHOD
void AttributeSet::dump() const {
749 dbgs() << getAsString(true) << " }\n";
753 //===----------------------------------------------------------------------===//
754 // AttributeSetNode Definition
755 //===----------------------------------------------------------------------===//
757 AttributeSetNode::AttributeSetNode(ArrayRef
<Attribute
> Attrs
)
758 : NumAttrs(Attrs
.size()) {
759 // There's memory after the node where we can store the entries in.
760 llvm::copy(Attrs
, getTrailingObjects
<Attribute
>());
762 for (const auto &I
: *this) {
763 if (I
.isStringAttribute())
764 StringAttrs
.insert({ I
.getKindAsString(), I
});
766 AvailableAttrs
.addAttribute(I
.getKindAsEnum());
770 AttributeSetNode
*AttributeSetNode::get(LLVMContext
&C
,
771 ArrayRef
<Attribute
> Attrs
) {
772 SmallVector
<Attribute
, 8> SortedAttrs(Attrs
.begin(), Attrs
.end());
773 llvm::sort(SortedAttrs
);
774 return getSorted(C
, SortedAttrs
);
777 AttributeSetNode
*AttributeSetNode::getSorted(LLVMContext
&C
,
778 ArrayRef
<Attribute
> SortedAttrs
) {
779 if (SortedAttrs
.empty())
782 // Build a key to look up the existing attributes.
783 LLVMContextImpl
*pImpl
= C
.pImpl
;
786 assert(llvm::is_sorted(SortedAttrs
) && "Expected sorted attributes!");
787 for (const auto &Attr
: SortedAttrs
)
791 AttributeSetNode
*PA
=
792 pImpl
->AttrsSetNodes
.FindNodeOrInsertPos(ID
, InsertPoint
);
794 // If we didn't find any existing attributes of the same shape then create a
795 // new one and insert it.
797 // Coallocate entries after the AttributeSetNode itself.
798 void *Mem
= ::operator new(totalSizeToAlloc
<Attribute
>(SortedAttrs
.size()));
799 PA
= new (Mem
) AttributeSetNode(SortedAttrs
);
800 pImpl
->AttrsSetNodes
.InsertNode(PA
, InsertPoint
);
803 // Return the AttributeSetNode that we found or created.
807 AttributeSetNode
*AttributeSetNode::get(LLVMContext
&C
, const AttrBuilder
&B
) {
808 // Add target-independent attributes.
809 SmallVector
<Attribute
, 8> Attrs
;
810 for (Attribute::AttrKind Kind
= Attribute::None
;
811 Kind
!= Attribute::EndAttrKinds
; Kind
= Attribute::AttrKind(Kind
+ 1)) {
812 if (!B
.contains(Kind
))
815 if (Attribute::isTypeAttrKind(Kind
)) {
816 Attrs
.push_back(Attribute::get(C
, Kind
, B
.getTypeAttr(Kind
)));
822 case Attribute::Alignment
:
823 assert(B
.getAlignment() && "Alignment must be set");
824 Attr
= Attribute::getWithAlignment(C
, *B
.getAlignment());
826 case Attribute::StackAlignment
:
827 assert(B
.getStackAlignment() && "StackAlignment must be set");
828 Attr
= Attribute::getWithStackAlignment(C
, *B
.getStackAlignment());
830 case Attribute::Dereferenceable
:
831 Attr
= Attribute::getWithDereferenceableBytes(
832 C
, B
.getDereferenceableBytes());
834 case Attribute::DereferenceableOrNull
:
835 Attr
= Attribute::getWithDereferenceableOrNullBytes(
836 C
, B
.getDereferenceableOrNullBytes());
838 case Attribute::AllocSize
: {
839 auto A
= B
.getAllocSizeArgs();
840 Attr
= Attribute::getWithAllocSizeArgs(C
, A
.first
, A
.second
);
843 case Attribute::VScaleRange
: {
844 auto A
= B
.getVScaleRangeArgs();
845 Attr
= Attribute::getWithVScaleRangeArgs(C
, A
.first
, A
.second
);
849 Attr
= Attribute::get(C
, Kind
);
851 Attrs
.push_back(Attr
);
854 // Add target-dependent (string) attributes.
855 for (const auto &TDA
: B
.td_attrs())
856 Attrs
.emplace_back(Attribute::get(C
, TDA
.first
, TDA
.second
));
858 return getSorted(C
, Attrs
);
861 bool AttributeSetNode::hasAttribute(StringRef Kind
) const {
862 return StringAttrs
.count(Kind
);
866 AttributeSetNode::findEnumAttribute(Attribute::AttrKind Kind
) const {
867 // Do a quick presence check.
868 if (!hasAttribute(Kind
))
871 // Attributes in a set are sorted by enum value, followed by string
872 // attributes. Binary search the one we want.
874 std::lower_bound(begin(), end() - StringAttrs
.size(), Kind
,
875 [](Attribute A
, Attribute::AttrKind Kind
) {
876 return A
.getKindAsEnum() < Kind
;
878 assert(I
!= end() && I
->hasAttribute(Kind
) && "Presence check failed?");
882 Attribute
AttributeSetNode::getAttribute(Attribute::AttrKind Kind
) const {
883 if (auto A
= findEnumAttribute(Kind
))
888 Attribute
AttributeSetNode::getAttribute(StringRef Kind
) const {
889 return StringAttrs
.lookup(Kind
);
892 MaybeAlign
AttributeSetNode::getAlignment() const {
893 if (auto A
= findEnumAttribute(Attribute::Alignment
))
894 return A
->getAlignment();
898 MaybeAlign
AttributeSetNode::getStackAlignment() const {
899 if (auto A
= findEnumAttribute(Attribute::StackAlignment
))
900 return A
->getStackAlignment();
904 Type
*AttributeSetNode::getAttributeType(Attribute::AttrKind Kind
) const {
905 if (auto A
= findEnumAttribute(Kind
))
906 return A
->getValueAsType();
910 uint64_t AttributeSetNode::getDereferenceableBytes() const {
911 if (auto A
= findEnumAttribute(Attribute::Dereferenceable
))
912 return A
->getDereferenceableBytes();
916 uint64_t AttributeSetNode::getDereferenceableOrNullBytes() const {
917 if (auto A
= findEnumAttribute(Attribute::DereferenceableOrNull
))
918 return A
->getDereferenceableOrNullBytes();
922 std::pair
<unsigned, Optional
<unsigned>>
923 AttributeSetNode::getAllocSizeArgs() const {
924 if (auto A
= findEnumAttribute(Attribute::AllocSize
))
925 return A
->getAllocSizeArgs();
926 return std::make_pair(0, 0);
929 std::pair
<unsigned, unsigned> AttributeSetNode::getVScaleRangeArgs() const {
930 if (auto A
= findEnumAttribute(Attribute::VScaleRange
))
931 return A
->getVScaleRangeArgs();
932 return std::make_pair(0, 0);
935 std::string
AttributeSetNode::getAsString(bool InAttrGrp
) const {
937 for (iterator I
= begin(), E
= end(); I
!= E
; ++I
) {
940 Str
+= I
->getAsString(InAttrGrp
);
945 //===----------------------------------------------------------------------===//
946 // AttributeListImpl Definition
947 //===----------------------------------------------------------------------===//
949 /// Map from AttributeList index to the internal array index. Adding one happens
950 /// to work, because -1 wraps around to 0.
951 static unsigned attrIdxToArrayIdx(unsigned Index
) {
955 AttributeListImpl::AttributeListImpl(ArrayRef
<AttributeSet
> Sets
)
956 : NumAttrSets(Sets
.size()) {
957 assert(!Sets
.empty() && "pointless AttributeListImpl");
959 // There's memory after the node where we can store the entries in.
960 llvm::copy(Sets
, getTrailingObjects
<AttributeSet
>());
962 // Initialize AvailableFunctionAttrs and AvailableSomewhereAttrs
964 for (const auto &I
: Sets
[attrIdxToArrayIdx(AttributeList::FunctionIndex
)])
965 if (!I
.isStringAttribute())
966 AvailableFunctionAttrs
.addAttribute(I
.getKindAsEnum());
968 for (const auto &Set
: Sets
)
969 for (const auto &I
: Set
)
970 if (!I
.isStringAttribute())
971 AvailableSomewhereAttrs
.addAttribute(I
.getKindAsEnum());
974 void AttributeListImpl::Profile(FoldingSetNodeID
&ID
) const {
975 Profile(ID
, makeArrayRef(begin(), end()));
978 void AttributeListImpl::Profile(FoldingSetNodeID
&ID
,
979 ArrayRef
<AttributeSet
> Sets
) {
980 for (const auto &Set
: Sets
)
981 ID
.AddPointer(Set
.SetNode
);
984 bool AttributeListImpl::hasAttrSomewhere(Attribute::AttrKind Kind
,
985 unsigned *Index
) const {
986 if (!AvailableSomewhereAttrs
.hasAttribute(Kind
))
990 for (unsigned I
= 0, E
= NumAttrSets
; I
!= E
; ++I
) {
991 if (begin()[I
].hasAttribute(Kind
)) {
1002 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1003 LLVM_DUMP_METHOD
void AttributeListImpl::dump() const {
1004 AttributeList(const_cast<AttributeListImpl
*>(this)).dump();
1008 //===----------------------------------------------------------------------===//
1009 // AttributeList Construction and Mutation Methods
1010 //===----------------------------------------------------------------------===//
1012 AttributeList
AttributeList::getImpl(LLVMContext
&C
,
1013 ArrayRef
<AttributeSet
> AttrSets
) {
1014 assert(!AttrSets
.empty() && "pointless AttributeListImpl");
1016 LLVMContextImpl
*pImpl
= C
.pImpl
;
1017 FoldingSetNodeID ID
;
1018 AttributeListImpl::Profile(ID
, AttrSets
);
1021 AttributeListImpl
*PA
=
1022 pImpl
->AttrsLists
.FindNodeOrInsertPos(ID
, InsertPoint
);
1024 // If we didn't find any existing attributes of the same shape then
1025 // create a new one and insert it.
1027 // Coallocate entries after the AttributeListImpl itself.
1028 void *Mem
= pImpl
->Alloc
.Allocate(
1029 AttributeListImpl::totalSizeToAlloc
<AttributeSet
>(AttrSets
.size()),
1030 alignof(AttributeListImpl
));
1031 PA
= new (Mem
) AttributeListImpl(AttrSets
);
1032 pImpl
->AttrsLists
.InsertNode(PA
, InsertPoint
);
1035 // Return the AttributesList that we found or created.
1036 return AttributeList(PA
);
1040 AttributeList::get(LLVMContext
&C
,
1041 ArrayRef
<std::pair
<unsigned, Attribute
>> Attrs
) {
1042 // If there are no attributes then return a null AttributesList pointer.
1046 assert(llvm::is_sorted(Attrs
,
1047 [](const std::pair
<unsigned, Attribute
> &LHS
,
1048 const std::pair
<unsigned, Attribute
> &RHS
) {
1049 return LHS
.first
< RHS
.first
;
1051 "Misordered Attributes list!");
1052 assert(llvm::all_of(Attrs
,
1053 [](const std::pair
<unsigned, Attribute
> &Pair
) {
1054 return Pair
.second
.isValid();
1056 "Pointless attribute!");
1058 // Create a vector if (unsigned, AttributeSetNode*) pairs from the attributes
1060 SmallVector
<std::pair
<unsigned, AttributeSet
>, 8> AttrPairVec
;
1061 for (ArrayRef
<std::pair
<unsigned, Attribute
>>::iterator I
= Attrs
.begin(),
1062 E
= Attrs
.end(); I
!= E
; ) {
1063 unsigned Index
= I
->first
;
1064 SmallVector
<Attribute
, 4> AttrVec
;
1065 while (I
!= E
&& I
->first
== Index
) {
1066 AttrVec
.push_back(I
->second
);
1070 AttrPairVec
.emplace_back(Index
, AttributeSet::get(C
, AttrVec
));
1073 return get(C
, AttrPairVec
);
1077 AttributeList::get(LLVMContext
&C
,
1078 ArrayRef
<std::pair
<unsigned, AttributeSet
>> Attrs
) {
1079 // If there are no attributes then return a null AttributesList pointer.
1083 assert(llvm::is_sorted(Attrs
,
1084 [](const std::pair
<unsigned, AttributeSet
> &LHS
,
1085 const std::pair
<unsigned, AttributeSet
> &RHS
) {
1086 return LHS
.first
< RHS
.first
;
1088 "Misordered Attributes list!");
1089 assert(llvm::none_of(Attrs
,
1090 [](const std::pair
<unsigned, AttributeSet
> &Pair
) {
1091 return !Pair
.second
.hasAttributes();
1093 "Pointless attribute!");
1095 unsigned MaxIndex
= Attrs
.back().first
;
1096 // If the MaxIndex is FunctionIndex and there are other indices in front
1097 // of it, we need to use the largest of those to get the right size.
1098 if (MaxIndex
== FunctionIndex
&& Attrs
.size() > 1)
1099 MaxIndex
= Attrs
[Attrs
.size() - 2].first
;
1101 SmallVector
<AttributeSet
, 4> AttrVec(attrIdxToArrayIdx(MaxIndex
) + 1);
1102 for (const auto &Pair
: Attrs
)
1103 AttrVec
[attrIdxToArrayIdx(Pair
.first
)] = Pair
.second
;
1105 return getImpl(C
, AttrVec
);
1108 AttributeList
AttributeList::get(LLVMContext
&C
, AttributeSet FnAttrs
,
1109 AttributeSet RetAttrs
,
1110 ArrayRef
<AttributeSet
> ArgAttrs
) {
1111 // Scan from the end to find the last argument with attributes. Most
1112 // arguments don't have attributes, so it's nice if we can have fewer unique
1113 // AttributeListImpls by dropping empty attribute sets at the end of the list.
1114 unsigned NumSets
= 0;
1115 for (size_t I
= ArgAttrs
.size(); I
!= 0; --I
) {
1116 if (ArgAttrs
[I
- 1].hasAttributes()) {
1122 // Check function and return attributes if we didn't have argument
1124 if (RetAttrs
.hasAttributes())
1126 else if (FnAttrs
.hasAttributes())
1130 // If all attribute sets were empty, we can use the empty attribute list.
1134 SmallVector
<AttributeSet
, 8> AttrSets
;
1135 AttrSets
.reserve(NumSets
);
1136 // If we have any attributes, we always have function attributes.
1137 AttrSets
.push_back(FnAttrs
);
1139 AttrSets
.push_back(RetAttrs
);
1141 // Drop the empty argument attribute sets at the end.
1142 ArgAttrs
= ArgAttrs
.take_front(NumSets
- 2);
1143 llvm::append_range(AttrSets
, ArgAttrs
);
1146 return getImpl(C
, AttrSets
);
1149 AttributeList
AttributeList::get(LLVMContext
&C
, unsigned Index
,
1150 const AttrBuilder
&B
) {
1151 if (!B
.hasAttributes())
1153 Index
= attrIdxToArrayIdx(Index
);
1154 SmallVector
<AttributeSet
, 8> AttrSets(Index
+ 1);
1155 AttrSets
[Index
] = AttributeSet::get(C
, B
);
1156 return getImpl(C
, AttrSets
);
1159 AttributeList
AttributeList::get(LLVMContext
&C
, unsigned Index
,
1160 ArrayRef
<Attribute::AttrKind
> Kinds
) {
1161 SmallVector
<std::pair
<unsigned, Attribute
>, 8> Attrs
;
1162 for (const auto K
: Kinds
)
1163 Attrs
.emplace_back(Index
, Attribute::get(C
, K
));
1164 return get(C
, Attrs
);
1167 AttributeList
AttributeList::get(LLVMContext
&C
, unsigned Index
,
1168 ArrayRef
<Attribute::AttrKind
> Kinds
,
1169 ArrayRef
<uint64_t> Values
) {
1170 assert(Kinds
.size() == Values
.size() && "Mismatched attribute values.");
1171 SmallVector
<std::pair
<unsigned, Attribute
>, 8> Attrs
;
1172 auto VI
= Values
.begin();
1173 for (const auto K
: Kinds
)
1174 Attrs
.emplace_back(Index
, Attribute::get(C
, K
, *VI
++));
1175 return get(C
, Attrs
);
1178 AttributeList
AttributeList::get(LLVMContext
&C
, unsigned Index
,
1179 ArrayRef
<StringRef
> Kinds
) {
1180 SmallVector
<std::pair
<unsigned, Attribute
>, 8> Attrs
;
1181 for (const auto &K
: Kinds
)
1182 Attrs
.emplace_back(Index
, Attribute::get(C
, K
));
1183 return get(C
, Attrs
);
1186 AttributeList
AttributeList::get(LLVMContext
&C
,
1187 ArrayRef
<AttributeList
> Attrs
) {
1190 if (Attrs
.size() == 1)
1193 unsigned MaxSize
= 0;
1194 for (const auto &List
: Attrs
)
1195 MaxSize
= std::max(MaxSize
, List
.getNumAttrSets());
1197 // If every list was empty, there is no point in merging the lists.
1201 SmallVector
<AttributeSet
, 8> NewAttrSets(MaxSize
);
1202 for (unsigned I
= 0; I
< MaxSize
; ++I
) {
1203 AttrBuilder CurBuilder
;
1204 for (const auto &List
: Attrs
)
1205 CurBuilder
.merge(List
.getAttributes(I
- 1));
1206 NewAttrSets
[I
] = AttributeSet::get(C
, CurBuilder
);
1209 return getImpl(C
, NewAttrSets
);
1212 AttributeList
AttributeList::addAttribute(LLVMContext
&C
, unsigned Index
,
1213 Attribute::AttrKind Kind
) const {
1214 if (hasAttribute(Index
, Kind
)) return *this;
1215 AttributeSet Attrs
= getAttributes(Index
);
1216 // TODO: Insert at correct position and avoid sort.
1217 SmallVector
<Attribute
, 8> NewAttrs(Attrs
.begin(), Attrs
.end());
1218 NewAttrs
.push_back(Attribute::get(C
, Kind
));
1219 return setAttributes(C
, Index
, AttributeSet::get(C
, NewAttrs
));
1222 AttributeList
AttributeList::addAttribute(LLVMContext
&C
, unsigned Index
,
1224 StringRef Value
) const {
1226 B
.addAttribute(Kind
, Value
);
1227 return addAttributes(C
, Index
, B
);
1230 AttributeList
AttributeList::addAttribute(LLVMContext
&C
, unsigned Index
,
1231 Attribute A
) const {
1234 return addAttributes(C
, Index
, B
);
1237 AttributeList
AttributeList::setAttributes(LLVMContext
&C
, unsigned Index
,
1238 AttributeSet Attrs
) const {
1239 Index
= attrIdxToArrayIdx(Index
);
1240 SmallVector
<AttributeSet
, 4> AttrSets(this->begin(), this->end());
1241 if (Index
>= AttrSets
.size())
1242 AttrSets
.resize(Index
+ 1);
1243 AttrSets
[Index
] = Attrs
;
1244 return AttributeList::getImpl(C
, AttrSets
);
1247 AttributeList
AttributeList::addAttributes(LLVMContext
&C
, unsigned Index
,
1248 const AttrBuilder
&B
) const {
1249 if (!B
.hasAttributes())
1253 return AttributeList::get(C
, {{Index
, AttributeSet::get(C
, B
)}});
1256 // FIXME it is not obvious how this should work for alignment. For now, say
1257 // we can't change a known alignment.
1258 const MaybeAlign OldAlign
= getAttributes(Index
).getAlignment();
1259 const MaybeAlign NewAlign
= B
.getAlignment();
1260 assert((!OldAlign
|| !NewAlign
|| OldAlign
== NewAlign
) &&
1261 "Attempt to change alignment!");
1264 AttrBuilder
Merged(getAttributes(Index
));
1266 return setAttributes(C
, Index
, AttributeSet::get(C
, Merged
));
1269 AttributeList
AttributeList::addParamAttribute(LLVMContext
&C
,
1270 ArrayRef
<unsigned> ArgNos
,
1271 Attribute A
) const {
1272 assert(llvm::is_sorted(ArgNos
));
1274 SmallVector
<AttributeSet
, 4> AttrSets(this->begin(), this->end());
1275 unsigned MaxIndex
= attrIdxToArrayIdx(ArgNos
.back() + FirstArgIndex
);
1276 if (MaxIndex
>= AttrSets
.size())
1277 AttrSets
.resize(MaxIndex
+ 1);
1279 for (unsigned ArgNo
: ArgNos
) {
1280 unsigned Index
= attrIdxToArrayIdx(ArgNo
+ FirstArgIndex
);
1281 AttrBuilder
B(AttrSets
[Index
]);
1283 AttrSets
[Index
] = AttributeSet::get(C
, B
);
1286 return getImpl(C
, AttrSets
);
1289 AttributeList
AttributeList::removeAttribute(LLVMContext
&C
, unsigned Index
,
1290 Attribute::AttrKind Kind
) const {
1291 if (!hasAttribute(Index
, Kind
)) return *this;
1293 Index
= attrIdxToArrayIdx(Index
);
1294 SmallVector
<AttributeSet
, 4> AttrSets(this->begin(), this->end());
1295 assert(Index
< AttrSets
.size());
1297 AttrSets
[Index
] = AttrSets
[Index
].removeAttribute(C
, Kind
);
1299 return getImpl(C
, AttrSets
);
1302 AttributeList
AttributeList::removeAttribute(LLVMContext
&C
, unsigned Index
,
1303 StringRef Kind
) const {
1304 if (!hasAttribute(Index
, Kind
)) return *this;
1306 Index
= attrIdxToArrayIdx(Index
);
1307 SmallVector
<AttributeSet
, 4> AttrSets(this->begin(), this->end());
1308 assert(Index
< AttrSets
.size());
1310 AttrSets
[Index
] = AttrSets
[Index
].removeAttribute(C
, Kind
);
1312 return getImpl(C
, AttrSets
);
1316 AttributeList::removeAttributes(LLVMContext
&C
, unsigned Index
,
1317 const AttrBuilder
&AttrsToRemove
) const {
1318 AttributeSet Attrs
= getAttributes(Index
);
1319 AttributeSet NewAttrs
= Attrs
.removeAttributes(C
, AttrsToRemove
);
1320 // If nothing was removed, return the original list.
1321 if (Attrs
== NewAttrs
)
1323 return setAttributes(C
, Index
, NewAttrs
);
1326 AttributeList
AttributeList::removeAttributes(LLVMContext
&C
,
1327 unsigned WithoutIndex
) const {
1330 WithoutIndex
= attrIdxToArrayIdx(WithoutIndex
);
1331 if (WithoutIndex
>= getNumAttrSets())
1333 SmallVector
<AttributeSet
, 4> AttrSets(this->begin(), this->end());
1334 AttrSets
[WithoutIndex
] = AttributeSet();
1335 return getImpl(C
, AttrSets
);
1338 AttributeList
AttributeList::addDereferenceableRetAttr(LLVMContext
&C
,
1339 uint64_t Bytes
) const {
1341 B
.addDereferenceableAttr(Bytes
);
1342 return addRetAttributes(C
, B
);
1345 AttributeList
AttributeList::addDereferenceableParamAttr(LLVMContext
&C
,
1347 uint64_t Bytes
) const {
1349 B
.addDereferenceableAttr(Bytes
);
1350 return addParamAttributes(C
, Index
, B
);
1354 AttributeList::addDereferenceableOrNullParamAttr(LLVMContext
&C
, unsigned Index
,
1355 uint64_t Bytes
) const {
1357 B
.addDereferenceableOrNullAttr(Bytes
);
1358 return addParamAttributes(C
, Index
, B
);
1362 AttributeList::addAllocSizeParamAttr(LLVMContext
&C
, unsigned Index
,
1363 unsigned ElemSizeArg
,
1364 const Optional
<unsigned> &NumElemsArg
) {
1366 B
.addAllocSizeAttr(ElemSizeArg
, NumElemsArg
);
1367 return addParamAttributes(C
, Index
, B
);
1370 //===----------------------------------------------------------------------===//
1371 // AttributeList Accessor Methods
1372 //===----------------------------------------------------------------------===//
1374 AttributeSet
AttributeList::getParamAttrs(unsigned ArgNo
) const {
1375 return getAttributes(ArgNo
+ FirstArgIndex
);
1378 AttributeSet
AttributeList::getRetAttrs() const {
1379 return getAttributes(ReturnIndex
);
1382 AttributeSet
AttributeList::getFnAttrs() const {
1383 return getAttributes(FunctionIndex
);
1386 bool AttributeList::hasAttribute(unsigned Index
,
1387 Attribute::AttrKind Kind
) const {
1388 return getAttributes(Index
).hasAttribute(Kind
);
1391 bool AttributeList::hasAttribute(unsigned Index
, StringRef Kind
) const {
1392 return getAttributes(Index
).hasAttribute(Kind
);
1395 bool AttributeList::hasAttributes(unsigned Index
) const {
1396 return getAttributes(Index
).hasAttributes();
1399 bool AttributeList::hasFnAttr(Attribute::AttrKind Kind
) const {
1400 return pImpl
&& pImpl
->hasFnAttribute(Kind
);
1403 bool AttributeList::hasFnAttr(StringRef Kind
) const {
1404 return hasAttribute(AttributeList::FunctionIndex
, Kind
);
1407 bool AttributeList::hasAttrSomewhere(Attribute::AttrKind Attr
,
1408 unsigned *Index
) const {
1409 return pImpl
&& pImpl
->hasAttrSomewhere(Attr
, Index
);
1412 Attribute
AttributeList::getAttribute(unsigned Index
,
1413 Attribute::AttrKind Kind
) const {
1414 return getAttributes(Index
).getAttribute(Kind
);
1417 Attribute
AttributeList::getAttribute(unsigned Index
, StringRef Kind
) const {
1418 return getAttributes(Index
).getAttribute(Kind
);
1421 MaybeAlign
AttributeList::getRetAlignment() const {
1422 return getAttributes(ReturnIndex
).getAlignment();
1425 MaybeAlign
AttributeList::getParamAlignment(unsigned ArgNo
) const {
1426 return getAttributes(ArgNo
+ FirstArgIndex
).getAlignment();
1429 MaybeAlign
AttributeList::getParamStackAlignment(unsigned ArgNo
) const {
1430 return getAttributes(ArgNo
+ FirstArgIndex
).getStackAlignment();
1433 Type
*AttributeList::getParamByValType(unsigned Index
) const {
1434 return getAttributes(Index
+FirstArgIndex
).getByValType();
1437 Type
*AttributeList::getParamStructRetType(unsigned Index
) const {
1438 return getAttributes(Index
+ FirstArgIndex
).getStructRetType();
1441 Type
*AttributeList::getParamByRefType(unsigned Index
) const {
1442 return getAttributes(Index
+ FirstArgIndex
).getByRefType();
1445 Type
*AttributeList::getParamPreallocatedType(unsigned Index
) const {
1446 return getAttributes(Index
+ FirstArgIndex
).getPreallocatedType();
1449 Type
*AttributeList::getParamInAllocaType(unsigned Index
) const {
1450 return getAttributes(Index
+ FirstArgIndex
).getInAllocaType();
1453 Type
*AttributeList::getParamElementType(unsigned Index
) const {
1454 return getAttributes(Index
+ FirstArgIndex
).getElementType();
1457 MaybeAlign
AttributeList::getFnStackAlignment() const {
1458 return getFnAttrs().getStackAlignment();
1461 MaybeAlign
AttributeList::getRetStackAlignment() const {
1462 return getRetAttrs().getStackAlignment();
1465 uint64_t AttributeList::getRetDereferenceableBytes() const {
1466 return getRetAttrs().getDereferenceableBytes();
1469 uint64_t AttributeList::getParamDereferenceableBytes(unsigned Index
) const {
1470 return getParamAttrs(Index
).getDereferenceableBytes();
1473 uint64_t AttributeList::getRetDereferenceableOrNullBytes() const {
1474 return getRetAttrs().getDereferenceableOrNullBytes();
1478 AttributeList::getParamDereferenceableOrNullBytes(unsigned Index
) const {
1479 return getParamAttrs(Index
).getDereferenceableOrNullBytes();
1482 std::string
AttributeList::getAsString(unsigned Index
, bool InAttrGrp
) const {
1483 return getAttributes(Index
).getAsString(InAttrGrp
);
1486 AttributeSet
AttributeList::getAttributes(unsigned Index
) const {
1487 Index
= attrIdxToArrayIdx(Index
);
1488 if (!pImpl
|| Index
>= getNumAttrSets())
1490 return pImpl
->begin()[Index
];
1493 bool AttributeList::hasParentContext(LLVMContext
&C
) const {
1494 assert(!isEmpty() && "an empty attribute list has no parent context");
1495 FoldingSetNodeID ID
;
1498 return C
.pImpl
->AttrsLists
.FindNodeOrInsertPos(ID
, Unused
) == pImpl
;
1501 AttributeList::iterator
AttributeList::begin() const {
1502 return pImpl
? pImpl
->begin() : nullptr;
1505 AttributeList::iterator
AttributeList::end() const {
1506 return pImpl
? pImpl
->end() : nullptr;
1509 //===----------------------------------------------------------------------===//
1510 // AttributeList Introspection Methods
1511 //===----------------------------------------------------------------------===//
1513 unsigned AttributeList::getNumAttrSets() const {
1514 return pImpl
? pImpl
->NumAttrSets
: 0;
1517 void AttributeList::print(raw_ostream
&O
) const {
1518 O
<< "AttributeList[\n";
1520 for (unsigned i
= index_begin(), e
= index_end(); i
!= e
; ++i
) {
1521 if (!getAttributes(i
).hasAttributes())
1525 case AttrIndex::ReturnIndex
:
1528 case AttrIndex::FunctionIndex
:
1532 O
<< "arg(" << i
- AttrIndex::FirstArgIndex
<< ")";
1534 O
<< " => " << getAsString(i
) << " }\n";
1540 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1541 LLVM_DUMP_METHOD
void AttributeList::dump() const { print(dbgs()); }
1544 //===----------------------------------------------------------------------===//
1545 // AttrBuilder Method Implementations
1546 //===----------------------------------------------------------------------===//
1548 // FIXME: Remove this ctor, use AttributeSet.
1549 AttrBuilder::AttrBuilder(AttributeList AL
, unsigned Index
) {
1550 AttributeSet AS
= AL
.getAttributes(Index
);
1551 for (const auto &A
: AS
)
1555 AttrBuilder::AttrBuilder(AttributeSet AS
) {
1556 for (const auto &A
: AS
)
1560 void AttrBuilder::clear() {
1562 TargetDepAttrs
.clear();
1564 StackAlignment
.reset();
1565 DerefBytes
= DerefOrNullBytes
= 0;
1567 VScaleRangeArgs
= 0;
1572 AttrBuilder::kindToTypeIndex(Attribute::AttrKind Kind
) const {
1573 if (Attribute::isTypeAttrKind(Kind
))
1574 return Kind
- Attribute::FirstTypeAttr
;
1578 AttrBuilder
&AttrBuilder::addAttribute(Attribute Attr
) {
1579 if (Attr
.isStringAttribute()) {
1580 addAttribute(Attr
.getKindAsString(), Attr
.getValueAsString());
1584 Attribute::AttrKind Kind
= Attr
.getKindAsEnum();
1587 if (Optional
<unsigned> TypeIndex
= kindToTypeIndex(Kind
))
1588 TypeAttrs
[*TypeIndex
] = Attr
.getValueAsType();
1589 else if (Kind
== Attribute::Alignment
)
1590 Alignment
= Attr
.getAlignment();
1591 else if (Kind
== Attribute::StackAlignment
)
1592 StackAlignment
= Attr
.getStackAlignment();
1593 else if (Kind
== Attribute::Dereferenceable
)
1594 DerefBytes
= Attr
.getDereferenceableBytes();
1595 else if (Kind
== Attribute::DereferenceableOrNull
)
1596 DerefOrNullBytes
= Attr
.getDereferenceableOrNullBytes();
1597 else if (Kind
== Attribute::AllocSize
)
1598 AllocSizeArgs
= Attr
.getValueAsInt();
1599 else if (Kind
== Attribute::VScaleRange
)
1600 VScaleRangeArgs
= Attr
.getValueAsInt();
1605 AttrBuilder
&AttrBuilder::addAttribute(StringRef A
, StringRef V
) {
1606 TargetDepAttrs
[A
] = V
;
1610 AttrBuilder
&AttrBuilder::removeAttribute(Attribute::AttrKind Val
) {
1611 assert((unsigned)Val
< Attribute::EndAttrKinds
&& "Attribute out of range!");
1614 if (Optional
<unsigned> TypeIndex
= kindToTypeIndex(Val
))
1615 TypeAttrs
[*TypeIndex
] = nullptr;
1616 else if (Val
== Attribute::Alignment
)
1618 else if (Val
== Attribute::StackAlignment
)
1619 StackAlignment
.reset();
1620 else if (Val
== Attribute::Dereferenceable
)
1622 else if (Val
== Attribute::DereferenceableOrNull
)
1623 DerefOrNullBytes
= 0;
1624 else if (Val
== Attribute::AllocSize
)
1626 else if (Val
== Attribute::VScaleRange
)
1627 VScaleRangeArgs
= 0;
1632 AttrBuilder
&AttrBuilder::removeAttributes(AttributeList A
, uint64_t Index
) {
1633 remove(A
.getAttributes(Index
));
1637 AttrBuilder
&AttrBuilder::removeAttribute(StringRef A
) {
1638 auto I
= TargetDepAttrs
.find(A
);
1639 if (I
!= TargetDepAttrs
.end())
1640 TargetDepAttrs
.erase(I
);
1644 std::pair
<unsigned, Optional
<unsigned>> AttrBuilder::getAllocSizeArgs() const {
1645 return unpackAllocSizeArgs(AllocSizeArgs
);
1648 std::pair
<unsigned, unsigned> AttrBuilder::getVScaleRangeArgs() const {
1649 return unpackVScaleRangeArgs(VScaleRangeArgs
);
1652 AttrBuilder
&AttrBuilder::addAlignmentAttr(MaybeAlign Align
) {
1656 assert(*Align
<= llvm::Value::MaximumAlignment
&& "Alignment too large.");
1658 Attrs
[Attribute::Alignment
] = true;
1663 AttrBuilder
&AttrBuilder::addStackAlignmentAttr(MaybeAlign Align
) {
1664 // Default alignment, allow the target to define how to align it.
1668 assert(*Align
<= 0x100 && "Alignment too large.");
1670 Attrs
[Attribute::StackAlignment
] = true;
1671 StackAlignment
= Align
;
1675 AttrBuilder
&AttrBuilder::addDereferenceableAttr(uint64_t Bytes
) {
1676 if (Bytes
== 0) return *this;
1678 Attrs
[Attribute::Dereferenceable
] = true;
1683 AttrBuilder
&AttrBuilder::addDereferenceableOrNullAttr(uint64_t Bytes
) {
1687 Attrs
[Attribute::DereferenceableOrNull
] = true;
1688 DerefOrNullBytes
= Bytes
;
1692 AttrBuilder
&AttrBuilder::addAllocSizeAttr(unsigned ElemSize
,
1693 const Optional
<unsigned> &NumElems
) {
1694 return addAllocSizeAttrFromRawRepr(packAllocSizeArgs(ElemSize
, NumElems
));
1697 AttrBuilder
&AttrBuilder::addAllocSizeAttrFromRawRepr(uint64_t RawArgs
) {
1698 // (0, 0) is our "not present" value, so we need to check for it here.
1699 assert(RawArgs
&& "Invalid allocsize arguments -- given allocsize(0, 0)");
1701 Attrs
[Attribute::AllocSize
] = true;
1702 // Reuse existing machinery to store this as a single 64-bit integer so we can
1703 // save a few bytes over using a pair<unsigned, Optional<unsigned>>.
1704 AllocSizeArgs
= RawArgs
;
1708 AttrBuilder
&AttrBuilder::addVScaleRangeAttr(unsigned MinValue
,
1709 unsigned MaxValue
) {
1710 return addVScaleRangeAttrFromRawRepr(packVScaleRangeArgs(MinValue
, MaxValue
));
1713 AttrBuilder
&AttrBuilder::addVScaleRangeAttrFromRawRepr(uint64_t RawArgs
) {
1714 // (0, 0) is not present hence ignore this case
1718 Attrs
[Attribute::VScaleRange
] = true;
1719 // Reuse existing machinery to store this as a single 64-bit integer so we can
1720 // save a few bytes over using a pair<unsigned, unsigned>.
1721 VScaleRangeArgs
= RawArgs
;
1725 Type
*AttrBuilder::getTypeAttr(Attribute::AttrKind Kind
) const {
1726 Optional
<unsigned> TypeIndex
= kindToTypeIndex(Kind
);
1727 assert(TypeIndex
&& "Not a type attribute");
1728 return TypeAttrs
[*TypeIndex
];
1731 AttrBuilder
&AttrBuilder::addTypeAttr(Attribute::AttrKind Kind
, Type
*Ty
) {
1732 Optional
<unsigned> TypeIndex
= kindToTypeIndex(Kind
);
1733 assert(TypeIndex
&& "Not a type attribute");
1735 TypeAttrs
[*TypeIndex
] = Ty
;
1739 AttrBuilder
&AttrBuilder::addByValAttr(Type
*Ty
) {
1740 return addTypeAttr(Attribute::ByVal
, Ty
);
1743 AttrBuilder
&AttrBuilder::addStructRetAttr(Type
*Ty
) {
1744 return addTypeAttr(Attribute::StructRet
, Ty
);
1747 AttrBuilder
&AttrBuilder::addByRefAttr(Type
*Ty
) {
1748 return addTypeAttr(Attribute::ByRef
, Ty
);
1751 AttrBuilder
&AttrBuilder::addPreallocatedAttr(Type
*Ty
) {
1752 return addTypeAttr(Attribute::Preallocated
, Ty
);
1755 AttrBuilder
&AttrBuilder::addInAllocaAttr(Type
*Ty
) {
1756 return addTypeAttr(Attribute::InAlloca
, Ty
);
1759 AttrBuilder
&AttrBuilder::merge(const AttrBuilder
&B
) {
1760 // FIXME: What if both have alignments, but they don't match?!
1762 Alignment
= B
.Alignment
;
1764 if (!StackAlignment
)
1765 StackAlignment
= B
.StackAlignment
;
1768 DerefBytes
= B
.DerefBytes
;
1770 if (!DerefOrNullBytes
)
1771 DerefOrNullBytes
= B
.DerefOrNullBytes
;
1774 AllocSizeArgs
= B
.AllocSizeArgs
;
1776 if (!VScaleRangeArgs
)
1777 VScaleRangeArgs
= B
.VScaleRangeArgs
;
1779 for (unsigned Index
= 0; Index
< Attribute::NumTypeAttrKinds
; ++Index
)
1780 if (!TypeAttrs
[Index
])
1781 TypeAttrs
[Index
] = B
.TypeAttrs
[Index
];
1785 for (const auto &I
: B
.td_attrs())
1786 TargetDepAttrs
[I
.first
] = I
.second
;
1791 AttrBuilder
&AttrBuilder::remove(const AttrBuilder
&B
) {
1792 // FIXME: What if both have alignments, but they don't match?!
1796 if (B
.StackAlignment
)
1797 StackAlignment
.reset();
1802 if (B
.DerefOrNullBytes
)
1803 DerefOrNullBytes
= 0;
1805 if (B
.AllocSizeArgs
)
1808 if (B
.VScaleRangeArgs
)
1809 VScaleRangeArgs
= 0;
1811 for (unsigned Index
= 0; Index
< Attribute::NumTypeAttrKinds
; ++Index
)
1812 if (B
.TypeAttrs
[Index
])
1813 TypeAttrs
[Index
] = nullptr;
1817 for (const auto &I
: B
.td_attrs())
1818 TargetDepAttrs
.erase(I
.first
);
1823 bool AttrBuilder::overlaps(const AttrBuilder
&B
) const {
1824 // First check if any of the target independent attributes overlap.
1825 if ((Attrs
& B
.Attrs
).any())
1828 // Then check if any target dependent ones do.
1829 for (const auto &I
: td_attrs())
1830 if (B
.contains(I
.first
))
1836 bool AttrBuilder::contains(StringRef A
) const {
1837 return TargetDepAttrs
.find(A
) != TargetDepAttrs
.end();
1840 bool AttrBuilder::hasAttributes() const {
1841 return !Attrs
.none() || !TargetDepAttrs
.empty();
1844 bool AttrBuilder::hasAttributes(AttributeList AL
, uint64_t Index
) const {
1845 AttributeSet AS
= AL
.getAttributes(Index
);
1847 for (const auto &Attr
: AS
) {
1848 if (Attr
.isEnumAttribute() || Attr
.isIntAttribute()) {
1849 if (contains(Attr
.getKindAsEnum()))
1852 assert(Attr
.isStringAttribute() && "Invalid attribute kind!");
1853 return contains(Attr
.getKindAsString());
1860 bool AttrBuilder::hasAlignmentAttr() const {
1861 return Alignment
!= 0;
1864 bool AttrBuilder::operator==(const AttrBuilder
&B
) const {
1865 if (Attrs
!= B
.Attrs
)
1868 for (const auto &TDA
: TargetDepAttrs
)
1869 if (B
.TargetDepAttrs
.find(TDA
.first
) == B
.TargetDepAttrs
.end())
1872 return Alignment
== B
.Alignment
&& StackAlignment
== B
.StackAlignment
&&
1873 DerefBytes
== B
.DerefBytes
&& TypeAttrs
== B
.TypeAttrs
&&
1874 VScaleRangeArgs
== B
.VScaleRangeArgs
;
1877 //===----------------------------------------------------------------------===//
1878 // AttributeFuncs Function Defintions
1879 //===----------------------------------------------------------------------===//
1881 /// Which attributes cannot be applied to a type.
1882 AttrBuilder
AttributeFuncs::typeIncompatible(Type
*Ty
) {
1883 AttrBuilder Incompatible
;
1885 if (!Ty
->isIntegerTy())
1886 // Attribute that only apply to integers.
1887 Incompatible
.addAttribute(Attribute::SExt
)
1888 .addAttribute(Attribute::ZExt
);
1890 if (!Ty
->isPointerTy())
1891 // Attribute that only apply to pointers.
1892 Incompatible
.addAttribute(Attribute::Nest
)
1893 .addAttribute(Attribute::NoAlias
)
1894 .addAttribute(Attribute::NoCapture
)
1895 .addAttribute(Attribute::NonNull
)
1896 .addAttribute(Attribute::ReadNone
)
1897 .addAttribute(Attribute::ReadOnly
)
1898 .addAttribute(Attribute::SwiftError
)
1899 .addAlignmentAttr(1) // the int here is ignored
1900 .addDereferenceableAttr(1) // the int here is ignored
1901 .addDereferenceableOrNullAttr(1) // the int here is ignored
1902 .addPreallocatedAttr(Ty
)
1903 .addInAllocaAttr(Ty
)
1905 .addStructRetAttr(Ty
)
1907 .addTypeAttr(Attribute::ElementType
, Ty
);
1909 // Some attributes can apply to all "values" but there are no `void` values.
1911 Incompatible
.addAttribute(Attribute::NoUndef
);
1913 return Incompatible
;
1916 AttrBuilder
AttributeFuncs::getUBImplyingAttributes() {
1918 B
.addAttribute(Attribute::NoUndef
);
1919 B
.addDereferenceableAttr(1);
1920 B
.addDereferenceableOrNullAttr(1);
1924 template<typename AttrClass
>
1925 static bool isEqual(const Function
&Caller
, const Function
&Callee
) {
1926 return Caller
.getFnAttribute(AttrClass::getKind()) ==
1927 Callee
.getFnAttribute(AttrClass::getKind());
1930 /// Compute the logical AND of the attributes of the caller and the
1933 /// This function sets the caller's attribute to false if the callee's attribute
1935 template<typename AttrClass
>
1936 static void setAND(Function
&Caller
, const Function
&Callee
) {
1937 if (AttrClass::isSet(Caller
, AttrClass::getKind()) &&
1938 !AttrClass::isSet(Callee
, AttrClass::getKind()))
1939 AttrClass::set(Caller
, AttrClass::getKind(), false);
1942 /// Compute the logical OR of the attributes of the caller and the
1945 /// This function sets the caller's attribute to true if the callee's attribute
1947 template<typename AttrClass
>
1948 static void setOR(Function
&Caller
, const Function
&Callee
) {
1949 if (!AttrClass::isSet(Caller
, AttrClass::getKind()) &&
1950 AttrClass::isSet(Callee
, AttrClass::getKind()))
1951 AttrClass::set(Caller
, AttrClass::getKind(), true);
1954 /// If the inlined function had a higher stack protection level than the
1955 /// calling function, then bump up the caller's stack protection level.
1956 static void adjustCallerSSPLevel(Function
&Caller
, const Function
&Callee
) {
1957 // If upgrading the SSP attribute, clear out the old SSP Attributes first.
1958 // Having multiple SSP attributes doesn't actually hurt, but it adds useless
1959 // clutter to the IR.
1960 AttrBuilder OldSSPAttr
;
1961 OldSSPAttr
.addAttribute(Attribute::StackProtect
)
1962 .addAttribute(Attribute::StackProtectStrong
)
1963 .addAttribute(Attribute::StackProtectReq
);
1965 if (Callee
.hasFnAttribute(Attribute::StackProtectReq
)) {
1966 Caller
.removeFnAttrs(OldSSPAttr
);
1967 Caller
.addFnAttr(Attribute::StackProtectReq
);
1968 } else if (Callee
.hasFnAttribute(Attribute::StackProtectStrong
) &&
1969 !Caller
.hasFnAttribute(Attribute::StackProtectReq
)) {
1970 Caller
.removeFnAttrs(OldSSPAttr
);
1971 Caller
.addFnAttr(Attribute::StackProtectStrong
);
1972 } else if (Callee
.hasFnAttribute(Attribute::StackProtect
) &&
1973 !Caller
.hasFnAttribute(Attribute::StackProtectReq
) &&
1974 !Caller
.hasFnAttribute(Attribute::StackProtectStrong
))
1975 Caller
.addFnAttr(Attribute::StackProtect
);
1978 /// If the inlined function required stack probes, then ensure that
1979 /// the calling function has those too.
1980 static void adjustCallerStackProbes(Function
&Caller
, const Function
&Callee
) {
1981 if (!Caller
.hasFnAttribute("probe-stack") &&
1982 Callee
.hasFnAttribute("probe-stack")) {
1983 Caller
.addFnAttr(Callee
.getFnAttribute("probe-stack"));
1987 /// If the inlined function defines the size of guard region
1988 /// on the stack, then ensure that the calling function defines a guard region
1989 /// that is no larger.
1991 adjustCallerStackProbeSize(Function
&Caller
, const Function
&Callee
) {
1992 Attribute CalleeAttr
= Callee
.getFnAttribute("stack-probe-size");
1993 if (CalleeAttr
.isValid()) {
1994 Attribute CallerAttr
= Caller
.getFnAttribute("stack-probe-size");
1995 if (CallerAttr
.isValid()) {
1996 uint64_t CallerStackProbeSize
, CalleeStackProbeSize
;
1997 CallerAttr
.getValueAsString().getAsInteger(0, CallerStackProbeSize
);
1998 CalleeAttr
.getValueAsString().getAsInteger(0, CalleeStackProbeSize
);
2000 if (CallerStackProbeSize
> CalleeStackProbeSize
) {
2001 Caller
.addFnAttr(CalleeAttr
);
2004 Caller
.addFnAttr(CalleeAttr
);
2009 /// If the inlined function defines a min legal vector width, then ensure
2010 /// the calling function has the same or larger min legal vector width. If the
2011 /// caller has the attribute, but the callee doesn't, we need to remove the
2012 /// attribute from the caller since we can't make any guarantees about the
2013 /// caller's requirements.
2014 /// This function is called after the inlining decision has been made so we have
2015 /// to merge the attribute this way. Heuristics that would use
2016 /// min-legal-vector-width to determine inline compatibility would need to be
2017 /// handled as part of inline cost analysis.
2019 adjustMinLegalVectorWidth(Function
&Caller
, const Function
&Callee
) {
2020 Attribute CallerAttr
= Caller
.getFnAttribute("min-legal-vector-width");
2021 if (CallerAttr
.isValid()) {
2022 Attribute CalleeAttr
= Callee
.getFnAttribute("min-legal-vector-width");
2023 if (CalleeAttr
.isValid()) {
2024 uint64_t CallerVectorWidth
, CalleeVectorWidth
;
2025 CallerAttr
.getValueAsString().getAsInteger(0, CallerVectorWidth
);
2026 CalleeAttr
.getValueAsString().getAsInteger(0, CalleeVectorWidth
);
2027 if (CallerVectorWidth
< CalleeVectorWidth
)
2028 Caller
.addFnAttr(CalleeAttr
);
2030 // If the callee doesn't have the attribute then we don't know anything
2031 // and must drop the attribute from the caller.
2032 Caller
.removeFnAttr("min-legal-vector-width");
2037 /// If the inlined function has null_pointer_is_valid attribute,
2038 /// set this attribute in the caller post inlining.
2040 adjustNullPointerValidAttr(Function
&Caller
, const Function
&Callee
) {
2041 if (Callee
.nullPointerIsDefined() && !Caller
.nullPointerIsDefined()) {
2042 Caller
.addFnAttr(Attribute::NullPointerIsValid
);
2047 static bool isSet(const Function
&Fn
,
2048 Attribute::AttrKind Kind
) {
2049 return Fn
.hasFnAttribute(Kind
);
2052 static void set(Function
&Fn
,
2053 Attribute::AttrKind Kind
, bool Val
) {
2057 Fn
.removeFnAttr(Kind
);
2061 struct StrBoolAttr
{
2062 static bool isSet(const Function
&Fn
,
2064 auto A
= Fn
.getFnAttribute(Kind
);
2065 return A
.getValueAsString().equals("true");
2068 static void set(Function
&Fn
,
2069 StringRef Kind
, bool Val
) {
2070 Fn
.addFnAttr(Kind
, Val
? "true" : "false");
2074 #define GET_ATTR_NAMES
2075 #define ATTRIBUTE_ENUM(ENUM_NAME, DISPLAY_NAME) \
2076 struct ENUM_NAME##Attr : EnumAttr { \
2077 static enum Attribute::AttrKind getKind() { \
2078 return llvm::Attribute::ENUM_NAME; \
2081 #define ATTRIBUTE_STRBOOL(ENUM_NAME, DISPLAY_NAME) \
2082 struct ENUM_NAME##Attr : StrBoolAttr { \
2083 static StringRef getKind() { return #DISPLAY_NAME; } \
2085 #include "llvm/IR/Attributes.inc"
2087 #define GET_ATTR_COMPAT_FUNC
2088 #include "llvm/IR/Attributes.inc"
2090 bool AttributeFuncs::areInlineCompatible(const Function
&Caller
,
2091 const Function
&Callee
) {
2092 return hasCompatibleFnAttrs(Caller
, Callee
);
2095 bool AttributeFuncs::areOutlineCompatible(const Function
&A
,
2096 const Function
&B
) {
2097 return hasCompatibleFnAttrs(A
, B
);
2100 void AttributeFuncs::mergeAttributesForInlining(Function
&Caller
,
2101 const Function
&Callee
) {
2102 mergeFnAttrs(Caller
, Callee
);
2105 void AttributeFuncs::mergeAttributesForOutlining(Function
&Base
,
2106 const Function
&ToMerge
) {
2108 // We merge functions so that they meet the most general case.
2109 // For example, if the NoNansFPMathAttr is set in one function, but not in
2110 // the other, in the merged function we can say that the NoNansFPMathAttr
2112 // However if we have the SpeculativeLoadHardeningAttr set true in one
2113 // function, but not the other, we make sure that the function retains
2114 // that aspect in the merged function.
2115 mergeFnAttrs(Base
, ToMerge
);