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