LLVM 22.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"
29#include "llvm/IR/Function.h"
30#include "llvm/IR/LLVMContext.h"
31#include "llvm/IR/Operator.h"
32#include "llvm/IR/Type.h"
35#include "llvm/Support/ModRef.h"
37#include <algorithm>
38#include <cassert>
39#include <cstddef>
40#include <cstdint>
41#include <limits>
42#include <optional>
43#include <string>
44#include <tuple>
45#include <utility>
46
47using namespace llvm;
48
49//===----------------------------------------------------------------------===//
50// Attribute Construction Methods
51//===----------------------------------------------------------------------===//
52
53// allocsize has two integer arguments, but because they're both 32 bits, we can
54// pack them into one 64-bit value, at the cost of making said value
55// nonsensical.
56//
57// In order to do this, we need to reserve one value of the second (optional)
58// allocsize argument to signify "not present."
59static const unsigned AllocSizeNumElemsNotPresent = -1;
60
61static uint64_t packAllocSizeArgs(unsigned ElemSizeArg,
62 const std::optional<unsigned> &NumElemsArg) {
63 assert((!NumElemsArg || *NumElemsArg != AllocSizeNumElemsNotPresent) &&
64 "Attempting to pack a reserved value");
65
66 return uint64_t(ElemSizeArg) << 32 |
67 NumElemsArg.value_or(AllocSizeNumElemsNotPresent);
68}
69
70static std::pair<unsigned, std::optional<unsigned>>
72 unsigned NumElems = Num & std::numeric_limits<unsigned>::max();
73 unsigned ElemSizeArg = Num >> 32;
74
75 std::optional<unsigned> NumElemsArg;
76 if (NumElems != AllocSizeNumElemsNotPresent)
77 NumElemsArg = NumElems;
78 return std::make_pair(ElemSizeArg, NumElemsArg);
79}
80
81static uint64_t packVScaleRangeArgs(unsigned MinValue,
82 std::optional<unsigned> MaxValue) {
83 return uint64_t(MinValue) << 32 | MaxValue.value_or(0);
84}
85
86static std::pair<unsigned, std::optional<unsigned>>
88 unsigned MaxValue = Value & std::numeric_limits<unsigned>::max();
89 unsigned MinValue = Value >> 32;
90
91 return std::make_pair(MinValue,
92 MaxValue > 0 ? MaxValue : std::optional<unsigned>());
93}
94
96 uint64_t Val) {
97 bool IsIntAttr = Attribute::isIntAttrKind(Kind);
98 assert((IsIntAttr || Attribute::isEnumAttrKind(Kind)) &&
99 "Not an enum or int attribute");
100
101 LLVMContextImpl *pImpl = Context.pImpl;
103 ID.AddInteger(Kind);
104 if (IsIntAttr)
105 ID.AddInteger(Val);
106 else
107 assert(Val == 0 && "Value must be zero for enum attributes");
108
109 void *InsertPoint;
110 AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);
111
112 if (!PA) {
113 // If we didn't find any existing attributes of the same shape then create a
114 // new one and insert it.
115 if (!IsIntAttr)
116 PA = new (pImpl->Alloc) EnumAttributeImpl(Kind);
117 else
118 PA = new (pImpl->Alloc) IntAttributeImpl(Kind, Val);
119 pImpl->AttrsSet.InsertNode(PA, InsertPoint);
120 }
121
122 // Return the Attribute that we found or created.
123 return Attribute(PA);
124}
125
127 LLVMContextImpl *pImpl = Context.pImpl;
129 ID.AddString(Kind);
130 if (!Val.empty()) ID.AddString(Val);
131
132 void *InsertPoint;
133 AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);
134
135 if (!PA) {
136 // If we didn't find any existing attributes of the same shape then create a
137 // new one and insert it.
138 void *Mem =
140 alignof(StringAttributeImpl));
141 PA = new (Mem) StringAttributeImpl(Kind, Val);
142 pImpl->AttrsSet.InsertNode(PA, InsertPoint);
143 }
144
145 // Return the Attribute that we found or created.
146 return Attribute(PA);
147}
148
150 Type *Ty) {
151 assert(Attribute::isTypeAttrKind(Kind) && "Not a type attribute");
152 LLVMContextImpl *pImpl = Context.pImpl;
154 ID.AddInteger(Kind);
155 ID.AddPointer(Ty);
156
157 void *InsertPoint;
158 AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);
159
160 if (!PA) {
161 // If we didn't find any existing attributes of the same shape then create a
162 // new one and insert it.
163 PA = new (pImpl->Alloc) TypeAttributeImpl(Kind, Ty);
164 pImpl->AttrsSet.InsertNode(PA, InsertPoint);
165 }
166
167 // Return the Attribute that we found or created.
168 return Attribute(PA);
169}
170
172 const ConstantRange &CR) {
174 "Not a ConstantRange attribute");
175 assert(!CR.isFullSet() && "ConstantRange attribute must not be full");
176 LLVMContextImpl *pImpl = Context.pImpl;
178 ID.AddInteger(Kind);
179 CR.getLower().Profile(ID);
180 CR.getUpper().Profile(ID);
181
182 void *InsertPoint;
183 AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);
184
185 if (!PA) {
186 // If we didn't find any existing attributes of the same shape then create a
187 // new one and insert it.
188 PA = new (pImpl->ConstantRangeAttributeAlloc.Allocate())
190 pImpl->AttrsSet.InsertNode(PA, InsertPoint);
191 }
192
193 // Return the Attribute that we found or created.
194 return Attribute(PA);
195}
196
200 "Not a ConstantRangeList attribute");
201 LLVMContextImpl *pImpl = Context.pImpl;
203 ID.AddInteger(Kind);
204 ID.AddInteger(Val.size());
205 for (auto &CR : Val) {
206 CR.getLower().Profile(ID);
207 CR.getUpper().Profile(ID);
208 }
209
210 void *InsertPoint;
211 AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);
212
213 if (!PA) {
214 // If we didn't find any existing attributes of the same shape then create a
215 // new one and insert it.
216 // ConstantRangeListAttributeImpl is a dynamically sized class and cannot
217 // use SpecificBumpPtrAllocator. Instead, we use normal Alloc for
218 // allocation and record the allocated pointer in
219 // `ConstantRangeListAttributes`. LLVMContext destructor will call the
220 // destructor of the allocated pointer explicitly.
221 void *Mem = pImpl->Alloc.Allocate(
224 PA = new (Mem) ConstantRangeListAttributeImpl(Kind, Val);
225 pImpl->AttrsSet.InsertNode(PA, InsertPoint);
226 pImpl->ConstantRangeListAttributes.push_back(
227 reinterpret_cast<ConstantRangeListAttributeImpl *>(PA));
228 }
229
230 // Return the Attribute that we found or created.
231 return Attribute(PA);
232}
233
235 assert(A <= llvm::Value::MaximumAlignment && "Alignment too large.");
236 return get(Context, Alignment, A.value());
237}
238
240 assert(A <= 0x100 && "Alignment too large.");
241 return get(Context, StackAlignment, A.value());
242}
243
245 uint64_t Bytes) {
246 assert(Bytes && "Bytes must be non-zero.");
247 return get(Context, Dereferenceable, Bytes);
248}
249
251 uint64_t Bytes) {
252 assert(Bytes && "Bytes must be non-zero.");
253 return get(Context, DereferenceableOrNull, Bytes);
254}
255
257 return get(Context, ByVal, Ty);
258}
259
261 return get(Context, StructRet, Ty);
262}
263
265 return get(Context, ByRef, Ty);
266}
267
269 return get(Context, Preallocated, Ty);
270}
271
273 return get(Context, InAlloca, Ty);
274}
275
277 UWTableKind Kind) {
278 return get(Context, UWTable, uint64_t(Kind));
279}
280
282 MemoryEffects ME) {
283 return get(Context, Memory, ME.toIntValue());
284}
285
287 FPClassTest ClassMask) {
288 return get(Context, NoFPClass, ClassMask);
289}
290
292 return get(Context, Captures, CI.toIntValue());
293}
294
296Attribute::getWithAllocSizeArgs(LLVMContext &Context, unsigned ElemSizeArg,
297 const std::optional<unsigned> &NumElemsArg) {
298 assert(!(ElemSizeArg == 0 && NumElemsArg == 0) &&
299 "Invalid allocsize arguments -- given allocsize(0, 0)");
300 return get(Context, AllocSize, packAllocSizeArgs(ElemSizeArg, NumElemsArg));
301}
302
304 return get(Context, AllocKind, static_cast<uint64_t>(Kind));
305}
306
308 unsigned MinValue,
309 unsigned MaxValue) {
310 return get(Context, VScaleRange, packVScaleRangeArgs(MinValue, MaxValue));
311}
312
314 return StringSwitch<Attribute::AttrKind>(AttrName)
315#define GET_ATTR_NAMES
316#define ATTRIBUTE_ENUM(ENUM_NAME, DISPLAY_NAME) \
317 .Case(#DISPLAY_NAME, Attribute::ENUM_NAME)
318#include "llvm/IR/Attributes.inc"
320}
321
323 switch (AttrKind) {
324#define GET_ATTR_NAMES
325#define ATTRIBUTE_ENUM(ENUM_NAME, DISPLAY_NAME) \
326 case Attribute::ENUM_NAME: \
327 return #DISPLAY_NAME;
328#include "llvm/IR/Attributes.inc"
329 case Attribute::None:
330 return "none";
331 default:
332 llvm_unreachable("invalid Kind");
333 }
334}
335
338#define GET_ATTR_NAMES
339#define ATTRIBUTE_ALL(ENUM_NAME, DISPLAY_NAME) .Case(#DISPLAY_NAME, true)
340#include "llvm/IR/Attributes.inc"
341 .Default(false);
342}
343
344//===----------------------------------------------------------------------===//
345// Attribute Accessor Methods
346//===----------------------------------------------------------------------===//
347
349 return pImpl && pImpl->isEnumAttribute();
350}
351
353 return pImpl && pImpl->isIntAttribute();
354}
355
357 return pImpl && pImpl->isStringAttribute();
358}
359
361 return pImpl && pImpl->isTypeAttribute();
362}
363
365 return pImpl && pImpl->isConstantRangeAttribute();
366}
367
369 return pImpl && pImpl->isConstantRangeListAttribute();
370}
371
373 if (!pImpl) return None;
375 "Invalid attribute type to get the kind as an enum!");
376 return pImpl->getKindAsEnum();
377}
378
380 if (!pImpl) return 0;
382 "Expected the attribute to be an integer attribute!");
383 return pImpl->getValueAsInt();
384}
385
387 if (!pImpl) return false;
389 "Expected the attribute to be a string attribute!");
390 return pImpl->getValueAsBool();
391}
392
394 if (!pImpl) return {};
396 "Invalid attribute type to get the kind as a string!");
397 return pImpl->getKindAsString();
398}
399
401 if (!pImpl) return {};
403 "Invalid attribute type to get the value as a string!");
404 return pImpl->getValueAsString();
405}
406
408 if (!pImpl) return {};
410 "Invalid attribute type to get the value as a type!");
411 return pImpl->getValueAsType();
412}
413
416 "Invalid attribute type to get the value as a ConstantRange!");
417 return pImpl->getValueAsConstantRange();
418}
419
422 "Invalid attribute type to get the value as a ConstantRangeList!");
423 return pImpl->getValueAsConstantRangeList();
424}
425
427 return (pImpl && pImpl->hasAttribute(Kind)) || (!pImpl && Kind == None);
428}
429
431 if (!isStringAttribute()) return false;
432 return pImpl && pImpl->hasAttribute(Kind);
433}
434
436 assert(hasAttribute(Attribute::Alignment) &&
437 "Trying to get alignment from non-alignment attribute!");
438 return MaybeAlign(pImpl->getValueAsInt());
439}
440
442 assert(hasAttribute(Attribute::StackAlignment) &&
443 "Trying to get alignment from non-alignment attribute!");
444 return MaybeAlign(pImpl->getValueAsInt());
445}
446
448 assert(hasAttribute(Attribute::Dereferenceable) &&
449 "Trying to get dereferenceable bytes from "
450 "non-dereferenceable attribute!");
451 return pImpl->getValueAsInt();
452}
453
455 assert(hasAttribute(Attribute::DereferenceableOrNull) &&
456 "Trying to get dereferenceable bytes from "
457 "non-dereferenceable attribute!");
458 return pImpl->getValueAsInt();
459}
460
461std::pair<unsigned, std::optional<unsigned>>
463 assert(hasAttribute(Attribute::AllocSize) &&
464 "Trying to get allocsize args from non-allocsize attribute");
465 return unpackAllocSizeArgs(pImpl->getValueAsInt());
466}
467
469 assert(hasAttribute(Attribute::VScaleRange) &&
470 "Trying to get vscale args from non-vscale attribute");
471 return unpackVScaleRangeArgs(pImpl->getValueAsInt()).first;
472}
473
474std::optional<unsigned> Attribute::getVScaleRangeMax() const {
475 assert(hasAttribute(Attribute::VScaleRange) &&
476 "Trying to get vscale args from non-vscale attribute");
477 return unpackVScaleRangeArgs(pImpl->getValueAsInt()).second;
478}
479
481 assert(hasAttribute(Attribute::UWTable) &&
482 "Trying to get unwind table kind from non-uwtable attribute");
483 return UWTableKind(pImpl->getValueAsInt());
484}
485
487 assert(hasAttribute(Attribute::AllocKind) &&
488 "Trying to get allockind value from non-allockind attribute");
489 return AllocFnKind(pImpl->getValueAsInt());
490}
491
493 assert(hasAttribute(Attribute::Memory) &&
494 "Can only call getMemoryEffects() on memory attribute");
496}
497
499 assert(hasAttribute(Attribute::Captures) &&
500 "Can only call getCaptureInfo() on captures attribute");
502}
503
505 assert(hasAttribute(Attribute::NoFPClass) &&
506 "Can only call getNoFPClass() on nofpclass attribute");
507 return static_cast<FPClassTest>(pImpl->getValueAsInt());
508}
509
511 assert(hasAttribute(Attribute::Range) &&
512 "Trying to get range args from non-range attribute");
513 return pImpl->getValueAsConstantRange();
514}
515
517 assert(hasAttribute(Attribute::Initializes) &&
518 "Trying to get initializes attr from non-ConstantRangeList attribute");
519 return pImpl->getValueAsConstantRangeList();
520}
521
522static const char *getModRefStr(ModRefInfo MR) {
523 switch (MR) {
525 return "none";
526 case ModRefInfo::Ref:
527 return "read";
528 case ModRefInfo::Mod:
529 return "write";
531 return "readwrite";
532 }
533 llvm_unreachable("Invalid ModRefInfo");
534}
535
536std::string Attribute::getAsString(bool InAttrGrp) const {
537 if (!pImpl) return {};
538
539 if (isEnumAttribute())
541
542 if (isTypeAttribute()) {
543 std::string Result = getNameFromAttrKind(getKindAsEnum()).str();
544 Result += '(';
545 raw_string_ostream OS(Result);
546 getValueAsType()->print(OS, false, true);
547 OS.flush();
548 Result += ')';
549 return Result;
550 }
551
552 // FIXME: These should be output like this:
553 //
554 // align=4
555 // alignstack=8
556 //
557 if (hasAttribute(Attribute::Alignment))
558 return (InAttrGrp ? "align=" + Twine(getValueAsInt())
559 : "align " + Twine(getValueAsInt()))
560 .str();
561
562 auto AttrWithBytesToString = [&](const char *Name) {
563 return (InAttrGrp ? Name + ("=" + Twine(getValueAsInt()))
564 : Name + ("(" + Twine(getValueAsInt())) + ")")
565 .str();
566 };
567
568 if (hasAttribute(Attribute::StackAlignment))
569 return AttrWithBytesToString("alignstack");
570
571 if (hasAttribute(Attribute::Dereferenceable))
572 return AttrWithBytesToString("dereferenceable");
573
574 if (hasAttribute(Attribute::DereferenceableOrNull))
575 return AttrWithBytesToString("dereferenceable_or_null");
576
577 if (hasAttribute(Attribute::AllocSize)) {
578 unsigned ElemSize;
579 std::optional<unsigned> NumElems;
580 std::tie(ElemSize, NumElems) = getAllocSizeArgs();
581
582 return (NumElems
583 ? "allocsize(" + Twine(ElemSize) + "," + Twine(*NumElems) + ")"
584 : "allocsize(" + Twine(ElemSize) + ")")
585 .str();
586 }
587
588 if (hasAttribute(Attribute::VScaleRange)) {
589 unsigned MinValue = getVScaleRangeMin();
590 std::optional<unsigned> MaxValue = getVScaleRangeMax();
591 return ("vscale_range(" + Twine(MinValue) + "," +
592 Twine(MaxValue.value_or(0)) + ")")
593 .str();
594 }
595
596 if (hasAttribute(Attribute::UWTable)) {
598 assert(Kind != UWTableKind::None && "uwtable attribute should not be none");
599 return Kind == UWTableKind::Default ? "uwtable" : "uwtable(sync)";
600 }
601
602 if (hasAttribute(Attribute::AllocKind)) {
603 AllocFnKind Kind = getAllocKind();
606 parts.push_back("alloc");
608 parts.push_back("realloc");
610 parts.push_back("free");
612 parts.push_back("uninitialized");
614 parts.push_back("zeroed");
616 parts.push_back("aligned");
617 return ("allockind(\"" +
618 Twine(llvm::join(parts.begin(), parts.end(), ",")) + "\")")
619 .str();
620 }
621
622 if (hasAttribute(Attribute::Memory)) {
623 std::string Result;
624 raw_string_ostream OS(Result);
625 bool First = true;
626 OS << "memory(";
627
629
630 // Print access kind for "other" as the default access kind. This way it
631 // will apply to any new location kinds that get split out of "other".
633 if (OtherMR != ModRefInfo::NoModRef || ME.getModRef() == OtherMR) {
634 First = false;
635 OS << getModRefStr(OtherMR);
636 }
637
638 for (auto Loc : MemoryEffects::locations()) {
639 ModRefInfo MR = ME.getModRef(Loc);
640 if (MR == OtherMR)
641 continue;
642
643 if (!First)
644 OS << ", ";
645 First = false;
646
647 switch (Loc) {
649 OS << "argmem: ";
650 break;
652 OS << "inaccessiblemem: ";
653 break;
655 OS << "errnomem: ";
656 break;
658 llvm_unreachable("This is represented as the default access kind");
659 }
660 OS << getModRefStr(MR);
661 }
662 OS << ")";
663 OS.flush();
664 return Result;
665 }
666
667 if (hasAttribute(Attribute::Captures)) {
668 std::string Result;
669 raw_string_ostream OS(Result);
670 OS << getCaptureInfo();
671 return Result;
672 }
673
674 if (hasAttribute(Attribute::NoFPClass)) {
675 std::string Result = "nofpclass";
676 raw_string_ostream OS(Result);
677 OS << getNoFPClass();
678 return Result;
679 }
680
681 if (hasAttribute(Attribute::Range)) {
682 std::string Result;
683 raw_string_ostream OS(Result);
685 OS << "range(";
686 OS << "i" << CR.getBitWidth() << " ";
687 OS << CR.getLower() << ", " << CR.getUpper();
688 OS << ")";
689 OS.flush();
690 return Result;
691 }
692
693 if (hasAttribute(Attribute::Initializes)) {
694 std::string Result;
695 raw_string_ostream OS(Result);
697 OS << "initializes(";
698 CRL.print(OS);
699 OS << ")";
700 OS.flush();
701 return Result;
702 }
703
704 // Convert target-dependent attributes to strings of the form:
705 //
706 // "kind"
707 // "kind" = "value"
708 //
709 if (isStringAttribute()) {
710 std::string Result;
711 {
712 raw_string_ostream OS(Result);
713 OS << '"' << getKindAsString() << '"';
714
715 // Since some attribute strings contain special characters that cannot be
716 // printable, those have to be escaped to make the attribute value
717 // printable as is. e.g. "\01__gnu_mcount_nc"
718 const auto &AttrVal = pImpl->getValueAsString();
719 if (!AttrVal.empty()) {
720 OS << "=\"";
721 printEscapedString(AttrVal, OS);
722 OS << "\"";
723 }
724 }
725 return Result;
726 }
727
728 llvm_unreachable("Unknown attribute");
729}
730
732 assert(isValid() && "invalid Attribute doesn't refer to any context");
734 pImpl->Profile(ID);
735 void *Unused;
736 return C.pImpl->AttrsSet.FindNodeOrInsertPos(ID, Unused) == pImpl;
737}
738
740 if (!pImpl && !A.pImpl)
741 return 0;
742 if (!pImpl)
743 return 1;
744 if (!A.pImpl)
745 return -1;
746 return pImpl->cmp(*A.pImpl, /*KindOnly=*/true);
747}
748
750 if (!pImpl && !A.pImpl) return false;
751 if (!pImpl) return true;
752 if (!A.pImpl) return false;
753 return *pImpl < *A.pImpl;
754}
755
757 ID.AddPointer(pImpl);
758}
759
761 FnAttr = (1 << 0),
762 ParamAttr = (1 << 1),
763 RetAttr = (1 << 2),
765 IntersectAnd = (1 << 3),
766 IntersectMin = (2 << 3),
767 IntersectCustom = (3 << 3),
769};
770
771#define GET_ATTR_PROP_TABLE
772#include "llvm/IR/Attributes.inc"
773
775 unsigned Index = Kind - 1;
776 assert(Index < std::size(AttrPropTable) && "Invalid attribute kind");
777 return AttrPropTable[Index];
778}
779
781 AttributeProperty Prop) {
782 return getAttributeProperties(Kind) & Prop;
783}
784
786 return hasAttributeProperty(Kind, AttributeProperty::FnAttr);
787}
788
790 return hasAttributeProperty(Kind, AttributeProperty::ParamAttr);
791}
792
794 return hasAttributeProperty(Kind, AttributeProperty::RetAttr);
795}
796
798 AttributeProperty Prop) {
799 assert((Prop == AttributeProperty::IntersectPreserve ||
800 Prop == AttributeProperty::IntersectAnd ||
801 Prop == AttributeProperty::IntersectMin ||
802 Prop == AttributeProperty::IntersectCustom) &&
803 "Unknown intersect property");
804 return (getAttributeProperties(Kind) &
805 AttributeProperty::IntersectPropertyMask) == Prop;
806}
807
809 return hasIntersectProperty(Kind, AttributeProperty::IntersectPreserve);
810}
812 return hasIntersectProperty(Kind, AttributeProperty::IntersectAnd);
813}
815 return hasIntersectProperty(Kind, AttributeProperty::IntersectMin);
816}
818 return hasIntersectProperty(Kind, AttributeProperty::IntersectCustom);
819}
820
821//===----------------------------------------------------------------------===//
822// AttributeImpl Definition
823//===----------------------------------------------------------------------===//
824
826 if (isStringAttribute()) return false;
827 return getKindAsEnum() == A;
828}
829
831 if (!isStringAttribute()) return false;
832 return getKindAsString() == Kind;
833}
834
838 return static_cast<const EnumAttributeImpl *>(this)->getEnumKind();
839}
840
843 return static_cast<const IntAttributeImpl *>(this)->getValue();
844}
845
847 assert(getValueAsString().empty() || getValueAsString() == "false" || getValueAsString() == "true");
848 return getValueAsString() == "true";
849}
850
853 return static_cast<const StringAttributeImpl *>(this)->getStringKind();
854}
855
858 return static_cast<const StringAttributeImpl *>(this)->getStringValue();
859}
860
863 return static_cast<const TypeAttributeImpl *>(this)->getTypeValue();
864}
865
868 return static_cast<const ConstantRangeAttributeImpl *>(this)
869 ->getConstantRangeValue();
870}
871
874 return static_cast<const ConstantRangeListAttributeImpl *>(this)
875 ->getConstantRangeListValue();
876}
877
878int AttributeImpl::cmp(const AttributeImpl &AI, bool KindOnly) const {
879 if (this == &AI)
880 return 0;
881
882 // This sorts the attributes with Attribute::AttrKinds coming first (sorted
883 // relative to their enum value) and then strings.
884 if (!isStringAttribute()) {
885 if (AI.isStringAttribute())
886 return -1;
887
888 if (getKindAsEnum() != AI.getKindAsEnum())
889 return getKindAsEnum() < AI.getKindAsEnum() ? -1 : 1;
890 else if (KindOnly)
891 return 0;
892
893 assert(!AI.isEnumAttribute() && "Non-unique attribute");
894 assert(!AI.isTypeAttribute() && "Comparison of types would be unstable");
895 assert(!AI.isConstantRangeAttribute() && "Unclear how to compare ranges");
897 "Unclear how to compare range list");
898 // TODO: Is this actually needed?
899 assert(AI.isIntAttribute() && "Only possibility left");
900 if (getValueAsInt() < AI.getValueAsInt())
901 return -1;
902 return getValueAsInt() == AI.getValueAsInt() ? 0 : 1;
903 }
904 if (!AI.isStringAttribute())
905 return 1;
906 if (KindOnly)
908 if (getKindAsString() == AI.getKindAsString())
911}
912
914 return cmp(AI, /*KindOnly=*/false) < 0;
915}
916
917//===----------------------------------------------------------------------===//
918// AttributeSet Definition
919//===----------------------------------------------------------------------===//
920
923}
924
926 return AttributeSet(AttributeSetNode::get(C, Attrs));
927}
928
930 Attribute::AttrKind Kind) const {
931 if (hasAttribute(Kind)) return *this;
932 AttrBuilder B(C);
933 B.addAttribute(Kind);
935}
936
938 StringRef Value) const {
939 AttrBuilder B(C);
940 B.addAttribute(Kind, Value);
942}
943
945 const AttributeSet AS) const {
946 if (!hasAttributes())
947 return AS;
948
949 if (!AS.hasAttributes())
950 return *this;
951
952 AttrBuilder B(C, *this);
953 B.merge(AttrBuilder(C, AS));
954 return get(C, B);
955}
956
958 Attribute::AttrKind Kind) const {
959 if (!hasAttribute(Kind)) return *this;
960 AttrBuilder B(C, *this);
961 B.removeAttribute(Kind);
962 return get(C, B);
963}
964
966 StringRef Kind) const {
967 if (!hasAttribute(Kind)) return *this;
968 AttrBuilder B(C, *this);
969 B.removeAttribute(Kind);
970 return get(C, B);
971}
972
974 const AttributeMask &Attrs) const {
975 AttrBuilder B(C, *this);
976 // If there is nothing to remove, directly return the original set.
977 if (!B.overlaps(Attrs))
978 return *this;
979
980 B.remove(Attrs);
981 return get(C, B);
982}
983
984std::optional<AttributeSet>
986 if (*this == Other)
987 return *this;
988
989 AttrBuilder Intersected(C);
990 // Iterate over both attr sets at once.
991 auto ItBegin0 = begin();
992 auto ItEnd0 = end();
993 auto ItBegin1 = Other.begin();
994 auto ItEnd1 = Other.end();
995
996 while (ItBegin0 != ItEnd0 || ItBegin1 != ItEnd1) {
997 // Loop through all attributes in both this and Other in sorted order. If
998 // the attribute is only present in one of the sets, it will be set in
999 // Attr0. If it is present in both sets both Attr0 and Attr1 will be set.
1000 Attribute Attr0, Attr1;
1001 if (ItBegin1 == ItEnd1)
1002 Attr0 = *ItBegin0++;
1003 else if (ItBegin0 == ItEnd0)
1004 Attr0 = *ItBegin1++;
1005 else {
1006 int Cmp = ItBegin0->cmpKind(*ItBegin1);
1007 if (Cmp == 0) {
1008 Attr0 = *ItBegin0++;
1009 Attr1 = *ItBegin1++;
1010 } else if (Cmp < 0)
1011 Attr0 = *ItBegin0++;
1012 else
1013 Attr0 = *ItBegin1++;
1014 }
1015 assert(Attr0.isValid() && "Iteration should always yield a valid attr");
1016
1017 auto IntersectEq = [&]() {
1018 if (!Attr1.isValid())
1019 return false;
1020 if (Attr0 != Attr1)
1021 return false;
1022 Intersected.addAttribute(Attr0);
1023 return true;
1024 };
1025
1026 // Non-enum assume we must preserve. Handle early so we can unconditionally
1027 // use Kind below.
1028 if (!Attr0.hasKindAsEnum()) {
1029 if (!IntersectEq())
1030 return std::nullopt;
1031 continue;
1032 }
1033
1034 Attribute::AttrKind Kind = Attr0.getKindAsEnum();
1035 // If we don't have both attributes, then fail if the attribute is
1036 // must-preserve or drop it otherwise.
1037 if (!Attr1.isValid()) {
1039 return std::nullopt;
1040 continue;
1041 }
1042
1043 // We have both attributes so apply the intersection rule.
1044 assert(Attr1.hasKindAsEnum() && Kind == Attr1.getKindAsEnum() &&
1045 "Iterator picked up two different attributes in the same iteration");
1046
1047 // Attribute we can intersect with "and"
1048 if (Attribute::intersectWithAnd(Kind)) {
1050 "Invalid attr type of intersectAnd");
1051 Intersected.addAttribute(Kind);
1052 continue;
1053 }
1054
1055 // Attribute we can intersect with "min"
1056 if (Attribute::intersectWithMin(Kind)) {
1058 "Invalid attr type of intersectMin");
1059 uint64_t NewVal = std::min(Attr0.getValueAsInt(), Attr1.getValueAsInt());
1060 Intersected.addRawIntAttr(Kind, NewVal);
1061 continue;
1062 }
1063 // Attribute we can intersect but need a custom rule for.
1065 switch (Kind) {
1066 case Attribute::Alignment:
1067 // If `byval` is present, alignment become must-preserve. This is
1068 // handled below if we have `byval`.
1069 Intersected.addAlignmentAttr(
1070 std::min(Attr0.getAlignment().valueOrOne(),
1071 Attr1.getAlignment().valueOrOne()));
1072 break;
1073 case Attribute::Memory:
1074 Intersected.addMemoryAttr(Attr0.getMemoryEffects() |
1075 Attr1.getMemoryEffects());
1076 break;
1077 case Attribute::Captures:
1078 Intersected.addCapturesAttr(Attr0.getCaptureInfo() |
1079 Attr1.getCaptureInfo());
1080 break;
1081 case Attribute::NoFPClass:
1082 Intersected.addNoFPClassAttr(Attr0.getNoFPClass() &
1083 Attr1.getNoFPClass());
1084 break;
1085 case Attribute::Range: {
1086 ConstantRange Range0 = Attr0.getRange();
1087 ConstantRange Range1 = Attr1.getRange();
1088 ConstantRange NewRange = Range0.unionWith(Range1);
1089 if (!NewRange.isFullSet())
1090 Intersected.addRangeAttr(NewRange);
1091 } break;
1092 default:
1093 llvm_unreachable("Unknown attribute with custom intersection rule");
1094 }
1095 continue;
1096 }
1097
1098 // Attributes with no intersection rule. Only intersect if they are equal.
1099 // Otherwise fail.
1100 if (!IntersectEq())
1101 return std::nullopt;
1102
1103 // Special handling of `byval`. `byval` essentially turns align attr into
1104 // must-preserve
1105 if (Kind == Attribute::ByVal &&
1106 getAttribute(Attribute::Alignment) !=
1107 Other.getAttribute(Attribute::Alignment))
1108 return std::nullopt;
1109 }
1110
1111 return get(C, Intersected);
1112}
1113
1115 return SetNode ? SetNode->getNumAttributes() : 0;
1116}
1117
1119 return SetNode ? SetNode->hasAttribute(Kind) : false;
1120}
1121
1123 return SetNode ? SetNode->hasAttribute(Kind) : false;
1124}
1125
1127 return SetNode ? SetNode->getAttribute(Kind) : Attribute();
1128}
1129
1131 return SetNode ? SetNode->getAttribute(Kind) : Attribute();
1132}
1133
1135 return SetNode ? SetNode->getAlignment() : std::nullopt;
1136}
1137
1139 return SetNode ? SetNode->getStackAlignment() : std::nullopt;
1140}
1141
1143 return SetNode ? SetNode->getDereferenceableBytes() : 0;
1144}
1145
1147 return SetNode ? SetNode->getDereferenceableOrNullBytes() : 0;
1148}
1149
1151 return SetNode ? SetNode->getAttributeType(Attribute::ByRef) : nullptr;
1152}
1153
1155 return SetNode ? SetNode->getAttributeType(Attribute::ByVal) : nullptr;
1156}
1157
1159 return SetNode ? SetNode->getAttributeType(Attribute::StructRet) : nullptr;
1160}
1161
1163 return SetNode ? SetNode->getAttributeType(Attribute::Preallocated) : nullptr;
1164}
1165
1167 return SetNode ? SetNode->getAttributeType(Attribute::InAlloca) : nullptr;
1168}
1169
1171 return SetNode ? SetNode->getAttributeType(Attribute::ElementType) : nullptr;
1172}
1173
1174std::optional<std::pair<unsigned, std::optional<unsigned>>>
1176 if (SetNode)
1177 return SetNode->getAllocSizeArgs();
1178 return std::nullopt;
1179}
1180
1182 return SetNode ? SetNode->getVScaleRangeMin() : 1;
1183}
1184
1185std::optional<unsigned> AttributeSet::getVScaleRangeMax() const {
1186 return SetNode ? SetNode->getVScaleRangeMax() : std::nullopt;
1187}
1188
1190 return SetNode ? SetNode->getUWTableKind() : UWTableKind::None;
1191}
1192
1194 return SetNode ? SetNode->getAllocKind() : AllocFnKind::Unknown;
1195}
1196
1198 return SetNode ? SetNode->getMemoryEffects() : MemoryEffects::unknown();
1199}
1200
1202 return SetNode ? SetNode->getCaptureInfo() : CaptureInfo::all();
1203}
1204
1206 return SetNode ? SetNode->getNoFPClass() : fcNone;
1207}
1208
1209std::string AttributeSet::getAsString(bool InAttrGrp) const {
1210 return SetNode ? SetNode->getAsString(InAttrGrp) : "";
1211}
1212
1214 assert(hasAttributes() && "empty AttributeSet doesn't refer to any context");
1216 SetNode->Profile(ID);
1217 void *Unused;
1218 return C.pImpl->AttrsSetNodes.FindNodeOrInsertPos(ID, Unused) == SetNode;
1219}
1220
1222 return SetNode ? SetNode->begin() : nullptr;
1223}
1224
1226 return SetNode ? SetNode->end() : nullptr;
1227}
1228
1229#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1231 dbgs() << "AS =\n";
1232 dbgs() << " { ";
1233 dbgs() << getAsString(true) << " }\n";
1234}
1235#endif
1236
1237//===----------------------------------------------------------------------===//
1238// AttributeSetNode Definition
1239//===----------------------------------------------------------------------===//
1240
1241AttributeSetNode::AttributeSetNode(ArrayRef<Attribute> Attrs)
1242 : NumAttrs(Attrs.size()) {
1243 // There's memory after the node where we can store the entries in.
1244 llvm::copy(Attrs, getTrailingObjects());
1245
1246 for (const auto &I : *this) {
1247 if (I.isStringAttribute())
1248 StringAttrs.insert({ I.getKindAsString(), I });
1249 else
1250 AvailableAttrs.addAttribute(I.getKindAsEnum());
1251 }
1252}
1253
1255 ArrayRef<Attribute> Attrs) {
1256 SmallVector<Attribute, 8> SortedAttrs(Attrs);
1257 llvm::sort(SortedAttrs);
1258 return getSorted(C, SortedAttrs);
1259}
1260
1261AttributeSetNode *AttributeSetNode::getSorted(LLVMContext &C,
1262 ArrayRef<Attribute> SortedAttrs) {
1263 if (SortedAttrs.empty())
1264 return nullptr;
1265
1266 // Build a key to look up the existing attributes.
1267 LLVMContextImpl *pImpl = C.pImpl;
1269
1270 assert(llvm::is_sorted(SortedAttrs) && "Expected sorted attributes!");
1271 for (const auto &Attr : SortedAttrs)
1272 Attr.Profile(ID);
1273
1274 void *InsertPoint;
1275 AttributeSetNode *PA =
1276 pImpl->AttrsSetNodes.FindNodeOrInsertPos(ID, InsertPoint);
1277
1278 // If we didn't find any existing attributes of the same shape then create a
1279 // new one and insert it.
1280 if (!PA) {
1281 // Coallocate entries after the AttributeSetNode itself.
1282 void *Mem = ::operator new(totalSizeToAlloc<Attribute>(SortedAttrs.size()));
1283 PA = new (Mem) AttributeSetNode(SortedAttrs);
1284 pImpl->AttrsSetNodes.InsertNode(PA, InsertPoint);
1285 }
1286
1287 // Return the AttributeSetNode that we found or created.
1288 return PA;
1289}
1290
1292 return getSorted(C, B.attrs());
1293}
1294
1296 return StringAttrs.count(Kind);
1297}
1298
1299std::optional<Attribute>
1300AttributeSetNode::findEnumAttribute(Attribute::AttrKind Kind) const {
1301 // Do a quick presence check.
1302 if (!hasAttribute(Kind))
1303 return std::nullopt;
1304
1305 // Attributes in a set are sorted by enum value, followed by string
1306 // attributes. Binary search the one we want.
1307 const Attribute *I =
1308 std::lower_bound(begin(), end() - StringAttrs.size(), Kind,
1309 [](Attribute A, Attribute::AttrKind Kind) {
1310 return A.getKindAsEnum() < Kind;
1311 });
1312 assert(I != end() && I->hasAttribute(Kind) && "Presence check failed?");
1313 return *I;
1314}
1315
1317 if (auto A = findEnumAttribute(Kind))
1318 return *A;
1319 return {};
1320}
1321
1323 return StringAttrs.lookup(Kind);
1324}
1325
1327 if (auto A = findEnumAttribute(Attribute::Alignment))
1328 return A->getAlignment();
1329 return std::nullopt;
1330}
1331
1333 if (auto A = findEnumAttribute(Attribute::StackAlignment))
1334 return A->getStackAlignment();
1335 return std::nullopt;
1336}
1337
1339 if (auto A = findEnumAttribute(Kind))
1340 return A->getValueAsType();
1341 return nullptr;
1342}
1343
1345 if (auto A = findEnumAttribute(Attribute::Dereferenceable))
1346 return A->getDereferenceableBytes();
1347 return 0;
1348}
1349
1351 if (auto A = findEnumAttribute(Attribute::DereferenceableOrNull))
1352 return A->getDereferenceableOrNullBytes();
1353 return 0;
1354}
1355
1356std::optional<std::pair<unsigned, std::optional<unsigned>>>
1358 if (auto A = findEnumAttribute(Attribute::AllocSize))
1359 return A->getAllocSizeArgs();
1360 return std::nullopt;
1361}
1362
1364 if (auto A = findEnumAttribute(Attribute::VScaleRange))
1365 return A->getVScaleRangeMin();
1366 return 1;
1367}
1368
1369std::optional<unsigned> AttributeSetNode::getVScaleRangeMax() const {
1370 if (auto A = findEnumAttribute(Attribute::VScaleRange))
1371 return A->getVScaleRangeMax();
1372 return std::nullopt;
1373}
1374
1376 if (auto A = findEnumAttribute(Attribute::UWTable))
1377 return A->getUWTableKind();
1378 return UWTableKind::None;
1379}
1380
1382 if (auto A = findEnumAttribute(Attribute::AllocKind))
1383 return A->getAllocKind();
1384 return AllocFnKind::Unknown;
1385}
1386
1388 if (auto A = findEnumAttribute(Attribute::Memory))
1389 return A->getMemoryEffects();
1390 return MemoryEffects::unknown();
1391}
1392
1394 if (auto A = findEnumAttribute(Attribute::Captures))
1395 return A->getCaptureInfo();
1396 return CaptureInfo::all();
1397}
1398
1400 if (auto A = findEnumAttribute(Attribute::NoFPClass))
1401 return A->getNoFPClass();
1402 return fcNone;
1403}
1404
1405std::string AttributeSetNode::getAsString(bool InAttrGrp) const {
1406 std::string Str;
1407 for (iterator I = begin(), E = end(); I != E; ++I) {
1408 if (I != begin())
1409 Str += ' ';
1410 Str += I->getAsString(InAttrGrp);
1411 }
1412 return Str;
1413}
1414
1415//===----------------------------------------------------------------------===//
1416// AttributeListImpl Definition
1417//===----------------------------------------------------------------------===//
1418
1419/// Map from AttributeList index to the internal array index. Adding one happens
1420/// to work, because -1 wraps around to 0.
1421static unsigned attrIdxToArrayIdx(unsigned Index) {
1422 return Index + 1;
1423}
1424
1426 : NumAttrSets(Sets.size()) {
1427 assert(!Sets.empty() && "pointless AttributeListImpl");
1428
1429 // There's memory after the node where we can store the entries in.
1431
1432 // Initialize AvailableFunctionAttrs and AvailableSomewhereAttrs
1433 // summary bitsets.
1434 for (const auto &I : Sets[attrIdxToArrayIdx(AttributeList::FunctionIndex)])
1435 if (!I.isStringAttribute())
1436 AvailableFunctionAttrs.addAttribute(I.getKindAsEnum());
1437
1438 for (const auto &Set : Sets)
1439 for (const auto &I : Set)
1440 if (!I.isStringAttribute())
1441 AvailableSomewhereAttrs.addAttribute(I.getKindAsEnum());
1442}
1443
1445 Profile(ID, ArrayRef(begin(), end()));
1446}
1447
1450 for (const auto &Set : Sets)
1451 ID.AddPointer(Set.SetNode);
1452}
1453
1455 unsigned *Index) const {
1456 if (!AvailableSomewhereAttrs.hasAttribute(Kind))
1457 return false;
1458
1459 if (Index) {
1460 for (unsigned I = 0, E = NumAttrSets; I != E; ++I) {
1461 if (begin()[I].hasAttribute(Kind)) {
1462 *Index = I - 1;
1463 break;
1464 }
1465 }
1466 }
1467
1468 return true;
1469}
1470
1471
1472#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1474 AttributeList(const_cast<AttributeListImpl *>(this)).dump();
1475}
1476#endif
1477
1478//===----------------------------------------------------------------------===//
1479// AttributeList Construction and Mutation Methods
1480//===----------------------------------------------------------------------===//
1481
1482AttributeList AttributeList::getImpl(LLVMContext &C,
1483 ArrayRef<AttributeSet> AttrSets) {
1484 assert(!AttrSets.empty() && "pointless AttributeListImpl");
1485
1486 LLVMContextImpl *pImpl = C.pImpl;
1488 AttributeListImpl::Profile(ID, AttrSets);
1489
1490 void *InsertPoint;
1491 AttributeListImpl *PA =
1492 pImpl->AttrsLists.FindNodeOrInsertPos(ID, InsertPoint);
1493
1494 // If we didn't find any existing attributes of the same shape then
1495 // create a new one and insert it.
1496 if (!PA) {
1497 // Coallocate entries after the AttributeListImpl itself.
1498 void *Mem = pImpl->Alloc.Allocate(
1499 AttributeListImpl::totalSizeToAlloc<AttributeSet>(AttrSets.size()),
1500 alignof(AttributeListImpl));
1501 PA = new (Mem) AttributeListImpl(AttrSets);
1502 pImpl->AttrsLists.InsertNode(PA, InsertPoint);
1503 }
1504
1505 // Return the AttributesList that we found or created.
1506 return AttributeList(PA);
1507}
1508
1511 ArrayRef<std::pair<unsigned, Attribute>> Attrs) {
1512 // If there are no attributes then return a null AttributesList pointer.
1513 if (Attrs.empty())
1514 return {};
1515
1517 "Misordered Attributes list!");
1518 assert(llvm::all_of(Attrs,
1519 [](const std::pair<unsigned, Attribute> &Pair) {
1520 return Pair.second.isValid();
1521 }) &&
1522 "Pointless attribute!");
1523
1524 // Create a vector if (unsigned, AttributeSetNode*) pairs from the attributes
1525 // list.
1527 for (ArrayRef<std::pair<unsigned, Attribute>>::iterator I = Attrs.begin(),
1528 E = Attrs.end(); I != E; ) {
1529 unsigned Index = I->first;
1531 while (I != E && I->first == Index) {
1532 AttrVec.push_back(I->second);
1533 ++I;
1534 }
1535
1536 AttrPairVec.emplace_back(Index, AttributeSet::get(C, AttrVec));
1537 }
1538
1539 return get(C, AttrPairVec);
1540}
1541
1544 ArrayRef<std::pair<unsigned, AttributeSet>> Attrs) {
1545 // If there are no attributes then return a null AttributesList pointer.
1546 if (Attrs.empty())
1547 return {};
1548
1550 "Misordered Attributes list!");
1551 assert(llvm::none_of(Attrs,
1552 [](const std::pair<unsigned, AttributeSet> &Pair) {
1553 return !Pair.second.hasAttributes();
1554 }) &&
1555 "Pointless attribute!");
1556
1557 unsigned MaxIndex = Attrs.back().first;
1558 // If the MaxIndex is FunctionIndex and there are other indices in front
1559 // of it, we need to use the largest of those to get the right size.
1560 if (MaxIndex == FunctionIndex && Attrs.size() > 1)
1561 MaxIndex = Attrs[Attrs.size() - 2].first;
1562
1563 SmallVector<AttributeSet, 4> AttrVec(attrIdxToArrayIdx(MaxIndex) + 1);
1564 for (const auto &Pair : Attrs)
1565 AttrVec[attrIdxToArrayIdx(Pair.first)] = Pair.second;
1566
1567 return getImpl(C, AttrVec);
1568}
1569
1571 AttributeSet RetAttrs,
1572 ArrayRef<AttributeSet> ArgAttrs) {
1573 // Scan from the end to find the last argument with attributes. Most
1574 // arguments don't have attributes, so it's nice if we can have fewer unique
1575 // AttributeListImpls by dropping empty attribute sets at the end of the list.
1576 unsigned NumSets = 0;
1577 for (size_t I = ArgAttrs.size(); I != 0; --I) {
1578 if (ArgAttrs[I - 1].hasAttributes()) {
1579 NumSets = I + 2;
1580 break;
1581 }
1582 }
1583 if (NumSets == 0) {
1584 // Check function and return attributes if we didn't have argument
1585 // attributes.
1586 if (RetAttrs.hasAttributes())
1587 NumSets = 2;
1588 else if (FnAttrs.hasAttributes())
1589 NumSets = 1;
1590 }
1591
1592 // If all attribute sets were empty, we can use the empty attribute list.
1593 if (NumSets == 0)
1594 return {};
1595
1597 AttrSets.reserve(NumSets);
1598 // If we have any attributes, we always have function attributes.
1599 AttrSets.push_back(FnAttrs);
1600 if (NumSets > 1)
1601 AttrSets.push_back(RetAttrs);
1602 if (NumSets > 2) {
1603 // Drop the empty argument attribute sets at the end.
1604 ArgAttrs = ArgAttrs.take_front(NumSets - 2);
1605 llvm::append_range(AttrSets, ArgAttrs);
1606 }
1607
1608 return getImpl(C, AttrSets);
1609}
1610
1612 AttributeSet Attrs) {
1613 if (!Attrs.hasAttributes())
1614 return {};
1615 Index = attrIdxToArrayIdx(Index);
1616 SmallVector<AttributeSet, 8> AttrSets(Index + 1);
1617 AttrSets[Index] = Attrs;
1618 return getImpl(C, AttrSets);
1619}
1620
1622 const AttrBuilder &B) {
1623 return get(C, Index, AttributeSet::get(C, B));
1624}
1625
1629 for (const auto K : Kinds)
1630 Attrs.emplace_back(Index, Attribute::get(C, K));
1631 return get(C, Attrs);
1632}
1633
1636 ArrayRef<uint64_t> Values) {
1637 assert(Kinds.size() == Values.size() && "Mismatched attribute values.");
1639 auto VI = Values.begin();
1640 for (const auto K : Kinds)
1641 Attrs.emplace_back(Index, Attribute::get(C, K, *VI++));
1642 return get(C, Attrs);
1643}
1644
1646 ArrayRef<StringRef> Kinds) {
1648 for (const auto &K : Kinds)
1649 Attrs.emplace_back(Index, Attribute::get(C, K));
1650 return get(C, Attrs);
1651}
1652
1655 if (Attrs.empty())
1656 return {};
1657 if (Attrs.size() == 1)
1658 return Attrs[0];
1659
1660 unsigned MaxSize = 0;
1661 for (const auto &List : Attrs)
1662 MaxSize = std::max(MaxSize, List.getNumAttrSets());
1663
1664 // If every list was empty, there is no point in merging the lists.
1665 if (MaxSize == 0)
1666 return {};
1667
1668 SmallVector<AttributeSet, 8> NewAttrSets(MaxSize);
1669 for (unsigned I = 0; I < MaxSize; ++I) {
1670 AttrBuilder CurBuilder(C);
1671 for (const auto &List : Attrs)
1672 CurBuilder.merge(AttrBuilder(C, List.getAttributes(I - 1)));
1673 NewAttrSets[I] = AttributeSet::get(C, CurBuilder);
1674 }
1675
1676 return getImpl(C, NewAttrSets);
1677}
1678
1681 Attribute::AttrKind Kind) const {
1682 AttributeSet Attrs = getAttributes(Index);
1683 if (Attrs.hasAttribute(Kind))
1684 return *this;
1685 // TODO: Insert at correct position and avoid sort.
1686 SmallVector<Attribute, 8> NewAttrs(Attrs.begin(), Attrs.end());
1687 NewAttrs.push_back(Attribute::get(C, Kind));
1688 return setAttributesAtIndex(C, Index, AttributeSet::get(C, NewAttrs));
1689}
1690
1692 StringRef Kind,
1693 StringRef Value) const {
1694 AttrBuilder B(C);
1695 B.addAttribute(Kind, Value);
1696 return addAttributesAtIndex(C, Index, B);
1697}
1698
1700 Attribute A) const {
1701 AttrBuilder B(C);
1702 B.addAttribute(A);
1703 return addAttributesAtIndex(C, Index, B);
1704}
1705
1706AttributeList AttributeList::setAttributesAtIndex(LLVMContext &C,
1707 unsigned Index,
1708 AttributeSet Attrs) const {
1709 Index = attrIdxToArrayIdx(Index);
1710 SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
1711 if (Index >= AttrSets.size())
1712 AttrSets.resize(Index + 1);
1713 AttrSets[Index] = Attrs;
1714
1715 // Remove trailing empty attribute sets.
1716 while (!AttrSets.empty() && !AttrSets.back().hasAttributes())
1717 AttrSets.pop_back();
1718 if (AttrSets.empty())
1719 return {};
1720 return AttributeList::getImpl(C, AttrSets);
1721}
1722
1724 unsigned Index,
1725 const AttrBuilder &B) const {
1726 if (!B.hasAttributes())
1727 return *this;
1728
1729 if (!pImpl)
1730 return AttributeList::get(C, {{Index, AttributeSet::get(C, B)}});
1731
1732 AttrBuilder Merged(C, getAttributes(Index));
1733 Merged.merge(B);
1734 return setAttributesAtIndex(C, Index, AttributeSet::get(C, Merged));
1735}
1736
1738 ArrayRef<unsigned> ArgNos,
1739 Attribute A) const {
1740 assert(llvm::is_sorted(ArgNos));
1741
1742 SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
1743 unsigned MaxIndex = attrIdxToArrayIdx(ArgNos.back() + FirstArgIndex);
1744 if (MaxIndex >= AttrSets.size())
1745 AttrSets.resize(MaxIndex + 1);
1746
1747 for (unsigned ArgNo : ArgNos) {
1748 unsigned Index = attrIdxToArrayIdx(ArgNo + FirstArgIndex);
1749 AttrBuilder B(C, AttrSets[Index]);
1750 B.addAttribute(A);
1751 AttrSets[Index] = AttributeSet::get(C, B);
1752 }
1753
1754 return getImpl(C, AttrSets);
1755}
1756
1759 Attribute::AttrKind Kind) const {
1760 AttributeSet Attrs = getAttributes(Index);
1761 AttributeSet NewAttrs = Attrs.removeAttribute(C, Kind);
1762 if (Attrs == NewAttrs)
1763 return *this;
1764 return setAttributesAtIndex(C, Index, NewAttrs);
1765}
1766
1768 unsigned Index,
1769 StringRef Kind) const {
1770 AttributeSet Attrs = getAttributes(Index);
1771 AttributeSet NewAttrs = Attrs.removeAttribute(C, Kind);
1772 if (Attrs == NewAttrs)
1773 return *this;
1774 return setAttributesAtIndex(C, Index, NewAttrs);
1775}
1776
1778 LLVMContext &C, unsigned Index, const AttributeMask &AttrsToRemove) const {
1779 AttributeSet Attrs = getAttributes(Index);
1780 AttributeSet NewAttrs = Attrs.removeAttributes(C, AttrsToRemove);
1781 // If nothing was removed, return the original list.
1782 if (Attrs == NewAttrs)
1783 return *this;
1784 return setAttributesAtIndex(C, Index, NewAttrs);
1785}
1786
1789 unsigned WithoutIndex) const {
1790 if (!pImpl)
1791 return {};
1792 if (attrIdxToArrayIdx(WithoutIndex) >= getNumAttrSets())
1793 return *this;
1794 return setAttributesAtIndex(C, WithoutIndex, AttributeSet());
1795}
1796
1798 uint64_t Bytes) const {
1799 AttrBuilder B(C);
1800 B.addDereferenceableAttr(Bytes);
1801 return addRetAttributes(C, B);
1802}
1803
1805 unsigned Index,
1806 uint64_t Bytes) const {
1807 AttrBuilder B(C);
1808 B.addDereferenceableAttr(Bytes);
1809 return addParamAttributes(C, Index, B);
1810}
1811
1814 uint64_t Bytes) const {
1815 AttrBuilder B(C);
1816 B.addDereferenceableOrNullAttr(Bytes);
1817 return addParamAttributes(C, Index, B);
1818}
1819
1821 const ConstantRange &CR) const {
1822 AttrBuilder B(C);
1823 B.addRangeAttr(CR);
1824 return addRetAttributes(C, B);
1825}
1826
1828 LLVMContext &C, unsigned Index, unsigned ElemSizeArg,
1829 const std::optional<unsigned> &NumElemsArg) const {
1830 AttrBuilder B(C);
1831 B.addAllocSizeAttr(ElemSizeArg, NumElemsArg);
1832 return addParamAttributes(C, Index, B);
1833}
1834
1835std::optional<AttributeList>
1837 // Trivial case, the two lists are equal.
1838 if (*this == Other)
1839 return *this;
1840
1842 auto IndexIt =
1843 index_iterator(std::max(getNumAttrSets(), Other.getNumAttrSets()));
1844 for (unsigned Idx : IndexIt) {
1845 auto IntersectedAS =
1846 getAttributes(Idx).intersectWith(C, Other.getAttributes(Idx));
1847 // If any index fails to intersect, fail.
1848 if (!IntersectedAS)
1849 return std::nullopt;
1850 if (!IntersectedAS->hasAttributes())
1851 continue;
1852 IntersectedAttrs.push_back(std::make_pair(Idx, *IntersectedAS));
1853 }
1854
1855 llvm::sort(IntersectedAttrs, llvm::less_first());
1856 return AttributeList::get(C, IntersectedAttrs);
1857}
1858
1859//===----------------------------------------------------------------------===//
1860// AttributeList Accessor Methods
1861//===----------------------------------------------------------------------===//
1862
1864 return getAttributes(ArgNo + FirstArgIndex);
1865}
1866
1868 return getAttributes(ReturnIndex);
1869}
1870
1873}
1874
1876 Attribute::AttrKind Kind) const {
1877 return getAttributes(Index).hasAttribute(Kind);
1878}
1879
1880bool AttributeList::hasAttributeAtIndex(unsigned Index, StringRef Kind) const {
1881 return getAttributes(Index).hasAttribute(Kind);
1882}
1883
1884bool AttributeList::hasAttributesAtIndex(unsigned Index) const {
1885 return getAttributes(Index).hasAttributes();
1886}
1887
1889 return pImpl && pImpl->hasFnAttribute(Kind);
1890}
1891
1894}
1895
1897 unsigned *Index) const {
1898 return pImpl && pImpl->hasAttrSomewhere(Attr, Index);
1899}
1900
1902 Attribute::AttrKind Kind) const {
1903 return getAttributes(Index).getAttribute(Kind);
1904}
1905
1907 StringRef Kind) const {
1908 return getAttributes(Index).getAttribute(Kind);
1909}
1910
1913}
1914
1916 return getAttributes(ArgNo + FirstArgIndex).getAlignment();
1917}
1918
1921}
1922
1925}
1926
1929}
1930
1932 return getAttributes(Index + FirstArgIndex).getByRefType();
1933}
1934
1937}
1938
1941}
1942
1944 return getAttributes(Index + FirstArgIndex).getElementType();
1945}
1946
1948 return getFnAttrs().getStackAlignment();
1949}
1950
1952 return getRetAttrs().getStackAlignment();
1953}
1954
1957}
1958
1960 return getParamAttrs(Index).getDereferenceableBytes();
1961}
1962
1965}
1966
1970}
1971
1972std::optional<ConstantRange>
1973AttributeList::getParamRange(unsigned ArgNo) const {
1974 auto RangeAttr = getParamAttrs(ArgNo).getAttribute(Attribute::Range);
1975 if (RangeAttr.isValid())
1976 return RangeAttr.getRange();
1977 return std::nullopt;
1978}
1979
1981 return getRetAttrs().getNoFPClass();
1982}
1983
1985 return getParamAttrs(Index).getNoFPClass();
1986}
1987
1989 return getFnAttrs().getUWTableKind();
1990}
1991
1993 return getFnAttrs().getAllocKind();
1994}
1995
1997 return getFnAttrs().getMemoryEffects();
1998}
1999
2000std::string AttributeList::getAsString(unsigned Index, bool InAttrGrp) const {
2001 return getAttributes(Index).getAsString(InAttrGrp);
2002}
2003
2005 Index = attrIdxToArrayIdx(Index);
2006 if (!pImpl || Index >= getNumAttrSets())
2007 return {};
2008 return pImpl->begin()[Index];
2009}
2010
2012 assert(!isEmpty() && "an empty attribute list has no parent context");
2014 pImpl->Profile(ID);
2015 void *Unused;
2016 return C.pImpl->AttrsLists.FindNodeOrInsertPos(ID, Unused) == pImpl;
2017}
2018
2020 return pImpl ? pImpl->begin() : nullptr;
2021}
2022
2024 return pImpl ? pImpl->end() : nullptr;
2025}
2026
2027//===----------------------------------------------------------------------===//
2028// AttributeList Introspection Methods
2029//===----------------------------------------------------------------------===//
2030
2032 return pImpl ? pImpl->NumAttrSets : 0;
2033}
2034
2036 O << "AttributeList[\n";
2037
2038 for (unsigned i : indexes()) {
2039 if (!getAttributes(i).hasAttributes())
2040 continue;
2041 O << " { ";
2042 switch (i) {
2044 O << "return";
2045 break;
2047 O << "function";
2048 break;
2049 default:
2050 O << "arg(" << i - AttrIndex::FirstArgIndex << ")";
2051 }
2052 O << " => " << getAsString(i) << " }\n";
2053 }
2054
2055 O << "]\n";
2056}
2057
2058#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2060#endif
2061
2062//===----------------------------------------------------------------------===//
2063// AttrBuilder Method Implementations
2064//===----------------------------------------------------------------------===//
2065
2067 append_range(Attrs, AS);
2068 assert(is_sorted(Attrs) && "AttributeSet should be sorted");
2069}
2070
2071void AttrBuilder::clear() { Attrs.clear(); }
2072
2073/// Attribute comparator that only compares attribute keys. Enum attributes are
2074/// sorted before string attributes.
2076 bool operator()(Attribute A0, Attribute A1) const {
2077 bool A0IsString = A0.isStringAttribute();
2078 bool A1IsString = A1.isStringAttribute();
2079 if (A0IsString) {
2080 if (A1IsString)
2081 return A0.getKindAsString() < A1.getKindAsString();
2082 else
2083 return false;
2084 }
2085 if (A1IsString)
2086 return true;
2087 return A0.getKindAsEnum() < A1.getKindAsEnum();
2088 }
2090 if (A0.isStringAttribute())
2091 return false;
2092 return A0.getKindAsEnum() < Kind;
2093 }
2094 bool operator()(Attribute A0, StringRef Kind) const {
2095 if (A0.isStringAttribute())
2096 return A0.getKindAsString() < Kind;
2097 return true;
2098 }
2099};
2100
2101template <typename K>
2103 Attribute Attr) {
2104 auto It = lower_bound(Attrs, Kind, AttributeComparator());
2105 if (It != Attrs.end() && It->hasAttribute(Kind))
2106 std::swap(*It, Attr);
2107 else
2108 Attrs.insert(It, Attr);
2109}
2110
2112 if (Attr.isStringAttribute())
2113 addAttributeImpl(Attrs, Attr.getKindAsString(), Attr);
2114 else
2115 addAttributeImpl(Attrs, Attr.getKindAsEnum(), Attr);
2116 return *this;
2117}
2118
2120 addAttributeImpl(Attrs, Kind, Attribute::get(Ctx, Kind));
2121 return *this;
2122}
2123
2125 addAttributeImpl(Attrs, A, Attribute::get(Ctx, A, V));
2126 return *this;
2127}
2128
2130 assert((unsigned)Val < Attribute::EndAttrKinds && "Attribute out of range!");
2131 auto It = lower_bound(Attrs, Val, AttributeComparator());
2132 if (It != Attrs.end() && It->hasAttribute(Val))
2133 Attrs.erase(It);
2134 return *this;
2135}
2136
2138 auto It = lower_bound(Attrs, A, AttributeComparator());
2139 if (It != Attrs.end() && It->hasAttribute(A))
2140 Attrs.erase(It);
2141 return *this;
2142}
2143
2144std::optional<uint64_t>
2146 assert(Attribute::isIntAttrKind(Kind) && "Not an int attribute");
2147 Attribute A = getAttribute(Kind);
2148 if (A.isValid())
2149 return A.getValueAsInt();
2150 return std::nullopt;
2151}
2152
2154 uint64_t Value) {
2155 return addAttribute(Attribute::get(Ctx, Kind, Value));
2156}
2157
2158std::optional<std::pair<unsigned, std::optional<unsigned>>>
2160 Attribute A = getAttribute(Attribute::AllocSize);
2161 if (A.isValid())
2162 return A.getAllocSizeArgs();
2163 return std::nullopt;
2164}
2165
2167 if (!Align)
2168 return *this;
2169
2170 assert(*Align <= llvm::Value::MaximumAlignment && "Alignment too large.");
2171 return addRawIntAttr(Attribute::Alignment, Align->value());
2172}
2173
2175 // Default alignment, allow the target to define how to align it.
2176 if (!Align)
2177 return *this;
2178
2179 assert(*Align <= 0x100 && "Alignment too large.");
2180 return addRawIntAttr(Attribute::StackAlignment, Align->value());
2181}
2182
2184 if (Bytes == 0) return *this;
2185
2186 return addRawIntAttr(Attribute::Dereferenceable, Bytes);
2187}
2188
2190 if (Bytes == 0)
2191 return *this;
2192
2193 return addRawIntAttr(Attribute::DereferenceableOrNull, Bytes);
2194}
2195
2198 const std::optional<unsigned> &NumElems) {
2199 return addAllocSizeAttrFromRawRepr(packAllocSizeArgs(ElemSize, NumElems));
2200}
2201
2203 // (0, 0) is our "not present" value, so we need to check for it here.
2204 assert(RawArgs && "Invalid allocsize arguments -- given allocsize(0, 0)");
2205 return addRawIntAttr(Attribute::AllocSize, RawArgs);
2206}
2207
2209 std::optional<unsigned> MaxValue) {
2210 return addVScaleRangeAttrFromRawRepr(packVScaleRangeArgs(MinValue, MaxValue));
2211}
2212
2214 // (0, 0) is not present hence ignore this case
2215 if (RawArgs == 0)
2216 return *this;
2217
2218 return addRawIntAttr(Attribute::VScaleRange, RawArgs);
2219}
2220
2222 if (Kind == UWTableKind::None)
2223 return *this;
2224 return addRawIntAttr(Attribute::UWTable, uint64_t(Kind));
2225}
2226
2228 return addRawIntAttr(Attribute::Memory, ME.toIntValue());
2229}
2230
2232 return addRawIntAttr(Attribute::Captures, CI.toIntValue());
2233}
2234
2236 if (Mask == fcNone)
2237 return *this;
2238
2239 return addRawIntAttr(Attribute::NoFPClass, Mask);
2240}
2241
2243 return addRawIntAttr(Attribute::AllocKind, static_cast<uint64_t>(Kind));
2244}
2245
2247 assert(Attribute::isTypeAttrKind(Kind) && "Not a type attribute");
2248 Attribute A = getAttribute(Kind);
2249 return A.isValid() ? A.getValueAsType() : nullptr;
2250}
2251
2253 return addAttribute(Attribute::get(Ctx, Kind, Ty));
2254}
2255
2257 return addTypeAttr(Attribute::ByVal, Ty);
2258}
2259
2261 return addTypeAttr(Attribute::StructRet, Ty);
2262}
2263
2265 return addTypeAttr(Attribute::ByRef, Ty);
2266}
2267
2269 return addTypeAttr(Attribute::Preallocated, Ty);
2270}
2271
2273 return addTypeAttr(Attribute::InAlloca, Ty);
2274}
2275
2277 const ConstantRange &CR) {
2278 if (CR.isFullSet())
2279 return *this;
2280
2281 return addAttribute(Attribute::get(Ctx, Kind, CR));
2282}
2283
2285 return addConstantRangeAttr(Attribute::Range, CR);
2286}
2287
2291 return addAttribute(Attribute::get(Ctx, Kind, Val));
2292}
2293
2295 return addConstantRangeListAttr(Attribute::Initializes, CRL.rangesRef());
2296}
2297
2299 if (I.hasMetadata(LLVMContext::MD_nonnull))
2300 addAttribute(Attribute::NonNull);
2301
2302 if (I.hasMetadata(LLVMContext::MD_noundef))
2303 addAttribute(Attribute::NoUndef);
2304
2305 if (const MDNode *Align = I.getMetadata(LLVMContext::MD_align)) {
2306 ConstantInt *CI = mdconst::extract<ConstantInt>(Align->getOperand(0));
2308 }
2309
2310 if (const MDNode *Dereferenceable =
2311 I.getMetadata(LLVMContext::MD_dereferenceable)) {
2312 ConstantInt *CI =
2313 mdconst::extract<ConstantInt>(Dereferenceable->getOperand(0));
2315 }
2316
2317 if (const MDNode *DereferenceableOrNull =
2318 I.getMetadata(LLVMContext::MD_dereferenceable_or_null)) {
2319 ConstantInt *CI =
2320 mdconst::extract<ConstantInt>(DereferenceableOrNull->getOperand(0));
2322 }
2323
2324 if (const MDNode *Range = I.getMetadata(LLVMContext::MD_range))
2326
2327 return *this;
2328}
2329
2331 // TODO: Could make this O(n) as we're merging two sorted lists.
2332 for (const auto &I : B.attrs())
2333 addAttribute(I);
2334
2335 return *this;
2336}
2337
2339 erase_if(Attrs, [&](Attribute A) { return AM.contains(A); });
2340 return *this;
2341}
2342
2344 return any_of(Attrs, [&](Attribute A) { return AM.contains(A); });
2345}
2346
2348 assert((unsigned)A < Attribute::EndAttrKinds && "Attribute out of range!");
2349 auto It = lower_bound(Attrs, A, AttributeComparator());
2350 if (It != Attrs.end() && It->hasAttribute(A))
2351 return *It;
2352 return {};
2353}
2354
2356 auto It = lower_bound(Attrs, A, AttributeComparator());
2357 if (It != Attrs.end() && It->hasAttribute(A))
2358 return *It;
2359 return {};
2360}
2361
2362std::optional<ConstantRange> AttrBuilder::getRange() const {
2363 const Attribute RangeAttr = getAttribute(Attribute::Range);
2364 if (RangeAttr.isValid())
2365 return RangeAttr.getRange();
2366 return std::nullopt;
2367}
2368
2370 return getAttribute(A).isValid();
2371}
2372
2374 return getAttribute(A).isValid();
2375}
2376
2378 return Attrs == B.Attrs;
2379}
2380
2381//===----------------------------------------------------------------------===//
2382// AttributeFuncs Function Defintions
2383//===----------------------------------------------------------------------===//
2384
2385/// Returns true if this is a type legal for the 'nofpclass' attribute. This
2386/// follows the same type rules as FPMathOperator.
2389}
2390
2391/// Which attributes cannot be applied to a type.
2393 AttributeSafetyKind ASK) {
2394 AttributeMask Incompatible;
2395
2396 if (!Ty->isIntegerTy()) {
2397 // Attributes that only apply to integers.
2398 if (ASK & ASK_SAFE_TO_DROP)
2399 Incompatible.addAttribute(Attribute::AllocAlign);
2400 if (ASK & ASK_UNSAFE_TO_DROP)
2401 Incompatible.addAttribute(Attribute::SExt).addAttribute(Attribute::ZExt);
2402 }
2403
2404 if (!Ty->isIntOrIntVectorTy()) {
2405 // Attributes that only apply to integers or vector of integers.
2406 if (ASK & ASK_SAFE_TO_DROP)
2407 Incompatible.addAttribute(Attribute::Range);
2408 } else {
2409 Attribute RangeAttr = AS.getAttribute(Attribute::Range);
2410 if (RangeAttr.isValid() &&
2411 RangeAttr.getRange().getBitWidth() != Ty->getScalarSizeInBits())
2412 Incompatible.addAttribute(Attribute::Range);
2413 }
2414
2415 if (!Ty->isPointerTy()) {
2416 // Attributes that only apply to pointers.
2417 if (ASK & ASK_SAFE_TO_DROP)
2418 Incompatible.addAttribute(Attribute::NoAlias)
2419 .addAttribute(Attribute::NonNull)
2420 .addAttribute(Attribute::ReadNone)
2421 .addAttribute(Attribute::ReadOnly)
2422 .addAttribute(Attribute::Dereferenceable)
2423 .addAttribute(Attribute::DereferenceableOrNull)
2424 .addAttribute(Attribute::Writable)
2425 .addAttribute(Attribute::DeadOnUnwind)
2426 .addAttribute(Attribute::Initializes)
2427 .addAttribute(Attribute::Captures)
2428 .addAttribute(Attribute::DeadOnReturn);
2429 if (ASK & ASK_UNSAFE_TO_DROP)
2430 Incompatible.addAttribute(Attribute::Nest)
2431 .addAttribute(Attribute::SwiftError)
2432 .addAttribute(Attribute::Preallocated)
2433 .addAttribute(Attribute::InAlloca)
2434 .addAttribute(Attribute::ByVal)
2435 .addAttribute(Attribute::StructRet)
2436 .addAttribute(Attribute::ByRef)
2437 .addAttribute(Attribute::ElementType)
2438 .addAttribute(Attribute::AllocatedPointer);
2439 }
2440
2441 // Attributes that only apply to pointers or vectors of pointers.
2442 if (!Ty->isPtrOrPtrVectorTy()) {
2443 if (ASK & ASK_SAFE_TO_DROP)
2444 Incompatible.addAttribute(Attribute::Alignment);
2445 }
2446
2447 if (ASK & ASK_SAFE_TO_DROP) {
2449 Incompatible.addAttribute(Attribute::NoFPClass);
2450 }
2451
2452 // Some attributes can apply to all "values" but there are no `void` values.
2453 if (Ty->isVoidTy()) {
2454 if (ASK & ASK_SAFE_TO_DROP)
2455 Incompatible.addAttribute(Attribute::NoUndef);
2456 }
2457
2458 return Incompatible;
2459}
2460
2462 AttributeMask AM;
2463 AM.addAttribute(Attribute::NoUndef);
2464 AM.addAttribute(Attribute::Dereferenceable);
2465 AM.addAttribute(Attribute::DereferenceableOrNull);
2466 return AM;
2467}
2468
2469/// Callees with dynamic denormal modes are compatible with any caller mode.
2470static bool denormModeCompatible(DenormalMode CallerMode,
2471 DenormalMode CalleeMode) {
2472 if (CallerMode == CalleeMode || CalleeMode == DenormalMode::getDynamic())
2473 return true;
2474
2475 // If they don't exactly match, it's OK if the mismatched component is
2476 // dynamic.
2477 if (CalleeMode.Input == CallerMode.Input &&
2478 CalleeMode.Output == DenormalMode::Dynamic)
2479 return true;
2480
2481 if (CalleeMode.Output == CallerMode.Output &&
2482 CalleeMode.Input == DenormalMode::Dynamic)
2483 return true;
2484 return false;
2485}
2486
2487static bool checkDenormMode(const Function &Caller, const Function &Callee) {
2488 DenormalMode CallerMode = Caller.getDenormalModeRaw();
2489 DenormalMode CalleeMode = Callee.getDenormalModeRaw();
2490
2491 if (denormModeCompatible(CallerMode, CalleeMode)) {
2492 DenormalMode CallerModeF32 = Caller.getDenormalModeF32Raw();
2493 DenormalMode CalleeModeF32 = Callee.getDenormalModeF32Raw();
2494 if (CallerModeF32 == DenormalMode::getInvalid())
2495 CallerModeF32 = CallerMode;
2496 if (CalleeModeF32 == DenormalMode::getInvalid())
2497 CalleeModeF32 = CalleeMode;
2498 return denormModeCompatible(CallerModeF32, CalleeModeF32);
2499 }
2500
2501 return false;
2502}
2503
2504static bool checkStrictFP(const Function &Caller, const Function &Callee) {
2505 // Do not inline strictfp function into non-strictfp one. It would require
2506 // conversion of all FP operations in host function to constrained intrinsics.
2507 return !Callee.getAttributes().hasFnAttr(Attribute::StrictFP) ||
2508 Caller.getAttributes().hasFnAttr(Attribute::StrictFP);
2509}
2510
2511template<typename AttrClass>
2512static bool isEqual(const Function &Caller, const Function &Callee) {
2513 return Caller.getFnAttribute(AttrClass::getKind()) ==
2514 Callee.getFnAttribute(AttrClass::getKind());
2515}
2516
2517static bool isEqual(const Function &Caller, const Function &Callee,
2518 const StringRef &AttrName) {
2519 return Caller.getFnAttribute(AttrName) == Callee.getFnAttribute(AttrName);
2520}
2521
2522/// Compute the logical AND of the attributes of the caller and the
2523/// callee.
2524///
2525/// This function sets the caller's attribute to false if the callee's attribute
2526/// is false.
2527template<typename AttrClass>
2528static void setAND(Function &Caller, const Function &Callee) {
2529 if (AttrClass::isSet(Caller, AttrClass::getKind()) &&
2530 !AttrClass::isSet(Callee, AttrClass::getKind()))
2531 AttrClass::set(Caller, AttrClass::getKind(), false);
2532}
2533
2534/// Compute the logical OR of the attributes of the caller and the
2535/// callee.
2536///
2537/// This function sets the caller's attribute to true if the callee's attribute
2538/// is true.
2539template<typename AttrClass>
2540static void setOR(Function &Caller, const Function &Callee) {
2541 if (!AttrClass::isSet(Caller, AttrClass::getKind()) &&
2542 AttrClass::isSet(Callee, AttrClass::getKind()))
2543 AttrClass::set(Caller, AttrClass::getKind(), true);
2544}
2545
2546/// If the inlined function had a higher stack protection level than the
2547/// calling function, then bump up the caller's stack protection level.
2548static void adjustCallerSSPLevel(Function &Caller, const Function &Callee) {
2549 // If the calling function has *no* stack protection level (e.g. it was built
2550 // with Clang's -fno-stack-protector or no_stack_protector attribute), don't
2551 // change it as that could change the program's semantics.
2552 if (!Caller.hasStackProtectorFnAttr())
2553 return;
2554
2555 // If upgrading the SSP attribute, clear out the old SSP Attributes first.
2556 // Having multiple SSP attributes doesn't actually hurt, but it adds useless
2557 // clutter to the IR.
2558 AttributeMask OldSSPAttr;
2559 OldSSPAttr.addAttribute(Attribute::StackProtect)
2560 .addAttribute(Attribute::StackProtectStrong)
2561 .addAttribute(Attribute::StackProtectReq);
2562
2563 if (Callee.hasFnAttribute(Attribute::StackProtectReq)) {
2564 Caller.removeFnAttrs(OldSSPAttr);
2565 Caller.addFnAttr(Attribute::StackProtectReq);
2566 } else if (Callee.hasFnAttribute(Attribute::StackProtectStrong) &&
2567 !Caller.hasFnAttribute(Attribute::StackProtectReq)) {
2568 Caller.removeFnAttrs(OldSSPAttr);
2569 Caller.addFnAttr(Attribute::StackProtectStrong);
2570 } else if (Callee.hasFnAttribute(Attribute::StackProtect) &&
2571 !Caller.hasFnAttribute(Attribute::StackProtectReq) &&
2572 !Caller.hasFnAttribute(Attribute::StackProtectStrong))
2573 Caller.addFnAttr(Attribute::StackProtect);
2574}
2575
2576/// If the inlined function required stack probes, then ensure that
2577/// the calling function has those too.
2578static void adjustCallerStackProbes(Function &Caller, const Function &Callee) {
2579 if (!Caller.hasFnAttribute("probe-stack") &&
2580 Callee.hasFnAttribute("probe-stack")) {
2581 Caller.addFnAttr(Callee.getFnAttribute("probe-stack"));
2582 }
2583}
2584
2585/// If the inlined function defines the size of guard region
2586/// on the stack, then ensure that the calling function defines a guard region
2587/// that is no larger.
2588static void
2590 Attribute CalleeAttr = Callee.getFnAttribute("stack-probe-size");
2591 if (CalleeAttr.isValid()) {
2592 Attribute CallerAttr = Caller.getFnAttribute("stack-probe-size");
2593 if (CallerAttr.isValid()) {
2594 uint64_t CallerStackProbeSize, CalleeStackProbeSize;
2595 CallerAttr.getValueAsString().getAsInteger(0, CallerStackProbeSize);
2596 CalleeAttr.getValueAsString().getAsInteger(0, CalleeStackProbeSize);
2597
2598 if (CallerStackProbeSize > CalleeStackProbeSize) {
2599 Caller.addFnAttr(CalleeAttr);
2600 }
2601 } else {
2602 Caller.addFnAttr(CalleeAttr);
2603 }
2604 }
2605}
2606
2607/// If the inlined function defines a min legal vector width, then ensure
2608/// the calling function has the same or larger min legal vector width. If the
2609/// caller has the attribute, but the callee doesn't, we need to remove the
2610/// attribute from the caller since we can't make any guarantees about the
2611/// caller's requirements.
2612/// This function is called after the inlining decision has been made so we have
2613/// to merge the attribute this way. Heuristics that would use
2614/// min-legal-vector-width to determine inline compatibility would need to be
2615/// handled as part of inline cost analysis.
2616static void
2618 Attribute CallerAttr = Caller.getFnAttribute("min-legal-vector-width");
2619 if (CallerAttr.isValid()) {
2620 Attribute CalleeAttr = Callee.getFnAttribute("min-legal-vector-width");
2621 if (CalleeAttr.isValid()) {
2622 uint64_t CallerVectorWidth, CalleeVectorWidth;
2623 CallerAttr.getValueAsString().getAsInteger(0, CallerVectorWidth);
2624 CalleeAttr.getValueAsString().getAsInteger(0, CalleeVectorWidth);
2625 if (CallerVectorWidth < CalleeVectorWidth)
2626 Caller.addFnAttr(CalleeAttr);
2627 } else {
2628 // If the callee doesn't have the attribute then we don't know anything
2629 // and must drop the attribute from the caller.
2630 Caller.removeFnAttr("min-legal-vector-width");
2631 }
2632 }
2633}
2634
2635/// If the inlined function has null_pointer_is_valid attribute,
2636/// set this attribute in the caller post inlining.
2637static void
2639 if (Callee.nullPointerIsDefined() && !Caller.nullPointerIsDefined()) {
2640 Caller.addFnAttr(Attribute::NullPointerIsValid);
2641 }
2642}
2643
2644struct EnumAttr {
2645 static bool isSet(const Function &Fn,
2646 Attribute::AttrKind Kind) {
2647 return Fn.hasFnAttribute(Kind);
2648 }
2649
2650 static void set(Function &Fn,
2651 Attribute::AttrKind Kind, bool Val) {
2652 if (Val)
2653 Fn.addFnAttr(Kind);
2654 else
2655 Fn.removeFnAttr(Kind);
2656 }
2657};
2658
2660 static bool isSet(const Function &Fn,
2661 StringRef Kind) {
2662 auto A = Fn.getFnAttribute(Kind);
2663 return A.getValueAsString() == "true";
2664 }
2665
2666 static void set(Function &Fn,
2667 StringRef Kind, bool Val) {
2668 Fn.addFnAttr(Kind, Val ? "true" : "false");
2669 }
2670};
2671
2672#define GET_ATTR_NAMES
2673#define ATTRIBUTE_ENUM(ENUM_NAME, DISPLAY_NAME) \
2674 struct ENUM_NAME##Attr : EnumAttr { \
2675 static enum Attribute::AttrKind getKind() { \
2676 return llvm::Attribute::ENUM_NAME; \
2677 } \
2678 };
2679#define ATTRIBUTE_STRBOOL(ENUM_NAME, DISPLAY_NAME) \
2680 struct ENUM_NAME##Attr : StrBoolAttr { \
2681 static StringRef getKind() { return #DISPLAY_NAME; } \
2682 };
2683#include "llvm/IR/Attributes.inc"
2684
2685#define GET_ATTR_COMPAT_FUNC
2686#include "llvm/IR/Attributes.inc"
2687
2689 const Function &Callee) {
2690 return hasCompatibleFnAttrs(Caller, Callee);
2691}
2692
2694 const Function &B) {
2695 return hasCompatibleFnAttrs(A, B);
2696}
2697
2699 const Function &Callee) {
2700 mergeFnAttrs(Caller, Callee);
2701}
2702
2704 const Function &ToMerge) {
2705
2706 // We merge functions so that they meet the most general case.
2707 // For example, if the NoNansFPMathAttr is set in one function, but not in
2708 // the other, in the merged function we can say that the NoNansFPMathAttr
2709 // is not set.
2710 // However if we have the SpeculativeLoadHardeningAttr set true in one
2711 // function, but not the other, we make sure that the function retains
2712 // that aspect in the merged function.
2713 mergeFnAttrs(Base, ToMerge);
2714}
2715
2717 uint64_t Width) {
2718 Attribute Attr = Fn.getFnAttribute("min-legal-vector-width");
2719 if (Attr.isValid()) {
2720 uint64_t OldWidth;
2721 Attr.getValueAsString().getAsInteger(0, OldWidth);
2722 if (Width > OldWidth)
2723 Fn.addFnAttr("min-legal-vector-width", llvm::utostr(Width));
2724 }
2725}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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:87
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:760
@ RetAttr
Definition: Attributes.cpp:763
@ IntersectPreserve
Definition: Attributes.cpp:764
@ IntersectMin
Definition: Attributes.cpp:766
@ IntersectCustom
Definition: Attributes.cpp:767
@ ParamAttr
Definition: Attributes.cpp:762
@ FnAttr
Definition: Attributes.cpp:761
@ IntersectPropertyMask
Definition: Attributes.cpp:768
@ IntersectAnd
Definition: Attributes.cpp:765
static void adjustCallerStackProbeSize(Function &Caller, const Function &Callee)
If the inlined function defines the size of guard region on the stack, then ensure that the calling f...
static void adjustCallerSSPLevel(Function &Caller, const Function &Callee)
If the inlined function had a higher stack protection level than the calling function,...
static bool checkStrictFP(const Function &Caller, const Function &Callee)
static uint64_t packAllocSizeArgs(unsigned ElemSizeArg, const std::optional< unsigned > &NumElemsArg)
Definition: Attributes.cpp:61
static uint64_t packVScaleRangeArgs(unsigned MinValue, std::optional< unsigned > MaxValue)
Definition: Attributes.cpp:81
static bool hasIntersectProperty(Attribute::AttrKind Kind, AttributeProperty Prop)
Definition: Attributes.cpp:797
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:59
static std::pair< unsigned, std::optional< unsigned > > unpackAllocSizeArgs(uint64_t Num)
Definition: Attributes.cpp:71
static bool checkDenormMode(const Function &Caller, const Function &Callee)
static unsigned getAttributeProperties(Attribute::AttrKind Kind)
Definition: Attributes.cpp:774
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:780
static const char * getModRefStr(ModRefInfo MR)
Definition: Attributes.cpp:522
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")
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Definition: Compiler.h:638
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
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
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
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...
LLVM_ABI void Profile(FoldingSetNodeID &id) const
Used to insert APInt objects, or objects that contain APInt objects, into FoldingSets.
Definition: APInt.cpp:156
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:156
ArrayRef< T > take_front(size_t N=1) const
Return a copy of *this with only the first N elements.
Definition: ArrayRef.h:224
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:147
iterator begin() const
Definition: ArrayRef.h:135
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:142
LLVM_ABI AttrBuilder & addStructRetAttr(Type *Ty)
This turns a sret type into the form used internally in Attribute.
LLVM_ABI AttrBuilder & addAlignmentAttr(MaybeAlign Align)
This turns an alignment into the form used internally in Attribute.
LLVM_ABI AttrBuilder & addVScaleRangeAttrFromRawRepr(uint64_t RawVScaleRangeRepr)
Add a vscale_range attribute, using the representation returned by Attribute.getIntValue().
LLVM_ABI void clear()
LLVM_ABI std::optional< uint64_t > getRawIntAttr(Attribute::AttrKind Kind) const
Return raw (possibly packed/encoded) value of integer attribute or std::nullopt if not set.
LLVM_ABI AttrBuilder & addAllocKindAttr(AllocFnKind Kind)
LLVM_ABI Attribute getAttribute(Attribute::AttrKind Kind) const
Return Attribute with the given Kind.
LLVM_ABI AttrBuilder & addByRefAttr(Type *Ty)
This turns a byref type into the form used internally in Attribute.
LLVM_ABI AttrBuilder & addNoFPClassAttr(FPClassTest NoFPClassMask)
LLVM_ABI AttrBuilder & addCapturesAttr(CaptureInfo CI)
Add captures attribute.
LLVM_ABI bool overlaps(const AttributeMask &AM) const
Return true if the builder has any attribute that's in the specified builder.
LLVM_ABI AttrBuilder & merge(const AttrBuilder &B)
Add the attributes from the builder.
LLVM_ABI 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:1083
LLVM_ABI AttrBuilder & addRawIntAttr(Attribute::AttrKind Kind, uint64_t Value)
Add integer attribute with raw value (packed/encoded if necessary).
LLVM_ABI AttrBuilder & addAttribute(Attribute::AttrKind Val)
Add an attribute to the builder.
LLVM_ABI AttrBuilder & addByValAttr(Type *Ty)
This turns a byval type into the form used internally in Attribute.
LLVM_ABI AttrBuilder & addDereferenceableAttr(uint64_t Bytes)
This turns the number of dereferenceable bytes into the form used internally in Attribute.
LLVM_ABI AttrBuilder & addInitializesAttr(const ConstantRangeList &CRL)
Add initializes attribute.
LLVM_ABI bool contains(Attribute::AttrKind A) const
Return true if the builder has the specified attribute.
LLVM_ABI AttrBuilder & addMemoryAttr(MemoryEffects ME)
Add memory effect attribute.
LLVM_ABI AttrBuilder & addConstantRangeListAttr(Attribute::AttrKind Kind, ArrayRef< ConstantRange > Val)
Add a ConstantRangeList attribute with the given ranges.
LLVM_ABI AttrBuilder & addConstantRangeAttr(Attribute::AttrKind Kind, const ConstantRange &CR)
Add a ConstantRange attribute with the given range.
LLVM_ABI AttrBuilder & addAllocSizeAttrFromRawRepr(uint64_t RawAllocSizeRepr)
Add an allocsize attribute, using the representation returned by Attribute.getIntValue().
LLVM_ABI AttrBuilder & addPreallocatedAttr(Type *Ty)
This turns a preallocated type into the form used internally in Attribute.
LLVM_ABI AttrBuilder & addStackAlignmentAttr(MaybeAlign Align)
This turns a stack alignment into the form used internally in Attribute.
LLVM_ABI AttrBuilder & addInAllocaAttr(Type *Ty)
This turns an inalloca type into the form used internally in Attribute.
LLVM_ABI AttrBuilder & removeAttribute(Attribute::AttrKind Val)
Remove an attribute from the builder.
LLVM_ABI bool operator==(const AttrBuilder &B) const
LLVM_ABI Type * getTypeAttr(Attribute::AttrKind Kind) const
Retrieve type for the given type attribute.
LLVM_ABI AttrBuilder & remove(const AttributeMask &AM)
Remove the attributes from the builder.
LLVM_ABI AttrBuilder & addFromEquivalentMetadata(const Instruction &I)
Add 0 or more parameter attributes which are equivalent to metadata attached to I.
LLVM_ABI std::optional< ConstantRange > getRange() const
Retrieve the range if the attribute exists (std::nullopt is returned otherwise).
LLVM_ABI AttrBuilder & addDereferenceableOrNullAttr(uint64_t Bytes)
This turns the number of dereferenceable_or_null bytes into the form used internally in Attribute.
LLVM_ABI AttrBuilder & addTypeAttr(Attribute::AttrKind Kind, Type *Ty)
Add a type attribute with the given type.
LLVM_ABI std::optional< std::pair< unsigned, std::optional< unsigned > > > getAllocSizeArgs() const
Retrieve the allocsize args, or std::nullopt if the attribute does not exist.
LLVM_ABI AttrBuilder & addAllocSizeAttr(unsigned ElemSizeArg, const std::optional< unsigned > &NumElemsArg)
This turns one (or two) ints into the form used internally in Attribute.
LLVM_ABI AttrBuilder & addRangeAttr(const ConstantRange &CR)
Add range attribute.
LLVM_ABI 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
int cmp(const AttributeImpl &AI, bool KindOnly) const
Used to sort attributes.
Definition: Attributes.cpp:878
bool isConstantRangeAttribute() const
Definition: AttributeImpl.h:66
bool hasAttribute(Attribute::AttrKind A) const
Definition: Attributes.cpp:825
void Profile(FoldingSetNodeID &ID) const
Definition: AttributeImpl.h:95
Type * getValueAsType() const
Definition: Attributes.cpp:861
Attribute::AttrKind getKindAsEnum() const
Definition: Attributes.cpp:835
bool operator<(const AttributeImpl &AI) const
Used when sorting the attributes.
Definition: Attributes.cpp:913
uint64_t getValueAsInt() const
Definition: Attributes.cpp:841
bool isIntAttribute() const
Definition: AttributeImpl.h:63
bool isTypeAttribute() const
Definition: AttributeImpl.h:65
bool getValueAsBool() const
Definition: Attributes.cpp:846
StringRef getKindAsString() const
Definition: Attributes.cpp:851
StringRef getValueAsString() const
Definition: Attributes.cpp:856
bool isEnumAttribute() const
Definition: AttributeImpl.h:62
ArrayRef< ConstantRange > getValueAsConstantRangeList() const
Definition: Attributes.cpp:872
bool isConstantRangeListAttribute() const
Definition: AttributeImpl.h:69
bool isStringAttribute() const
Definition: AttributeImpl.h:64
const ConstantRange & getValueAsConstantRange() const
Definition: Attributes.cpp:866
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
LLVM_ABI bool hasAttributeAtIndex(unsigned Index, Attribute::AttrKind Kind) const
Return true if the attribute exists at the given index.
LLVM_ABI Type * getParamStructRetType(unsigned ArgNo) const
Return the sret type for the specified function parameter.
LLVM_ABI AttributeList addDereferenceableParamAttr(LLVMContext &C, unsigned ArgNo, uint64_t Bytes) const
Add the dereferenceable attribute to the attribute set at the given arg index.
LLVM_ABI AttributeList removeAttributeAtIndex(LLVMContext &C, unsigned Index, Attribute::AttrKind Kind) const
Remove the specified attribute at the specified index from this attribute list.
LLVM_ABI AttributeList addRangeRetAttr(LLVMContext &C, const ConstantRange &CR) const
Add the range attribute to the attribute set at the return value index.
LLVM_ABI bool hasAttributesAtIndex(unsigned Index) const
Return true if attribute exists at the given index.
friend class AttributeListImpl
Definition: Attributes.h:516
LLVM_ABI AttributeSet getFnAttrs() const
The function attributes are returned.
index_iterator indexes() const
Use this to iterate over the valid attribute indexes.
Definition: Attributes.h:1027
LLVM_ABI 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:517
AttributeList()=default
LLVM_ABI iterator begin() const
LLVM_ABI 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:636
LLVM_ABI void print(raw_ostream &O) const
LLVM_ABI AttributeList addDereferenceableRetAttr(LLVMContext &C, uint64_t Bytes) const
Add the dereferenceable attribute to the attribute set at the given index.
static LLVM_ABI AttributeList get(LLVMContext &C, ArrayRef< std::pair< unsigned, Attribute > > Attrs)
Create an AttributeList with the specified parameters in it.
LLVM_ABI AllocFnKind getAllocKind() const
bool isEmpty() const
Return true if there are no attributes.
Definition: Attributes.h:1039
LLVM_ABI AttributeSet getRetAttrs() const
The attributes for the ret value are returned.
friend class AttrBuilder
Definition: Attributes.h:515
LLVM_ABI bool hasFnAttr(Attribute::AttrKind Kind) const
Return true if the attribute exists for the function.
LLVM_ABI uint64_t getParamDereferenceableBytes(unsigned Index) const
Get the number of dereferenceable bytes (or zero if unknown) of an arg.
LLVM_ABI MaybeAlign getParamAlignment(unsigned ArgNo) const
Return the alignment for the specified function parameter.
LLVM_ABI 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.
LLVM_ABI iterator end() const
LLVM_ABI Type * getParamInAllocaType(unsigned ArgNo) const
Return the inalloca type for the specified function parameter.
LLVM_ABI unsigned getNumAttrSets() const
LLVM_ABI FPClassTest getRetNoFPClass() const
Get the disallowed floating-point classes of the return value.
LLVM_ABI std::string getAsString(unsigned Index, bool InAttrGrp=false) const
Return the attributes at the index as a string.
LLVM_ABI UWTableKind getUWTableKind() const
Get the unwind table kind requested for the function.
LLVM_ABI MaybeAlign getRetAlignment() const
Return the alignment of the return value.
LLVM_ABI Type * getParamElementType(unsigned ArgNo) const
Return the elementtype type for the specified function parameter.
LLVM_ABI Attribute getAttributeAtIndex(unsigned Index, Attribute::AttrKind Kind) const
Return the attribute object that exists at the given index.
LLVM_ABI Type * getParamPreallocatedType(unsigned ArgNo) const
Return the preallocated type for the specified function parameter.
LLVM_ABI bool hasParentContext(LLVMContext &C) const
Return true if this attribute list belongs to the LLVMContext.
const AttributeSet * iterator
Definition: Attributes.h:995
LLVM_ABI MaybeAlign getFnStackAlignment() const
Get the stack alignment of the function.
LLVM_ABI AttributeList addAttributesAtIndex(LLVMContext &C, unsigned Index, const AttrBuilder &B) const
Add attributes to the attribute set at the given index.
LLVM_ABI Type * getParamByValType(unsigned ArgNo) const
Return the byval type for the specified function parameter.
LLVM_ABI MaybeAlign getParamStackAlignment(unsigned ArgNo) const
Return the stack alignment for the specified function parameter.
LLVM_ABI uint64_t getRetDereferenceableBytes() const
Get the number of dereferenceable bytes (or zero if unknown) of the return value.
LLVM_ABI AttributeList addAllocSizeParamAttr(LLVMContext &C, unsigned ArgNo, unsigned ElemSizeArg, const std::optional< unsigned > &NumElemsArg) const
Add the allocsize attribute to the attribute set at the given arg index.
LLVM_ABI uint64_t getParamDereferenceableOrNullBytes(unsigned ArgNo) const
Get the number of dereferenceable_or_null bytes (or zero if unknown) of an arg.
LLVM_ABI 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.
LLVM_ABI AttributeSet getAttributes(unsigned Index) const
The attributes for the specified index are returned.
LLVM_ABI FPClassTest getParamNoFPClass(unsigned ArgNo) const
Get the disallowed floating-point classes of the argument value.
LLVM_ABI std::optional< AttributeList > intersectWith(LLVMContext &C, AttributeList Other) const
Try to intersect this AttributeList with Other.
LLVM_ABI Type * getParamByRefType(unsigned ArgNo) const
Return the byref type for the specified function parameter.
LLVM_ABI AttributeList addAttributeAtIndex(LLVMContext &C, unsigned Index, Attribute::AttrKind Kind) const
Add an attribute to the attribute set at the given index.
LLVM_ABI 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:664
LLVM_ABI std::optional< ConstantRange > getParamRange(unsigned ArgNo) const
Get range (or std::nullopt if unknown) of an arg.
LLVM_ABI uint64_t getRetDereferenceableOrNullBytes() const
Get the number of dereferenceable_or_null bytes (or zero if unknown) of the return value.
LLVM_ABI void dump() const
AttributeList addParamAttribute(LLVMContext &C, unsigned ArgNo, Attribute::AttrKind Kind) const
Add an argument attribute to the list.
Definition: Attributes.h:644
LLVM_ABI MemoryEffects getMemoryEffects() const
Returns memory effects of the function.
AttributeMask & addAttribute(Attribute::AttrKind Val)
Add an attribute to the mask.
Definition: AttributeMask.h:44
bool contains(Attribute::AttrKind A) const
Return true if the builder has the specified attribute.
Definition: AttributeMask.h:67
MaybeAlign getStackAlignment() const
uint64_t getDereferenceableOrNullBytes() const
std::optional< unsigned > getVScaleRangeMax() const
bool hasAttribute(Attribute::AttrKind Kind) const
Type * getAttributeType(Attribute::AttrKind Kind) const
AllocFnKind getAllocKind() const
CaptureInfo getCaptureInfo() const
unsigned getVScaleRangeMin() const
MaybeAlign getAlignment() const
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)
FPClassTest getNoFPClass() const
Attribute getAttribute(Attribute::AttrKind Kind) const
LLVM_ABI AllocFnKind getAllocKind() const
bool hasAttributes() const
Return true if attributes exists in this set.
Definition: Attributes.h:427
LLVM_ABI AttributeSet removeAttribute(LLVMContext &C, Attribute::AttrKind Kind) const
Remove the specified attribute from this set.
Definition: Attributes.cpp:957
LLVM_ABI Type * getInAllocaType() const
LLVM_ABI Type * getByValType() const
LLVM_ABI AttributeSet addAttributes(LLVMContext &C, AttributeSet AS) const
Add attributes to the attribute set.
Definition: Attributes.cpp:944
LLVM_ABI MemoryEffects getMemoryEffects() const
LLVM_ABI bool hasAttribute(Attribute::AttrKind Kind) const
Return true if the attribute exists in this set.
LLVM_ABI std::optional< AttributeSet > intersectWith(LLVMContext &C, AttributeSet Other) const
Try to intersect this AttributeSet with Other.
Definition: Attributes.cpp:985
LLVM_ABI Type * getStructRetType() const
LLVM_ABI std::string getAsString(bool InAttrGrp=false) const
LLVM_ABI unsigned getVScaleRangeMin() const
LLVM_ABI std::optional< std::pair< unsigned, std::optional< unsigned > > > getAllocSizeArgs() const
LLVM_ABI UWTableKind getUWTableKind() const
LLVM_ABI bool hasParentContext(LLVMContext &C) const
Return true if this attribute set belongs to the LLVMContext.
LLVM_ABI iterator begin() const
LLVM_ABI iterator end() const
LLVM_ABI AttributeSet removeAttributes(LLVMContext &C, const AttributeMask &AttrsToRemove) const
Remove the specified attributes from this set.
Definition: Attributes.cpp:973
LLVM_ABI std::optional< unsigned > getVScaleRangeMax() const
LLVM_ABI MaybeAlign getStackAlignment() const
LLVM_ABI Attribute getAttribute(Attribute::AttrKind Kind) const
Return the attribute object.
LLVM_ABI Type * getPreallocatedType() const
LLVM_ABI uint64_t getDereferenceableBytes() const
LLVM_ABI MaybeAlign getAlignment() const
LLVM_ABI FPClassTest getNoFPClass() const
LLVM_ABI Type * getElementType() const
LLVM_ABI Type * getByRefType() const
LLVM_ABI CaptureInfo getCaptureInfo() const
AttributeSet()=default
AttributeSet is a trivially copyable value type.
static LLVM_ABI AttributeSet get(LLVMContext &C, const AttrBuilder &B)
Definition: Attributes.cpp:921
LLVM_ABI uint64_t getDereferenceableOrNullBytes() const
LLVM_ABI unsigned getNumAttributes() const
Return the number of attributes in this set.
LLVM_ABI AttributeSet addAttribute(LLVMContext &C, Attribute::AttrKind Kind) const
Add an argument attribute.
Definition: Attributes.cpp:929
void dump() const
LLVM_ABI bool isStringAttribute() const
Return true if the attribute is a string (target-dependent) attribute.
Definition: Attributes.cpp:356
static LLVM_ABI Attribute getWithStructRetType(LLVMContext &Context, Type *Ty)
Definition: Attributes.cpp:260
static LLVM_ABI Attribute::AttrKind getAttrKindFromName(StringRef AttrName)
Definition: Attributes.cpp:313
LLVM_ABI bool isEnumAttribute() const
Return true if the attribute is an Attribute::AttrKind type.
Definition: Attributes.cpp:348
static LLVM_ABI Attribute getWithStackAlignment(LLVMContext &Context, Align Alignment)
Definition: Attributes.cpp:239
LLVM_ABI const ConstantRange & getRange() const
Returns the value of the range attribute.
Definition: Attributes.cpp:510
static LLVM_ABI bool intersectWithCustom(AttrKind Kind)
Definition: Attributes.cpp:817
LLVM_ABI bool isIntAttribute() const
Return true if the attribute is an integer attribute.
Definition: Attributes.cpp:352
static LLVM_ABI Attribute getWithByRefType(LLVMContext &Context, Type *Ty)
Definition: Attributes.cpp:264
LLVM_ABI std::optional< unsigned > getVScaleRangeMax() const
Returns the maximum value for the vscale_range attribute or std::nullopt when unknown.
Definition: Attributes.cpp:474
LLVM_ABI uint64_t getValueAsInt() const
Return the attribute's value as an integer.
Definition: Attributes.cpp:379
LLVM_ABI unsigned getVScaleRangeMin() const
Returns the minimum value for the vscale_range attribute.
Definition: Attributes.cpp:468
LLVM_ABI AllocFnKind getAllocKind() const
Definition: Attributes.cpp:486
LLVM_ABI bool isConstantRangeAttribute() const
Return true if the attribute is a ConstantRange attribute.
Definition: Attributes.cpp:364
static LLVM_ABI Attribute getWithAllocKind(LLVMContext &Context, AllocFnKind Kind)
Definition: Attributes.cpp:303
LLVM_ABI StringRef getKindAsString() const
Return the attribute's kind as a string.
Definition: Attributes.cpp:393
static LLVM_ABI Attribute getWithPreallocatedType(LLVMContext &Context, Type *Ty)
Definition: Attributes.cpp:268
static LLVM_ABI bool intersectWithMin(AttrKind Kind)
Definition: Attributes.cpp:814
static LLVM_ABI Attribute get(LLVMContext &Context, AttrKind Kind, uint64_t Val=0)
Return a uniquified Attribute object.
Definition: Attributes.cpp:95
static LLVM_ABI bool canUseAsRetAttr(AttrKind Kind)
Definition: Attributes.cpp:793
static bool isTypeAttrKind(AttrKind Kind)
Definition: Attributes.h:107
LLVM_ABI std::string getAsString(bool InAttrGrp=false) const
The Attribute is converted to a string of equivalent mnemonic.
Definition: Attributes.cpp:536
LLVM_ABI uint64_t getDereferenceableOrNullBytes() const
Returns the number of dereferenceable_or_null bytes from the dereferenceable_or_null attribute.
Definition: Attributes.cpp:454
static LLVM_ABI Attribute getWithDereferenceableBytes(LLVMContext &Context, uint64_t Bytes)
Definition: Attributes.cpp:244
LLVM_ABI std::pair< unsigned, std::optional< unsigned > > getAllocSizeArgs() const
Returns the argument numbers for the allocsize attribute.
Definition: Attributes.cpp:462
static LLVM_ABI Attribute getWithUWTableKind(LLVMContext &Context, UWTableKind Kind)
Definition: Attributes.cpp:276
LLVM_ABI FPClassTest getNoFPClass() const
Return the FPClassTest for nofpclass.
Definition: Attributes.cpp:504
static LLVM_ABI Attribute getWithAllocSizeArgs(LLVMContext &Context, unsigned ElemSizeArg, const std::optional< unsigned > &NumElemsArg)
Definition: Attributes.cpp:296
LLVM_ABI Attribute::AttrKind getKindAsEnum() const
Return the attribute's kind as an enum (Attribute::AttrKind).
Definition: Attributes.cpp:372
Attribute()=default
LLVM_ABI bool getValueAsBool() const
Return the attribute's value as a boolean.
Definition: Attributes.cpp:386
LLVM_ABI ArrayRef< ConstantRange > getInitializes() const
Returns the value of the initializes attribute.
Definition: Attributes.cpp:516
LLVM_ABI const ConstantRange & getValueAsConstantRange() const
Return the attribute's value as a ConstantRange.
Definition: Attributes.cpp:414
LLVM_ABI uint64_t getDereferenceableBytes() const
Returns the number of dereferenceable bytes from the dereferenceable attribute.
Definition: Attributes.cpp:447
static LLVM_ABI Attribute getWithVScaleRangeArgs(LLVMContext &Context, unsigned MinValue, unsigned MaxValue)
Definition: Attributes.cpp:307
LLVM_ABI MemoryEffects getMemoryEffects() const
Returns memory effects.
Definition: Attributes.cpp:492
LLVM_ABI void Profile(FoldingSetNodeID &ID) const
Definition: Attributes.cpp:756
LLVM_ABI UWTableKind getUWTableKind() const
Definition: Attributes.cpp:480
static LLVM_ABI Attribute getWithDereferenceableOrNullBytes(LLVMContext &Context, uint64_t Bytes)
Definition: Attributes.cpp:250
LLVM_ABI ArrayRef< ConstantRange > getValueAsConstantRangeList() const
Return the attribute's value as a ConstantRange array.
Definition: Attributes.cpp:420
LLVM_ABI StringRef getValueAsString() const
Return the attribute's value as a string.
Definition: Attributes.cpp:400
static LLVM_ABI bool isExistingAttribute(StringRef Name)
Return true if the provided string matches the IR name of an attribute.
Definition: Attributes.cpp:336
bool hasKindAsEnum() const
Returns true if the attribute's kind can be represented as an enum (Enum, Integer,...
Definition: Attributes.h:233
static LLVM_ABI StringRef getNameFromAttrKind(Attribute::AttrKind AttrKind)
Definition: Attributes.cpp:322
static LLVM_ABI bool canUseAsFnAttr(AttrKind Kind)
Definition: Attributes.cpp:785
static LLVM_ABI bool intersectWithAnd(AttrKind Kind)
Definition: Attributes.cpp:811
static LLVM_ABI Attribute getWithNoFPClass(LLVMContext &Context, FPClassTest Mask)
Definition: Attributes.cpp:286
AttrKind
This enumeration lists the attributes that can be associated with parameters, function results,...
Definition: Attributes.h:88
@ None
No attributes have been set.
Definition: Attributes.h:90
@ EndAttrKinds
Sentinel value useful for loops.
Definition: Attributes.h:93
static bool isConstantRangeAttrKind(AttrKind Kind)
Definition: Attributes.h:110
LLVM_ABI bool hasParentContext(LLVMContext &C) const
Return true if this attribute belongs to the LLVMContext.
Definition: Attributes.cpp:731
LLVM_ABI bool isTypeAttribute() const
Return true if the attribute is a type attribute.
Definition: Attributes.cpp:360
static LLVM_ABI Attribute getWithCaptureInfo(LLVMContext &Context, CaptureInfo CI)
Definition: Attributes.cpp:291
static LLVM_ABI Attribute getWithInAllocaType(LLVMContext &Context, Type *Ty)
Definition: Attributes.cpp:272
static bool isIntAttrKind(AttrKind Kind)
Definition: Attributes.h:104
static bool isConstantRangeListAttrKind(AttrKind Kind)
Definition: Attributes.h:113
LLVM_ABI bool isConstantRangeListAttribute() const
Return true if the attribute is a ConstantRangeList attribute.
Definition: Attributes.cpp:368
static LLVM_ABI Attribute getWithByValType(LLVMContext &Context, Type *Ty)
Definition: Attributes.cpp:256
LLVM_ABI bool hasAttribute(AttrKind Val) const
Return true if the attribute is present.
Definition: Attributes.cpp:426
static bool isEnumAttrKind(AttrKind Kind)
Definition: Attributes.h:101
static LLVM_ABI Attribute getWithMemoryEffects(LLVMContext &Context, MemoryEffects ME)
Definition: Attributes.cpp:281
static LLVM_ABI bool canUseAsParamAttr(AttrKind Kind)
Definition: Attributes.cpp:789
bool isValid() const
Return true if the attribute is any kind of attribute.
Definition: Attributes.h:223
LLVM_ABI MaybeAlign getStackAlignment() const
Returns the stack alignment field of an attribute as a byte alignment value.
Definition: Attributes.cpp:441
LLVM_ABI MaybeAlign getAlignment() const
Returns the alignment field of an attribute as a byte alignment value.
Definition: Attributes.cpp:435
LLVM_ABI CaptureInfo getCaptureInfo() const
Returns information from captures attribute.
Definition: Attributes.cpp:498
static LLVM_ABI bool intersectMustPreserve(AttrKind Kind)
Definition: Attributes.cpp:808
LLVM_ABI int cmpKind(Attribute A) const
Used to sort attribute by kind.
Definition: Attributes.cpp:739
LLVM_ABI bool operator<(Attribute A) const
Less-than operator. Useful for sorting the attributes list.
Definition: Attributes.cpp:749
static LLVM_ABI Attribute getWithAlignment(LLVMContext &Context, Align Alignment)
Return a uniquified Attribute object that has the specific alignment set.
Definition: Attributes.cpp:234
LLVM_ABI Type * getValueAsType() const
Return the attribute's value as a Type.
Definition: Attributes.cpp:407
LLVM_ATTRIBUTE_RETURNS_NONNULL void * Allocate(size_t Size, Align Alignment)
Allocate space at the specified alignment.
Definition: Allocator.h:149
Represents which components of the pointer may be captured in which location.
Definition: ModRef.h:354
static CaptureInfo createFromIntValue(uint32_t Data)
Definition: ModRef.h:425
static CaptureInfo all()
Create CaptureInfo that may capture all components of the pointer.
Definition: ModRef.h:370
uint32_t toIntValue() const
Convert CaptureInfo into an encoded integer value (used by captures attribute).
Definition: ModRef.h:432
This is the shared class of boolean and integer constants.
Definition: Constants.h:87
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
Definition: Constants.h:163
static size_t totalSizeToAlloc(ArrayRef< ConstantRange > Val)
This class represents a list of constant ranges.
ArrayRef< ConstantRange > rangesRef() const
LLVM_ABI void print(raw_ostream &OS) const
Print out the ranges to a stream.
This class represents a range of values.
Definition: ConstantRange.h:47
const APInt & getLower() const
Return the lower value for this range.
LLVM_ABI bool isFullSet() const
Return true if this set contains all of the elements possible for this data-type.
const APInt & getUpper() const
Return the upper value for this range.
LLVM_ABI ConstantRange unionWith(const ConstantRange &CR, PreferredRangeType Type=Smallest) const
Return the range that results from the union of this range with another range.
uint32_t getBitWidth() const
Get the bit width of this ConstantRange.
static bool isSupportedFloatingPointType(Type *Ty)
Returns true if Ty is a supported floating-point type for phi, select, or call FPMathOperators.
Definition: Operator.h:344
FoldingSetNodeID - This class is used to gather all the unique data bits of a node.
Definition: FoldingSet.h:330
void addFnAttr(Attribute::AttrKind Kind)
Add function attributes to this function.
Definition: Function.cpp:637
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
Definition: Function.cpp:762
void removeFnAttr(Attribute::AttrKind Kind)
Remove function attributes from this function.
Definition: Function.cpp:685
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition: Function.cpp:727
FoldingSet< AttributeImpl > AttrsSet
BumpPtrAllocator Alloc
FoldingSet< AttributeSetNode > AttrsSetNodes
FoldingSet< AttributeListImpl > AttrsLists
SpecificBumpPtrAllocator< ConstantRangeAttributeImpl > ConstantRangeAttributeAlloc
std::vector< ConstantRangeListAttributeImpl * > ConstantRangeListAttributes
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:68
Metadata node.
Definition: Metadata.h:1077
ModRefInfo getModRef(Location Loc) const
Get ModRefInfo for the given Location.
Definition: ModRef.h:188
static MemoryEffectsBase createFromIntValue(uint32_t Data)
Create MemoryEffectsBase from an encoded integer value (used by memory attribute).
Definition: ModRef.h:177
static auto locations()
Returns iterator over all supported location kinds.
Definition: ModRef.h:98
uint32_t toIntValue() const
Convert MemoryEffectsBase into an encoded integer value (used by memory attribute).
Definition: ModRef.h:183
static MemoryEffectsBase unknown()
Create MemoryEffectsBase that can read and write any memory.
Definition: ModRef.h:115
size_t size() const
Definition: SmallVector.h:79
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:574
reference emplace_back(ArgTypes &&... Args)
Definition: SmallVector.h:938
void reserve(size_type N)
Definition: SmallVector.h:664
void resize(size_type N)
Definition: SmallVector.h:639
void push_back(const T &Elt)
Definition: SmallVector.h:414
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1197
static size_t totalSizeToAlloc(StringRef Kind, StringRef Val)
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:55
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
Definition: StringRef.h:480
std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:233
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:151
int compare(StringRef RHS) const
compare - Compare two strings; the result is negative, zero, or positive if this string is lexicograp...
Definition: StringRef.h:187
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:43
R Default(T Value)
Definition: StringSwitch.h:177
const T * getTrailingObjects() const
Returns a pointer to the trailing object array of the given type (which must be one of those specifie...
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:82
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
bool isIntOrIntVectorTy() const
Return true if this is an integer type or a vector of integer types.
Definition: Type.h:246
bool isPointerTy() const
True if this is an instance of PointerType.
Definition: Type.h:267
bool isPtrOrPtrVectorTy() const
Return true if this is a pointer type or a vector of pointer types.
Definition: Type.h:270
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition: Type.h:240
LLVM_ABI void print(raw_ostream &O, bool IsForDebug=false, bool NoDetails=false) const
Print the current type.
bool isVoidTy() const
Return true if this is 'void'.
Definition: Type.h:139
LLVM Value Representation.
Definition: Value.h:75
static constexpr uint64_t MaximumAlignment
Definition: Value.h:830
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:662
This class provides various memory handling functions that manipulate MemoryBlock instances.
Definition: Memory.h:54
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
LLVM_ABI bool areInlineCompatible(const Function &Caller, const Function &Callee)
LLVM_ABI AttributeMask getUBImplyingAttributes()
Get param/return attributes which imply immediate undefined behavior if an invalid value is passed.
LLVM_ABI bool isNoFPClassCompatibleType(Type *Ty)
Returns true if this is a type legal for the 'nofpclass' attribute.
LLVM_ABI bool areOutlineCompatible(const Function &A, const Function &B)
Checks if there are any incompatible function attributes between A and B.
LLVM_ABI void updateMinLegalVectorWidthAttr(Function &Fn, uint64_t Width)
Update min-legal-vector-width if it is in Attribute and less than Width.
LLVM_ABI void mergeAttributesForOutlining(Function &Base, const Function &ToMerge)
Merges the functions attributes from ToMerge into function Base.
LLVM_ABI AttributeMask typeIncompatible(Type *Ty, AttributeSet AS, AttributeSafetyKind ASK=ASK_ALL)
Which attributes cannot be applied to a type.
LLVM_ABI void mergeAttributesForInlining(Function &Caller, const Function &Callee)
Merge caller's and callee's attributes.
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:1744
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:1702
AllocFnKind
Definition: Attributes.h:51
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
Definition: STLExtras.h:2155
LLVM_ABI ConstantRange getConstantRangeFromMetadata(const MDNode &RangeMD)
Parse out a conservative ConstantRange from !range metadata.
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:1751
UWTableKind
Definition: CodeGen.h:148
@ None
No unwind table requested.
void sort(IteratorTy Start, IteratorTy End)
Definition: STLExtras.h:1669
FPClassTest
Floating-point class tests, supported by 'is_fpclass' intrinsic.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:207
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:1758
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:1939
ModRefInfo
Flags indicating whether a memory access modifies or references memory.
Definition: ModRef.h:28
@ 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.
@ ErrnoMem
Errno memory.
@ ArgMem
Access to memory via argument pointers.
@ Other
Any other memory.
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
@ InaccessibleMem
Memory that is inaccessible via LLVM IR.
auto lower_bound(R &&Range, T &&Value)
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
Definition: STLExtras.h:2013
OutputIt copy(R &&Range, OutputIt Out)
Definition: STLExtras.h:1854
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:2139
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition: BitVector.h:858
Attribute comparator that only compares attribute keys.
bool operator()(Attribute A0, StringRef Kind) const
bool operator()(Attribute A0, Attribute A1) const
bool operator()(Attribute A0, Attribute::AttrKind Kind) const
static void set(Function &Fn, Attribute::AttrKind Kind, bool Val)
static bool isSet(const Function &Fn, Attribute::AttrKind Kind)
static bool isSet(const Function &Fn, StringRef Kind)
static void set(Function &Fn, StringRef Kind, bool Val)
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
uint64_t value() const
This is a hole in the type system and should not be abused.
Definition: Alignment.h:85
Represent subnormal handling kind for floating point instruction inputs and outputs.
DenormalModeKind Input
Denormal treatment kind for floating point instruction inputs in the default floating-point environme...
@ Dynamic
Denormals have unknown treatment.
static constexpr DenormalMode getInvalid()
DenormalModeKind Output
Denormal flushing mode for floating point instruction results in the default floating point environme...
static constexpr DenormalMode getDynamic()
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Definition: Alignment.h:117
Align valueOrOne() const
For convenience, returns a valid alignment or 1 if undefined.
Definition: Alignment.h:141
Function object to check whether the first component of a container supported by std::get (like std::...
Definition: STLExtras.h:1472