LLVM 19.0.0git
Attributes.cpp
Go to the documentation of this file.
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.
12//
13//===----------------------------------------------------------------------===//
14
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/STLExtras.h"
23#include "llvm/ADT/StringRef.h"
25#include "llvm/Config/llvm-config.h"
27#include "llvm/IR/Function.h"
28#include "llvm/IR/LLVMContext.h"
29#include "llvm/IR/Type.h"
32#include "llvm/Support/ModRef.h"
34#include <algorithm>
35#include <cassert>
36#include <cstddef>
37#include <cstdint>
38#include <limits>
39#include <optional>
40#include <string>
41#include <tuple>
42#include <utility>
43
44using namespace llvm;
45
46//===----------------------------------------------------------------------===//
47// Attribute Construction Methods
48//===----------------------------------------------------------------------===//
49
50// allocsize has two integer arguments, but because they're both 32 bits, we can
51// pack them into one 64-bit value, at the cost of making said value
52// nonsensical.
53//
54// In order to do this, we need to reserve one value of the second (optional)
55// allocsize argument to signify "not present."
56static const unsigned AllocSizeNumElemsNotPresent = -1;
57
58static uint64_t packAllocSizeArgs(unsigned ElemSizeArg,
59 const std::optional<unsigned> &NumElemsArg) {
60 assert((!NumElemsArg || *NumElemsArg != AllocSizeNumElemsNotPresent) &&
61 "Attempting to pack a reserved value");
62
63 return uint64_t(ElemSizeArg) << 32 |
64 NumElemsArg.value_or(AllocSizeNumElemsNotPresent);
65}
66
67static std::pair<unsigned, std::optional<unsigned>>
69 unsigned NumElems = Num & std::numeric_limits<unsigned>::max();
70 unsigned ElemSizeArg = Num >> 32;
71
72 std::optional<unsigned> NumElemsArg;
73 if (NumElems != AllocSizeNumElemsNotPresent)
74 NumElemsArg = NumElems;
75 return std::make_pair(ElemSizeArg, NumElemsArg);
76}
77
78static uint64_t packVScaleRangeArgs(unsigned MinValue,
79 std::optional<unsigned> MaxValue) {
80 return uint64_t(MinValue) << 32 | MaxValue.value_or(0);
81}
82
83static std::pair<unsigned, std::optional<unsigned>>
85 unsigned MaxValue = Value & std::numeric_limits<unsigned>::max();
86 unsigned MinValue = Value >> 32;
87
88 return std::make_pair(MinValue,
89 MaxValue > 0 ? MaxValue : std::optional<unsigned>());
90}
91
93 uint64_t Val) {
94 bool IsIntAttr = Attribute::isIntAttrKind(Kind);
95 assert((IsIntAttr || Attribute::isEnumAttrKind(Kind)) &&
96 "Not an enum or int attribute");
97
100 ID.AddInteger(Kind);
101 if (IsIntAttr)
102 ID.AddInteger(Val);
103 else
104 assert(Val == 0 && "Value must be zero for enum attributes");
105
106 void *InsertPoint;
107 AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);
108
109 if (!PA) {
110 // If we didn't find any existing attributes of the same shape then create a
111 // new one and insert it.
112 if (!IsIntAttr)
113 PA = new (pImpl->Alloc) EnumAttributeImpl(Kind);
114 else
115 PA = new (pImpl->Alloc) IntAttributeImpl(Kind, Val);
116 pImpl->AttrsSet.InsertNode(PA, InsertPoint);
117 }
118
119 // Return the Attribute that we found or created.
120 return Attribute(PA);
121}
122
126 ID.AddString(Kind);
127 if (!Val.empty()) ID.AddString(Val);
128
129 void *InsertPoint;
130 AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);
131
132 if (!PA) {
133 // If we didn't find any existing attributes of the same shape then create a
134 // new one and insert it.
135 void *Mem =
137 alignof(StringAttributeImpl));
138 PA = new (Mem) StringAttributeImpl(Kind, Val);
139 pImpl->AttrsSet.InsertNode(PA, InsertPoint);
140 }
141
142 // Return the Attribute that we found or created.
143 return Attribute(PA);
144}
145
147 Type *Ty) {
148 assert(Attribute::isTypeAttrKind(Kind) && "Not a type attribute");
151 ID.AddInteger(Kind);
152 ID.AddPointer(Ty);
153
154 void *InsertPoint;
155 AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);
156
157 if (!PA) {
158 // If we didn't find any existing attributes of the same shape then create a
159 // new one and insert it.
160 PA = new (pImpl->Alloc) TypeAttributeImpl(Kind, Ty);
161 pImpl->AttrsSet.InsertNode(PA, InsertPoint);
162 }
163
164 // Return the Attribute that we found or created.
165 return Attribute(PA);
166}
167
169 assert(A <= llvm::Value::MaximumAlignment && "Alignment too large.");
170 return get(Context, Alignment, A.value());
171}
172
174 assert(A <= 0x100 && "Alignment too large.");
175 return get(Context, StackAlignment, A.value());
176}
177
179 uint64_t Bytes) {
180 assert(Bytes && "Bytes must be non-zero.");
181 return get(Context, Dereferenceable, Bytes);
182}
183
185 uint64_t Bytes) {
186 assert(Bytes && "Bytes must be non-zero.");
187 return get(Context, DereferenceableOrNull, Bytes);
188}
189
191 return get(Context, ByVal, Ty);
192}
193
195 return get(Context, StructRet, Ty);
196}
197
199 return get(Context, ByRef, Ty);
200}
201
203 return get(Context, Preallocated, Ty);
204}
205
207 return get(Context, InAlloca, Ty);
208}
209
211 UWTableKind Kind) {
212 return get(Context, UWTable, uint64_t(Kind));
213}
214
216 MemoryEffects ME) {
217 return get(Context, Memory, ME.toIntValue());
218}
219
221 FPClassTest ClassMask) {
222 return get(Context, NoFPClass, ClassMask);
223}
224
226Attribute::getWithAllocSizeArgs(LLVMContext &Context, unsigned ElemSizeArg,
227 const std::optional<unsigned> &NumElemsArg) {
228 assert(!(ElemSizeArg == 0 && NumElemsArg && *NumElemsArg == 0) &&
229 "Invalid allocsize arguments -- given allocsize(0, 0)");
230 return get(Context, AllocSize, packAllocSizeArgs(ElemSizeArg, NumElemsArg));
231}
232
234 unsigned MinValue,
235 unsigned MaxValue) {
236 return get(Context, VScaleRange, packVScaleRangeArgs(MinValue, MaxValue));
237}
238
240 return StringSwitch<Attribute::AttrKind>(AttrName)
241#define GET_ATTR_NAMES
242#define ATTRIBUTE_ENUM(ENUM_NAME, DISPLAY_NAME) \
243 .Case(#DISPLAY_NAME, Attribute::ENUM_NAME)
244#include "llvm/IR/Attributes.inc"
246}
247
249 switch (AttrKind) {
250#define GET_ATTR_NAMES
251#define ATTRIBUTE_ENUM(ENUM_NAME, DISPLAY_NAME) \
252 case Attribute::ENUM_NAME: \
253 return #DISPLAY_NAME;
254#include "llvm/IR/Attributes.inc"
255 case Attribute::None:
256 return "none";
257 default:
258 llvm_unreachable("invalid Kind");
259 }
260}
261
264#define GET_ATTR_NAMES
265#define ATTRIBUTE_ALL(ENUM_NAME, DISPLAY_NAME) .Case(#DISPLAY_NAME, true)
266#include "llvm/IR/Attributes.inc"
267 .Default(false);
268}
269
270//===----------------------------------------------------------------------===//
271// Attribute Accessor Methods
272//===----------------------------------------------------------------------===//
273
275 return pImpl && pImpl->isEnumAttribute();
276}
277
279 return pImpl && pImpl->isIntAttribute();
280}
281
283 return pImpl && pImpl->isStringAttribute();
284}
285
287 return pImpl && pImpl->isTypeAttribute();
288}
289
291 if (!pImpl) return None;
293 "Invalid attribute type to get the kind as an enum!");
294 return pImpl->getKindAsEnum();
295}
296
298 if (!pImpl) return 0;
300 "Expected the attribute to be an integer attribute!");
301 return pImpl->getValueAsInt();
302}
303
305 if (!pImpl) return false;
307 "Expected the attribute to be a string attribute!");
308 return pImpl->getValueAsBool();
309}
310
312 if (!pImpl) return {};
314 "Invalid attribute type to get the kind as a string!");
315 return pImpl->getKindAsString();
316}
317
319 if (!pImpl) return {};
321 "Invalid attribute type to get the value as a string!");
322 return pImpl->getValueAsString();
323}
324
326 if (!pImpl) return {};
328 "Invalid attribute type to get the value as a type!");
329 return pImpl->getValueAsType();
330}
331
332
334 return (pImpl && pImpl->hasAttribute(Kind)) || (!pImpl && Kind == None);
335}
336
338 if (!isStringAttribute()) return false;
339 return pImpl && pImpl->hasAttribute(Kind);
340}
341
343 assert(hasAttribute(Attribute::Alignment) &&
344 "Trying to get alignment from non-alignment attribute!");
345 return MaybeAlign(pImpl->getValueAsInt());
346}
347
349 assert(hasAttribute(Attribute::StackAlignment) &&
350 "Trying to get alignment from non-alignment attribute!");
351 return MaybeAlign(pImpl->getValueAsInt());
352}
353
355 assert(hasAttribute(Attribute::Dereferenceable) &&
356 "Trying to get dereferenceable bytes from "
357 "non-dereferenceable attribute!");
358 return pImpl->getValueAsInt();
359}
360
362 assert(hasAttribute(Attribute::DereferenceableOrNull) &&
363 "Trying to get dereferenceable bytes from "
364 "non-dereferenceable attribute!");
365 return pImpl->getValueAsInt();
366}
367
368std::pair<unsigned, std::optional<unsigned>>
370 assert(hasAttribute(Attribute::AllocSize) &&
371 "Trying to get allocsize args from non-allocsize attribute");
372 return unpackAllocSizeArgs(pImpl->getValueAsInt());
373}
374
376 assert(hasAttribute(Attribute::VScaleRange) &&
377 "Trying to get vscale args from non-vscale attribute");
378 return unpackVScaleRangeArgs(pImpl->getValueAsInt()).first;
379}
380
381std::optional<unsigned> Attribute::getVScaleRangeMax() const {
382 assert(hasAttribute(Attribute::VScaleRange) &&
383 "Trying to get vscale args from non-vscale attribute");
384 return unpackVScaleRangeArgs(pImpl->getValueAsInt()).second;
385}
386
388 assert(hasAttribute(Attribute::UWTable) &&
389 "Trying to get unwind table kind from non-uwtable attribute");
390 return UWTableKind(pImpl->getValueAsInt());
391}
392
394 assert(hasAttribute(Attribute::AllocKind) &&
395 "Trying to get allockind value from non-allockind attribute");
396 return AllocFnKind(pImpl->getValueAsInt());
397}
398
400 assert(hasAttribute(Attribute::Memory) &&
401 "Can only call getMemoryEffects() on memory attribute");
403}
404
406 assert(hasAttribute(Attribute::NoFPClass) &&
407 "Can only call getNoFPClass() on nofpclass attribute");
408 return static_cast<FPClassTest>(pImpl->getValueAsInt());
409}
410
411static const char *getModRefStr(ModRefInfo MR) {
412 switch (MR) {
414 return "none";
415 case ModRefInfo::Ref:
416 return "read";
417 case ModRefInfo::Mod:
418 return "write";
420 return "readwrite";
421 }
422 llvm_unreachable("Invalid ModRefInfo");
423}
424
425std::string Attribute::getAsString(bool InAttrGrp) const {
426 if (!pImpl) return {};
427
428 if (isEnumAttribute())
430
431 if (isTypeAttribute()) {
432 std::string Result = getNameFromAttrKind(getKindAsEnum()).str();
433 Result += '(';
434 raw_string_ostream OS(Result);
435 getValueAsType()->print(OS, false, true);
436 OS.flush();
437 Result += ')';
438 return Result;
439 }
440
441 // FIXME: These should be output like this:
442 //
443 // align=4
444 // alignstack=8
445 //
446 if (hasAttribute(Attribute::Alignment))
447 return (InAttrGrp ? "align=" + Twine(getValueAsInt())
448 : "align " + Twine(getValueAsInt()))
449 .str();
450
451 auto AttrWithBytesToString = [&](const char *Name) {
452 return (InAttrGrp ? Name + ("=" + Twine(getValueAsInt()))
453 : Name + ("(" + Twine(getValueAsInt())) + ")")
454 .str();
455 };
456
457 if (hasAttribute(Attribute::StackAlignment))
458 return AttrWithBytesToString("alignstack");
459
460 if (hasAttribute(Attribute::Dereferenceable))
461 return AttrWithBytesToString("dereferenceable");
462
463 if (hasAttribute(Attribute::DereferenceableOrNull))
464 return AttrWithBytesToString("dereferenceable_or_null");
465
466 if (hasAttribute(Attribute::AllocSize)) {
467 unsigned ElemSize;
468 std::optional<unsigned> NumElems;
469 std::tie(ElemSize, NumElems) = getAllocSizeArgs();
470
471 return (NumElems
472 ? "allocsize(" + Twine(ElemSize) + "," + Twine(*NumElems) + ")"
473 : "allocsize(" + Twine(ElemSize) + ")")
474 .str();
475 }
476
477 if (hasAttribute(Attribute::VScaleRange)) {
478 unsigned MinValue = getVScaleRangeMin();
479 std::optional<unsigned> MaxValue = getVScaleRangeMax();
480 return ("vscale_range(" + Twine(MinValue) + "," +
481 Twine(MaxValue.value_or(0)) + ")")
482 .str();
483 }
484
485 if (hasAttribute(Attribute::UWTable)) {
487 if (Kind != UWTableKind::None) {
488 return Kind == UWTableKind::Default
489 ? "uwtable"
490 : ("uwtable(" +
491 Twine(Kind == UWTableKind::Sync ? "sync" : "async") + ")")
492 .str();
493 }
494 }
495
496 if (hasAttribute(Attribute::AllocKind)) {
497 AllocFnKind Kind = getAllocKind();
500 parts.push_back("alloc");
502 parts.push_back("realloc");
504 parts.push_back("free");
506 parts.push_back("uninitialized");
508 parts.push_back("zeroed");
510 parts.push_back("aligned");
511 return ("allockind(\"" +
512 Twine(llvm::join(parts.begin(), parts.end(), ",")) + "\")")
513 .str();
514 }
515
516 if (hasAttribute(Attribute::Memory)) {
517 std::string Result;
518 raw_string_ostream OS(Result);
519 bool First = true;
520 OS << "memory(";
521
523
524 // Print access kind for "other" as the default access kind. This way it
525 // will apply to any new location kinds that get split out of "other".
527 if (OtherMR != ModRefInfo::NoModRef || ME.getModRef() == OtherMR) {
528 First = false;
529 OS << getModRefStr(OtherMR);
530 }
531
532 for (auto Loc : MemoryEffects::locations()) {
533 ModRefInfo MR = ME.getModRef(Loc);
534 if (MR == OtherMR)
535 continue;
536
537 if (!First)
538 OS << ", ";
539 First = false;
540
541 switch (Loc) {
543 OS << "argmem: ";
544 break;
546 OS << "inaccessiblemem: ";
547 break;
549 llvm_unreachable("This is represented as the default access kind");
550 }
551 OS << getModRefStr(MR);
552 }
553 OS << ")";
554 OS.flush();
555 return Result;
556 }
557
558 if (hasAttribute(Attribute::NoFPClass)) {
559 std::string Result = "nofpclass";
560 raw_string_ostream OS(Result);
561 OS << getNoFPClass();
562 return Result;
563 }
564
565 // Convert target-dependent attributes to strings of the form:
566 //
567 // "kind"
568 // "kind" = "value"
569 //
570 if (isStringAttribute()) {
571 std::string Result;
572 {
573 raw_string_ostream OS(Result);
574 OS << '"' << getKindAsString() << '"';
575
576 // Since some attribute strings contain special characters that cannot be
577 // printable, those have to be escaped to make the attribute value
578 // printable as is. e.g. "\01__gnu_mcount_nc"
579 const auto &AttrVal = pImpl->getValueAsString();
580 if (!AttrVal.empty()) {
581 OS << "=\"";
582 printEscapedString(AttrVal, OS);
583 OS << "\"";
584 }
585 }
586 return Result;
587 }
588
589 llvm_unreachable("Unknown attribute");
590}
591
593 assert(isValid() && "invalid Attribute doesn't refer to any context");
595 pImpl->Profile(ID);
596 void *Unused;
597 return C.pImpl->AttrsSet.FindNodeOrInsertPos(ID, Unused) == pImpl;
598}
599
601 if (!pImpl && !A.pImpl) return false;
602 if (!pImpl) return true;
603 if (!A.pImpl) return false;
604 return *pImpl < *A.pImpl;
605}
606
608 ID.AddPointer(pImpl);
609}
610
612 FnAttr = (1 << 0),
613 ParamAttr = (1 << 1),
614 RetAttr = (1 << 2),
615};
616
617#define GET_ATTR_PROP_TABLE
618#include "llvm/IR/Attributes.inc"
619
621 AttributeProperty Prop) {
622 unsigned Index = Kind - 1;
623 assert(Index < std::size(AttrPropTable) && "Invalid attribute kind");
624 return AttrPropTable[Index] & Prop;
625}
626
628 return hasAttributeProperty(Kind, AttributeProperty::FnAttr);
629}
630
632 return hasAttributeProperty(Kind, AttributeProperty::ParamAttr);
633}
634
636 return hasAttributeProperty(Kind, AttributeProperty::RetAttr);
637}
638
639//===----------------------------------------------------------------------===//
640// AttributeImpl Definition
641//===----------------------------------------------------------------------===//
642
644 if (isStringAttribute()) return false;
645 return getKindAsEnum() == A;
646}
647
649 if (!isStringAttribute()) return false;
650 return getKindAsString() == Kind;
651}
652
655 return static_cast<const EnumAttributeImpl *>(this)->getEnumKind();
656}
657
660 return static_cast<const IntAttributeImpl *>(this)->getValue();
661}
662
664 assert(getValueAsString().empty() || getValueAsString() == "false" || getValueAsString() == "true");
665 return getValueAsString() == "true";
666}
667
670 return static_cast<const StringAttributeImpl *>(this)->getStringKind();
671}
672
675 return static_cast<const StringAttributeImpl *>(this)->getStringValue();
676}
677
680 return static_cast<const TypeAttributeImpl *>(this)->getTypeValue();
681}
682
684 if (this == &AI)
685 return false;
686
687 // This sorts the attributes with Attribute::AttrKinds coming first (sorted
688 // relative to their enum value) and then strings.
689 if (!isStringAttribute()) {
690 if (AI.isStringAttribute())
691 return true;
692 if (getKindAsEnum() != AI.getKindAsEnum())
693 return getKindAsEnum() < AI.getKindAsEnum();
694 assert(!AI.isEnumAttribute() && "Non-unique attribute");
695 assert(!AI.isTypeAttribute() && "Comparison of types would be unstable");
696 // TODO: Is this actually needed?
697 assert(AI.isIntAttribute() && "Only possibility left");
698 return getValueAsInt() < AI.getValueAsInt();
699 }
700
701 if (!AI.isStringAttribute())
702 return false;
703 if (getKindAsString() == AI.getKindAsString())
704 return getValueAsString() < AI.getValueAsString();
705 return getKindAsString() < AI.getKindAsString();
706}
707
708//===----------------------------------------------------------------------===//
709// AttributeSet Definition
710//===----------------------------------------------------------------------===//
711
714}
715
717 return AttributeSet(AttributeSetNode::get(C, Attrs));
718}
719
721 Attribute::AttrKind Kind) const {
722 if (hasAttribute(Kind)) return *this;
723 AttrBuilder B(C);
724 B.addAttribute(Kind);
726}
727
729 StringRef Value) const {
730 AttrBuilder B(C);
731 B.addAttribute(Kind, Value);
733}
734
736 const AttributeSet AS) const {
737 if (!hasAttributes())
738 return AS;
739
740 if (!AS.hasAttributes())
741 return *this;
742
743 AttrBuilder B(C, *this);
744 B.merge(AttrBuilder(C, AS));
745 return get(C, B);
746}
747
749 Attribute::AttrKind Kind) const {
750 if (!hasAttribute(Kind)) return *this;
751 AttrBuilder B(C, *this);
752 B.removeAttribute(Kind);
753 return get(C, B);
754}
755
757 StringRef Kind) const {
758 if (!hasAttribute(Kind)) return *this;
759 AttrBuilder B(C, *this);
760 B.removeAttribute(Kind);
761 return get(C, B);
762}
763
765 const AttributeMask &Attrs) const {
766 AttrBuilder B(C, *this);
767 // If there is nothing to remove, directly return the original set.
768 if (!B.overlaps(Attrs))
769 return *this;
770
771 B.remove(Attrs);
772 return get(C, B);
773}
774
776 return SetNode ? SetNode->getNumAttributes() : 0;
777}
778
780 return SetNode ? SetNode->hasAttribute(Kind) : false;
781}
782
784 return SetNode ? SetNode->hasAttribute(Kind) : false;
785}
786
788 return SetNode ? SetNode->getAttribute(Kind) : Attribute();
789}
790
792 return SetNode ? SetNode->getAttribute(Kind) : Attribute();
793}
794
796 return SetNode ? SetNode->getAlignment() : std::nullopt;
797}
798
800 return SetNode ? SetNode->getStackAlignment() : std::nullopt;
801}
802
804 return SetNode ? SetNode->getDereferenceableBytes() : 0;
805}
806
808 return SetNode ? SetNode->getDereferenceableOrNullBytes() : 0;
809}
810
812 return SetNode ? SetNode->getAttributeType(Attribute::ByRef) : nullptr;
813}
814
816 return SetNode ? SetNode->getAttributeType(Attribute::ByVal) : nullptr;
817}
818
820 return SetNode ? SetNode->getAttributeType(Attribute::StructRet) : nullptr;
821}
822
824 return SetNode ? SetNode->getAttributeType(Attribute::Preallocated) : nullptr;
825}
826
828 return SetNode ? SetNode->getAttributeType(Attribute::InAlloca) : nullptr;
829}
830
832 return SetNode ? SetNode->getAttributeType(Attribute::ElementType) : nullptr;
833}
834
835std::optional<std::pair<unsigned, std::optional<unsigned>>>
837 if (SetNode)
838 return SetNode->getAllocSizeArgs();
839 return std::nullopt;
840}
841
843 return SetNode ? SetNode->getVScaleRangeMin() : 1;
844}
845
846std::optional<unsigned> AttributeSet::getVScaleRangeMax() const {
847 return SetNode ? SetNode->getVScaleRangeMax() : std::nullopt;
848}
849
851 return SetNode ? SetNode->getUWTableKind() : UWTableKind::None;
852}
853
855 return SetNode ? SetNode->getAllocKind() : AllocFnKind::Unknown;
856}
857
859 return SetNode ? SetNode->getMemoryEffects() : MemoryEffects::unknown();
860}
861
863 return SetNode ? SetNode->getNoFPClass() : fcNone;
864}
865
866std::string AttributeSet::getAsString(bool InAttrGrp) const {
867 return SetNode ? SetNode->getAsString(InAttrGrp) : "";
868}
869
871 assert(hasAttributes() && "empty AttributeSet doesn't refer to any context");
873 SetNode->Profile(ID);
874 void *Unused;
875 return C.pImpl->AttrsSetNodes.FindNodeOrInsertPos(ID, Unused) == SetNode;
876}
877
879 return SetNode ? SetNode->begin() : nullptr;
880}
881
883 return SetNode ? SetNode->end() : nullptr;
884}
885
886#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
888 dbgs() << "AS =\n";
889 dbgs() << " { ";
890 dbgs() << getAsString(true) << " }\n";
891}
892#endif
893
894//===----------------------------------------------------------------------===//
895// AttributeSetNode Definition
896//===----------------------------------------------------------------------===//
897
898AttributeSetNode::AttributeSetNode(ArrayRef<Attribute> Attrs)
899 : NumAttrs(Attrs.size()) {
900 // There's memory after the node where we can store the entries in.
901 llvm::copy(Attrs, getTrailingObjects<Attribute>());
902
903 for (const auto &I : *this) {
904 if (I.isStringAttribute())
905 StringAttrs.insert({ I.getKindAsString(), I });
906 else
907 AvailableAttrs.addAttribute(I.getKindAsEnum());
908 }
909}
910
912 ArrayRef<Attribute> Attrs) {
913 SmallVector<Attribute, 8> SortedAttrs(Attrs.begin(), Attrs.end());
914 llvm::sort(SortedAttrs);
915 return getSorted(C, SortedAttrs);
916}
917
918AttributeSetNode *AttributeSetNode::getSorted(LLVMContext &C,
919 ArrayRef<Attribute> SortedAttrs) {
920 if (SortedAttrs.empty())
921 return nullptr;
922
923 // Build a key to look up the existing attributes.
924 LLVMContextImpl *pImpl = C.pImpl;
926
927 assert(llvm::is_sorted(SortedAttrs) && "Expected sorted attributes!");
928 for (const auto &Attr : SortedAttrs)
929 Attr.Profile(ID);
930
931 void *InsertPoint;
932 AttributeSetNode *PA =
933 pImpl->AttrsSetNodes.FindNodeOrInsertPos(ID, InsertPoint);
934
935 // If we didn't find any existing attributes of the same shape then create a
936 // new one and insert it.
937 if (!PA) {
938 // Coallocate entries after the AttributeSetNode itself.
939 void *Mem = ::operator new(totalSizeToAlloc<Attribute>(SortedAttrs.size()));
940 PA = new (Mem) AttributeSetNode(SortedAttrs);
941 pImpl->AttrsSetNodes.InsertNode(PA, InsertPoint);
942 }
943
944 // Return the AttributeSetNode that we found or created.
945 return PA;
946}
947
949 return getSorted(C, B.attrs());
950}
951
953 return StringAttrs.count(Kind);
954}
955
956std::optional<Attribute>
957AttributeSetNode::findEnumAttribute(Attribute::AttrKind Kind) const {
958 // Do a quick presence check.
959 if (!hasAttribute(Kind))
960 return std::nullopt;
961
962 // Attributes in a set are sorted by enum value, followed by string
963 // attributes. Binary search the one we want.
964 const Attribute *I =
965 std::lower_bound(begin(), end() - StringAttrs.size(), Kind,
967 return A.getKindAsEnum() < Kind;
968 });
969 assert(I != end() && I->hasAttribute(Kind) && "Presence check failed?");
970 return *I;
971}
972
974 if (auto A = findEnumAttribute(Kind))
975 return *A;
976 return {};
977}
978
980 return StringAttrs.lookup(Kind);
981}
982
984 if (auto A = findEnumAttribute(Attribute::Alignment))
985 return A->getAlignment();
986 return std::nullopt;
987}
988
990 if (auto A = findEnumAttribute(Attribute::StackAlignment))
991 return A->getStackAlignment();
992 return std::nullopt;
993}
994
996 if (auto A = findEnumAttribute(Kind))
997 return A->getValueAsType();
998 return nullptr;
999}
1000
1002 if (auto A = findEnumAttribute(Attribute::Dereferenceable))
1003 return A->getDereferenceableBytes();
1004 return 0;
1005}
1006
1008 if (auto A = findEnumAttribute(Attribute::DereferenceableOrNull))
1009 return A->getDereferenceableOrNullBytes();
1010 return 0;
1011}
1012
1013std::optional<std::pair<unsigned, std::optional<unsigned>>>
1015 if (auto A = findEnumAttribute(Attribute::AllocSize))
1016 return A->getAllocSizeArgs();
1017 return std::nullopt;
1018}
1019
1021 if (auto A = findEnumAttribute(Attribute::VScaleRange))
1022 return A->getVScaleRangeMin();
1023 return 1;
1024}
1025
1026std::optional<unsigned> AttributeSetNode::getVScaleRangeMax() const {
1027 if (auto A = findEnumAttribute(Attribute::VScaleRange))
1028 return A->getVScaleRangeMax();
1029 return std::nullopt;
1030}
1031
1033 if (auto A = findEnumAttribute(Attribute::UWTable))
1034 return A->getUWTableKind();
1035 return UWTableKind::None;
1036}
1037
1039 if (auto A = findEnumAttribute(Attribute::AllocKind))
1040 return A->getAllocKind();
1041 return AllocFnKind::Unknown;
1042}
1043
1045 if (auto A = findEnumAttribute(Attribute::Memory))
1046 return A->getMemoryEffects();
1047 return MemoryEffects::unknown();
1048}
1049
1051 if (auto A = findEnumAttribute(Attribute::NoFPClass))
1052 return A->getNoFPClass();
1053 return fcNone;
1054}
1055
1056std::string AttributeSetNode::getAsString(bool InAttrGrp) const {
1057 std::string Str;
1058 for (iterator I = begin(), E = end(); I != E; ++I) {
1059 if (I != begin())
1060 Str += ' ';
1061 Str += I->getAsString(InAttrGrp);
1062 }
1063 return Str;
1064}
1065
1066//===----------------------------------------------------------------------===//
1067// AttributeListImpl Definition
1068//===----------------------------------------------------------------------===//
1069
1070/// Map from AttributeList index to the internal array index. Adding one happens
1071/// to work, because -1 wraps around to 0.
1072static unsigned attrIdxToArrayIdx(unsigned Index) {
1073 return Index + 1;
1074}
1075
1077 : NumAttrSets(Sets.size()) {
1078 assert(!Sets.empty() && "pointless AttributeListImpl");
1079
1080 // There's memory after the node where we can store the entries in.
1081 llvm::copy(Sets, getTrailingObjects<AttributeSet>());
1082
1083 // Initialize AvailableFunctionAttrs and AvailableSomewhereAttrs
1084 // summary bitsets.
1085 for (const auto &I : Sets[attrIdxToArrayIdx(AttributeList::FunctionIndex)])
1086 if (!I.isStringAttribute())
1087 AvailableFunctionAttrs.addAttribute(I.getKindAsEnum());
1088
1089 for (const auto &Set : Sets)
1090 for (const auto &I : Set)
1091 if (!I.isStringAttribute())
1092 AvailableSomewhereAttrs.addAttribute(I.getKindAsEnum());
1093}
1094
1096 Profile(ID, ArrayRef(begin(), end()));
1097}
1098
1101 for (const auto &Set : Sets)
1102 ID.AddPointer(Set.SetNode);
1103}
1104
1106 unsigned *Index) const {
1107 if (!AvailableSomewhereAttrs.hasAttribute(Kind))
1108 return false;
1109
1110 if (Index) {
1111 for (unsigned I = 0, E = NumAttrSets; I != E; ++I) {
1112 if (begin()[I].hasAttribute(Kind)) {
1113 *Index = I - 1;
1114 break;
1115 }
1116 }
1117 }
1118
1119 return true;
1120}
1121
1122
1123#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1125 AttributeList(const_cast<AttributeListImpl *>(this)).dump();
1126}
1127#endif
1128
1129//===----------------------------------------------------------------------===//
1130// AttributeList Construction and Mutation Methods
1131//===----------------------------------------------------------------------===//
1132
1133AttributeList AttributeList::getImpl(LLVMContext &C,
1134 ArrayRef<AttributeSet> AttrSets) {
1135 assert(!AttrSets.empty() && "pointless AttributeListImpl");
1136
1137 LLVMContextImpl *pImpl = C.pImpl;
1139 AttributeListImpl::Profile(ID, AttrSets);
1140
1141 void *InsertPoint;
1142 AttributeListImpl *PA =
1143 pImpl->AttrsLists.FindNodeOrInsertPos(ID, InsertPoint);
1144
1145 // If we didn't find any existing attributes of the same shape then
1146 // create a new one and insert it.
1147 if (!PA) {
1148 // Coallocate entries after the AttributeListImpl itself.
1149 void *Mem = pImpl->Alloc.Allocate(
1150 AttributeListImpl::totalSizeToAlloc<AttributeSet>(AttrSets.size()),
1151 alignof(AttributeListImpl));
1152 PA = new (Mem) AttributeListImpl(AttrSets);
1153 pImpl->AttrsLists.InsertNode(PA, InsertPoint);
1154 }
1155
1156 // Return the AttributesList that we found or created.
1157 return AttributeList(PA);
1158}
1159
1162 ArrayRef<std::pair<unsigned, Attribute>> Attrs) {
1163 // If there are no attributes then return a null AttributesList pointer.
1164 if (Attrs.empty())
1165 return {};
1166
1168 "Misordered Attributes list!");
1169 assert(llvm::all_of(Attrs,
1170 [](const std::pair<unsigned, Attribute> &Pair) {
1171 return Pair.second.isValid();
1172 }) &&
1173 "Pointless attribute!");
1174
1175 // Create a vector if (unsigned, AttributeSetNode*) pairs from the attributes
1176 // list.
1178 for (ArrayRef<std::pair<unsigned, Attribute>>::iterator I = Attrs.begin(),
1179 E = Attrs.end(); I != E; ) {
1180 unsigned Index = I->first;
1182 while (I != E && I->first == Index) {
1183 AttrVec.push_back(I->second);
1184 ++I;
1185 }
1186
1187 AttrPairVec.emplace_back(Index, AttributeSet::get(C, AttrVec));
1188 }
1189
1190 return get(C, AttrPairVec);
1191}
1192
1195 ArrayRef<std::pair<unsigned, AttributeSet>> Attrs) {
1196 // If there are no attributes then return a null AttributesList pointer.
1197 if (Attrs.empty())
1198 return {};
1199
1201 "Misordered Attributes list!");
1202 assert(llvm::none_of(Attrs,
1203 [](const std::pair<unsigned, AttributeSet> &Pair) {
1204 return !Pair.second.hasAttributes();
1205 }) &&
1206 "Pointless attribute!");
1207
1208 unsigned MaxIndex = Attrs.back().first;
1209 // If the MaxIndex is FunctionIndex and there are other indices in front
1210 // of it, we need to use the largest of those to get the right size.
1211 if (MaxIndex == FunctionIndex && Attrs.size() > 1)
1212 MaxIndex = Attrs[Attrs.size() - 2].first;
1213
1214 SmallVector<AttributeSet, 4> AttrVec(attrIdxToArrayIdx(MaxIndex) + 1);
1215 for (const auto &Pair : Attrs)
1216 AttrVec[attrIdxToArrayIdx(Pair.first)] = Pair.second;
1217
1218 return getImpl(C, AttrVec);
1219}
1220
1222 AttributeSet RetAttrs,
1223 ArrayRef<AttributeSet> ArgAttrs) {
1224 // Scan from the end to find the last argument with attributes. Most
1225 // arguments don't have attributes, so it's nice if we can have fewer unique
1226 // AttributeListImpls by dropping empty attribute sets at the end of the list.
1227 unsigned NumSets = 0;
1228 for (size_t I = ArgAttrs.size(); I != 0; --I) {
1229 if (ArgAttrs[I - 1].hasAttributes()) {
1230 NumSets = I + 2;
1231 break;
1232 }
1233 }
1234 if (NumSets == 0) {
1235 // Check function and return attributes if we didn't have argument
1236 // attributes.
1237 if (RetAttrs.hasAttributes())
1238 NumSets = 2;
1239 else if (FnAttrs.hasAttributes())
1240 NumSets = 1;
1241 }
1242
1243 // If all attribute sets were empty, we can use the empty attribute list.
1244 if (NumSets == 0)
1245 return {};
1246
1248 AttrSets.reserve(NumSets);
1249 // If we have any attributes, we always have function attributes.
1250 AttrSets.push_back(FnAttrs);
1251 if (NumSets > 1)
1252 AttrSets.push_back(RetAttrs);
1253 if (NumSets > 2) {
1254 // Drop the empty argument attribute sets at the end.
1255 ArgAttrs = ArgAttrs.take_front(NumSets - 2);
1256 llvm::append_range(AttrSets, ArgAttrs);
1257 }
1258
1259 return getImpl(C, AttrSets);
1260}
1261
1263 AttributeSet Attrs) {
1264 if (!Attrs.hasAttributes())
1265 return {};
1267 SmallVector<AttributeSet, 8> AttrSets(Index + 1);
1268 AttrSets[Index] = Attrs;
1269 return getImpl(C, AttrSets);
1270}
1271
1273 const AttrBuilder &B) {
1274 return get(C, Index, AttributeSet::get(C, B));
1275}
1276
1280 for (const auto K : Kinds)
1281 Attrs.emplace_back(Index, Attribute::get(C, K));
1282 return get(C, Attrs);
1283}
1284
1287 ArrayRef<uint64_t> Values) {
1288 assert(Kinds.size() == Values.size() && "Mismatched attribute values.");
1290 auto VI = Values.begin();
1291 for (const auto K : Kinds)
1292 Attrs.emplace_back(Index, Attribute::get(C, K, *VI++));
1293 return get(C, Attrs);
1294}
1295
1297 ArrayRef<StringRef> Kinds) {
1299 for (const auto &K : Kinds)
1300 Attrs.emplace_back(Index, Attribute::get(C, K));
1301 return get(C, Attrs);
1302}
1303
1306 if (Attrs.empty())
1307 return {};
1308 if (Attrs.size() == 1)
1309 return Attrs[0];
1310
1311 unsigned MaxSize = 0;
1312 for (const auto &List : Attrs)
1313 MaxSize = std::max(MaxSize, List.getNumAttrSets());
1314
1315 // If every list was empty, there is no point in merging the lists.
1316 if (MaxSize == 0)
1317 return {};
1318
1319 SmallVector<AttributeSet, 8> NewAttrSets(MaxSize);
1320 for (unsigned I = 0; I < MaxSize; ++I) {
1321 AttrBuilder CurBuilder(C);
1322 for (const auto &List : Attrs)
1323 CurBuilder.merge(AttrBuilder(C, List.getAttributes(I - 1)));
1324 NewAttrSets[I] = AttributeSet::get(C, CurBuilder);
1325 }
1326
1327 return getImpl(C, NewAttrSets);
1328}
1329
1332 Attribute::AttrKind Kind) const {
1334 if (Attrs.hasAttribute(Kind))
1335 return *this;
1336 // TODO: Insert at correct position and avoid sort.
1337 SmallVector<Attribute, 8> NewAttrs(Attrs.begin(), Attrs.end());
1338 NewAttrs.push_back(Attribute::get(C, Kind));
1339 return setAttributesAtIndex(C, Index, AttributeSet::get(C, NewAttrs));
1340}
1341
1343 StringRef Kind,
1344 StringRef Value) const {
1345 AttrBuilder B(C);
1346 B.addAttribute(Kind, Value);
1347 return addAttributesAtIndex(C, Index, B);
1348}
1349
1351 Attribute A) const {
1352 AttrBuilder B(C);
1353 B.addAttribute(A);
1354 return addAttributesAtIndex(C, Index, B);
1355}
1356
1357AttributeList AttributeList::setAttributesAtIndex(LLVMContext &C,
1358 unsigned Index,
1359 AttributeSet Attrs) const {
1361 SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
1362 if (Index >= AttrSets.size())
1363 AttrSets.resize(Index + 1);
1364 AttrSets[Index] = Attrs;
1365
1366 // Remove trailing empty attribute sets.
1367 while (!AttrSets.empty() && !AttrSets.back().hasAttributes())
1368 AttrSets.pop_back();
1369 if (AttrSets.empty())
1370 return {};
1371 return AttributeList::getImpl(C, AttrSets);
1372}
1373
1375 unsigned Index,
1376 const AttrBuilder &B) const {
1377 if (!B.hasAttributes())
1378 return *this;
1379
1380 if (!pImpl)
1382
1383 AttrBuilder Merged(C, getAttributes(Index));
1384 Merged.merge(B);
1385 return setAttributesAtIndex(C, Index, AttributeSet::get(C, Merged));
1386}
1387
1389 ArrayRef<unsigned> ArgNos,
1390 Attribute A) const {
1391 assert(llvm::is_sorted(ArgNos));
1392
1393 SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
1394 unsigned MaxIndex = attrIdxToArrayIdx(ArgNos.back() + FirstArgIndex);
1395 if (MaxIndex >= AttrSets.size())
1396 AttrSets.resize(MaxIndex + 1);
1397
1398 for (unsigned ArgNo : ArgNos) {
1399 unsigned Index = attrIdxToArrayIdx(ArgNo + FirstArgIndex);
1400 AttrBuilder B(C, AttrSets[Index]);
1401 B.addAttribute(A);
1402 AttrSets[Index] = AttributeSet::get(C, B);
1403 }
1404
1405 return getImpl(C, AttrSets);
1406}
1407
1410 Attribute::AttrKind Kind) const {
1412 AttributeSet NewAttrs = Attrs.removeAttribute(C, Kind);
1413 if (Attrs == NewAttrs)
1414 return *this;
1415 return setAttributesAtIndex(C, Index, NewAttrs);
1416}
1417
1419 unsigned Index,
1420 StringRef Kind) const {
1422 AttributeSet NewAttrs = Attrs.removeAttribute(C, Kind);
1423 if (Attrs == NewAttrs)
1424 return *this;
1425 return setAttributesAtIndex(C, Index, NewAttrs);
1426}
1427
1429 LLVMContext &C, unsigned Index, const AttributeMask &AttrsToRemove) const {
1431 AttributeSet NewAttrs = Attrs.removeAttributes(C, AttrsToRemove);
1432 // If nothing was removed, return the original list.
1433 if (Attrs == NewAttrs)
1434 return *this;
1435 return setAttributesAtIndex(C, Index, NewAttrs);
1436}
1437
1440 unsigned WithoutIndex) const {
1441 if (!pImpl)
1442 return {};
1443 if (attrIdxToArrayIdx(WithoutIndex) >= getNumAttrSets())
1444 return *this;
1445 return setAttributesAtIndex(C, WithoutIndex, AttributeSet());
1446}
1447
1449 uint64_t Bytes) const {
1450 AttrBuilder B(C);
1451 B.addDereferenceableAttr(Bytes);
1452 return addRetAttributes(C, B);
1453}
1454
1456 unsigned Index,
1457 uint64_t Bytes) const {
1458 AttrBuilder B(C);
1459 B.addDereferenceableAttr(Bytes);
1460 return addParamAttributes(C, Index, B);
1461}
1462
1465 uint64_t Bytes) const {
1466 AttrBuilder B(C);
1467 B.addDereferenceableOrNullAttr(Bytes);
1468 return addParamAttributes(C, Index, B);
1469}
1470
1472 LLVMContext &C, unsigned Index, unsigned ElemSizeArg,
1473 const std::optional<unsigned> &NumElemsArg) {
1474 AttrBuilder B(C);
1475 B.addAllocSizeAttr(ElemSizeArg, NumElemsArg);
1476 return addParamAttributes(C, Index, B);
1477}
1478
1479//===----------------------------------------------------------------------===//
1480// AttributeList Accessor Methods
1481//===----------------------------------------------------------------------===//
1482
1484 return getAttributes(ArgNo + FirstArgIndex);
1485}
1486
1488 return getAttributes(ReturnIndex);
1489}
1490
1493}
1494
1496 Attribute::AttrKind Kind) const {
1497 return getAttributes(Index).hasAttribute(Kind);
1498}
1499
1501 return getAttributes(Index).hasAttribute(Kind);
1502}
1503
1506}
1507
1509 return pImpl && pImpl->hasFnAttribute(Kind);
1510}
1511
1514}
1515
1517 unsigned *Index) const {
1518 return pImpl && pImpl->hasAttrSomewhere(Attr, Index);
1519}
1520
1522 Attribute::AttrKind Kind) const {
1523 return getAttributes(Index).getAttribute(Kind);
1524}
1525
1527 StringRef Kind) const {
1528 return getAttributes(Index).getAttribute(Kind);
1529}
1530
1533}
1534
1536 return getAttributes(ArgNo + FirstArgIndex).getAlignment();
1537}
1538
1541}
1542
1545}
1546
1549}
1550
1553}
1554
1557}
1558
1561}
1562
1565}
1566
1568 return getFnAttrs().getStackAlignment();
1569}
1570
1572 return getRetAttrs().getStackAlignment();
1573}
1574
1577}
1578
1581}
1582
1585}
1586
1590}
1591
1593 return getRetAttrs().getNoFPClass();
1594}
1595
1598}
1599
1601 return getFnAttrs().getUWTableKind();
1602}
1603
1605 return getFnAttrs().getAllocKind();
1606}
1607
1609 return getFnAttrs().getMemoryEffects();
1610}
1611
1612std::string AttributeList::getAsString(unsigned Index, bool InAttrGrp) const {
1613 return getAttributes(Index).getAsString(InAttrGrp);
1614}
1615
1618 if (!pImpl || Index >= getNumAttrSets())
1619 return {};
1620 return pImpl->begin()[Index];
1621}
1622
1624 assert(!isEmpty() && "an empty attribute list has no parent context");
1626 pImpl->Profile(ID);
1627 void *Unused;
1628 return C.pImpl->AttrsLists.FindNodeOrInsertPos(ID, Unused) == pImpl;
1629}
1630
1632 return pImpl ? pImpl->begin() : nullptr;
1633}
1634
1636 return pImpl ? pImpl->end() : nullptr;
1637}
1638
1639//===----------------------------------------------------------------------===//
1640// AttributeList Introspection Methods
1641//===----------------------------------------------------------------------===//
1642
1644 return pImpl ? pImpl->NumAttrSets : 0;
1645}
1646
1648 O << "AttributeList[\n";
1649
1650 for (unsigned i : indexes()) {
1651 if (!getAttributes(i).hasAttributes())
1652 continue;
1653 O << " { ";
1654 switch (i) {
1656 O << "return";
1657 break;
1659 O << "function";
1660 break;
1661 default:
1662 O << "arg(" << i - AttrIndex::FirstArgIndex << ")";
1663 }
1664 O << " => " << getAsString(i) << " }\n";
1665 }
1666
1667 O << "]\n";
1668}
1669
1670#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1672#endif
1673
1674//===----------------------------------------------------------------------===//
1675// AttrBuilder Method Implementations
1676//===----------------------------------------------------------------------===//
1677
1679 append_range(Attrs, AS);
1680 assert(is_sorted(Attrs) && "AttributeSet should be sorted");
1681}
1682
1683void AttrBuilder::clear() { Attrs.clear(); }
1684
1685/// Attribute comparator that only compares attribute keys. Enum attributes are
1686/// sorted before string attributes.
1688 bool operator()(Attribute A0, Attribute A1) const {
1689 bool A0IsString = A0.isStringAttribute();
1690 bool A1IsString = A1.isStringAttribute();
1691 if (A0IsString) {
1692 if (A1IsString)
1693 return A0.getKindAsString() < A1.getKindAsString();
1694 else
1695 return false;
1696 }
1697 if (A1IsString)
1698 return true;
1699 return A0.getKindAsEnum() < A1.getKindAsEnum();
1700 }
1702 if (A0.isStringAttribute())
1703 return false;
1704 return A0.getKindAsEnum() < Kind;
1705 }
1706 bool operator()(Attribute A0, StringRef Kind) const {
1707 if (A0.isStringAttribute())
1708 return A0.getKindAsString() < Kind;
1709 return true;
1710 }
1711};
1712
1713template <typename K>
1715 Attribute Attr) {
1716 auto It = lower_bound(Attrs, Kind, AttributeComparator());
1717 if (It != Attrs.end() && It->hasAttribute(Kind))
1718 std::swap(*It, Attr);
1719 else
1720 Attrs.insert(It, Attr);
1721}
1722
1724 if (Attr.isStringAttribute())
1725 addAttributeImpl(Attrs, Attr.getKindAsString(), Attr);
1726 else
1727 addAttributeImpl(Attrs, Attr.getKindAsEnum(), Attr);
1728 return *this;
1729}
1730
1732 addAttributeImpl(Attrs, Kind, Attribute::get(Ctx, Kind));
1733 return *this;
1734}
1735
1737 addAttributeImpl(Attrs, A, Attribute::get(Ctx, A, V));
1738 return *this;
1739}
1740
1742 assert((unsigned)Val < Attribute::EndAttrKinds && "Attribute out of range!");
1743 auto It = lower_bound(Attrs, Val, AttributeComparator());
1744 if (It != Attrs.end() && It->hasAttribute(Val))
1745 Attrs.erase(It);
1746 return *this;
1747}
1748
1750 auto It = lower_bound(Attrs, A, AttributeComparator());
1751 if (It != Attrs.end() && It->hasAttribute(A))
1752 Attrs.erase(It);
1753 return *this;
1754}
1755
1756std::optional<uint64_t>
1758 assert(Attribute::isIntAttrKind(Kind) && "Not an int attribute");
1759 Attribute A = getAttribute(Kind);
1760 if (A.isValid())
1761 return A.getValueAsInt();
1762 return std::nullopt;
1763}
1764
1766 uint64_t Value) {
1767 return addAttribute(Attribute::get(Ctx, Kind, Value));
1768}
1769
1770std::optional<std::pair<unsigned, std::optional<unsigned>>>
1772 Attribute A = getAttribute(Attribute::AllocSize);
1773 if (A.isValid())
1774 return A.getAllocSizeArgs();
1775 return std::nullopt;
1776}
1777
1779 if (!Align)
1780 return *this;
1781
1782 assert(*Align <= llvm::Value::MaximumAlignment && "Alignment too large.");
1783 return addRawIntAttr(Attribute::Alignment, Align->value());
1784}
1785
1787 // Default alignment, allow the target to define how to align it.
1788 if (!Align)
1789 return *this;
1790
1791 assert(*Align <= 0x100 && "Alignment too large.");
1792 return addRawIntAttr(Attribute::StackAlignment, Align->value());
1793}
1794
1796 if (Bytes == 0) return *this;
1797
1798 return addRawIntAttr(Attribute::Dereferenceable, Bytes);
1799}
1800
1802 if (Bytes == 0)
1803 return *this;
1804
1805 return addRawIntAttr(Attribute::DereferenceableOrNull, Bytes);
1806}
1807
1810 const std::optional<unsigned> &NumElems) {
1811 return addAllocSizeAttrFromRawRepr(packAllocSizeArgs(ElemSize, NumElems));
1812}
1813
1815 // (0, 0) is our "not present" value, so we need to check for it here.
1816 assert(RawArgs && "Invalid allocsize arguments -- given allocsize(0, 0)");
1817 return addRawIntAttr(Attribute::AllocSize, RawArgs);
1818}
1819
1821 std::optional<unsigned> MaxValue) {
1822 return addVScaleRangeAttrFromRawRepr(packVScaleRangeArgs(MinValue, MaxValue));
1823}
1824
1826 // (0, 0) is not present hence ignore this case
1827 if (RawArgs == 0)
1828 return *this;
1829
1830 return addRawIntAttr(Attribute::VScaleRange, RawArgs);
1831}
1832
1834 if (Kind == UWTableKind::None)
1835 return *this;
1836 return addRawIntAttr(Attribute::UWTable, uint64_t(Kind));
1837}
1838
1840 return addRawIntAttr(Attribute::Memory, ME.toIntValue());
1841}
1842
1844 if (Mask == fcNone)
1845 return *this;
1846
1847 return addRawIntAttr(Attribute::NoFPClass, Mask);
1848}
1849
1851 return addRawIntAttr(Attribute::AllocKind, static_cast<uint64_t>(Kind));
1852}
1853
1855 assert(Attribute::isTypeAttrKind(Kind) && "Not a type attribute");
1856 Attribute A = getAttribute(Kind);
1857 return A.isValid() ? A.getValueAsType() : nullptr;
1858}
1859
1861 return addAttribute(Attribute::get(Ctx, Kind, Ty));
1862}
1863
1865 return addTypeAttr(Attribute::ByVal, Ty);
1866}
1867
1869 return addTypeAttr(Attribute::StructRet, Ty);
1870}
1871
1873 return addTypeAttr(Attribute::ByRef, Ty);
1874}
1875
1877 return addTypeAttr(Attribute::Preallocated, Ty);
1878}
1879
1881 return addTypeAttr(Attribute::InAlloca, Ty);
1882}
1883
1885 // TODO: Could make this O(n) as we're merging two sorted lists.
1886 for (const auto &I : B.attrs())
1887 addAttribute(I);
1888
1889 return *this;
1890}
1891
1893 erase_if(Attrs, [&](Attribute A) { return AM.contains(A); });
1894 return *this;
1895}
1896
1898 return any_of(Attrs, [&](Attribute A) { return AM.contains(A); });
1899}
1900
1902 assert((unsigned)A < Attribute::EndAttrKinds && "Attribute out of range!");
1903 auto It = lower_bound(Attrs, A, AttributeComparator());
1904 if (It != Attrs.end() && It->hasAttribute(A))
1905 return *It;
1906 return {};
1907}
1908
1910 auto It = lower_bound(Attrs, A, AttributeComparator());
1911 if (It != Attrs.end() && It->hasAttribute(A))
1912 return *It;
1913 return {};
1914}
1915
1917 return getAttribute(A).isValid();
1918}
1919
1921 return getAttribute(A).isValid();
1922}
1923
1925 return Attrs == B.Attrs;
1926}
1927
1928//===----------------------------------------------------------------------===//
1929// AttributeFuncs Function Defintions
1930//===----------------------------------------------------------------------===//
1931
1932/// Returns true if this is a type legal for the 'nofpclass' attribute. This
1933/// follows the same type rules as FPMathOperator.
1934///
1935/// TODO: Consider relaxing to any FP type struct fields.
1937 while (ArrayType *ArrTy = dyn_cast<ArrayType>(Ty))
1938 Ty = ArrTy->getElementType();
1939 return Ty->isFPOrFPVectorTy();
1940}
1941
1942/// Which attributes cannot be applied to a type.
1944 AttributeSafetyKind ASK) {
1945 AttributeMask Incompatible;
1946
1947 if (!Ty->isIntegerTy()) {
1948 // Attributes that only apply to integers.
1949 if (ASK & ASK_SAFE_TO_DROP)
1950 Incompatible.addAttribute(Attribute::AllocAlign);
1951 if (ASK & ASK_UNSAFE_TO_DROP)
1952 Incompatible.addAttribute(Attribute::SExt).addAttribute(Attribute::ZExt);
1953 }
1954
1955 if (!Ty->isPointerTy()) {
1956 // Attributes that only apply to pointers.
1957 if (ASK & ASK_SAFE_TO_DROP)
1958 Incompatible.addAttribute(Attribute::NoAlias)
1959 .addAttribute(Attribute::NoCapture)
1960 .addAttribute(Attribute::NonNull)
1961 .addAttribute(Attribute::ReadNone)
1962 .addAttribute(Attribute::ReadOnly)
1963 .addAttribute(Attribute::Dereferenceable)
1964 .addAttribute(Attribute::DereferenceableOrNull)
1965 .addAttribute(Attribute::Writable)
1966 .addAttribute(Attribute::DeadOnUnwind);
1967 if (ASK & ASK_UNSAFE_TO_DROP)
1968 Incompatible.addAttribute(Attribute::Nest)
1969 .addAttribute(Attribute::SwiftError)
1970 .addAttribute(Attribute::Preallocated)
1971 .addAttribute(Attribute::InAlloca)
1972 .addAttribute(Attribute::ByVal)
1973 .addAttribute(Attribute::StructRet)
1974 .addAttribute(Attribute::ByRef)
1975 .addAttribute(Attribute::ElementType)
1976 .addAttribute(Attribute::AllocatedPointer);
1977 }
1978
1979 // Attributes that only apply to pointers or vectors of pointers.
1980 if (!Ty->isPtrOrPtrVectorTy()) {
1981 if (ASK & ASK_SAFE_TO_DROP)
1982 Incompatible.addAttribute(Attribute::Alignment);
1983 }
1984
1985 if (ASK & ASK_SAFE_TO_DROP) {
1987 Incompatible.addAttribute(Attribute::NoFPClass);
1988 }
1989
1990 // Some attributes can apply to all "values" but there are no `void` values.
1991 if (Ty->isVoidTy()) {
1992 if (ASK & ASK_SAFE_TO_DROP)
1993 Incompatible.addAttribute(Attribute::NoUndef);
1994 }
1995
1996 return Incompatible;
1997}
1998
2000 AttributeMask AM;
2001 AM.addAttribute(Attribute::NoUndef);
2002 AM.addAttribute(Attribute::Dereferenceable);
2003 AM.addAttribute(Attribute::DereferenceableOrNull);
2004 return AM;
2005}
2006
2007/// Callees with dynamic denormal modes are compatible with any caller mode.
2008static bool denormModeCompatible(DenormalMode CallerMode,
2009 DenormalMode CalleeMode) {
2010 if (CallerMode == CalleeMode || CalleeMode == DenormalMode::getDynamic())
2011 return true;
2012
2013 // If they don't exactly match, it's OK if the mismatched component is
2014 // dynamic.
2015 if (CalleeMode.Input == CallerMode.Input &&
2016 CalleeMode.Output == DenormalMode::Dynamic)
2017 return true;
2018
2019 if (CalleeMode.Output == CallerMode.Output &&
2020 CalleeMode.Input == DenormalMode::Dynamic)
2021 return true;
2022 return false;
2023}
2024
2025static bool checkDenormMode(const Function &Caller, const Function &Callee) {
2026 DenormalMode CallerMode = Caller.getDenormalModeRaw();
2027 DenormalMode CalleeMode = Callee.getDenormalModeRaw();
2028
2029 if (denormModeCompatible(CallerMode, CalleeMode)) {
2030 DenormalMode CallerModeF32 = Caller.getDenormalModeF32Raw();
2031 DenormalMode CalleeModeF32 = Callee.getDenormalModeF32Raw();
2032 if (CallerModeF32 == DenormalMode::getInvalid())
2033 CallerModeF32 = CallerMode;
2034 if (CalleeModeF32 == DenormalMode::getInvalid())
2035 CalleeModeF32 = CalleeMode;
2036 return denormModeCompatible(CallerModeF32, CalleeModeF32);
2037 }
2038
2039 return false;
2040}
2041
2042static bool checkStrictFP(const Function &Caller, const Function &Callee) {
2043 // Do not inline strictfp function into non-strictfp one. It would require
2044 // conversion of all FP operations in host function to constrained intrinsics.
2045 return !Callee.getAttributes().hasFnAttr(Attribute::StrictFP) ||
2046 Caller.getAttributes().hasFnAttr(Attribute::StrictFP);
2047}
2048
2049template<typename AttrClass>
2050static bool isEqual(const Function &Caller, const Function &Callee) {
2051 return Caller.getFnAttribute(AttrClass::getKind()) ==
2052 Callee.getFnAttribute(AttrClass::getKind());
2053}
2054
2055static bool isEqual(const Function &Caller, const Function &Callee,
2056 const StringRef &AttrName) {
2057 return Caller.getFnAttribute(AttrName) == Callee.getFnAttribute(AttrName);
2058}
2059
2060/// Compute the logical AND of the attributes of the caller and the
2061/// callee.
2062///
2063/// This function sets the caller's attribute to false if the callee's attribute
2064/// is false.
2065template<typename AttrClass>
2066static void setAND(Function &Caller, const Function &Callee) {
2067 if (AttrClass::isSet(Caller, AttrClass::getKind()) &&
2068 !AttrClass::isSet(Callee, AttrClass::getKind()))
2069 AttrClass::set(Caller, AttrClass::getKind(), false);
2070}
2071
2072/// Compute the logical OR of the attributes of the caller and the
2073/// callee.
2074///
2075/// This function sets the caller's attribute to true if the callee's attribute
2076/// is true.
2077template<typename AttrClass>
2078static void setOR(Function &Caller, const Function &Callee) {
2079 if (!AttrClass::isSet(Caller, AttrClass::getKind()) &&
2080 AttrClass::isSet(Callee, AttrClass::getKind()))
2081 AttrClass::set(Caller, AttrClass::getKind(), true);
2082}
2083
2084/// If the inlined function had a higher stack protection level than the
2085/// calling function, then bump up the caller's stack protection level.
2086static void adjustCallerSSPLevel(Function &Caller, const Function &Callee) {
2087 // If the calling function has *no* stack protection level (e.g. it was built
2088 // with Clang's -fno-stack-protector or no_stack_protector attribute), don't
2089 // change it as that could change the program's semantics.
2090 if (!Caller.hasStackProtectorFnAttr())
2091 return;
2092
2093 // If upgrading the SSP attribute, clear out the old SSP Attributes first.
2094 // Having multiple SSP attributes doesn't actually hurt, but it adds useless
2095 // clutter to the IR.
2096 AttributeMask OldSSPAttr;
2097 OldSSPAttr.addAttribute(Attribute::StackProtect)
2098 .addAttribute(Attribute::StackProtectStrong)
2099 .addAttribute(Attribute::StackProtectReq);
2100
2101 if (Callee.hasFnAttribute(Attribute::StackProtectReq)) {
2102 Caller.removeFnAttrs(OldSSPAttr);
2103 Caller.addFnAttr(Attribute::StackProtectReq);
2104 } else if (Callee.hasFnAttribute(Attribute::StackProtectStrong) &&
2105 !Caller.hasFnAttribute(Attribute::StackProtectReq)) {
2106 Caller.removeFnAttrs(OldSSPAttr);
2107 Caller.addFnAttr(Attribute::StackProtectStrong);
2108 } else if (Callee.hasFnAttribute(Attribute::StackProtect) &&
2109 !Caller.hasFnAttribute(Attribute::StackProtectReq) &&
2110 !Caller.hasFnAttribute(Attribute::StackProtectStrong))
2111 Caller.addFnAttr(Attribute::StackProtect);
2112}
2113
2114/// If the inlined function required stack probes, then ensure that
2115/// the calling function has those too.
2116static void adjustCallerStackProbes(Function &Caller, const Function &Callee) {
2117 if (!Caller.hasFnAttribute("probe-stack") &&
2118 Callee.hasFnAttribute("probe-stack")) {
2119 Caller.addFnAttr(Callee.getFnAttribute("probe-stack"));
2120 }
2121}
2122
2123/// If the inlined function defines the size of guard region
2124/// on the stack, then ensure that the calling function defines a guard region
2125/// that is no larger.
2126static void
2128 Attribute CalleeAttr = Callee.getFnAttribute("stack-probe-size");
2129 if (CalleeAttr.isValid()) {
2130 Attribute CallerAttr = Caller.getFnAttribute("stack-probe-size");
2131 if (CallerAttr.isValid()) {
2132 uint64_t CallerStackProbeSize, CalleeStackProbeSize;
2133 CallerAttr.getValueAsString().getAsInteger(0, CallerStackProbeSize);
2134 CalleeAttr.getValueAsString().getAsInteger(0, CalleeStackProbeSize);
2135
2136 if (CallerStackProbeSize > CalleeStackProbeSize) {
2137 Caller.addFnAttr(CalleeAttr);
2138 }
2139 } else {
2140 Caller.addFnAttr(CalleeAttr);
2141 }
2142 }
2143}
2144
2145/// If the inlined function defines a min legal vector width, then ensure
2146/// the calling function has the same or larger min legal vector width. If the
2147/// caller has the attribute, but the callee doesn't, we need to remove the
2148/// attribute from the caller since we can't make any guarantees about the
2149/// caller's requirements.
2150/// This function is called after the inlining decision has been made so we have
2151/// to merge the attribute this way. Heuristics that would use
2152/// min-legal-vector-width to determine inline compatibility would need to be
2153/// handled as part of inline cost analysis.
2154static void
2156 Attribute CallerAttr = Caller.getFnAttribute("min-legal-vector-width");
2157 if (CallerAttr.isValid()) {
2158 Attribute CalleeAttr = Callee.getFnAttribute("min-legal-vector-width");
2159 if (CalleeAttr.isValid()) {
2160 uint64_t CallerVectorWidth, CalleeVectorWidth;
2161 CallerAttr.getValueAsString().getAsInteger(0, CallerVectorWidth);
2162 CalleeAttr.getValueAsString().getAsInteger(0, CalleeVectorWidth);
2163 if (CallerVectorWidth < CalleeVectorWidth)
2164 Caller.addFnAttr(CalleeAttr);
2165 } else {
2166 // If the callee doesn't have the attribute then we don't know anything
2167 // and must drop the attribute from the caller.
2168 Caller.removeFnAttr("min-legal-vector-width");
2169 }
2170 }
2171}
2172
2173/// If the inlined function has null_pointer_is_valid attribute,
2174/// set this attribute in the caller post inlining.
2175static void
2177 if (Callee.nullPointerIsDefined() && !Caller.nullPointerIsDefined()) {
2178 Caller.addFnAttr(Attribute::NullPointerIsValid);
2179 }
2180}
2181
2182struct EnumAttr {
2183 static bool isSet(const Function &Fn,
2184 Attribute::AttrKind Kind) {
2185 return Fn.hasFnAttribute(Kind);
2186 }
2187
2188 static void set(Function &Fn,
2189 Attribute::AttrKind Kind, bool Val) {
2190 if (Val)
2191 Fn.addFnAttr(Kind);
2192 else
2193 Fn.removeFnAttr(Kind);
2194 }
2195};
2196
2198 static bool isSet(const Function &Fn,
2199 StringRef Kind) {
2200 auto A = Fn.getFnAttribute(Kind);
2201 return A.getValueAsString().equals("true");
2202 }
2203
2204 static void set(Function &Fn,
2205 StringRef Kind, bool Val) {
2206 Fn.addFnAttr(Kind, Val ? "true" : "false");
2207 }
2208};
2209
2210#define GET_ATTR_NAMES
2211#define ATTRIBUTE_ENUM(ENUM_NAME, DISPLAY_NAME) \
2212 struct ENUM_NAME##Attr : EnumAttr { \
2213 static enum Attribute::AttrKind getKind() { \
2214 return llvm::Attribute::ENUM_NAME; \
2215 } \
2216 };
2217#define ATTRIBUTE_STRBOOL(ENUM_NAME, DISPLAY_NAME) \
2218 struct ENUM_NAME##Attr : StrBoolAttr { \
2219 static StringRef getKind() { return #DISPLAY_NAME; } \
2220 };
2221#include "llvm/IR/Attributes.inc"
2222
2223#define GET_ATTR_COMPAT_FUNC
2224#include "llvm/IR/Attributes.inc"
2225
2227 const Function &Callee) {
2228 return hasCompatibleFnAttrs(Caller, Callee);
2229}
2230
2232 const Function &B) {
2233 return hasCompatibleFnAttrs(A, B);
2234}
2235
2237 const Function &Callee) {
2238 mergeFnAttrs(Caller, Callee);
2239}
2240
2242 const Function &ToMerge) {
2243
2244 // We merge functions so that they meet the most general case.
2245 // For example, if the NoNansFPMathAttr is set in one function, but not in
2246 // the other, in the merged function we can say that the NoNansFPMathAttr
2247 // is not set.
2248 // However if we have the SpeculativeLoadHardeningAttr set true in one
2249 // function, but not the other, we make sure that the function retains
2250 // that aspect in the merged function.
2251 mergeFnAttrs(Base, ToMerge);
2252}
2253
2255 uint64_t Width) {
2256 Attribute Attr = Fn.getFnAttribute("min-legal-vector-width");
2257 if (Attr.isValid()) {
2258 uint64_t OldWidth;
2259 Attr.getValueAsString().getAsInteger(0, OldWidth);
2260 if (Width > OldWidth)
2261 Fn.addFnAttr("min-legal-vector-width", llvm::utostr(Width));
2262 }
2263}
This file defines various helper methods and classes used by LLVMContextImpl for creating and managin...
static void addAttributeImpl(SmallVectorImpl< Attribute > &Attrs, K Kind, Attribute Attr)
static void setAND(Function &Caller, const Function &Callee)
Compute the logical AND of the attributes of the caller and the callee.
static void adjustCallerStackProbes(Function &Caller, const Function &Callee)
If the inlined function required stack probes, then ensure that the calling function has those too.
static std::pair< unsigned, std::optional< unsigned > > unpackVScaleRangeArgs(uint64_t Value)
Definition: Attributes.cpp:84
static void adjustMinLegalVectorWidth(Function &Caller, const Function &Callee)
If the inlined function defines a min legal vector width, then ensure the calling function has the sa...
AttributeProperty
Definition: Attributes.cpp:611
@ RetAttr
Definition: Attributes.cpp:614
@ ParamAttr
Definition: Attributes.cpp:613
@ FnAttr
Definition: Attributes.cpp:612
static void adjustCallerStackProbeSize(Function &Caller, const Function &Callee)
If the inlined function defines the size of guard region on the stack, then ensure that the calling f...
static void adjustCallerSSPLevel(Function &Caller, const Function &Callee)
If the inlined function had a higher stack protection level than the calling function,...
static bool checkStrictFP(const Function &Caller, const Function &Callee)
static uint64_t packAllocSizeArgs(unsigned ElemSizeArg, const std::optional< unsigned > &NumElemsArg)
Definition: Attributes.cpp:58
static uint64_t packVScaleRangeArgs(unsigned MinValue, std::optional< unsigned > MaxValue)
Definition: Attributes.cpp:78
static unsigned attrIdxToArrayIdx(unsigned Index)
Map from AttributeList index to the internal array index.
static bool denormModeCompatible(DenormalMode CallerMode, DenormalMode CalleeMode)
Callees with dynamic denormal modes are compatible with any caller mode.
static void adjustNullPointerValidAttr(Function &Caller, const Function &Callee)
If the inlined function has null_pointer_is_valid attribute, set this attribute in the caller post in...
static const unsigned AllocSizeNumElemsNotPresent
Definition: Attributes.cpp:56
static std::pair< unsigned, std::optional< unsigned > > unpackAllocSizeArgs(uint64_t Num)
Definition: Attributes.cpp:68
static bool checkDenormMode(const Function &Caller, const Function &Callee)
static void setOR(Function &Caller, const Function &Callee)
Compute the logical OR of the attributes of the caller and the callee.
static bool hasAttributeProperty(Attribute::AttrKind Kind, AttributeProperty Prop)
Definition: Attributes.cpp:620
static const char * getModRefStr(ModRefInfo MR)
Definition: Attributes.cpp:411
This file contains the simple types necessary to represent the attributes associated with functions a...
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Definition: Compiler.h:529
std::string Name
This file defines a hash set that can be used to remove duplication of nodes in a graph.
#define I(x, y, z)
Definition: MD5.cpp:58
Load MIR Sample Profile
LLVMContext & Context
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file contains some templates that are useful if you are working with the STL at all.
raw_pwrite_stream & OS
This file defines the SmallVector class.
This file contains some functions that are useful when dealing with strings.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
const T & back() const
back - Get the last element.
Definition: ArrayRef.h:174
ArrayRef< T > take_front(size_t N=1) const
Return a copy of *this with only the first N elements.
Definition: ArrayRef.h:228
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:165
iterator begin() const
Definition: ArrayRef.h:153
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:160
Class to represent array types.
Definition: DerivedTypes.h:371
AttrBuilder & addStructRetAttr(Type *Ty)
This turns a sret type into the form used internally in Attribute.
AttrBuilder & addAlignmentAttr(MaybeAlign Align)
This turns an alignment into the form used internally in Attribute.
AttrBuilder & addVScaleRangeAttrFromRawRepr(uint64_t RawVScaleRangeRepr)
Add a vscale_range attribute, using the representation returned by Attribute.getIntValue().
std::optional< uint64_t > getRawIntAttr(Attribute::AttrKind Kind) const
Return raw (possibly packed/encoded) value of integer attribute or std::nullopt if not set.
AttrBuilder & addAllocKindAttr(AllocFnKind Kind)
Attribute getAttribute(Attribute::AttrKind Kind) const
Return Attribute with the given Kind.
AttrBuilder & addByRefAttr(Type *Ty)
This turns a byref type into the form used internally in Attribute.
AttrBuilder & addNoFPClassAttr(FPClassTest NoFPClassMask)
bool overlaps(const AttributeMask &AM) const
Return true if the builder has any attribute that's in the specified builder.
AttrBuilder & merge(const AttrBuilder &B)
Add the attributes from the builder.
AttrBuilder & addVScaleRangeAttr(unsigned MinValue, std::optional< unsigned > MaxValue)
This turns two ints into the form used internally in Attribute.
AttrBuilder(LLVMContext &Ctx)
Definition: Attributes.h:995
AttrBuilder & addRawIntAttr(Attribute::AttrKind Kind, uint64_t Value)
Add integer attribute with raw value (packed/encoded if necessary).
AttrBuilder & addAttribute(Attribute::AttrKind Val)
Add an attribute to the builder.
AttrBuilder & addByValAttr(Type *Ty)
This turns a byval type into the form used internally in Attribute.
AttrBuilder & addDereferenceableAttr(uint64_t Bytes)
This turns the number of dereferenceable bytes into the form used internally in Attribute.
bool contains(Attribute::AttrKind A) const
Return true if the builder has the specified attribute.
AttrBuilder & addMemoryAttr(MemoryEffects ME)
Add memory effect attribute.
AttrBuilder & addAllocSizeAttrFromRawRepr(uint64_t RawAllocSizeRepr)
Add an allocsize attribute, using the representation returned by Attribute.getIntValue().
AttrBuilder & addPreallocatedAttr(Type *Ty)
This turns a preallocated type into the form used internally in Attribute.
AttrBuilder & addStackAlignmentAttr(MaybeAlign Align)
This turns a stack alignment into the form used internally in Attribute.
AttrBuilder & addInAllocaAttr(Type *Ty)
This turns an inalloca type into the form used internally in Attribute.
AttrBuilder & removeAttribute(Attribute::AttrKind Val)
Remove an attribute from the builder.
bool operator==(const AttrBuilder &B) const
Type * getTypeAttr(Attribute::AttrKind Kind) const
Retrieve type for the given type attribute.
AttrBuilder & remove(const AttributeMask &AM)
Remove the attributes from the builder.
AttrBuilder & addDereferenceableOrNullAttr(uint64_t Bytes)
This turns the number of dereferenceable_or_null bytes into the form used internally in Attribute.
AttrBuilder & addTypeAttr(Attribute::AttrKind Kind, Type *Ty)
Add a type attribute with the given type.
std::optional< std::pair< unsigned, std::optional< unsigned > > > getAllocSizeArgs() const
Retrieve the allocsize args, or std::nullopt if the attribute does not exist.
AttrBuilder & addAllocSizeAttr(unsigned ElemSizeArg, const std::optional< unsigned > &NumElemsArg)
This turns one (or two) ints into the form used internally in Attribute.
AttrBuilder & addUWTableAttr(UWTableKind Kind)
This turns the unwind table kind into the form used internally in Attribute.
void addAttribute(Attribute::AttrKind Kind)
bool hasAttribute(Attribute::AttrKind Kind) const
bool hasAttribute(Attribute::AttrKind A) const
Definition: Attributes.cpp:643
void Profile(FoldingSetNodeID &ID) const
Definition: AttributeImpl.h:78
Type * getValueAsType() const
Definition: Attributes.cpp:678
Attribute::AttrKind getKindAsEnum() const
Definition: Attributes.cpp:653
bool operator<(const AttributeImpl &AI) const
Used when sorting the attributes.
Definition: Attributes.cpp:683
uint64_t getValueAsInt() const
Definition: Attributes.cpp:658
bool isIntAttribute() const
Definition: AttributeImpl.h:59
bool isTypeAttribute() const
Definition: AttributeImpl.h:61
bool getValueAsBool() const
Definition: Attributes.cpp:663
StringRef getKindAsString() const
Definition: Attributes.cpp:668
StringRef getValueAsString() const
Definition: Attributes.cpp:673
bool isEnumAttribute() const
Definition: AttributeImpl.h:58
bool isStringAttribute() const
Definition: AttributeImpl.h:60
bool hasAttrSomewhere(Attribute::AttrKind Kind, unsigned *Index=nullptr) const
Return true if the specified attribute is set for at least one parameter or for the return value.
iterator begin() const
void Profile(FoldingSetNodeID &ID) const
AttributeListImpl(ArrayRef< AttributeSet > Sets)
iterator end() const
friend class AttributeList
bool hasAttributeAtIndex(unsigned Index, Attribute::AttrKind Kind) const
Return true if the attribute exists at the given index.
Type * getParamStructRetType(unsigned ArgNo) const
Return the sret type for the specified function parameter.
AttributeList addDereferenceableParamAttr(LLVMContext &C, unsigned ArgNo, uint64_t Bytes) const
Add the dereferenceable attribute to the attribute set at the given arg index.
AttributeList removeAttributeAtIndex(LLVMContext &C, unsigned Index, Attribute::AttrKind Kind) const
Remove the specified attribute at the specified index from this attribute list.
bool hasAttributesAtIndex(unsigned Index) const
Return true if attribute exists at the given index.
friend class AttributeListImpl
Definition: Attributes.h:445
AttributeSet getFnAttrs() const
The function attributes are returned.
index_iterator indexes() const
Use this to iterate over the valid attribute indexes.
Definition: Attributes.h:939
AttributeList removeAttributesAtIndex(LLVMContext &C, unsigned Index, const AttributeMask &AttrsToRemove) const
Remove the specified attributes at the specified index from this attribute list.
friend class AttributeSet
Definition: Attributes.h:446
AttributeList()=default
AttributeList addAllocSizeParamAttr(LLVMContext &C, unsigned ArgNo, unsigned ElemSizeArg, const std::optional< unsigned > &NumElemsArg)
Add the allocsize attribute to the attribute set at the given arg index.
iterator begin() const
MaybeAlign getRetStackAlignment() const
Get the stack alignment of the return value.
AttributeList addRetAttributes(LLVMContext &C, const AttrBuilder &B) const
Add a return value attribute to the list.
Definition: Attributes.h:565
void print(raw_ostream &O) const
AttributeList addDereferenceableRetAttr(LLVMContext &C, uint64_t Bytes) const
Add the dereferenceable attribute to the attribute set at the given index.
static AttributeList get(LLVMContext &C, ArrayRef< std::pair< unsigned, Attribute > > Attrs)
Create an AttributeList with the specified parameters in it.
AllocFnKind getAllocKind() const
bool isEmpty() const
Return true if there are no attributes.
Definition: Attributes.h:951
AttributeSet getRetAttrs() const
The attributes for the ret value are returned.
friend class AttrBuilder
Definition: Attributes.h:444
bool hasFnAttr(Attribute::AttrKind Kind) const
Return true if the attribute exists for the function.
uint64_t getParamDereferenceableBytes(unsigned Index) const
Get the number of dereferenceable bytes (or zero if unknown) of an arg.
MaybeAlign getParamAlignment(unsigned ArgNo) const
Return the alignment for the specified function parameter.
bool hasAttrSomewhere(Attribute::AttrKind Kind, unsigned *Index=nullptr) const
Return true if the specified attribute is set for at least one parameter or for the return value.
iterator end() const
Type * getParamInAllocaType(unsigned ArgNo) const
Return the inalloca type for the specified function parameter.
unsigned getNumAttrSets() const
FPClassTest getRetNoFPClass() const
Get the disallowed floating-point classes of the return value.
std::string getAsString(unsigned Index, bool InAttrGrp=false) const
Return the attributes at the index as a string.
UWTableKind getUWTableKind() const
Get the unwind table kind requested for the function.
MaybeAlign getRetAlignment() const
Return the alignment of the return value.
Type * getParamElementType(unsigned ArgNo) const
Return the elementtype type for the specified function parameter.
Attribute getAttributeAtIndex(unsigned Index, Attribute::AttrKind Kind) const
Return the attribute object that exists at the given index.
Type * getParamPreallocatedType(unsigned ArgNo) const
Return the preallocated type for the specified function parameter.
bool hasParentContext(LLVMContext &C) const
Return true if this attribute list belongs to the LLVMContext.
const AttributeSet * iterator
Definition: Attributes.h:907
MaybeAlign getFnStackAlignment() const
Get the stack alignment of the function.
AttributeList addAttributesAtIndex(LLVMContext &C, unsigned Index, const AttrBuilder &B) const
Add attributes to the attribute set at the given index.
Type * getParamByValType(unsigned ArgNo) const
Return the byval type for the specified function parameter.
MaybeAlign getParamStackAlignment(unsigned ArgNo) const
Return the stack alignment for the specified function parameter.
uint64_t getRetDereferenceableBytes() const
Get the number of dereferenceable bytes (or zero if unknown) of the return value.
uint64_t getParamDereferenceableOrNullBytes(unsigned ArgNo) const
Get the number of dereferenceable_or_null bytes (or zero if unknown) of an arg.
AttributeList addDereferenceableOrNullParamAttr(LLVMContext &C, unsigned ArgNo, uint64_t Bytes) const
Add the dereferenceable_or_null attribute to the attribute set at the given arg index.
AttributeSet getAttributes(unsigned Index) const
The attributes for the specified index are returned.
FPClassTest getParamNoFPClass(unsigned ArgNo) const
Get the disallowed floating-point classes of the argument value.
Type * getParamByRefType(unsigned ArgNo) const
Return the byref type for the specified function parameter.
AttributeList addAttributeAtIndex(LLVMContext &C, unsigned Index, Attribute::AttrKind Kind) const
Add an attribute to the attribute set at the given index.
AttributeSet getParamAttrs(unsigned ArgNo) const
The attributes for the argument or parameter at the given index are returned.
AttributeList addParamAttributes(LLVMContext &C, unsigned ArgNo, const AttrBuilder &B) const
Add an argument attribute to the list.
Definition: Attributes.h:594
uint64_t getRetDereferenceableOrNullBytes() const
Get the number of dereferenceable_or_null bytes (or zero if unknown) of the return value.
AttributeList addParamAttribute(LLVMContext &C, unsigned ArgNo, Attribute::AttrKind Kind) const
Add an argument attribute to the list.
Definition: Attributes.h:573
MemoryEffects getMemoryEffects() const
Returns memory effects of the function.
AttributeMask & addAttribute(Attribute::AttrKind Val)
Add an attribute to the mask.
Definition: AttributeMask.h:44
bool contains(Attribute::AttrKind A) const
Return true if the builder has the specified attribute.
Definition: AttributeMask.h:67
MaybeAlign getStackAlignment() const
Definition: Attributes.cpp:989
uint64_t getDereferenceableOrNullBytes() const
std::optional< unsigned > getVScaleRangeMax() const
bool hasAttribute(Attribute::AttrKind Kind) const
Type * getAttributeType(Attribute::AttrKind Kind) const
Definition: Attributes.cpp:995
AllocFnKind getAllocKind() const
unsigned getVScaleRangeMin() const
MaybeAlign getAlignment() const
Definition: Attributes.cpp:983
MemoryEffects getMemoryEffects() const
iterator begin() const
UWTableKind getUWTableKind() const
std::optional< std::pair< unsigned, std::optional< unsigned > > > getAllocSizeArgs() const
iterator end() const
uint64_t getDereferenceableBytes() const
unsigned getNumAttributes() const
Return the number of attributes this AttributeList contains.
void Profile(FoldingSetNodeID &ID) const
std::string getAsString(bool InAttrGrp) const
static AttributeSetNode * get(LLVMContext &C, const AttrBuilder &B)
Definition: Attributes.cpp:948
FPClassTest getNoFPClass() const
Attribute getAttribute(Attribute::AttrKind Kind) const
Definition: Attributes.cpp:973
AllocFnKind getAllocKind() const
Definition: Attributes.cpp:854
bool hasAttributes() const
Return true if attributes exists in this set.
Definition: Attributes.h:357
AttributeSet removeAttribute(LLVMContext &C, Attribute::AttrKind Kind) const
Remove the specified attribute from this set.
Definition: Attributes.cpp:748
Type * getInAllocaType() const
Definition: Attributes.cpp:827
Type * getByValType() const
Definition: Attributes.cpp:815
AttributeSet addAttributes(LLVMContext &C, AttributeSet AS) const
Add attributes to the attribute set.
Definition: Attributes.cpp:735
MemoryEffects getMemoryEffects() const
Definition: Attributes.cpp:858
bool hasAttribute(Attribute::AttrKind Kind) const
Return true if the attribute exists in this set.
Definition: Attributes.cpp:779
Type * getStructRetType() const
Definition: Attributes.cpp:819
std::string getAsString(bool InAttrGrp=false) const
Definition: Attributes.cpp:866
unsigned getVScaleRangeMin() const
Definition: Attributes.cpp:842
std::optional< std::pair< unsigned, std::optional< unsigned > > > getAllocSizeArgs() const
Definition: Attributes.cpp:836
UWTableKind getUWTableKind() const
Definition: Attributes.cpp:850
bool hasParentContext(LLVMContext &C) const
Return true if this attribute set belongs to the LLVMContext.
Definition: Attributes.cpp:870
iterator begin() const
Definition: Attributes.cpp:878
iterator end() const
Definition: Attributes.cpp:882
AttributeSet removeAttributes(LLVMContext &C, const AttributeMask &AttrsToRemove) const
Remove the specified attributes from this set.
Definition: Attributes.cpp:764
std::optional< unsigned > getVScaleRangeMax() const
Definition: Attributes.cpp:846
MaybeAlign getStackAlignment() const
Definition: Attributes.cpp:799
Attribute getAttribute(Attribute::AttrKind Kind) const
Return the attribute object.
Definition: Attributes.cpp:787
Type * getPreallocatedType() const
Definition: Attributes.cpp:823
uint64_t getDereferenceableBytes() const
Definition: Attributes.cpp:803
MaybeAlign getAlignment() const
Definition: Attributes.cpp:795
FPClassTest getNoFPClass() const
Definition: Attributes.cpp:862
Type * getElementType() const
Definition: Attributes.cpp:831
Type * getByRefType() const
Definition: Attributes.cpp:811
AttributeSet()=default
AttributeSet is a trivially copyable value type.
static AttributeSet get(LLVMContext &C, const AttrBuilder &B)
Definition: Attributes.cpp:712
uint64_t getDereferenceableOrNullBytes() const
Definition: Attributes.cpp:807
unsigned getNumAttributes() const
Return the number of attributes in this set.
Definition: Attributes.cpp:775
AttributeSet addAttribute(LLVMContext &C, Attribute::AttrKind Kind) const
Add an argument attribute.
Definition: Attributes.cpp:720
void dump() const
Definition: Attributes.cpp:887
bool isStringAttribute() const
Return true if the attribute is a string (target-dependent) attribute.
Definition: Attributes.cpp:282
static Attribute getWithStructRetType(LLVMContext &Context, Type *Ty)
Definition: Attributes.cpp:194
static Attribute::AttrKind getAttrKindFromName(StringRef AttrName)
Definition: Attributes.cpp:239
bool isEnumAttribute() const
Return true if the attribute is an Attribute::AttrKind type.
Definition: Attributes.cpp:274
static Attribute getWithStackAlignment(LLVMContext &Context, Align Alignment)
Definition: Attributes.cpp:173
bool isIntAttribute() const
Return true if the attribute is an integer attribute.
Definition: Attributes.cpp:278
static Attribute getWithByRefType(LLVMContext &Context, Type *Ty)
Definition: Attributes.cpp:198
std::optional< unsigned > getVScaleRangeMax() const
Returns the maximum value for the vscale_range attribute or std::nullopt when unknown.
Definition: Attributes.cpp:381
uint64_t getValueAsInt() const
Return the attribute's value as an integer.
Definition: Attributes.cpp:297
unsigned getVScaleRangeMin() const
Returns the minimum value for the vscale_range attribute.
Definition: Attributes.cpp:375
AllocFnKind getAllocKind() const
Definition: Attributes.cpp:393
StringRef getKindAsString() const
Return the attribute's kind as a string.
Definition: Attributes.cpp:311
static Attribute getWithPreallocatedType(LLVMContext &Context, Type *Ty)
Definition: Attributes.cpp:202
static Attribute get(LLVMContext &Context, AttrKind Kind, uint64_t Val=0)
Return a uniquified Attribute object.
Definition: Attributes.cpp:92
static bool canUseAsRetAttr(AttrKind Kind)
Definition: Attributes.cpp:635
static bool isTypeAttrKind(AttrKind Kind)
Definition: Attributes.h:103
std::string getAsString(bool InAttrGrp=false) const
The Attribute is converted to a string of equivalent mnemonic.
Definition: Attributes.cpp:425
uint64_t getDereferenceableOrNullBytes() const
Returns the number of dereferenceable_or_null bytes from the dereferenceable_or_null attribute.
Definition: Attributes.cpp:361
static Attribute getWithDereferenceableBytes(LLVMContext &Context, uint64_t Bytes)
Definition: Attributes.cpp:178
std::pair< unsigned, std::optional< unsigned > > getAllocSizeArgs() const
Returns the argument numbers for the allocsize attribute.
Definition: Attributes.cpp:369
static Attribute getWithUWTableKind(LLVMContext &Context, UWTableKind Kind)
Definition: Attributes.cpp:210
FPClassTest getNoFPClass() const
Return the FPClassTest for nofpclass.
Definition: Attributes.cpp:405
static Attribute getWithAllocSizeArgs(LLVMContext &Context, unsigned ElemSizeArg, const std::optional< unsigned > &NumElemsArg)
Definition: Attributes.cpp:226
Attribute::AttrKind getKindAsEnum() const
Return the attribute's kind as an enum (Attribute::AttrKind).
Definition: Attributes.cpp:290
Attribute()=default
bool getValueAsBool() const
Return the attribute's value as a boolean.
Definition: Attributes.cpp:304
uint64_t getDereferenceableBytes() const
Returns the number of dereferenceable bytes from the dereferenceable attribute.
Definition: Attributes.cpp:354
static Attribute getWithVScaleRangeArgs(LLVMContext &Context, unsigned MinValue, unsigned MaxValue)
Definition: Attributes.cpp:233
MemoryEffects getMemoryEffects() const
Returns memory effects.
Definition: Attributes.cpp:399
void Profile(FoldingSetNodeID &ID) const
Definition: Attributes.cpp:607
UWTableKind getUWTableKind() const
Definition: Attributes.cpp:387
static Attribute getWithDereferenceableOrNullBytes(LLVMContext &Context, uint64_t Bytes)
Definition: Attributes.cpp:184
StringRef getValueAsString() const
Return the attribute's value as a string.
Definition: Attributes.cpp:318
static bool isExistingAttribute(StringRef Name)
Return true if the provided string matches the IR name of an attribute.
Definition: Attributes.cpp:262
static StringRef getNameFromAttrKind(Attribute::AttrKind AttrKind)
Definition: Attributes.cpp:248
static bool canUseAsFnAttr(AttrKind Kind)
Definition: Attributes.cpp:627
static Attribute getWithNoFPClass(LLVMContext &Context, FPClassTest Mask)
Definition: Attributes.cpp:220
AttrKind
This enumeration lists the attributes that can be associated with parameters, function results,...
Definition: Attributes.h:84
@ None
No attributes have been set.
Definition: Attributes.h:86
@ EndAttrKinds
Sentinel value useful for loops.
Definition: Attributes.h:89
bool hasParentContext(LLVMContext &C) const
Return true if this attribute belongs to the LLVMContext.
Definition: Attributes.cpp:592
bool isTypeAttribute() const
Return true if the attribute is a type attribute.
Definition: Attributes.cpp:286
static Attribute getWithInAllocaType(LLVMContext &Context, Type *Ty)
Definition: Attributes.cpp:206
static bool isIntAttrKind(AttrKind Kind)
Definition: Attributes.h:100
static Attribute getWithByValType(LLVMContext &Context, Type *Ty)
Definition: Attributes.cpp:190
bool hasAttribute(AttrKind Val) const
Return true if the attribute is present.
Definition: Attributes.cpp:333
static bool isEnumAttrKind(AttrKind Kind)
Definition: Attributes.h:97
static Attribute getWithMemoryEffects(LLVMContext &Context, MemoryEffects ME)
Definition: Attributes.cpp:215
static bool canUseAsParamAttr(AttrKind Kind)
Definition: Attributes.cpp:631
bool isValid() const
Return true if the attribute is any kind of attribute.
Definition: Attributes.h:184
MaybeAlign getStackAlignment() const
Returns the stack alignment field of an attribute as a byte alignment value.
Definition: Attributes.cpp:348
MaybeAlign getAlignment() const
Returns the alignment field of an attribute as a byte alignment value.
Definition: Attributes.cpp:342
bool operator<(Attribute A) const
Less-than operator. Useful for sorting the attributes list.
Definition: Attributes.cpp:600
static Attribute getWithAlignment(LLVMContext &Context, Align Alignment)
Return a uniquified Attribute object that has the specific alignment set.
Definition: Attributes.cpp:168
Type * getValueAsType() const
Return the attribute's value as a Type.
Definition: Attributes.cpp:325
LLVM_ATTRIBUTE_RETURNS_NONNULL void * Allocate(size_t Size, Align Alignment)
Allocate space at the specified alignment.
Definition: Allocator.h:148
FoldingSetNodeID - This class is used to gather all the unique data bits of a node.
Definition: FoldingSet.h:319
void addFnAttr(Attribute::AttrKind Kind)
Add function attributes to this function.
Definition: Function.cpp:579
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
Definition: Function.cpp:695
void removeFnAttr(Attribute::AttrKind Kind)
Remove function attributes from this function.
Definition: Function.cpp:627
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition: Function.cpp:669
FoldingSet< AttributeImpl > AttrsSet
BumpPtrAllocator Alloc
FoldingSet< AttributeSetNode > AttrsSetNodes
FoldingSet< AttributeListImpl > AttrsLists
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:67
LLVMContextImpl *const pImpl
Definition: LLVMContext.h:69
ModRefInfo getModRef(Location Loc) const
Get ModRefInfo for the given Location.
Definition: ModRef.h:165
static MemoryEffectsBase createFromIntValue(uint32_t Data)
Create MemoryEffectsBase from an encoded integer value (used by memory attribute).
Definition: ModRef.h:154
static auto locations()
Returns iterator over all supported location kinds.
Definition: ModRef.h:95
uint32_t toIntValue() const
Convert MemoryEffectsBase into an encoded integer value (used by memory attribute).
Definition: ModRef.h:160
static MemoryEffectsBase unknown()
Create MemoryEffectsBase that can read and write any memory.
Definition: ModRef.h:112
size_t size() const
Definition: SmallVector.h:91
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:586
reference emplace_back(ArgTypes &&... Args)
Definition: SmallVector.h:950
void reserve(size_type N)
Definition: SmallVector.h:676
void resize(size_type N)
Definition: SmallVector.h:651
void push_back(const T &Elt)
Definition: SmallVector.h:426
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1209
static size_t totalSizeToAlloc(StringRef Kind, StringRef Val)
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
Definition: StringRef.h:466
std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:222
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:134
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:44
R Default(T Value)
Definition: StringSwitch.h:182
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
bool isPointerTy() const
True if this is an instance of PointerType.
Definition: Type.h:255
void print(raw_ostream &O, bool IsForDebug=false, bool NoDetails=false) const
Print the current type.
bool isPtrOrPtrVectorTy() const
Return true if this is a pointer type or a vector of pointer types.
Definition: Type.h:262
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition: Type.h:228
bool isFPOrFPVectorTy() const
Return true if this is a FP type or a vector of FP.
Definition: Type.h:216
bool isVoidTy() const
Return true if this is 'void'.
Definition: Type.h:140
LLVM Value Representation.
Definition: Value.h:74
static constexpr uint64_t MaximumAlignment
Definition: Value.h:807
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:660
This class provides various memory handling functions that manipulate MemoryBlock instances.
Definition: Memory.h:52
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool areInlineCompatible(const Function &Caller, const Function &Callee)
AttributeMask getUBImplyingAttributes()
Get param/return attributes which imply immediate undefined behavior if an invalid value is passed.
bool isNoFPClassCompatibleType(Type *Ty)
Returns true if this is a type legal for the 'nofpclass' attribute.
bool areOutlineCompatible(const Function &A, const Function &B)
Checks if there are any incompatible function attributes between A and B.
void updateMinLegalVectorWidthAttr(Function &Fn, uint64_t Width)
Update min-legal-vector-width if it is in Attribute and less than Width.
void mergeAttributesForOutlining(Function &Base, const Function &ToMerge)
Merges the functions attributes from ToMerge into function Base.
void mergeAttributesForInlining(Function &Caller, const Function &Callee)
Merge caller's and callee's attributes.
AttributeMask typeIncompatible(Type *Ty, AttributeSafetyKind ASK=ASK_ALL)
Which attributes cannot be applied to a type.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1731
bool isEqual(const GCNRPTracker::LiveRegSet &S1, const GCNRPTracker::LiveRegSet &S2)
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
Definition: STLExtras.h:1689
AllocFnKind
Definition: Attributes.h:47
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
Definition: STLExtras.h:2053
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1738
UWTableKind
Definition: CodeGen.h:120
@ None
No unwind table requested.
@ Sync
"Synchronous" unwind tables
void sort(IteratorTy Start, IteratorTy End)
Definition: STLExtras.h:1656
FPClassTest
Floating-point class tests, supported by 'is_fpclass' intrinsic.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1745
bool is_sorted(R &&Range, Compare C)
Wrapper function around std::is_sorted to check if elements in a range R are sorted with respect to a...
Definition: STLExtras.h:1911
ModRefInfo
Flags indicating whether a memory access modifies or references memory.
Definition: ModRef.h:27
@ Ref
The access may reference the value stored in memory.
@ ModRef
The access may reference and may modify the value stored in memory.
@ Mod
The access may modify the value stored in memory.
@ NoModRef
The access neither references nor modifies the value stored in memory.
@ ArgMem
Access to memory via argument pointers.
@ Other
Any other memory.
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
@ InaccessibleMem
Memory that is inaccessible via LLVM IR.
auto lower_bound(R &&Range, T &&Value)
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
Definition: STLExtras.h:1950
OutputIt copy(R &&Range, OutputIt Out)
Definition: STLExtras.h:1833
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
Definition: STLExtras.h:2031
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition: BitVector.h:860
Attribute comparator that only compares attribute keys.
bool operator()(Attribute A0, StringRef Kind) const
bool operator()(Attribute A0, Attribute A1) const
bool operator()(Attribute A0, Attribute::AttrKind Kind) const
static void set(Function &Fn, Attribute::AttrKind Kind, bool Val)
static bool isSet(const Function &Fn, Attribute::AttrKind Kind)
static bool isSet(const Function &Fn, StringRef Kind)
static void set(Function &Fn, StringRef Kind, bool Val)
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
uint64_t value() const
This is a hole in the type system and should not be abused.
Definition: Alignment.h:85
Represent subnormal handling kind for floating point instruction inputs and outputs.
DenormalModeKind Input
Denormal treatment kind for floating point instruction inputs in the default floating-point environme...
@ Dynamic
Denormals have unknown treatment.
static constexpr DenormalMode getInvalid()
DenormalModeKind Output
Denormal flushing mode for floating point instruction results in the default floating point environme...
static constexpr DenormalMode getDynamic()
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Definition: Alignment.h:117
Function object to check whether the first component of a container supported by std::get (like std::...
Definition: STLExtras.h:1459