LLVM 17.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"
26#include "llvm/IR/Function.h"
27#include "llvm/IR/LLVMContext.h"
28#include "llvm/IR/Type.h"
31#include "llvm/Support/ModRef.h"
33#include <algorithm>
34#include <cassert>
35#include <cstddef>
36#include <cstdint>
37#include <limits>
38#include <optional>
39#include <string>
40#include <tuple>
41#include <utility>
42
43using namespace llvm;
44
45//===----------------------------------------------------------------------===//
46// Attribute Construction Methods
47//===----------------------------------------------------------------------===//
48
49// allocsize has two integer arguments, but because they're both 32 bits, we can
50// pack them into one 64-bit value, at the cost of making said value
51// nonsensical.
52//
53// In order to do this, we need to reserve one value of the second (optional)
54// allocsize argument to signify "not present."
55static const unsigned AllocSizeNumElemsNotPresent = -1;
56
57static uint64_t packAllocSizeArgs(unsigned ElemSizeArg,
58 const std::optional<unsigned> &NumElemsArg) {
59 assert((!NumElemsArg || *NumElemsArg != AllocSizeNumElemsNotPresent) &&
60 "Attempting to pack a reserved value");
61
62 return uint64_t(ElemSizeArg) << 32 |
63 NumElemsArg.value_or(AllocSizeNumElemsNotPresent);
64}
65
66static std::pair<unsigned, std::optional<unsigned>>
68 unsigned NumElems = Num & std::numeric_limits<unsigned>::max();
69 unsigned ElemSizeArg = Num >> 32;
70
71 std::optional<unsigned> NumElemsArg;
72 if (NumElems != AllocSizeNumElemsNotPresent)
73 NumElemsArg = NumElems;
74 return std::make_pair(ElemSizeArg, NumElemsArg);
75}
76
77static uint64_t packVScaleRangeArgs(unsigned MinValue,
78 std::optional<unsigned> MaxValue) {
79 return uint64_t(MinValue) << 32 | MaxValue.value_or(0);
80}
81
82static std::pair<unsigned, std::optional<unsigned>>
84 unsigned MaxValue = Value & std::numeric_limits<unsigned>::max();
85 unsigned MinValue = Value >> 32;
86
87 return std::make_pair(MinValue,
88 MaxValue > 0 ? MaxValue : std::optional<unsigned>());
89}
90
92 uint64_t Val) {
93 bool IsIntAttr = Attribute::isIntAttrKind(Kind);
94 assert((IsIntAttr || Attribute::isEnumAttrKind(Kind)) &&
95 "Not an enum or int attribute");
96
99 ID.AddInteger(Kind);
100 if (IsIntAttr)
101 ID.AddInteger(Val);
102 else
103 assert(Val == 0 && "Value must be zero for enum attributes");
104
105 void *InsertPoint;
106 AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);
107
108 if (!PA) {
109 // If we didn't find any existing attributes of the same shape then create a
110 // new one and insert it.
111 if (!IsIntAttr)
112 PA = new (pImpl->Alloc) EnumAttributeImpl(Kind);
113 else
114 PA = new (pImpl->Alloc) IntAttributeImpl(Kind, Val);
115 pImpl->AttrsSet.InsertNode(PA, InsertPoint);
116 }
117
118 // Return the Attribute that we found or created.
119 return Attribute(PA);
120}
121
125 ID.AddString(Kind);
126 if (!Val.empty()) ID.AddString(Val);
127
128 void *InsertPoint;
129 AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);
130
131 if (!PA) {
132 // If we didn't find any existing attributes of the same shape then create a
133 // new one and insert it.
134 void *Mem =
136 alignof(StringAttributeImpl));
137 PA = new (Mem) StringAttributeImpl(Kind, Val);
138 pImpl->AttrsSet.InsertNode(PA, InsertPoint);
139 }
140
141 // Return the Attribute that we found or created.
142 return Attribute(PA);
143}
144
146 Type *Ty) {
147 assert(Attribute::isTypeAttrKind(Kind) && "Not a type attribute");
150 ID.AddInteger(Kind);
151 ID.AddPointer(Ty);
152
153 void *InsertPoint;
154 AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);
155
156 if (!PA) {
157 // If we didn't find any existing attributes of the same shape then create a
158 // new one and insert it.
159 PA = new (pImpl->Alloc) TypeAttributeImpl(Kind, Ty);
160 pImpl->AttrsSet.InsertNode(PA, InsertPoint);
161 }
162
163 // Return the Attribute that we found or created.
164 return Attribute(PA);
165}
166
168 assert(A <= llvm::Value::MaximumAlignment && "Alignment too large.");
169 return get(Context, Alignment, A.value());
170}
171
173 assert(A <= 0x100 && "Alignment too large.");
174 return get(Context, StackAlignment, A.value());
175}
176
178 uint64_t Bytes) {
179 assert(Bytes && "Bytes must be non-zero.");
180 return get(Context, Dereferenceable, Bytes);
181}
182
184 uint64_t Bytes) {
185 assert(Bytes && "Bytes must be non-zero.");
186 return get(Context, DereferenceableOrNull, Bytes);
187}
188
190 return get(Context, ByVal, Ty);
191}
192
194 return get(Context, StructRet, Ty);
195}
196
198 return get(Context, ByRef, Ty);
199}
200
202 return get(Context, Preallocated, Ty);
203}
204
206 return get(Context, InAlloca, Ty);
207}
208
210 UWTableKind Kind) {
211 return get(Context, UWTable, uint64_t(Kind));
212}
213
215 MemoryEffects ME) {
216 return get(Context, Memory, ME.toIntValue());
217}
218
220 FPClassTest ClassMask) {
221 return get(Context, NoFPClass, ClassMask);
222}
223
225Attribute::getWithAllocSizeArgs(LLVMContext &Context, unsigned ElemSizeArg,
226 const std::optional<unsigned> &NumElemsArg) {
227 assert(!(ElemSizeArg == 0 && NumElemsArg && *NumElemsArg == 0) &&
228 "Invalid allocsize arguments -- given allocsize(0, 0)");
229 return get(Context, AllocSize, packAllocSizeArgs(ElemSizeArg, NumElemsArg));
230}
231
233 unsigned MinValue,
234 unsigned MaxValue) {
235 return get(Context, VScaleRange, packVScaleRangeArgs(MinValue, MaxValue));
236}
237
239 return StringSwitch<Attribute::AttrKind>(AttrName)
240#define GET_ATTR_NAMES
241#define ATTRIBUTE_ENUM(ENUM_NAME, DISPLAY_NAME) \
242 .Case(#DISPLAY_NAME, Attribute::ENUM_NAME)
243#include "llvm/IR/Attributes.inc"
245}
246
248 switch (AttrKind) {
249#define GET_ATTR_NAMES
250#define ATTRIBUTE_ENUM(ENUM_NAME, DISPLAY_NAME) \
251 case Attribute::ENUM_NAME: \
252 return #DISPLAY_NAME;
253#include "llvm/IR/Attributes.inc"
254 case Attribute::None:
255 return "none";
256 default:
257 llvm_unreachable("invalid Kind");
258 }
259}
260
263#define GET_ATTR_NAMES
264#define ATTRIBUTE_ALL(ENUM_NAME, DISPLAY_NAME) .Case(#DISPLAY_NAME, true)
265#include "llvm/IR/Attributes.inc"
266 .Default(false);
267}
268
269//===----------------------------------------------------------------------===//
270// Attribute Accessor Methods
271//===----------------------------------------------------------------------===//
272
274 return pImpl && pImpl->isEnumAttribute();
275}
276
278 return pImpl && pImpl->isIntAttribute();
279}
280
282 return pImpl && pImpl->isStringAttribute();
283}
284
286 return pImpl && pImpl->isTypeAttribute();
287}
288
290 if (!pImpl) return None;
292 "Invalid attribute type to get the kind as an enum!");
293 return pImpl->getKindAsEnum();
294}
295
297 if (!pImpl) return 0;
299 "Expected the attribute to be an integer attribute!");
300 return pImpl->getValueAsInt();
301}
302
304 if (!pImpl) return false;
306 "Expected the attribute to be a string attribute!");
307 return pImpl->getValueAsBool();
308}
309
311 if (!pImpl) return {};
313 "Invalid attribute type to get the kind as a string!");
314 return pImpl->getKindAsString();
315}
316
318 if (!pImpl) return {};
320 "Invalid attribute type to get the value as a string!");
321 return pImpl->getValueAsString();
322}
323
325 if (!pImpl) return {};
327 "Invalid attribute type to get the value as a type!");
328 return pImpl->getValueAsType();
329}
330
331
333 return (pImpl && pImpl->hasAttribute(Kind)) || (!pImpl && Kind == None);
334}
335
337 if (!isStringAttribute()) return false;
338 return pImpl && pImpl->hasAttribute(Kind);
339}
340
342 assert(hasAttribute(Attribute::Alignment) &&
343 "Trying to get alignment from non-alignment attribute!");
344 return MaybeAlign(pImpl->getValueAsInt());
345}
346
348 assert(hasAttribute(Attribute::StackAlignment) &&
349 "Trying to get alignment from non-alignment attribute!");
350 return MaybeAlign(pImpl->getValueAsInt());
351}
352
354 assert(hasAttribute(Attribute::Dereferenceable) &&
355 "Trying to get dereferenceable bytes from "
356 "non-dereferenceable attribute!");
357 return pImpl->getValueAsInt();
358}
359
361 assert(hasAttribute(Attribute::DereferenceableOrNull) &&
362 "Trying to get dereferenceable bytes from "
363 "non-dereferenceable attribute!");
364 return pImpl->getValueAsInt();
365}
366
367std::pair<unsigned, std::optional<unsigned>>
369 assert(hasAttribute(Attribute::AllocSize) &&
370 "Trying to get allocsize args from non-allocsize attribute");
371 return unpackAllocSizeArgs(pImpl->getValueAsInt());
372}
373
375 assert(hasAttribute(Attribute::VScaleRange) &&
376 "Trying to get vscale args from non-vscale attribute");
377 return unpackVScaleRangeArgs(pImpl->getValueAsInt()).first;
378}
379
380std::optional<unsigned> Attribute::getVScaleRangeMax() const {
381 assert(hasAttribute(Attribute::VScaleRange) &&
382 "Trying to get vscale args from non-vscale attribute");
383 return unpackVScaleRangeArgs(pImpl->getValueAsInt()).second;
384}
385
387 assert(hasAttribute(Attribute::UWTable) &&
388 "Trying to get unwind table kind from non-uwtable attribute");
389 return UWTableKind(pImpl->getValueAsInt());
390}
391
393 assert(hasAttribute(Attribute::AllocKind) &&
394 "Trying to get allockind value from non-allockind attribute");
395 return AllocFnKind(pImpl->getValueAsInt());
396}
397
399 assert(hasAttribute(Attribute::Memory) &&
400 "Can only call getMemoryEffects() on memory attribute");
402}
403
405 assert(hasAttribute(Attribute::NoFPClass) &&
406 "Can only call getNoFPClass() on nofpclass attribute");
407 return static_cast<FPClassTest>(pImpl->getValueAsInt());
408}
409
410static const char *getModRefStr(ModRefInfo MR) {
411 switch (MR) {
413 return "none";
414 case ModRefInfo::Ref:
415 return "read";
416 case ModRefInfo::Mod:
417 return "write";
419 return "readwrite";
420 }
421 llvm_unreachable("Invalid ModRefInfo");
422}
423
424std::string Attribute::getAsString(bool InAttrGrp) const {
425 if (!pImpl) return {};
426
427 if (isEnumAttribute())
429
430 if (isTypeAttribute()) {
431 std::string Result = getNameFromAttrKind(getKindAsEnum()).str();
432 Result += '(';
433 raw_string_ostream OS(Result);
434 getValueAsType()->print(OS, false, true);
435 OS.flush();
436 Result += ')';
437 return Result;
438 }
439
440 // FIXME: These should be output like this:
441 //
442 // align=4
443 // alignstack=8
444 //
445 if (hasAttribute(Attribute::Alignment))
446 return (InAttrGrp ? "align=" + Twine(getValueAsInt())
447 : "align " + Twine(getValueAsInt()))
448 .str();
449
450 auto AttrWithBytesToString = [&](const char *Name) {
451 return (InAttrGrp ? Name + ("=" + Twine(getValueAsInt()))
452 : Name + ("(" + Twine(getValueAsInt())) + ")")
453 .str();
454 };
455
456 if (hasAttribute(Attribute::StackAlignment))
457 return AttrWithBytesToString("alignstack");
458
459 if (hasAttribute(Attribute::Dereferenceable))
460 return AttrWithBytesToString("dereferenceable");
461
462 if (hasAttribute(Attribute::DereferenceableOrNull))
463 return AttrWithBytesToString("dereferenceable_or_null");
464
465 if (hasAttribute(Attribute::AllocSize)) {
466 unsigned ElemSize;
467 std::optional<unsigned> NumElems;
468 std::tie(ElemSize, NumElems) = getAllocSizeArgs();
469
470 return (NumElems
471 ? "allocsize(" + Twine(ElemSize) + "," + Twine(*NumElems) + ")"
472 : "allocsize(" + Twine(ElemSize) + ")")
473 .str();
474 }
475
476 if (hasAttribute(Attribute::VScaleRange)) {
477 unsigned MinValue = getVScaleRangeMin();
478 std::optional<unsigned> MaxValue = getVScaleRangeMax();
479 return ("vscale_range(" + Twine(MinValue) + "," +
480 Twine(MaxValue.value_or(0)) + ")")
481 .str();
482 }
483
484 if (hasAttribute(Attribute::UWTable)) {
486 if (Kind != UWTableKind::None) {
487 return Kind == UWTableKind::Default
488 ? "uwtable"
489 : ("uwtable(" +
490 Twine(Kind == UWTableKind::Sync ? "sync" : "async") + ")")
491 .str();
492 }
493 }
494
495 if (hasAttribute(Attribute::AllocKind)) {
496 AllocFnKind Kind = getAllocKind();
499 parts.push_back("alloc");
501 parts.push_back("realloc");
503 parts.push_back("free");
505 parts.push_back("uninitialized");
507 parts.push_back("zeroed");
509 parts.push_back("aligned");
510 return ("allockind(\"" +
511 Twine(llvm::join(parts.begin(), parts.end(), ",")) + "\")")
512 .str();
513 }
514
515 if (hasAttribute(Attribute::Memory)) {
516 std::string Result;
517 raw_string_ostream OS(Result);
518 bool First = true;
519 OS << "memory(";
520
522
523 // Print access kind for "other" as the default access kind. This way it
524 // will apply to any new location kinds that get split out of "other".
526 if (OtherMR != ModRefInfo::NoModRef || ME.getModRef() == OtherMR) {
527 First = false;
528 OS << getModRefStr(OtherMR);
529 }
530
531 for (auto Loc : MemoryEffects::locations()) {
532 ModRefInfo MR = ME.getModRef(Loc);
533 if (MR == OtherMR)
534 continue;
535
536 if (!First)
537 OS << ", ";
538 First = false;
539
540 switch (Loc) {
542 OS << "argmem: ";
543 break;
545 OS << "inaccessiblemem: ";
546 break;
548 llvm_unreachable("This is represented as the default access kind");
549 }
550 OS << getModRefStr(MR);
551 }
552 OS << ")";
553 OS.flush();
554 return Result;
555 }
556
557 if (hasAttribute(Attribute::NoFPClass)) {
558 std::string Result = "nofpclass";
559 raw_string_ostream OS(Result);
560 OS << getNoFPClass();
561 return Result;
562 }
563
564 // Convert target-dependent attributes to strings of the form:
565 //
566 // "kind"
567 // "kind" = "value"
568 //
569 if (isStringAttribute()) {
570 std::string Result;
571 {
572 raw_string_ostream OS(Result);
573 OS << '"' << getKindAsString() << '"';
574
575 // Since some attribute strings contain special characters that cannot be
576 // printable, those have to be escaped to make the attribute value
577 // printable as is. e.g. "\01__gnu_mcount_nc"
578 const auto &AttrVal = pImpl->getValueAsString();
579 if (!AttrVal.empty()) {
580 OS << "=\"";
581 printEscapedString(AttrVal, OS);
582 OS << "\"";
583 }
584 }
585 return Result;
586 }
587
588 llvm_unreachable("Unknown attribute");
589}
590
592 assert(isValid() && "invalid Attribute doesn't refer to any context");
594 pImpl->Profile(ID);
595 void *Unused;
596 return C.pImpl->AttrsSet.FindNodeOrInsertPos(ID, Unused) == pImpl;
597}
598
600 if (!pImpl && !A.pImpl) return false;
601 if (!pImpl) return true;
602 if (!A.pImpl) return false;
603 return *pImpl < *A.pImpl;
604}
605
607 ID.AddPointer(pImpl);
608}
609
611 FnAttr = (1 << 0),
612 ParamAttr = (1 << 1),
613 RetAttr = (1 << 2),
614};
615
616#define GET_ATTR_PROP_TABLE
617#include "llvm/IR/Attributes.inc"
618
620 AttributeProperty Prop) {
621 unsigned Index = Kind - 1;
622 assert(Index < std::size(AttrPropTable) && "Invalid attribute kind");
623 return AttrPropTable[Index] & Prop;
624}
625
627 return hasAttributeProperty(Kind, AttributeProperty::FnAttr);
628}
629
631 return hasAttributeProperty(Kind, AttributeProperty::ParamAttr);
632}
633
635 return hasAttributeProperty(Kind, AttributeProperty::RetAttr);
636}
637
638//===----------------------------------------------------------------------===//
639// AttributeImpl Definition
640//===----------------------------------------------------------------------===//
641
643 if (isStringAttribute()) return false;
644 return getKindAsEnum() == A;
645}
646
648 if (!isStringAttribute()) return false;
649 return getKindAsString() == Kind;
650}
651
654 return static_cast<const EnumAttributeImpl *>(this)->getEnumKind();
655}
656
659 return static_cast<const IntAttributeImpl *>(this)->getValue();
660}
661
663 assert(getValueAsString().empty() || getValueAsString() == "false" || getValueAsString() == "true");
664 return getValueAsString() == "true";
665}
666
669 return static_cast<const StringAttributeImpl *>(this)->getStringKind();
670}
671
674 return static_cast<const StringAttributeImpl *>(this)->getStringValue();
675}
676
679 return static_cast<const TypeAttributeImpl *>(this)->getTypeValue();
680}
681
683 if (this == &AI)
684 return false;
685
686 // This sorts the attributes with Attribute::AttrKinds coming first (sorted
687 // relative to their enum value) and then strings.
688 if (!isStringAttribute()) {
689 if (AI.isStringAttribute())
690 return true;
691 if (getKindAsEnum() != AI.getKindAsEnum())
692 return getKindAsEnum() < AI.getKindAsEnum();
693 assert(!AI.isEnumAttribute() && "Non-unique attribute");
694 assert(!AI.isTypeAttribute() && "Comparison of types would be unstable");
695 // TODO: Is this actually needed?
696 assert(AI.isIntAttribute() && "Only possibility left");
697 return getValueAsInt() < AI.getValueAsInt();
698 }
699
700 if (!AI.isStringAttribute())
701 return false;
702 if (getKindAsString() == AI.getKindAsString())
703 return getValueAsString() < AI.getValueAsString();
704 return getKindAsString() < AI.getKindAsString();
705}
706
707//===----------------------------------------------------------------------===//
708// AttributeSet Definition
709//===----------------------------------------------------------------------===//
710
713}
714
716 return AttributeSet(AttributeSetNode::get(C, Attrs));
717}
718
720 Attribute::AttrKind Kind) const {
721 if (hasAttribute(Kind)) return *this;
722 AttrBuilder B(C);
723 B.addAttribute(Kind);
725}
726
728 StringRef Value) const {
729 AttrBuilder B(C);
730 B.addAttribute(Kind, Value);
732}
733
735 const AttributeSet AS) const {
736 if (!hasAttributes())
737 return AS;
738
739 if (!AS.hasAttributes())
740 return *this;
741
742 AttrBuilder B(C, *this);
743 B.merge(AttrBuilder(C, AS));
744 return get(C, B);
745}
746
748 Attribute::AttrKind Kind) const {
749 if (!hasAttribute(Kind)) return *this;
750 AttrBuilder B(C, *this);
751 B.removeAttribute(Kind);
752 return get(C, B);
753}
754
756 StringRef Kind) const {
757 if (!hasAttribute(Kind)) return *this;
758 AttrBuilder B(C, *this);
759 B.removeAttribute(Kind);
760 return get(C, B);
761}
762
764 const AttributeMask &Attrs) const {
765 AttrBuilder B(C, *this);
766 // If there is nothing to remove, directly return the original set.
767 if (!B.overlaps(Attrs))
768 return *this;
769
770 B.remove(Attrs);
771 return get(C, B);
772}
773
775 return SetNode ? SetNode->getNumAttributes() : 0;
776}
777
779 return SetNode ? SetNode->hasAttribute(Kind) : false;
780}
781
783 return SetNode ? SetNode->hasAttribute(Kind) : false;
784}
785
787 return SetNode ? SetNode->getAttribute(Kind) : Attribute();
788}
789
791 return SetNode ? SetNode->getAttribute(Kind) : Attribute();
792}
793
795 return SetNode ? SetNode->getAlignment() : std::nullopt;
796}
797
799 return SetNode ? SetNode->getStackAlignment() : std::nullopt;
800}
801
803 return SetNode ? SetNode->getDereferenceableBytes() : 0;
804}
805
807 return SetNode ? SetNode->getDereferenceableOrNullBytes() : 0;
808}
809
811 return SetNode ? SetNode->getAttributeType(Attribute::ByRef) : nullptr;
812}
813
815 return SetNode ? SetNode->getAttributeType(Attribute::ByVal) : nullptr;
816}
817
819 return SetNode ? SetNode->getAttributeType(Attribute::StructRet) : nullptr;
820}
821
823 return SetNode ? SetNode->getAttributeType(Attribute::Preallocated) : nullptr;
824}
825
827 return SetNode ? SetNode->getAttributeType(Attribute::InAlloca) : nullptr;
828}
829
831 return SetNode ? SetNode->getAttributeType(Attribute::ElementType) : nullptr;
832}
833
834std::optional<std::pair<unsigned, std::optional<unsigned>>>
836 if (SetNode)
837 return SetNode->getAllocSizeArgs();
838 return std::nullopt;
839}
840
842 return SetNode ? SetNode->getVScaleRangeMin() : 1;
843}
844
845std::optional<unsigned> AttributeSet::getVScaleRangeMax() const {
846 return SetNode ? SetNode->getVScaleRangeMax() : std::nullopt;
847}
848
850 return SetNode ? SetNode->getUWTableKind() : UWTableKind::None;
851}
852
854 return SetNode ? SetNode->getAllocKind() : AllocFnKind::Unknown;
855}
856
858 return SetNode ? SetNode->getMemoryEffects() : MemoryEffects::unknown();
859}
860
862 return SetNode ? SetNode->getNoFPClass() : fcNone;
863}
864
865std::string AttributeSet::getAsString(bool InAttrGrp) const {
866 return SetNode ? SetNode->getAsString(InAttrGrp) : "";
867}
868
870 assert(hasAttributes() && "empty AttributeSet doesn't refer to any context");
872 SetNode->Profile(ID);
873 void *Unused;
874 return C.pImpl->AttrsSetNodes.FindNodeOrInsertPos(ID, Unused) == SetNode;
875}
876
878 return SetNode ? SetNode->begin() : nullptr;
879}
880
882 return SetNode ? SetNode->end() : nullptr;
883}
884
885#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
887 dbgs() << "AS =\n";
888 dbgs() << " { ";
889 dbgs() << getAsString(true) << " }\n";
890}
891#endif
892
893//===----------------------------------------------------------------------===//
894// AttributeSetNode Definition
895//===----------------------------------------------------------------------===//
896
897AttributeSetNode::AttributeSetNode(ArrayRef<Attribute> Attrs)
898 : NumAttrs(Attrs.size()) {
899 // There's memory after the node where we can store the entries in.
900 llvm::copy(Attrs, getTrailingObjects<Attribute>());
901
902 for (const auto &I : *this) {
903 if (I.isStringAttribute())
904 StringAttrs.insert({ I.getKindAsString(), I });
905 else
906 AvailableAttrs.addAttribute(I.getKindAsEnum());
907 }
908}
909
911 ArrayRef<Attribute> Attrs) {
912 SmallVector<Attribute, 8> SortedAttrs(Attrs.begin(), Attrs.end());
913 llvm::sort(SortedAttrs);
914 return getSorted(C, SortedAttrs);
915}
916
917AttributeSetNode *AttributeSetNode::getSorted(LLVMContext &C,
918 ArrayRef<Attribute> SortedAttrs) {
919 if (SortedAttrs.empty())
920 return nullptr;
921
922 // Build a key to look up the existing attributes.
923 LLVMContextImpl *pImpl = C.pImpl;
925
926 assert(llvm::is_sorted(SortedAttrs) && "Expected sorted attributes!");
927 for (const auto &Attr : SortedAttrs)
928 Attr.Profile(ID);
929
930 void *InsertPoint;
931 AttributeSetNode *PA =
932 pImpl->AttrsSetNodes.FindNodeOrInsertPos(ID, InsertPoint);
933
934 // If we didn't find any existing attributes of the same shape then create a
935 // new one and insert it.
936 if (!PA) {
937 // Coallocate entries after the AttributeSetNode itself.
938 void *Mem = ::operator new(totalSizeToAlloc<Attribute>(SortedAttrs.size()));
939 PA = new (Mem) AttributeSetNode(SortedAttrs);
940 pImpl->AttrsSetNodes.InsertNode(PA, InsertPoint);
941 }
942
943 // Return the AttributeSetNode that we found or created.
944 return PA;
945}
946
948 return getSorted(C, B.attrs());
949}
950
952 return StringAttrs.count(Kind);
953}
954
955std::optional<Attribute>
956AttributeSetNode::findEnumAttribute(Attribute::AttrKind Kind) const {
957 // Do a quick presence check.
958 if (!hasAttribute(Kind))
959 return std::nullopt;
960
961 // Attributes in a set are sorted by enum value, followed by string
962 // attributes. Binary search the one we want.
963 const Attribute *I =
964 std::lower_bound(begin(), end() - StringAttrs.size(), Kind,
966 return A.getKindAsEnum() < Kind;
967 });
968 assert(I != end() && I->hasAttribute(Kind) && "Presence check failed?");
969 return *I;
970}
971
973 if (auto A = findEnumAttribute(Kind))
974 return *A;
975 return {};
976}
977
979 return StringAttrs.lookup(Kind);
980}
981
983 if (auto A = findEnumAttribute(Attribute::Alignment))
984 return A->getAlignment();
985 return std::nullopt;
986}
987
989 if (auto A = findEnumAttribute(Attribute::StackAlignment))
990 return A->getStackAlignment();
991 return std::nullopt;
992}
993
995 if (auto A = findEnumAttribute(Kind))
996 return A->getValueAsType();
997 return nullptr;
998}
999
1001 if (auto A = findEnumAttribute(Attribute::Dereferenceable))
1002 return A->getDereferenceableBytes();
1003 return 0;
1004}
1005
1007 if (auto A = findEnumAttribute(Attribute::DereferenceableOrNull))
1008 return A->getDereferenceableOrNullBytes();
1009 return 0;
1010}
1011
1012std::optional<std::pair<unsigned, std::optional<unsigned>>>
1014 if (auto A = findEnumAttribute(Attribute::AllocSize))
1015 return A->getAllocSizeArgs();
1016 return std::nullopt;
1017}
1018
1020 if (auto A = findEnumAttribute(Attribute::VScaleRange))
1021 return A->getVScaleRangeMin();
1022 return 1;
1023}
1024
1025std::optional<unsigned> AttributeSetNode::getVScaleRangeMax() const {
1026 if (auto A = findEnumAttribute(Attribute::VScaleRange))
1027 return A->getVScaleRangeMax();
1028 return std::nullopt;
1029}
1030
1032 if (auto A = findEnumAttribute(Attribute::UWTable))
1033 return A->getUWTableKind();
1034 return UWTableKind::None;
1035}
1036
1038 if (auto A = findEnumAttribute(Attribute::AllocKind))
1039 return A->getAllocKind();
1040 return AllocFnKind::Unknown;
1041}
1042
1044 if (auto A = findEnumAttribute(Attribute::Memory))
1045 return A->getMemoryEffects();
1046 return MemoryEffects::unknown();
1047}
1048
1050 if (auto A = findEnumAttribute(Attribute::NoFPClass))
1051 return A->getNoFPClass();
1052 return fcNone;
1053}
1054
1055std::string AttributeSetNode::getAsString(bool InAttrGrp) const {
1056 std::string Str;
1057 for (iterator I = begin(), E = end(); I != E; ++I) {
1058 if (I != begin())
1059 Str += ' ';
1060 Str += I->getAsString(InAttrGrp);
1061 }
1062 return Str;
1063}
1064
1065//===----------------------------------------------------------------------===//
1066// AttributeListImpl Definition
1067//===----------------------------------------------------------------------===//
1068
1069/// Map from AttributeList index to the internal array index. Adding one happens
1070/// to work, because -1 wraps around to 0.
1071static unsigned attrIdxToArrayIdx(unsigned Index) {
1072 return Index + 1;
1073}
1074
1076 : NumAttrSets(Sets.size()) {
1077 assert(!Sets.empty() && "pointless AttributeListImpl");
1078
1079 // There's memory after the node where we can store the entries in.
1080 llvm::copy(Sets, getTrailingObjects<AttributeSet>());
1081
1082 // Initialize AvailableFunctionAttrs and AvailableSomewhereAttrs
1083 // summary bitsets.
1084 for (const auto &I : Sets[attrIdxToArrayIdx(AttributeList::FunctionIndex)])
1085 if (!I.isStringAttribute())
1086 AvailableFunctionAttrs.addAttribute(I.getKindAsEnum());
1087
1088 for (const auto &Set : Sets)
1089 for (const auto &I : Set)
1090 if (!I.isStringAttribute())
1091 AvailableSomewhereAttrs.addAttribute(I.getKindAsEnum());
1092}
1093
1095 Profile(ID, ArrayRef(begin(), end()));
1096}
1097
1100 for (const auto &Set : Sets)
1101 ID.AddPointer(Set.SetNode);
1102}
1103
1105 unsigned *Index) const {
1106 if (!AvailableSomewhereAttrs.hasAttribute(Kind))
1107 return false;
1108
1109 if (Index) {
1110 for (unsigned I = 0, E = NumAttrSets; I != E; ++I) {
1111 if (begin()[I].hasAttribute(Kind)) {
1112 *Index = I - 1;
1113 break;
1114 }
1115 }
1116 }
1117
1118 return true;
1119}
1120
1121
1122#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1124 AttributeList(const_cast<AttributeListImpl *>(this)).dump();
1125}
1126#endif
1127
1128//===----------------------------------------------------------------------===//
1129// AttributeList Construction and Mutation Methods
1130//===----------------------------------------------------------------------===//
1131
1132AttributeList AttributeList::getImpl(LLVMContext &C,
1133 ArrayRef<AttributeSet> AttrSets) {
1134 assert(!AttrSets.empty() && "pointless AttributeListImpl");
1135
1136 LLVMContextImpl *pImpl = C.pImpl;
1138 AttributeListImpl::Profile(ID, AttrSets);
1139
1140 void *InsertPoint;
1141 AttributeListImpl *PA =
1142 pImpl->AttrsLists.FindNodeOrInsertPos(ID, InsertPoint);
1143
1144 // If we didn't find any existing attributes of the same shape then
1145 // create a new one and insert it.
1146 if (!PA) {
1147 // Coallocate entries after the AttributeListImpl itself.
1148 void *Mem = pImpl->Alloc.Allocate(
1149 AttributeListImpl::totalSizeToAlloc<AttributeSet>(AttrSets.size()),
1150 alignof(AttributeListImpl));
1151 PA = new (Mem) AttributeListImpl(AttrSets);
1152 pImpl->AttrsLists.InsertNode(PA, InsertPoint);
1153 }
1154
1155 // Return the AttributesList that we found or created.
1156 return AttributeList(PA);
1157}
1158
1161 ArrayRef<std::pair<unsigned, Attribute>> Attrs) {
1162 // If there are no attributes then return a null AttributesList pointer.
1163 if (Attrs.empty())
1164 return {};
1165
1167 "Misordered Attributes list!");
1168 assert(llvm::all_of(Attrs,
1169 [](const std::pair<unsigned, Attribute> &Pair) {
1170 return Pair.second.isValid();
1171 }) &&
1172 "Pointless attribute!");
1173
1174 // Create a vector if (unsigned, AttributeSetNode*) pairs from the attributes
1175 // list.
1177 for (ArrayRef<std::pair<unsigned, Attribute>>::iterator I = Attrs.begin(),
1178 E = Attrs.end(); I != E; ) {
1179 unsigned Index = I->first;
1181 while (I != E && I->first == Index) {
1182 AttrVec.push_back(I->second);
1183 ++I;
1184 }
1185
1186 AttrPairVec.emplace_back(Index, AttributeSet::get(C, AttrVec));
1187 }
1188
1189 return get(C, AttrPairVec);
1190}
1191
1194 ArrayRef<std::pair<unsigned, AttributeSet>> Attrs) {
1195 // If there are no attributes then return a null AttributesList pointer.
1196 if (Attrs.empty())
1197 return {};
1198
1200 "Misordered Attributes list!");
1201 assert(llvm::none_of(Attrs,
1202 [](const std::pair<unsigned, AttributeSet> &Pair) {
1203 return !Pair.second.hasAttributes();
1204 }) &&
1205 "Pointless attribute!");
1206
1207 unsigned MaxIndex = Attrs.back().first;
1208 // If the MaxIndex is FunctionIndex and there are other indices in front
1209 // of it, we need to use the largest of those to get the right size.
1210 if (MaxIndex == FunctionIndex && Attrs.size() > 1)
1211 MaxIndex = Attrs[Attrs.size() - 2].first;
1212
1213 SmallVector<AttributeSet, 4> AttrVec(attrIdxToArrayIdx(MaxIndex) + 1);
1214 for (const auto &Pair : Attrs)
1215 AttrVec[attrIdxToArrayIdx(Pair.first)] = Pair.second;
1216
1217 return getImpl(C, AttrVec);
1218}
1219
1221 AttributeSet RetAttrs,
1222 ArrayRef<AttributeSet> ArgAttrs) {
1223 // Scan from the end to find the last argument with attributes. Most
1224 // arguments don't have attributes, so it's nice if we can have fewer unique
1225 // AttributeListImpls by dropping empty attribute sets at the end of the list.
1226 unsigned NumSets = 0;
1227 for (size_t I = ArgAttrs.size(); I != 0; --I) {
1228 if (ArgAttrs[I - 1].hasAttributes()) {
1229 NumSets = I + 2;
1230 break;
1231 }
1232 }
1233 if (NumSets == 0) {
1234 // Check function and return attributes if we didn't have argument
1235 // attributes.
1236 if (RetAttrs.hasAttributes())
1237 NumSets = 2;
1238 else if (FnAttrs.hasAttributes())
1239 NumSets = 1;
1240 }
1241
1242 // If all attribute sets were empty, we can use the empty attribute list.
1243 if (NumSets == 0)
1244 return {};
1245
1247 AttrSets.reserve(NumSets);
1248 // If we have any attributes, we always have function attributes.
1249 AttrSets.push_back(FnAttrs);
1250 if (NumSets > 1)
1251 AttrSets.push_back(RetAttrs);
1252 if (NumSets > 2) {
1253 // Drop the empty argument attribute sets at the end.
1254 ArgAttrs = ArgAttrs.take_front(NumSets - 2);
1255 llvm::append_range(AttrSets, ArgAttrs);
1256 }
1257
1258 return getImpl(C, AttrSets);
1259}
1260
1262 AttributeSet Attrs) {
1263 if (!Attrs.hasAttributes())
1264 return {};
1266 SmallVector<AttributeSet, 8> AttrSets(Index + 1);
1267 AttrSets[Index] = Attrs;
1268 return getImpl(C, AttrSets);
1269}
1270
1272 const AttrBuilder &B) {
1273 return get(C, Index, AttributeSet::get(C, B));
1274}
1275
1279 for (const auto K : Kinds)
1280 Attrs.emplace_back(Index, Attribute::get(C, K));
1281 return get(C, Attrs);
1282}
1283
1286 ArrayRef<uint64_t> Values) {
1287 assert(Kinds.size() == Values.size() && "Mismatched attribute values.");
1289 auto VI = Values.begin();
1290 for (const auto K : Kinds)
1291 Attrs.emplace_back(Index, Attribute::get(C, K, *VI++));
1292 return get(C, Attrs);
1293}
1294
1296 ArrayRef<StringRef> Kinds) {
1298 for (const auto &K : Kinds)
1299 Attrs.emplace_back(Index, Attribute::get(C, K));
1300 return get(C, Attrs);
1301}
1302
1305 if (Attrs.empty())
1306 return {};
1307 if (Attrs.size() == 1)
1308 return Attrs[0];
1309
1310 unsigned MaxSize = 0;
1311 for (const auto &List : Attrs)
1312 MaxSize = std::max(MaxSize, List.getNumAttrSets());
1313
1314 // If every list was empty, there is no point in merging the lists.
1315 if (MaxSize == 0)
1316 return {};
1317
1318 SmallVector<AttributeSet, 8> NewAttrSets(MaxSize);
1319 for (unsigned I = 0; I < MaxSize; ++I) {
1320 AttrBuilder CurBuilder(C);
1321 for (const auto &List : Attrs)
1322 CurBuilder.merge(AttrBuilder(C, List.getAttributes(I - 1)));
1323 NewAttrSets[I] = AttributeSet::get(C, CurBuilder);
1324 }
1325
1326 return getImpl(C, NewAttrSets);
1327}
1328
1331 Attribute::AttrKind Kind) const {
1333 if (Attrs.hasAttribute(Kind))
1334 return *this;
1335 // TODO: Insert at correct position and avoid sort.
1336 SmallVector<Attribute, 8> NewAttrs(Attrs.begin(), Attrs.end());
1337 NewAttrs.push_back(Attribute::get(C, Kind));
1338 return setAttributesAtIndex(C, Index, AttributeSet::get(C, NewAttrs));
1339}
1340
1342 StringRef Kind,
1343 StringRef Value) const {
1344 AttrBuilder B(C);
1345 B.addAttribute(Kind, Value);
1346 return addAttributesAtIndex(C, Index, B);
1347}
1348
1350 Attribute A) const {
1351 AttrBuilder B(C);
1352 B.addAttribute(A);
1353 return addAttributesAtIndex(C, Index, B);
1354}
1355
1356AttributeList AttributeList::setAttributesAtIndex(LLVMContext &C,
1357 unsigned Index,
1358 AttributeSet Attrs) const {
1360 SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
1361 if (Index >= AttrSets.size())
1362 AttrSets.resize(Index + 1);
1363 AttrSets[Index] = Attrs;
1364
1365 // Remove trailing empty attribute sets.
1366 while (!AttrSets.empty() && !AttrSets.back().hasAttributes())
1367 AttrSets.pop_back();
1368 if (AttrSets.empty())
1369 return {};
1370 return AttributeList::getImpl(C, AttrSets);
1371}
1372
1374 unsigned Index,
1375 const AttrBuilder &B) const {
1376 if (!B.hasAttributes())
1377 return *this;
1378
1379 if (!pImpl)
1381
1382 AttrBuilder Merged(C, getAttributes(Index));
1383 Merged.merge(B);
1384 return setAttributesAtIndex(C, Index, AttributeSet::get(C, Merged));
1385}
1386
1388 ArrayRef<unsigned> ArgNos,
1389 Attribute A) const {
1390 assert(llvm::is_sorted(ArgNos));
1391
1392 SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
1393 unsigned MaxIndex = attrIdxToArrayIdx(ArgNos.back() + FirstArgIndex);
1394 if (MaxIndex >= AttrSets.size())
1395 AttrSets.resize(MaxIndex + 1);
1396
1397 for (unsigned ArgNo : ArgNos) {
1398 unsigned Index = attrIdxToArrayIdx(ArgNo + FirstArgIndex);
1399 AttrBuilder B(C, AttrSets[Index]);
1400 B.addAttribute(A);
1401 AttrSets[Index] = AttributeSet::get(C, B);
1402 }
1403
1404 return getImpl(C, AttrSets);
1405}
1406
1409 Attribute::AttrKind Kind) const {
1411 AttributeSet NewAttrs = Attrs.removeAttribute(C, Kind);
1412 if (Attrs == NewAttrs)
1413 return *this;
1414 return setAttributesAtIndex(C, Index, NewAttrs);
1415}
1416
1418 unsigned Index,
1419 StringRef Kind) const {
1421 AttributeSet NewAttrs = Attrs.removeAttribute(C, Kind);
1422 if (Attrs == NewAttrs)
1423 return *this;
1424 return setAttributesAtIndex(C, Index, NewAttrs);
1425}
1426
1428 LLVMContext &C, unsigned Index, const AttributeMask &AttrsToRemove) const {
1430 AttributeSet NewAttrs = Attrs.removeAttributes(C, AttrsToRemove);
1431 // If nothing was removed, return the original list.
1432 if (Attrs == NewAttrs)
1433 return *this;
1434 return setAttributesAtIndex(C, Index, NewAttrs);
1435}
1436
1439 unsigned WithoutIndex) const {
1440 if (!pImpl)
1441 return {};
1442 if (attrIdxToArrayIdx(WithoutIndex) >= getNumAttrSets())
1443 return *this;
1444 return setAttributesAtIndex(C, WithoutIndex, AttributeSet());
1445}
1446
1448 uint64_t Bytes) const {
1449 AttrBuilder B(C);
1450 B.addDereferenceableAttr(Bytes);
1451 return addRetAttributes(C, B);
1452}
1453
1455 unsigned Index,
1456 uint64_t Bytes) const {
1457 AttrBuilder B(C);
1458 B.addDereferenceableAttr(Bytes);
1459 return addParamAttributes(C, Index, B);
1460}
1461
1464 uint64_t Bytes) const {
1465 AttrBuilder B(C);
1466 B.addDereferenceableOrNullAttr(Bytes);
1467 return addParamAttributes(C, Index, B);
1468}
1469
1471 LLVMContext &C, unsigned Index, unsigned ElemSizeArg,
1472 const std::optional<unsigned> &NumElemsArg) {
1473 AttrBuilder B(C);
1474 B.addAllocSizeAttr(ElemSizeArg, NumElemsArg);
1475 return addParamAttributes(C, Index, B);
1476}
1477
1478//===----------------------------------------------------------------------===//
1479// AttributeList Accessor Methods
1480//===----------------------------------------------------------------------===//
1481
1483 return getAttributes(ArgNo + FirstArgIndex);
1484}
1485
1487 return getAttributes(ReturnIndex);
1488}
1489
1492}
1493
1495 Attribute::AttrKind Kind) const {
1496 return getAttributes(Index).hasAttribute(Kind);
1497}
1498
1500 return getAttributes(Index).hasAttribute(Kind);
1501}
1502
1505}
1506
1508 return pImpl && pImpl->hasFnAttribute(Kind);
1509}
1510
1513}
1514
1516 unsigned *Index) const {
1517 return pImpl && pImpl->hasAttrSomewhere(Attr, Index);
1518}
1519
1521 Attribute::AttrKind Kind) const {
1522 return getAttributes(Index).getAttribute(Kind);
1523}
1524
1526 StringRef Kind) const {
1527 return getAttributes(Index).getAttribute(Kind);
1528}
1529
1532}
1533
1535 return getAttributes(ArgNo + FirstArgIndex).getAlignment();
1536}
1537
1540}
1541
1544}
1545
1548}
1549
1552}
1553
1556}
1557
1560}
1561
1564}
1565
1567 return getFnAttrs().getStackAlignment();
1568}
1569
1571 return getRetAttrs().getStackAlignment();
1572}
1573
1576}
1577
1580}
1581
1584}
1585
1589}
1590
1592 return getRetAttrs().getNoFPClass();
1593}
1594
1597}
1598
1600 return getFnAttrs().getUWTableKind();
1601}
1602
1604 return getFnAttrs().getAllocKind();
1605}
1606
1608 return getFnAttrs().getMemoryEffects();
1609}
1610
1611std::string AttributeList::getAsString(unsigned Index, bool InAttrGrp) const {
1612 return getAttributes(Index).getAsString(InAttrGrp);
1613}
1614
1617 if (!pImpl || Index >= getNumAttrSets())
1618 return {};
1619 return pImpl->begin()[Index];
1620}
1621
1623 assert(!isEmpty() && "an empty attribute list has no parent context");
1625 pImpl->Profile(ID);
1626 void *Unused;
1627 return C.pImpl->AttrsLists.FindNodeOrInsertPos(ID, Unused) == pImpl;
1628}
1629
1631 return pImpl ? pImpl->begin() : nullptr;
1632}
1633
1635 return pImpl ? pImpl->end() : nullptr;
1636}
1637
1638//===----------------------------------------------------------------------===//
1639// AttributeList Introspection Methods
1640//===----------------------------------------------------------------------===//
1641
1643 return pImpl ? pImpl->NumAttrSets : 0;
1644}
1645
1647 O << "AttributeList[\n";
1648
1649 for (unsigned i : indexes()) {
1650 if (!getAttributes(i).hasAttributes())
1651 continue;
1652 O << " { ";
1653 switch (i) {
1655 O << "return";
1656 break;
1658 O << "function";
1659 break;
1660 default:
1661 O << "arg(" << i - AttrIndex::FirstArgIndex << ")";
1662 }
1663 O << " => " << getAsString(i) << " }\n";
1664 }
1665
1666 O << "]\n";
1667}
1668
1669#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1671#endif
1672
1673//===----------------------------------------------------------------------===//
1674// AttrBuilder Method Implementations
1675//===----------------------------------------------------------------------===//
1676
1678 append_range(Attrs, AS);
1679 assert(is_sorted(Attrs) && "AttributeSet should be sorted");
1680}
1681
1682void AttrBuilder::clear() { Attrs.clear(); }
1683
1684/// Attribute comparator that only compares attribute keys. Enum attributes are
1685/// sorted before string attributes.
1687 bool operator()(Attribute A0, Attribute A1) const {
1688 bool A0IsString = A0.isStringAttribute();
1689 bool A1IsString = A1.isStringAttribute();
1690 if (A0IsString) {
1691 if (A1IsString)
1692 return A0.getKindAsString() < A1.getKindAsString();
1693 else
1694 return false;
1695 }
1696 if (A1IsString)
1697 return true;
1698 return A0.getKindAsEnum() < A1.getKindAsEnum();
1699 }
1701 if (A0.isStringAttribute())
1702 return false;
1703 return A0.getKindAsEnum() < Kind;
1704 }
1705 bool operator()(Attribute A0, StringRef Kind) const {
1706 if (A0.isStringAttribute())
1707 return A0.getKindAsString() < Kind;
1708 return true;
1709 }
1710};
1711
1712template <typename K>
1714 Attribute Attr) {
1715 auto It = lower_bound(Attrs, Kind, AttributeComparator());
1716 if (It != Attrs.end() && It->hasAttribute(Kind))
1717 std::swap(*It, Attr);
1718 else
1719 Attrs.insert(It, Attr);
1720}
1721
1723 if (Attr.isStringAttribute())
1724 addAttributeImpl(Attrs, Attr.getKindAsString(), Attr);
1725 else
1726 addAttributeImpl(Attrs, Attr.getKindAsEnum(), Attr);
1727 return *this;
1728}
1729
1731 addAttributeImpl(Attrs, Kind, Attribute::get(Ctx, Kind));
1732 return *this;
1733}
1734
1736 addAttributeImpl(Attrs, A, Attribute::get(Ctx, A, V));
1737 return *this;
1738}
1739
1741 assert((unsigned)Val < Attribute::EndAttrKinds && "Attribute out of range!");
1742 auto It = lower_bound(Attrs, Val, AttributeComparator());
1743 if (It != Attrs.end() && It->hasAttribute(Val))
1744 Attrs.erase(It);
1745 return *this;
1746}
1747
1749 auto It = lower_bound(Attrs, A, AttributeComparator());
1750 if (It != Attrs.end() && It->hasAttribute(A))
1751 Attrs.erase(It);
1752 return *this;
1753}
1754
1755std::optional<uint64_t>
1757 assert(Attribute::isIntAttrKind(Kind) && "Not an int attribute");
1758 Attribute A = getAttribute(Kind);
1759 if (A.isValid())
1760 return A.getValueAsInt();
1761 return std::nullopt;
1762}
1763
1765 uint64_t Value) {
1766 return addAttribute(Attribute::get(Ctx, Kind, Value));
1767}
1768
1769std::optional<std::pair<unsigned, std::optional<unsigned>>>
1771 Attribute A = getAttribute(Attribute::AllocSize);
1772 if (A.isValid())
1773 return A.getAllocSizeArgs();
1774 return std::nullopt;
1775}
1776
1778 if (!Align)
1779 return *this;
1780
1781 assert(*Align <= llvm::Value::MaximumAlignment && "Alignment too large.");
1782 return addRawIntAttr(Attribute::Alignment, Align->value());
1783}
1784
1786 // Default alignment, allow the target to define how to align it.
1787 if (!Align)
1788 return *this;
1789
1790 assert(*Align <= 0x100 && "Alignment too large.");
1791 return addRawIntAttr(Attribute::StackAlignment, Align->value());
1792}
1793
1795 if (Bytes == 0) return *this;
1796
1797 return addRawIntAttr(Attribute::Dereferenceable, Bytes);
1798}
1799
1801 if (Bytes == 0)
1802 return *this;
1803
1804 return addRawIntAttr(Attribute::DereferenceableOrNull, Bytes);
1805}
1806
1809 const std::optional<unsigned> &NumElems) {
1810 return addAllocSizeAttrFromRawRepr(packAllocSizeArgs(ElemSize, NumElems));
1811}
1812
1814 // (0, 0) is our "not present" value, so we need to check for it here.
1815 assert(RawArgs && "Invalid allocsize arguments -- given allocsize(0, 0)");
1816 return addRawIntAttr(Attribute::AllocSize, RawArgs);
1817}
1818
1820 std::optional<unsigned> MaxValue) {
1821 return addVScaleRangeAttrFromRawRepr(packVScaleRangeArgs(MinValue, MaxValue));
1822}
1823
1825 // (0, 0) is not present hence ignore this case
1826 if (RawArgs == 0)
1827 return *this;
1828
1829 return addRawIntAttr(Attribute::VScaleRange, RawArgs);
1830}
1831
1833 if (Kind == UWTableKind::None)
1834 return *this;
1835 return addRawIntAttr(Attribute::UWTable, uint64_t(Kind));
1836}
1837
1839 return addRawIntAttr(Attribute::Memory, ME.toIntValue());
1840}
1841
1843 if (Mask == fcNone)
1844 return *this;
1845
1846 return addRawIntAttr(Attribute::NoFPClass, Mask);
1847}
1848
1850 return addRawIntAttr(Attribute::AllocKind, static_cast<uint64_t>(Kind));
1851}
1852
1854 assert(Attribute::isTypeAttrKind(Kind) && "Not a type attribute");
1855 Attribute A = getAttribute(Kind);
1856 return A.isValid() ? A.getValueAsType() : nullptr;
1857}
1858
1860 return addAttribute(Attribute::get(Ctx, Kind, Ty));
1861}
1862
1864 return addTypeAttr(Attribute::ByVal, Ty);
1865}
1866
1868 return addTypeAttr(Attribute::StructRet, Ty);
1869}
1870
1872 return addTypeAttr(Attribute::ByRef, Ty);
1873}
1874
1876 return addTypeAttr(Attribute::Preallocated, Ty);
1877}
1878
1880 return addTypeAttr(Attribute::InAlloca, Ty);
1881}
1882
1884 // TODO: Could make this O(n) as we're merging two sorted lists.
1885 for (const auto &I : B.attrs())
1886 addAttribute(I);
1887
1888 return *this;
1889}
1890
1892 erase_if(Attrs, [&](Attribute A) { return AM.contains(A); });
1893 return *this;
1894}
1895
1897 return any_of(Attrs, [&](Attribute A) { return AM.contains(A); });
1898}
1899
1901 assert((unsigned)A < Attribute::EndAttrKinds && "Attribute out of range!");
1902 auto It = lower_bound(Attrs, A, AttributeComparator());
1903 if (It != Attrs.end() && It->hasAttribute(A))
1904 return *It;
1905 return {};
1906}
1907
1909 auto It = lower_bound(Attrs, A, AttributeComparator());
1910 if (It != Attrs.end() && It->hasAttribute(A))
1911 return *It;
1912 return {};
1913}
1914
1916 return getAttribute(A).isValid();
1917}
1918
1920 return getAttribute(A).isValid();
1921}
1922
1924 return Attrs == B.Attrs;
1925}
1926
1927//===----------------------------------------------------------------------===//
1928// AttributeFuncs Function Defintions
1929//===----------------------------------------------------------------------===//
1930
1931/// Returns true if this is a type legal for the 'nofpclass' attribute. This
1932/// follows the same type rules as FPMathOperator.
1933///
1934/// TODO: Consider relaxing to any FP type struct fields.
1936 while (ArrayType *ArrTy = dyn_cast<ArrayType>(Ty))
1937 Ty = ArrTy->getElementType();
1938 return Ty->isFPOrFPVectorTy();
1939}
1940
1941/// Which attributes cannot be applied to a type.
1943 AttributeSafetyKind ASK) {
1944 AttributeMask Incompatible;
1945
1946 if (!Ty->isIntegerTy()) {
1947 // Attributes that only apply to integers.
1948 if (ASK & ASK_SAFE_TO_DROP)
1949 Incompatible.addAttribute(Attribute::AllocAlign);
1950 if (ASK & ASK_UNSAFE_TO_DROP)
1951 Incompatible.addAttribute(Attribute::SExt).addAttribute(Attribute::ZExt);
1952 }
1953
1954 if (!Ty->isPointerTy()) {
1955 // Attributes that only apply to pointers.
1956 if (ASK & ASK_SAFE_TO_DROP)
1957 Incompatible.addAttribute(Attribute::NoAlias)
1958 .addAttribute(Attribute::NoCapture)
1959 .addAttribute(Attribute::NonNull)
1960 .addAttribute(Attribute::ReadNone)
1961 .addAttribute(Attribute::ReadOnly)
1962 .addAttribute(Attribute::Dereferenceable)
1963 .addAttribute(Attribute::DereferenceableOrNull);
1964 if (ASK & ASK_UNSAFE_TO_DROP)
1965 Incompatible.addAttribute(Attribute::Nest)
1966 .addAttribute(Attribute::SwiftError)
1967 .addAttribute(Attribute::Preallocated)
1968 .addAttribute(Attribute::InAlloca)
1969 .addAttribute(Attribute::ByVal)
1970 .addAttribute(Attribute::StructRet)
1971 .addAttribute(Attribute::ByRef)
1972 .addAttribute(Attribute::ElementType)
1973 .addAttribute(Attribute::AllocatedPointer);
1974 }
1975
1976 // Attributes that only apply to pointers or vectors of pointers.
1977 if (!Ty->isPtrOrPtrVectorTy()) {
1978 if (ASK & ASK_SAFE_TO_DROP)
1979 Incompatible.addAttribute(Attribute::Alignment);
1980 }
1981
1982 if (ASK & ASK_SAFE_TO_DROP) {
1984 Incompatible.addAttribute(Attribute::NoFPClass);
1985 }
1986
1987 // Some attributes can apply to all "values" but there are no `void` values.
1988 if (Ty->isVoidTy()) {
1989 if (ASK & ASK_SAFE_TO_DROP)
1990 Incompatible.addAttribute(Attribute::NoUndef);
1991 }
1992
1993 return Incompatible;
1994}
1995
1997 AttributeMask AM;
1998 AM.addAttribute(Attribute::NoUndef);
1999 AM.addAttribute(Attribute::Dereferenceable);
2000 AM.addAttribute(Attribute::DereferenceableOrNull);
2001 return AM;
2002}
2003
2004/// Callees with dynamic denormal modes are compatible with any caller mode.
2005static bool denormModeCompatible(DenormalMode CallerMode,
2006 DenormalMode CalleeMode) {
2007 if (CallerMode == CalleeMode || CalleeMode == DenormalMode::getDynamic())
2008 return true;
2009
2010 // If they don't exactly match, it's OK if the mismatched component is
2011 // dynamic.
2012 if (CalleeMode.Input == CallerMode.Input &&
2013 CalleeMode.Output == DenormalMode::Dynamic)
2014 return true;
2015
2016 if (CalleeMode.Output == CallerMode.Output &&
2017 CalleeMode.Input == DenormalMode::Dynamic)
2018 return true;
2019 return false;
2020}
2021
2022static bool checkDenormMode(const Function &Caller, const Function &Callee) {
2023 DenormalMode CallerMode = Caller.getDenormalModeRaw();
2024 DenormalMode CalleeMode = Callee.getDenormalModeRaw();
2025
2026 if (denormModeCompatible(CallerMode, CalleeMode)) {
2027 DenormalMode CallerModeF32 = Caller.getDenormalModeF32Raw();
2028 DenormalMode CalleeModeF32 = Callee.getDenormalModeF32Raw();
2029 return denormModeCompatible(CallerModeF32, CalleeModeF32);
2030 }
2031
2032 return false;
2033}
2034
2035template<typename AttrClass>
2036static bool isEqual(const Function &Caller, const Function &Callee) {
2037 return Caller.getFnAttribute(AttrClass::getKind()) ==
2038 Callee.getFnAttribute(AttrClass::getKind());
2039}
2040
2041/// Compute the logical AND of the attributes of the caller and the
2042/// callee.
2043///
2044/// This function sets the caller's attribute to false if the callee's attribute
2045/// is false.
2046template<typename AttrClass>
2047static void setAND(Function &Caller, const Function &Callee) {
2048 if (AttrClass::isSet(Caller, AttrClass::getKind()) &&
2049 !AttrClass::isSet(Callee, AttrClass::getKind()))
2050 AttrClass::set(Caller, AttrClass::getKind(), false);
2051}
2052
2053/// Compute the logical OR of the attributes of the caller and the
2054/// callee.
2055///
2056/// This function sets the caller's attribute to true if the callee's attribute
2057/// is true.
2058template<typename AttrClass>
2059static void setOR(Function &Caller, const Function &Callee) {
2060 if (!AttrClass::isSet(Caller, AttrClass::getKind()) &&
2061 AttrClass::isSet(Callee, AttrClass::getKind()))
2062 AttrClass::set(Caller, AttrClass::getKind(), true);
2063}
2064
2065/// If the inlined function had a higher stack protection level than the
2066/// calling function, then bump up the caller's stack protection level.
2067static void adjustCallerSSPLevel(Function &Caller, const Function &Callee) {
2068 // If the calling function has *no* stack protection level (e.g. it was built
2069 // with Clang's -fno-stack-protector or no_stack_protector attribute), don't
2070 // change it as that could change the program's semantics.
2071 if (!Caller.hasStackProtectorFnAttr())
2072 return;
2073
2074 // If upgrading the SSP attribute, clear out the old SSP Attributes first.
2075 // Having multiple SSP attributes doesn't actually hurt, but it adds useless
2076 // clutter to the IR.
2077 AttributeMask OldSSPAttr;
2078 OldSSPAttr.addAttribute(Attribute::StackProtect)
2079 .addAttribute(Attribute::StackProtectStrong)
2080 .addAttribute(Attribute::StackProtectReq);
2081
2082 if (Callee.hasFnAttribute(Attribute::StackProtectReq)) {
2083 Caller.removeFnAttrs(OldSSPAttr);
2084 Caller.addFnAttr(Attribute::StackProtectReq);
2085 } else if (Callee.hasFnAttribute(Attribute::StackProtectStrong) &&
2086 !Caller.hasFnAttribute(Attribute::StackProtectReq)) {
2087 Caller.removeFnAttrs(OldSSPAttr);
2088 Caller.addFnAttr(Attribute::StackProtectStrong);
2089 } else if (Callee.hasFnAttribute(Attribute::StackProtect) &&
2090 !Caller.hasFnAttribute(Attribute::StackProtectReq) &&
2091 !Caller.hasFnAttribute(Attribute::StackProtectStrong))
2092 Caller.addFnAttr(Attribute::StackProtect);
2093}
2094
2095/// If the inlined function required stack probes, then ensure that
2096/// the calling function has those too.
2097static void adjustCallerStackProbes(Function &Caller, const Function &Callee) {
2098 if (!Caller.hasFnAttribute("probe-stack") &&
2099 Callee.hasFnAttribute("probe-stack")) {
2100 Caller.addFnAttr(Callee.getFnAttribute("probe-stack"));
2101 }
2102}
2103
2104/// If the inlined function defines the size of guard region
2105/// on the stack, then ensure that the calling function defines a guard region
2106/// that is no larger.
2107static void
2109 Attribute CalleeAttr = Callee.getFnAttribute("stack-probe-size");
2110 if (CalleeAttr.isValid()) {
2111 Attribute CallerAttr = Caller.getFnAttribute("stack-probe-size");
2112 if (CallerAttr.isValid()) {
2113 uint64_t CallerStackProbeSize, CalleeStackProbeSize;
2114 CallerAttr.getValueAsString().getAsInteger(0, CallerStackProbeSize);
2115 CalleeAttr.getValueAsString().getAsInteger(0, CalleeStackProbeSize);
2116
2117 if (CallerStackProbeSize > CalleeStackProbeSize) {
2118 Caller.addFnAttr(CalleeAttr);
2119 }
2120 } else {
2121 Caller.addFnAttr(CalleeAttr);
2122 }
2123 }
2124}
2125
2126/// If the inlined function defines a min legal vector width, then ensure
2127/// the calling function has the same or larger min legal vector width. If the
2128/// caller has the attribute, but the callee doesn't, we need to remove the
2129/// attribute from the caller since we can't make any guarantees about the
2130/// caller's requirements.
2131/// This function is called after the inlining decision has been made so we have
2132/// to merge the attribute this way. Heuristics that would use
2133/// min-legal-vector-width to determine inline compatibility would need to be
2134/// handled as part of inline cost analysis.
2135static void
2137 Attribute CallerAttr = Caller.getFnAttribute("min-legal-vector-width");
2138 if (CallerAttr.isValid()) {
2139 Attribute CalleeAttr = Callee.getFnAttribute("min-legal-vector-width");
2140 if (CalleeAttr.isValid()) {
2141 uint64_t CallerVectorWidth, CalleeVectorWidth;
2142 CallerAttr.getValueAsString().getAsInteger(0, CallerVectorWidth);
2143 CalleeAttr.getValueAsString().getAsInteger(0, CalleeVectorWidth);
2144 if (CallerVectorWidth < CalleeVectorWidth)
2145 Caller.addFnAttr(CalleeAttr);
2146 } else {
2147 // If the callee doesn't have the attribute then we don't know anything
2148 // and must drop the attribute from the caller.
2149 Caller.removeFnAttr("min-legal-vector-width");
2150 }
2151 }
2152}
2153
2154/// If the inlined function has null_pointer_is_valid attribute,
2155/// set this attribute in the caller post inlining.
2156static void
2158 if (Callee.nullPointerIsDefined() && !Caller.nullPointerIsDefined()) {
2159 Caller.addFnAttr(Attribute::NullPointerIsValid);
2160 }
2161}
2162
2163struct EnumAttr {
2164 static bool isSet(const Function &Fn,
2165 Attribute::AttrKind Kind) {
2166 return Fn.hasFnAttribute(Kind);
2167 }
2168
2169 static void set(Function &Fn,
2170 Attribute::AttrKind Kind, bool Val) {
2171 if (Val)
2172 Fn.addFnAttr(Kind);
2173 else
2174 Fn.removeFnAttr(Kind);
2175 }
2176};
2177
2179 static bool isSet(const Function &Fn,
2180 StringRef Kind) {
2181 auto A = Fn.getFnAttribute(Kind);
2182 return A.getValueAsString().equals("true");
2183 }
2184
2185 static void set(Function &Fn,
2186 StringRef Kind, bool Val) {
2187 Fn.addFnAttr(Kind, Val ? "true" : "false");
2188 }
2189};
2190
2191#define GET_ATTR_NAMES
2192#define ATTRIBUTE_ENUM(ENUM_NAME, DISPLAY_NAME) \
2193 struct ENUM_NAME##Attr : EnumAttr { \
2194 static enum Attribute::AttrKind getKind() { \
2195 return llvm::Attribute::ENUM_NAME; \
2196 } \
2197 };
2198#define ATTRIBUTE_STRBOOL(ENUM_NAME, DISPLAY_NAME) \
2199 struct ENUM_NAME##Attr : StrBoolAttr { \
2200 static StringRef getKind() { return #DISPLAY_NAME; } \
2201 };
2202#include "llvm/IR/Attributes.inc"
2203
2204#define GET_ATTR_COMPAT_FUNC
2205#include "llvm/IR/Attributes.inc"
2206
2208 const Function &Callee) {
2209 return hasCompatibleFnAttrs(Caller, Callee);
2210}
2211
2213 const Function &B) {
2214 return hasCompatibleFnAttrs(A, B);
2215}
2216
2218 const Function &Callee) {
2219 mergeFnAttrs(Caller, Callee);
2220}
2221
2223 const Function &ToMerge) {
2224
2225 // We merge functions so that they meet the most general case.
2226 // For example, if the NoNansFPMathAttr is set in one function, but not in
2227 // the other, in the merged function we can say that the NoNansFPMathAttr
2228 // is not set.
2229 // However if we have the SpeculativeLoadHardeningAttr set true in one
2230 // function, but not the other, we make sure that the function retains
2231 // that aspect in the merged function.
2232 mergeFnAttrs(Base, ToMerge);
2233}
2234
2236 uint64_t Width) {
2237 Attribute Attr = Fn.getFnAttribute("min-legal-vector-width");
2238 if (Attr.isValid()) {
2239 uint64_t OldWidth;
2240 Attr.getValueAsString().getAsInteger(0, OldWidth);
2241 if (Width > OldWidth)
2242 Fn.addFnAttr("min-legal-vector-width", llvm::utostr(Width));
2243 }
2244}
amdgpu Simplify well known AMD library false FunctionCallee Callee
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:83
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:610
@ RetAttr
Definition: Attributes.cpp:613
@ ParamAttr
Definition: Attributes.cpp:612
@ FnAttr
Definition: Attributes.cpp:611
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 uint64_t packAllocSizeArgs(unsigned ElemSizeArg, const std::optional< unsigned > &NumElemsArg)
Definition: Attributes.cpp:57
static uint64_t packVScaleRangeArgs(unsigned MinValue, std::optional< unsigned > MaxValue)
Definition: Attributes.cpp:77
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:55
static std::pair< unsigned, std::optional< unsigned > > unpackAllocSizeArgs(uint64_t Num)
Definition: Attributes.cpp:67
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:619
static const char * getModRefStr(ModRefInfo MR)
Definition: Attributes.cpp:410
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:492
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
@ VI
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:172
ArrayRef< T > take_front(size_t N=1) const
Return a copy of *this with only the first N elements.
Definition: ArrayRef.h:226
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:163
iterator begin() const
Definition: ArrayRef.h:151
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:158
Class to represent array types.
Definition: DerivedTypes.h:368
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:1057
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:642
void Profile(FoldingSetNodeID &ID) const
Definition: AttributeImpl.h:78
Type * getValueAsType() const
Definition: Attributes.cpp:677
Attribute::AttrKind getKindAsEnum() const
Definition: Attributes.cpp:652
bool operator<(const AttributeImpl &AI) const
Used when sorting the attributes.
Definition: Attributes.cpp:682
uint64_t getValueAsInt() const
Definition: Attributes.cpp:657
bool isIntAttribute() const
Definition: AttributeImpl.h:59
bool isTypeAttribute() const
Definition: AttributeImpl.h:61
bool getValueAsBool() const
Definition: Attributes.cpp:662
StringRef getKindAsString() const
Definition: Attributes.cpp:667
StringRef getValueAsString() const
Definition: Attributes.cpp:672
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:448
AttributeSet getFnAttrs() const
The function attributes are returned.
index_iterator indexes() const
Use this to iterate over the valid attribute indexes.
Definition: Attributes.h:942
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:449
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:568
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:954
AttributeSet getRetAttrs() const
The attributes for the ret value are returned.
friend class AttrBuilder
Definition: Attributes.h:447
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:910
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:597
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:576
MemoryEffects getMemoryEffects() const
Returns memory effects of the function.
AttributeMask & addAttribute(Attribute::AttrKind Val)
Add an attribute to the mask.
Definition: Attributes.h:1006
bool contains(Attribute::AttrKind A) const
Return true if the builder has the specified attribute.
Definition: Attributes.h:1029
MaybeAlign getStackAlignment() const
Definition: Attributes.cpp:988
uint64_t getDereferenceableOrNullBytes() const
std::optional< unsigned > getVScaleRangeMax() const
bool hasAttribute(Attribute::AttrKind Kind) const
Type * getAttributeType(Attribute::AttrKind Kind) const
Definition: Attributes.cpp:994
AllocFnKind getAllocKind() const
unsigned getVScaleRangeMin() const
MaybeAlign getAlignment() const
Definition: Attributes.cpp:982
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:947
FPClassTest getNoFPClass() const
Attribute getAttribute(Attribute::AttrKind Kind) const
Definition: Attributes.cpp:972
AllocFnKind getAllocKind() const
Definition: Attributes.cpp:853
bool hasAttributes() const
Return true if attributes exists in this set.
Definition: Attributes.h:360
AttributeSet removeAttribute(LLVMContext &C, Attribute::AttrKind Kind) const
Remove the specified attribute from this set.
Definition: Attributes.cpp:747
Type * getInAllocaType() const
Definition: Attributes.cpp:826
Type * getByValType() const
Definition: Attributes.cpp:814
AttributeSet addAttributes(LLVMContext &C, AttributeSet AS) const
Add attributes to the attribute set.
Definition: Attributes.cpp:734
MemoryEffects getMemoryEffects() const
Definition: Attributes.cpp:857
bool hasAttribute(Attribute::AttrKind Kind) const
Return true if the attribute exists in this set.
Definition: Attributes.cpp:778
Type * getStructRetType() const
Definition: Attributes.cpp:818
std::string getAsString(bool InAttrGrp=false) const
Definition: Attributes.cpp:865
unsigned getVScaleRangeMin() const
Definition: Attributes.cpp:841
std::optional< std::pair< unsigned, std::optional< unsigned > > > getAllocSizeArgs() const
Definition: Attributes.cpp:835
UWTableKind getUWTableKind() const
Definition: Attributes.cpp:849
bool hasParentContext(LLVMContext &C) const
Return true if this attribute set belongs to the LLVMContext.
Definition: Attributes.cpp:869
iterator begin() const
Definition: Attributes.cpp:877
iterator end() const
Definition: Attributes.cpp:881
AttributeSet removeAttributes(LLVMContext &C, const AttributeMask &AttrsToRemove) const
Remove the specified attributes from this set.
Definition: Attributes.cpp:763
std::optional< unsigned > getVScaleRangeMax() const
Definition: Attributes.cpp:845
MaybeAlign getStackAlignment() const
Definition: Attributes.cpp:798
Attribute getAttribute(Attribute::AttrKind Kind) const
Return the attribute object.
Definition: Attributes.cpp:786
Type * getPreallocatedType() const
Definition: Attributes.cpp:822
uint64_t getDereferenceableBytes() const
Definition: Attributes.cpp:802
MaybeAlign getAlignment() const
Definition: Attributes.cpp:794
FPClassTest getNoFPClass() const
Definition: Attributes.cpp:861
Type * getElementType() const
Definition: Attributes.cpp:830
Type * getByRefType() const
Definition: Attributes.cpp:810
AttributeSet()=default
AttributeSet is a trivially copyable value type.
static AttributeSet get(LLVMContext &C, const AttrBuilder &B)
Definition: Attributes.cpp:711
uint64_t getDereferenceableOrNullBytes() const
Definition: Attributes.cpp:806
unsigned getNumAttributes() const
Return the number of attributes in this set.
Definition: Attributes.cpp:774
AttributeSet addAttribute(LLVMContext &C, Attribute::AttrKind Kind) const
Add an argument attribute.
Definition: Attributes.cpp:719
void dump() const
Definition: Attributes.cpp:886
bool isStringAttribute() const
Return true if the attribute is a string (target-dependent) attribute.
Definition: Attributes.cpp:281
static Attribute getWithStructRetType(LLVMContext &Context, Type *Ty)
Definition: Attributes.cpp:193
static Attribute::AttrKind getAttrKindFromName(StringRef AttrName)
Definition: Attributes.cpp:238
bool isEnumAttribute() const
Return true if the attribute is an Attribute::AttrKind type.
Definition: Attributes.cpp:273
static Attribute getWithStackAlignment(LLVMContext &Context, Align Alignment)
Definition: Attributes.cpp:172
bool isIntAttribute() const
Return true if the attribute is an integer attribute.
Definition: Attributes.cpp:277
static Attribute getWithByRefType(LLVMContext &Context, Type *Ty)
Definition: Attributes.cpp:197
std::optional< unsigned > getVScaleRangeMax() const
Returns the maximum value for the vscale_range attribute or std::nullopt when unknown.
Definition: Attributes.cpp:380
uint64_t getValueAsInt() const
Return the attribute's value as an integer.
Definition: Attributes.cpp:296
unsigned getVScaleRangeMin() const
Returns the minimum value for the vscale_range attribute.
Definition: Attributes.cpp:374
AllocFnKind getAllocKind() const
Definition: Attributes.cpp:392
StringRef getKindAsString() const
Return the attribute's kind as a string.
Definition: Attributes.cpp:310
static Attribute getWithPreallocatedType(LLVMContext &Context, Type *Ty)
Definition: Attributes.cpp:201
static Attribute get(LLVMContext &Context, AttrKind Kind, uint64_t Val=0)
Return a uniquified Attribute object.
Definition: Attributes.cpp:91
static bool canUseAsRetAttr(AttrKind Kind)
Definition: Attributes.cpp:634
static bool isTypeAttrKind(AttrKind Kind)
Definition: Attributes.h:106
std::string getAsString(bool InAttrGrp=false) const
The Attribute is converted to a string of equivalent mnemonic.
Definition: Attributes.cpp:424
uint64_t getDereferenceableOrNullBytes() const
Returns the number of dereferenceable_or_null bytes from the dereferenceable_or_null attribute.
Definition: Attributes.cpp:360
static Attribute getWithDereferenceableBytes(LLVMContext &Context, uint64_t Bytes)
Definition: Attributes.cpp:177
std::pair< unsigned, std::optional< unsigned > > getAllocSizeArgs() const
Returns the argument numbers for the allocsize attribute.
Definition: Attributes.cpp:368
static Attribute getWithUWTableKind(LLVMContext &Context, UWTableKind Kind)
Definition: Attributes.cpp:209
FPClassTest getNoFPClass() const
Return the FPClassTest for nofpclass.
Definition: Attributes.cpp:404
static Attribute getWithAllocSizeArgs(LLVMContext &Context, unsigned ElemSizeArg, const std::optional< unsigned > &NumElemsArg)
Definition: Attributes.cpp:225
Attribute::AttrKind getKindAsEnum() const
Return the attribute's kind as an enum (Attribute::AttrKind).
Definition: Attributes.cpp:289
Attribute()=default
bool getValueAsBool() const
Return the attribute's value as a boolean.
Definition: Attributes.cpp:303
uint64_t getDereferenceableBytes() const
Returns the number of dereferenceable bytes from the dereferenceable attribute.
Definition: Attributes.cpp:353
static Attribute getWithVScaleRangeArgs(LLVMContext &Context, unsigned MinValue, unsigned MaxValue)
Definition: Attributes.cpp:232
MemoryEffects getMemoryEffects() const
Returns memory effects.
Definition: Attributes.cpp:398
void Profile(FoldingSetNodeID &ID) const
Definition: Attributes.cpp:606
UWTableKind getUWTableKind() const
Definition: Attributes.cpp:386
static Attribute getWithDereferenceableOrNullBytes(LLVMContext &Context, uint64_t Bytes)
Definition: Attributes.cpp:183
StringRef getValueAsString() const
Return the attribute's value as a string.
Definition: Attributes.cpp:317
static bool isExistingAttribute(StringRef Name)
Return true if the provided string matches the IR name of an attribute.
Definition: Attributes.cpp:261
static StringRef getNameFromAttrKind(Attribute::AttrKind AttrKind)
Definition: Attributes.cpp:247
static bool canUseAsFnAttr(AttrKind Kind)
Definition: Attributes.cpp:626
static Attribute getWithNoFPClass(LLVMContext &Context, FPClassTest Mask)
Definition: Attributes.cpp:219
AttrKind
This enumeration lists the attributes that can be associated with parameters, function results,...
Definition: Attributes.h:87
@ None
No attributes have been set.
Definition: Attributes.h:89
@ EndAttrKinds
Sentinal value useful for loops.
Definition: Attributes.h:92
bool hasParentContext(LLVMContext &C) const
Return true if this attribute belongs to the LLVMContext.
Definition: Attributes.cpp:591
bool isTypeAttribute() const
Return true if the attribute is a type attribute.
Definition: Attributes.cpp:285
static Attribute getWithInAllocaType(LLVMContext &Context, Type *Ty)
Definition: Attributes.cpp:205
static bool isIntAttrKind(AttrKind Kind)
Definition: Attributes.h:103
static Attribute getWithByValType(LLVMContext &Context, Type *Ty)
Definition: Attributes.cpp:189
bool hasAttribute(AttrKind Val) const
Return true if the attribute is present.
Definition: Attributes.cpp:332
static bool isEnumAttrKind(AttrKind Kind)
Definition: Attributes.h:100
static Attribute getWithMemoryEffects(LLVMContext &Context, MemoryEffects ME)
Definition: Attributes.cpp:214
static bool canUseAsParamAttr(AttrKind Kind)
Definition: Attributes.cpp:630
bool isValid() const
Return true if the attribute is any kind of attribute.
Definition: Attributes.h:187
MaybeAlign getStackAlignment() const
Returns the stack alignment field of an attribute as a byte alignment value.
Definition: Attributes.cpp:347
MaybeAlign getAlignment() const
Returns the alignment field of an attribute as a byte alignment value.
Definition: Attributes.cpp:341
bool operator<(Attribute A) const
Less-than operator. Useful for sorting the attributes list.
Definition: Attributes.cpp:599
static Attribute getWithAlignment(LLVMContext &Context, Align Alignment)
Return a uniquified Attribute object that has the specific alignment set.
Definition: Attributes.cpp:167
Type * getValueAsType() const
Return the attribute's value as a Type.
Definition: Attributes.cpp:324
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:318
void addFnAttr(Attribute::AttrKind Kind)
Add function attributes to this function.
Definition: Function.cpp:554
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
Definition: Function.cpp:670
void removeFnAttr(Attribute::AttrKind Kind)
Remove function attributes from this function.
Definition: Function.cpp:602
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition: Function.cpp:644
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
Summary of how a function affects memory in the program.
Definition: ModRef.h:63
static MemoryEffects createFromIntValue(uint32_t Data)
Create MemoryEffects from an encoded integer value (used by memory attribute).
Definition: ModRef.h:153
@ ArgMem
Access to memory via argument pointers.
Definition: ModRef.h:68
@ Other
Any other memory.
Definition: ModRef.h:72
@ InaccessibleMem
Memory that is inaccessible via LLVM IR.
Definition: ModRef.h:70
ModRefInfo getModRef(Location Loc) const
Get ModRefInfo for the given Location.
Definition: ModRef.h:164
uint32_t toIntValue() const
Convert MemoryEffects into an encoded integer value (used by memory attribute).
Definition: ModRef.h:159
static auto locations()
Returns iterator over all supported location kinds.
Definition: ModRef.h:96
static MemoryEffects unknown()
Create MemoryEffects that can read and write any memory.
Definition: ModRef.h:113
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:577
reference emplace_back(ArgTypes &&... Args)
Definition: SmallVector.h:941
void reserve(size_type N)
Definition: SmallVector.h:667
void resize(size_type N)
Definition: SmallVector.h:642
void push_back(const T &Elt)
Definition: SmallVector.h:416
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1200
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:468
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:256
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:229
bool isFPOrFPVectorTy() const
Return true if this is a FP type or a vector of FP.
Definition: Type.h:217
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:795
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:642
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:1819
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:1777
AllocFnKind
Definition: Attributes.h:50
void append_range(Container &C, Range &&R)
Wrapper function to append a range to a container.
Definition: STLExtras.h:2129
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:1826
UWTableKind
Definition: CodeGen.h:121
@ None
No unwind table requested.
@ Sync
"Synchronous" unwind tables
void sort(IteratorTy Start, IteratorTy End)
Definition: STLExtras.h:1744
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:1833
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:1999
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.
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:2038
OutputIt copy(R &&Range, OutputIt Out)
Definition: STLExtras.h:1921
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:2113
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.
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:1537