[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / lib / IR / Attributes.cpp
blobd0bf6c121d17ff06d8d36cb0427a4d6cedb402d3
1 //===- Attributes.cpp - Implement AttributesList --------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // \file
10 // This file 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"
36 #include <algorithm>
37 #include <cassert>
38 #include <climits>
39 #include <cstddef>
40 #include <cstdint>
41 #include <limits>
42 #include <string>
43 #include <tuple>
44 #include <utility>
46 using namespace llvm;
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
54 // nonsensical.
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,
93 uint64_t Val) {
94 if (Val)
95 assert(Attribute::isIntAttrKind(Kind) && "Not an int attribute");
96 else
97 assert(Attribute::isEnumAttrKind(Kind) && "Not an enum attribute");
99 LLVMContextImpl *pImpl = Context.pImpl;
100 FoldingSetNodeID ID;
101 ID.AddInteger(Kind);
102 if (Val) ID.AddInteger(Val);
104 void *InsertPoint;
105 AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);
107 if (!PA) {
108 // If we didn't find any existing attributes of the same shape then create a
109 // new one and insert it.
110 if (!Val)
111 PA = new (pImpl->Alloc) EnumAttributeImpl(Kind);
112 else
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;
123 FoldingSetNodeID ID;
124 ID.AddString(Kind);
125 if (!Val.empty()) ID.AddString(Val);
127 void *InsertPoint;
128 AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);
130 if (!PA) {
131 // If we didn't find any existing attributes of the same shape then create a
132 // new one and insert it.
133 void *Mem =
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,
145 Type *Ty) {
146 assert(Attribute::isTypeAttrKind(Kind) && "Not a type attribute");
147 LLVMContextImpl *pImpl = Context.pImpl;
148 FoldingSetNodeID ID;
149 ID.AddInteger(Kind);
150 ID.AddPointer(Ty);
152 void *InsertPoint;
153 AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);
155 if (!PA) {
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,
177 uint64_t Bytes) {
178 assert(Bytes && "Bytes must be non-zero.");
179 return get(Context, Dereferenceable, Bytes);
182 Attribute Attribute::getWithDereferenceableOrNullBytes(LLVMContext &Context,
183 uint64_t Bytes) {
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);
208 Attribute
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,
217 unsigned MinValue,
218 unsigned MaxValue) {
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) {
232 switch (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:
239 return "none";
240 default:
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"
250 .Default(false);
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();
371 Result += '(';
372 raw_string_ostream OS(Result);
373 getValueAsType()->print(OS, false, true);
374 OS.flush();
375 Result += ')';
376 return Result;
379 // FIXME: These should be output like this:
381 // align=4
382 // alignstack=8
384 if (hasAttribute(Attribute::Alignment)) {
385 std::string Result;
386 Result += "align";
387 Result += (InAttrGrp) ? "=" : " ";
388 Result += utostr(getValueAsInt());
389 return Result;
392 auto AttrWithBytesToString = [&](const char *Name) {
393 std::string Result;
394 Result += Name;
395 if (InAttrGrp) {
396 Result += "=";
397 Result += utostr(getValueAsInt());
398 } else {
399 Result += "(";
400 Result += utostr(getValueAsInt());
401 Result += ")";
403 return Result;
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)) {
416 unsigned ElemSize;
417 Optional<unsigned> NumElems;
418 std::tie(ElemSize, NumElems) = getAllocSizeArgs();
420 std::string Result = "allocsize(";
421 Result += utostr(ElemSize);
422 if (NumElems.hasValue()) {
423 Result += ',';
424 Result += utostr(*NumElems);
426 Result += ')';
427 return Result;
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);
436 Result += ',';
437 Result += utostr(MaxValue);
438 Result += ')';
439 return Result;
442 // Convert target-dependent attributes to strings of the form:
444 // "kind"
445 // "kind" = "value"
447 if (isStringAttribute()) {
448 std::string Result;
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()) {
458 OS << "=\"";
459 printEscapedString(AttrVal, OS);
460 OS << "\"";
463 return Result;
466 llvm_unreachable("Unknown attribute");
469 bool Attribute::hasParentContext(LLVMContext &C) const {
470 assert(isValid() && "invalid Attribute doesn't refer to any context");
471 FoldingSetNodeID ID;
472 pImpl->Profile(ID);
473 void *Unused;
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 {
489 FnAttr = (1 << 0),
490 ParamAttr = (1 << 1),
491 RetAttr = (1 << 2),
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 {
562 if (this == &AI)
563 return false;
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())
569 return true;
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())
580 return false;
581 if (getKindAsString() == AI.getKindAsString())
582 return getValueAsString() < AI.getValueAsString();
583 return getKindAsString() < AI.getKindAsString();
586 //===----------------------------------------------------------------------===//
587 // AttributeSet Definition
588 //===----------------------------------------------------------------------===//
590 AttributeSet AttributeSet::get(LLVMContext &C, const AttrBuilder &B) {
591 return AttributeSet(AttributeSetNode::get(C, B));
594 AttributeSet AttributeSet::get(LLVMContext &C, ArrayRef<Attribute> Attrs) {
595 return AttributeSet(AttributeSetNode::get(C, Attrs));
598 AttributeSet AttributeSet::addAttribute(LLVMContext &C,
599 Attribute::AttrKind Kind) const {
600 if (hasAttribute(Kind)) return *this;
601 AttrBuilder B;
602 B.addAttribute(Kind);
603 return addAttributes(C, AttributeSet::get(C, B));
606 AttributeSet AttributeSet::addAttribute(LLVMContext &C, StringRef Kind,
607 StringRef Value) const {
608 AttrBuilder B;
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())
616 return AS;
618 if (!AS.hasAttributes())
619 return *this;
621 AttrBuilder B(AS);
622 for (const auto &I : *this)
623 B.addAttribute(I);
625 return get(C, B);
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);
633 return get(C, B);
636 AttributeSet AttributeSet::removeAttribute(LLVMContext &C,
637 StringRef Kind) const {
638 if (!hasAttribute(Kind)) return *this;
639 AttrBuilder B(*this);
640 B.removeAttribute(Kind);
641 return get(C, B);
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))
649 return *this;
651 B.remove(Attrs);
652 return get(C, B);
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");
731 FoldingSetNodeID ID;
732 SetNode->Profile(ID);
733 void *Unused;
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 {
747 dbgs() << "AS =\n";
748 dbgs() << " { ";
749 dbgs() << getAsString(true) << " }\n";
751 #endif
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 });
765 else
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())
780 return nullptr;
782 // Build a key to look up the existing attributes.
783 LLVMContextImpl *pImpl = C.pImpl;
784 FoldingSetNodeID ID;
786 assert(llvm::is_sorted(SortedAttrs) && "Expected sorted attributes!");
787 for (const auto &Attr : SortedAttrs)
788 Attr.Profile(ID);
790 void *InsertPoint;
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.
796 if (!PA) {
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.
804 return PA;
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))
813 continue;
815 if (Attribute::isTypeAttrKind(Kind)) {
816 Attrs.push_back(Attribute::get(C, Kind, B.getTypeAttr(Kind)));
817 continue;
820 Attribute Attr;
821 switch (Kind) {
822 case Attribute::Alignment:
823 assert(B.getAlignment() && "Alignment must be set");
824 Attr = Attribute::getWithAlignment(C, *B.getAlignment());
825 break;
826 case Attribute::StackAlignment:
827 assert(B.getStackAlignment() && "StackAlignment must be set");
828 Attr = Attribute::getWithStackAlignment(C, *B.getStackAlignment());
829 break;
830 case Attribute::Dereferenceable:
831 Attr = Attribute::getWithDereferenceableBytes(
832 C, B.getDereferenceableBytes());
833 break;
834 case Attribute::DereferenceableOrNull:
835 Attr = Attribute::getWithDereferenceableOrNullBytes(
836 C, B.getDereferenceableOrNullBytes());
837 break;
838 case Attribute::AllocSize: {
839 auto A = B.getAllocSizeArgs();
840 Attr = Attribute::getWithAllocSizeArgs(C, A.first, A.second);
841 break;
843 case Attribute::VScaleRange: {
844 auto A = B.getVScaleRangeArgs();
845 Attr = Attribute::getWithVScaleRangeArgs(C, A.first, A.second);
846 break;
848 default:
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);
865 Optional<Attribute>
866 AttributeSetNode::findEnumAttribute(Attribute::AttrKind Kind) const {
867 // Do a quick presence check.
868 if (!hasAttribute(Kind))
869 return None;
871 // Attributes in a set are sorted by enum value, followed by string
872 // attributes. Binary search the one we want.
873 const Attribute *I =
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?");
879 return *I;
882 Attribute AttributeSetNode::getAttribute(Attribute::AttrKind Kind) const {
883 if (auto A = findEnumAttribute(Kind))
884 return *A;
885 return {};
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();
895 return None;
898 MaybeAlign AttributeSetNode::getStackAlignment() const {
899 if (auto A = findEnumAttribute(Attribute::StackAlignment))
900 return A->getStackAlignment();
901 return None;
904 Type *AttributeSetNode::getAttributeType(Attribute::AttrKind Kind) const {
905 if (auto A = findEnumAttribute(Kind))
906 return A->getValueAsType();
907 return nullptr;
910 uint64_t AttributeSetNode::getDereferenceableBytes() const {
911 if (auto A = findEnumAttribute(Attribute::Dereferenceable))
912 return A->getDereferenceableBytes();
913 return 0;
916 uint64_t AttributeSetNode::getDereferenceableOrNullBytes() const {
917 if (auto A = findEnumAttribute(Attribute::DereferenceableOrNull))
918 return A->getDereferenceableOrNullBytes();
919 return 0;
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 {
936 std::string Str;
937 for (iterator I = begin(), E = end(); I != E; ++I) {
938 if (I != begin())
939 Str += ' ';
940 Str += I->getAsString(InAttrGrp);
942 return Str;
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) {
952 return Index + 1;
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
963 // summary bitsets.
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))
987 return false;
989 if (Index) {
990 for (unsigned I = 0, E = NumAttrSets; I != E; ++I) {
991 if (begin()[I].hasAttribute(Kind)) {
992 *Index = I - 1;
993 break;
998 return true;
1002 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1003 LLVM_DUMP_METHOD void AttributeListImpl::dump() const {
1004 AttributeList(const_cast<AttributeListImpl *>(this)).dump();
1006 #endif
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);
1020 void *InsertPoint;
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.
1026 if (!PA) {
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);
1039 AttributeList
1040 AttributeList::get(LLVMContext &C,
1041 ArrayRef<std::pair<unsigned, Attribute>> Attrs) {
1042 // If there are no attributes then return a null AttributesList pointer.
1043 if (Attrs.empty())
1044 return {};
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;
1050 }) &&
1051 "Misordered Attributes list!");
1052 assert(llvm::all_of(Attrs,
1053 [](const std::pair<unsigned, Attribute> &Pair) {
1054 return Pair.second.isValid();
1055 }) &&
1056 "Pointless attribute!");
1058 // Create a vector if (unsigned, AttributeSetNode*) pairs from the attributes
1059 // list.
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);
1067 ++I;
1070 AttrPairVec.emplace_back(Index, AttributeSet::get(C, AttrVec));
1073 return get(C, AttrPairVec);
1076 AttributeList
1077 AttributeList::get(LLVMContext &C,
1078 ArrayRef<std::pair<unsigned, AttributeSet>> Attrs) {
1079 // If there are no attributes then return a null AttributesList pointer.
1080 if (Attrs.empty())
1081 return {};
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;
1087 }) &&
1088 "Misordered Attributes list!");
1089 assert(llvm::none_of(Attrs,
1090 [](const std::pair<unsigned, AttributeSet> &Pair) {
1091 return !Pair.second.hasAttributes();
1092 }) &&
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()) {
1117 NumSets = I + 2;
1118 break;
1121 if (NumSets == 0) {
1122 // Check function and return attributes if we didn't have argument
1123 // attributes.
1124 if (RetAttrs.hasAttributes())
1125 NumSets = 2;
1126 else if (FnAttrs.hasAttributes())
1127 NumSets = 1;
1130 // If all attribute sets were empty, we can use the empty attribute list.
1131 if (NumSets == 0)
1132 return {};
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);
1138 if (NumSets > 1)
1139 AttrSets.push_back(RetAttrs);
1140 if (NumSets > 2) {
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())
1152 return {};
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) {
1188 if (Attrs.empty())
1189 return {};
1190 if (Attrs.size() == 1)
1191 return Attrs[0];
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.
1198 if (MaxSize == 0)
1199 return {};
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,
1223 StringRef Kind,
1224 StringRef Value) const {
1225 AttrBuilder B;
1226 B.addAttribute(Kind, Value);
1227 return addAttributes(C, Index, B);
1230 AttributeList AttributeList::addAttribute(LLVMContext &C, unsigned Index,
1231 Attribute A) const {
1232 AttrBuilder B;
1233 B.addAttribute(A);
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())
1250 return *this;
1252 if (!pImpl)
1253 return AttributeList::get(C, {{Index, AttributeSet::get(C, B)}});
1255 #ifndef NDEBUG
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!");
1262 #endif
1264 AttrBuilder Merged(getAttributes(Index));
1265 Merged.merge(B);
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]);
1282 B.addAttribute(A);
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);
1315 AttributeList
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)
1322 return *this;
1323 return setAttributes(C, Index, NewAttrs);
1326 AttributeList AttributeList::removeAttributes(LLVMContext &C,
1327 unsigned WithoutIndex) const {
1328 if (!pImpl)
1329 return {};
1330 WithoutIndex = attrIdxToArrayIdx(WithoutIndex);
1331 if (WithoutIndex >= getNumAttrSets())
1332 return *this;
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 {
1340 AttrBuilder B;
1341 B.addDereferenceableAttr(Bytes);
1342 return addRetAttributes(C, B);
1345 AttributeList AttributeList::addDereferenceableParamAttr(LLVMContext &C,
1346 unsigned Index,
1347 uint64_t Bytes) const {
1348 AttrBuilder B;
1349 B.addDereferenceableAttr(Bytes);
1350 return addParamAttributes(C, Index, B);
1353 AttributeList
1354 AttributeList::addDereferenceableOrNullParamAttr(LLVMContext &C, unsigned Index,
1355 uint64_t Bytes) const {
1356 AttrBuilder B;
1357 B.addDereferenceableOrNullAttr(Bytes);
1358 return addParamAttributes(C, Index, B);
1361 AttributeList
1362 AttributeList::addAllocSizeParamAttr(LLVMContext &C, unsigned Index,
1363 unsigned ElemSizeArg,
1364 const Optional<unsigned> &NumElemsArg) {
1365 AttrBuilder B;
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();
1477 uint64_t
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())
1489 return {};
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;
1496 pImpl->Profile(ID);
1497 void *Unused;
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())
1522 continue;
1523 O << " { ";
1524 switch (i) {
1525 case AttrIndex::ReturnIndex:
1526 O << "return";
1527 break;
1528 case AttrIndex::FunctionIndex:
1529 O << "function";
1530 break;
1531 default:
1532 O << "arg(" << i - AttrIndex::FirstArgIndex << ")";
1534 O << " => " << getAsString(i) << " }\n";
1537 O << "]\n";
1540 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1541 LLVM_DUMP_METHOD void AttributeList::dump() const { print(dbgs()); }
1542 #endif
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)
1552 addAttribute(A);
1555 AttrBuilder::AttrBuilder(AttributeSet AS) {
1556 for (const auto &A : AS)
1557 addAttribute(A);
1560 void AttrBuilder::clear() {
1561 Attrs.reset();
1562 TargetDepAttrs.clear();
1563 Alignment.reset();
1564 StackAlignment.reset();
1565 DerefBytes = DerefOrNullBytes = 0;
1566 AllocSizeArgs = 0;
1567 VScaleRangeArgs = 0;
1568 TypeAttrs = {};
1571 Optional<unsigned>
1572 AttrBuilder::kindToTypeIndex(Attribute::AttrKind Kind) const {
1573 if (Attribute::isTypeAttrKind(Kind))
1574 return Kind - Attribute::FirstTypeAttr;
1575 return None;
1578 AttrBuilder &AttrBuilder::addAttribute(Attribute Attr) {
1579 if (Attr.isStringAttribute()) {
1580 addAttribute(Attr.getKindAsString(), Attr.getValueAsString());
1581 return *this;
1584 Attribute::AttrKind Kind = Attr.getKindAsEnum();
1585 Attrs[Kind] = true;
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();
1602 return *this;
1605 AttrBuilder &AttrBuilder::addAttribute(StringRef A, StringRef V) {
1606 TargetDepAttrs[A] = V;
1607 return *this;
1610 AttrBuilder &AttrBuilder::removeAttribute(Attribute::AttrKind Val) {
1611 assert((unsigned)Val < Attribute::EndAttrKinds && "Attribute out of range!");
1612 Attrs[Val] = false;
1614 if (Optional<unsigned> TypeIndex = kindToTypeIndex(Val))
1615 TypeAttrs[*TypeIndex] = nullptr;
1616 else if (Val == Attribute::Alignment)
1617 Alignment.reset();
1618 else if (Val == Attribute::StackAlignment)
1619 StackAlignment.reset();
1620 else if (Val == Attribute::Dereferenceable)
1621 DerefBytes = 0;
1622 else if (Val == Attribute::DereferenceableOrNull)
1623 DerefOrNullBytes = 0;
1624 else if (Val == Attribute::AllocSize)
1625 AllocSizeArgs = 0;
1626 else if (Val == Attribute::VScaleRange)
1627 VScaleRangeArgs = 0;
1629 return *this;
1632 AttrBuilder &AttrBuilder::removeAttributes(AttributeList A, uint64_t Index) {
1633 remove(A.getAttributes(Index));
1634 return *this;
1637 AttrBuilder &AttrBuilder::removeAttribute(StringRef A) {
1638 auto I = TargetDepAttrs.find(A);
1639 if (I != TargetDepAttrs.end())
1640 TargetDepAttrs.erase(I);
1641 return *this;
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) {
1653 if (!Align)
1654 return *this;
1656 assert(*Align <= llvm::Value::MaximumAlignment && "Alignment too large.");
1658 Attrs[Attribute::Alignment] = true;
1659 Alignment = Align;
1660 return *this;
1663 AttrBuilder &AttrBuilder::addStackAlignmentAttr(MaybeAlign Align) {
1664 // Default alignment, allow the target to define how to align it.
1665 if (!Align)
1666 return *this;
1668 assert(*Align <= 0x100 && "Alignment too large.");
1670 Attrs[Attribute::StackAlignment] = true;
1671 StackAlignment = Align;
1672 return *this;
1675 AttrBuilder &AttrBuilder::addDereferenceableAttr(uint64_t Bytes) {
1676 if (Bytes == 0) return *this;
1678 Attrs[Attribute::Dereferenceable] = true;
1679 DerefBytes = Bytes;
1680 return *this;
1683 AttrBuilder &AttrBuilder::addDereferenceableOrNullAttr(uint64_t Bytes) {
1684 if (Bytes == 0)
1685 return *this;
1687 Attrs[Attribute::DereferenceableOrNull] = true;
1688 DerefOrNullBytes = Bytes;
1689 return *this;
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;
1705 return *this;
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
1715 if (RawArgs == 0)
1716 return *this;
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;
1722 return *this;
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");
1734 Attrs[Kind] = true;
1735 TypeAttrs[*TypeIndex] = Ty;
1736 return *this;
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?!
1761 if (!Alignment)
1762 Alignment = B.Alignment;
1764 if (!StackAlignment)
1765 StackAlignment = B.StackAlignment;
1767 if (!DerefBytes)
1768 DerefBytes = B.DerefBytes;
1770 if (!DerefOrNullBytes)
1771 DerefOrNullBytes = B.DerefOrNullBytes;
1773 if (!AllocSizeArgs)
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];
1783 Attrs |= B.Attrs;
1785 for (const auto &I : B.td_attrs())
1786 TargetDepAttrs[I.first] = I.second;
1788 return *this;
1791 AttrBuilder &AttrBuilder::remove(const AttrBuilder &B) {
1792 // FIXME: What if both have alignments, but they don't match?!
1793 if (B.Alignment)
1794 Alignment.reset();
1796 if (B.StackAlignment)
1797 StackAlignment.reset();
1799 if (B.DerefBytes)
1800 DerefBytes = 0;
1802 if (B.DerefOrNullBytes)
1803 DerefOrNullBytes = 0;
1805 if (B.AllocSizeArgs)
1806 AllocSizeArgs = 0;
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;
1815 Attrs &= ~B.Attrs;
1817 for (const auto &I : B.td_attrs())
1818 TargetDepAttrs.erase(I.first);
1820 return *this;
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())
1826 return true;
1828 // Then check if any target dependent ones do.
1829 for (const auto &I : td_attrs())
1830 if (B.contains(I.first))
1831 return true;
1833 return false;
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()))
1850 return true;
1851 } else {
1852 assert(Attr.isStringAttribute() && "Invalid attribute kind!");
1853 return contains(Attr.getKindAsString());
1857 return false;
1860 bool AttrBuilder::hasAlignmentAttr() const {
1861 return Alignment != 0;
1864 bool AttrBuilder::operator==(const AttrBuilder &B) const {
1865 if (Attrs != B.Attrs)
1866 return false;
1868 for (const auto &TDA : TargetDepAttrs)
1869 if (B.TargetDepAttrs.find(TDA.first) == B.TargetDepAttrs.end())
1870 return false;
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)
1904 .addByValAttr(Ty)
1905 .addStructRetAttr(Ty)
1906 .addByRefAttr(Ty)
1907 .addTypeAttr(Attribute::ElementType, Ty);
1909 // Some attributes can apply to all "values" but there are no `void` values.
1910 if (Ty->isVoidTy())
1911 Incompatible.addAttribute(Attribute::NoUndef);
1913 return Incompatible;
1916 AttrBuilder AttributeFuncs::getUBImplyingAttributes() {
1917 AttrBuilder B;
1918 B.addAttribute(Attribute::NoUndef);
1919 B.addDereferenceableAttr(1);
1920 B.addDereferenceableOrNullAttr(1);
1921 return B;
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
1931 /// callee.
1933 /// This function sets the caller's attribute to false if the callee's attribute
1934 /// is false.
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
1943 /// callee.
1945 /// This function sets the caller's attribute to true if the callee's attribute
1946 /// is true.
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.
1990 static void
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);
2003 } else {
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.
2018 static void
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);
2029 } else {
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.
2039 static void
2040 adjustNullPointerValidAttr(Function &Caller, const Function &Callee) {
2041 if (Callee.nullPointerIsDefined() && !Caller.nullPointerIsDefined()) {
2042 Caller.addFnAttr(Attribute::NullPointerIsValid);
2046 struct EnumAttr {
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) {
2054 if (Val)
2055 Fn.addFnAttr(Kind);
2056 else
2057 Fn.removeFnAttr(Kind);
2061 struct StrBoolAttr {
2062 static bool isSet(const Function &Fn,
2063 StringRef Kind) {
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
2111 // is not set.
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);