25#include "llvm/Config/llvm-config.h"
62 const std::optional<unsigned> &NumElemsArg) {
64 "Attempting to pack a reserved value");
70static std::pair<unsigned, std::optional<unsigned>>
72 unsigned NumElems = Num & std::numeric_limits<unsigned>::max();
73 unsigned ElemSizeArg = Num >> 32;
75 std::optional<unsigned> NumElemsArg;
77 NumElemsArg = NumElems;
78 return std::make_pair(ElemSizeArg, NumElemsArg);
82 std::optional<unsigned> MaxValue) {
83 return uint64_t(MinValue) << 32 | MaxValue.value_or(0);
86static std::pair<unsigned, std::optional<unsigned>>
88 unsigned MaxValue =
Value & std::numeric_limits<unsigned>::max();
89 unsigned MinValue =
Value >> 32;
91 return std::make_pair(MinValue,
92 MaxValue > 0 ? MaxValue : std::optional<unsigned>());
99 "Not an enum or int attribute");
103 assert(Val == 0 &&
"Value must be zero for enum attributes");
116 pImpl->IntAttrs.insert(PA, Token);
134 pImpl->StringAttrs.insert(PA, Token);
151 pImpl->TypeAttrs.insert(PA, Token);
161 "Not a ConstantRange attribute");
175 PA =
new (pImpl->ConstantRangeAttributeAlloc.Allocate())
177 pImpl->AttrsSet.insert(PA, Token);
187 "Not a ConstantRangeList attribute");
191 ID.AddInteger(Val.
size());
192 for (
auto &CR : Val) {
193 CR.getLower().Profile(ID);
194 CR.getUpper().Profile(ID);
208 void *Mem = pImpl->Alloc.Allocate(
212 pImpl->AttrsSet.insert(PA, Token);
213 pImpl->ConstantRangeListAttributes.push_back(
223 return get(Context, Alignment,
A.value());
227 assert(
A <= 0x100 &&
"Alignment too large.");
228 return get(Context, StackAlignment,
A.value());
233 assert(Bytes &&
"Bytes must be non-zero.");
234 return get(Context, Dereferenceable, Bytes);
239 assert(Bytes &&
"Bytes must be non-zero.");
240 return get(Context, DereferenceableOrNull, Bytes);
244 return get(Context, ByVal, Ty);
248 return get(Context, StructRet, Ty);
252 return get(Context, ByRef, Ty);
256 return get(Context, Preallocated, Ty);
260 return get(Context, InAlloca, Ty);
275 return get(Context, NoFPClass, ClassMask);
289 const std::optional<unsigned> &NumElemsArg) {
290 assert(!(ElemSizeArg == 0 && NumElemsArg == 0) &&
291 "Invalid allocsize arguments -- given allocsize(0, 0)");
296 return get(Context, AllocKind,
static_cast<uint64_t
>(Kind));
307#define GET_ATTR_NAMES
308#define ATTRIBUTE_ENUM(ENUM_NAME, DISPLAY_NAME) \
309 .Case(#DISPLAY_NAME, Attribute::ENUM_NAME)
310#include "llvm/IR/Attributes.inc"
316#define GET_ATTR_NAMES
317#define ATTRIBUTE_ENUM(ENUM_NAME, DISPLAY_NAME) \
318 case Attribute::ENUM_NAME: \
319 return #DISPLAY_NAME;
320#include "llvm/IR/Attributes.inc"
330#define GET_ATTR_NAMES
331#define ATTRIBUTE_ALL(ENUM_NAME, DISPLAY_NAME) .Case(#DISPLAY_NAME, true)
332#include "llvm/IR/Attributes.inc"
341 return pImpl && pImpl->isEnumAttribute();
345 return pImpl && pImpl->isIntAttribute();
349 return pImpl && pImpl->isStringAttribute();
353 return pImpl && pImpl->isTypeAttribute();
357 return pImpl && pImpl->isConstantRangeAttribute();
361 return pImpl && pImpl->isConstantRangeListAttribute();
365 if (!pImpl)
return None;
367 "Invalid attribute type to get the kind as an enum!");
368 return pImpl->getKindAsEnum();
372 if (!pImpl)
return 0;
374 "Expected the attribute to be an integer attribute!");
375 return pImpl->getValueAsInt();
379 if (!pImpl)
return false;
381 "Expected the attribute to be a string attribute!");
382 return pImpl->getValueAsBool();
386 if (!pImpl)
return {};
388 "Invalid attribute type to get the kind as a string!");
389 return pImpl->getKindAsString();
393 if (!pImpl)
return {};
395 "Invalid attribute type to get the value as a string!");
396 return pImpl->getValueAsString();
400 if (!pImpl)
return {};
402 "Invalid attribute type to get the value as a type!");
403 return pImpl->getValueAsType();
408 "Invalid attribute type to get the value as a ConstantRange!");
409 return pImpl->getValueAsConstantRange();
414 "Invalid attribute type to get the value as a ConstantRangeList!");
415 return pImpl->getValueAsConstantRangeList();
419 return (pImpl && pImpl->hasAttribute(Kind)) || (!pImpl && Kind ==
None);
424 return pImpl && pImpl->hasAttribute(Kind);
429 "Trying to get alignment from non-alignment attribute!");
435 "Trying to get alignment from non-alignment attribute!");
441 "Trying to get dereferenceable bytes from "
442 "non-dereferenceable attribute!");
443 return pImpl->getValueAsInt();
448 "Trying to get dead_on_return bytes from"
449 "a parameter without such an attribute!");
455 "Trying to get dereferenceable bytes from "
456 "non-dereferenceable attribute!");
457 return pImpl->getValueAsInt();
460std::pair<unsigned, std::optional<unsigned>>
463 "Trying to get allocsize args from non-allocsize attribute");
469 "Trying to get vscale args from non-vscale attribute");
475 "Trying to get vscale args from non-vscale attribute");
481 "Trying to get unwind table kind from non-uwtable attribute");
487 "Trying to get allockind value from non-allockind attribute");
493 "Can only call getMemoryEffects() on memory attribute");
499 "Can only call getCaptureInfo() on captures attribute");
509 "Can only call getNoFPClass() on nofpclass attribute");
510 return static_cast<FPClassTest>(pImpl->getValueAsInt());
515 "Trying to get range args from non-range attribute");
516 return pImpl->getValueAsConstantRange();
521 "Trying to get initializes attr from non-ConstantRangeList attribute");
522 return pImpl->getValueAsConstantRangeList();
540 if (!pImpl)
return {};
564 auto AttrWithBytesToString = [&](
const char *Name) {
571 return AttrWithBytesToString(
"alignstack");
574 return AttrWithBytesToString(
"dereferenceable");
577 return AttrWithBytesToString(
"dereferenceable_or_null");
581 if (DeadBytes == std::numeric_limits<uint64_t>::max())
582 return "dead_on_return";
583 return AttrWithBytesToString(
"dead_on_return");
588 std::optional<unsigned> NumElems;
592 ?
"allocsize(" +
Twine(ElemSize) +
"," +
Twine(*NumElems) +
")"
593 :
"allocsize(" +
Twine(ElemSize) +
")")
600 return (
"vscale_range(" +
Twine(MinValue) +
"," +
601 Twine(MaxValue.value_or(0)) +
")")
626 return (
"allockind(\"" +
647 bool TargetPrintedForAll =
false;
653 if (!
First && !TargetPrintedForAll)
661 if (!TargetPrintedForAll) {
662 OS <<
"target_mem: ";
664 TargetPrintedForAll =
true;
675 OS <<
"inaccessiblemem: ";
683 OS <<
"target_mem0: ";
686 OS <<
"target_mem1: ";
702 std::string Result =
"denormal_fpenv(";
706 FPEnv.
print(OS,
true);
713 std::string Result =
"nofpclass";
733 OS <<
"initializes(";
753 const auto &AttrVal = pImpl->getValueAsString();
754 if (!AttrVal.empty()) {
767 assert(
isValid() &&
"invalid Attribute doesn't refer to any context");
770 if (pImpl->isEnumAttribute())
771 return pI->
EnumAttrs[pImpl->getKindAsEnum() - FirstEnumAttr] == pImpl;
772 if (pImpl->isIntAttribute())
773 return pI->
IntAttrs.lookup({pImpl->getKindAsEnum(), pImpl->getValueAsInt()},
775 if (pImpl->isStringAttribute())
777 {pImpl->getKindAsString(), pImpl->getValueAsString()}, Token) ==
779 if (pImpl->isTypeAttribute())
781 {pImpl->getKindAsEnum(), pImpl->getValueAsType()}, Token) ==
785 return pI->
AttrsSet.lookup(ID, Token) == pImpl;
789 if (!pImpl && !
A.pImpl)
795 return pImpl->cmp(*
A.pImpl,
true);
799 if (!pImpl && !
A.pImpl)
return false;
800 if (!pImpl)
return true;
801 if (!
A.pImpl)
return false;
802 return *pImpl < *
A.pImpl;
817#define GET_ATTR_PROP_TABLE
818#include "llvm/IR/Attributes.inc"
821 unsigned Index = Kind - 1;
822 assert(Index < std::size(AttrPropTable) &&
"Invalid attribute kind");
823 return AttrPropTable[Index];
853 "Unknown intersect property");
919 ->getConstantRangeValue();
925 ->getConstantRangeListValue();
947 "Unclear how to compare range list");
964 return cmp(AI,
false) < 0;
983 B.addAttribute(Kind);
990 B.addAttribute(Kind,
Value);
995 const AttributeSet AS)
const {
1002 AttrBuilder
B(
C, *
this);
1003 B.merge(AttrBuilder(
C, AS));
1008 const AttrBuilder &
B)
const {
1012 if (!
B.hasAttributes())
1015 AttrBuilder Merged(
C, *
this);
1017 return get(
C, Merged);
1023 AttrBuilder
B(
C, *
this);
1024 B.removeAttribute(Kind);
1031 AttrBuilder
B(
C, *
this);
1032 B.removeAttribute(Kind);
1038 AttrBuilder
B(
C, *
this);
1040 if (!
B.overlaps(Attrs))
1047std::optional<AttributeSet>
1052 AttrBuilder Intersected(
C);
1054 auto ItBegin0 =
begin();
1055 auto ItEnd0 =
end();
1056 auto ItBegin1 =
Other.begin();
1057 auto ItEnd1 =
Other.end();
1059 while (ItBegin0 != ItEnd0 || ItBegin1 != ItEnd1) {
1064 if (ItBegin1 == ItEnd1)
1065 Attr0 = *ItBegin0++;
1066 else if (ItBegin0 == ItEnd0)
1067 Attr0 = *ItBegin1++;
1069 int Cmp = ItBegin0->cmpKind(*ItBegin1);
1071 Attr0 = *ItBegin0++;
1072 Attr1 = *ItBegin1++;
1074 Attr0 = *ItBegin0++;
1076 Attr0 = *ItBegin1++;
1078 assert(Attr0.
isValid() &&
"Iteration should always yield a valid attr");
1080 auto IntersectEq = [&]() {
1085 Intersected.addAttribute(Attr0);
1093 return std::nullopt;
1102 return std::nullopt;
1108 "Iterator picked up two different attributes in the same iteration");
1113 "Invalid attr type of intersectAnd");
1114 Intersected.addAttribute(Kind);
1121 "Invalid attr type of intersectMin");
1123 Intersected.addRawIntAttr(Kind, NewVal);
1129 case Attribute::Alignment:
1132 Intersected.addAlignmentAttr(
1136 case Attribute::Memory:
1140 case Attribute::Captures:
1144 case Attribute::NoFPClass:
1148 case Attribute::Range: {
1153 Intersected.addRangeAttr(NewRange);
1164 return std::nullopt;
1168 if (Kind == Attribute::ByVal &&
1170 Other.getAttribute(Attribute::Alignment))
1171 return std::nullopt;
1174 return get(
C, Intersected);
1178 return SetNode ? SetNode->getNumAttributes() : 0;
1182 return SetNode ? SetNode->hasAttribute(Kind) :
false;
1186 return SetNode ? SetNode->hasAttribute(Kind) :
false;
1190 return SetNode ? SetNode->getAttribute(Kind) :
Attribute();
1194 return SetNode ? SetNode->getAttribute(Kind) :
Attribute();
1198 return SetNode ? SetNode->getAlignment() : std::nullopt;
1202 return SetNode ? SetNode->getStackAlignment() : std::nullopt;
1206 return SetNode ? SetNode->getDereferenceableBytes() : 0;
1214 return SetNode ? SetNode->getDereferenceableOrNullBytes() : 0;
1218 return SetNode ? SetNode->getAttributeType(Attribute::ByRef) :
nullptr;
1222 return SetNode ? SetNode->getAttributeType(Attribute::ByVal) :
nullptr;
1226 return SetNode ? SetNode->getAttributeType(Attribute::StructRet) :
nullptr;
1230 return SetNode ? SetNode->getAttributeType(Attribute::Preallocated) :
nullptr;
1234 return SetNode ? SetNode->getAttributeType(Attribute::InAlloca) :
nullptr;
1238 return SetNode ? SetNode->getAttributeType(Attribute::ElementType) :
nullptr;
1241std::optional<std::pair<unsigned, std::optional<unsigned>>>
1244 return SetNode->getAllocSizeArgs();
1245 return std::nullopt;
1249 return SetNode ? SetNode->getVScaleRangeMin() : 1;
1253 return SetNode ? SetNode->getVScaleRangeMax() : std::nullopt;
1273 return SetNode ? SetNode->getNoFPClass() :
fcNone;
1277 return SetNode ? SetNode->getAsString(InAttrGrp) :
"";
1283 return C.pImpl->AttrsSetNodes.lookup(SetNode->getKey(), Token) == SetNode;
1287 return SetNode ? SetNode->begin() :
nullptr;
1291 return SetNode ? SetNode->end() :
nullptr;
1294#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1307 : NumAttrs(Attrs.
size()) {
1311 for (
const auto &
I : *
this) {
1312 if (
I.isStringAttribute())
1313 StringAttrs.insert({
I.getKindAsString(),
I });
1315 AvailableAttrs.addAttribute(
I.getKindAsEnum());
1323 return getSorted(
C, SortedAttrs);
1329 if (SortedAttrs.
empty())
1341 C.pImpl->AttrsSetNodes.insert(PA, Token);
1349 return getSorted(
C,
B.attrs());
1353 return StringAttrs.count(Kind);
1356std::optional<Attribute>
1360 return std::nullopt;
1365 std::lower_bound(
begin(),
end() - StringAttrs.size(), Kind,
1367 return A.getKindAsEnum() < Kind;
1369 assert(
I !=
end() &&
I->hasAttribute(Kind) &&
"Presence check failed?");
1374 if (
auto A = findEnumAttribute(Kind))
1380 return StringAttrs.lookup(Kind);
1384 if (
auto A = findEnumAttribute(Attribute::Alignment))
1385 return A->getAlignment();
1386 return std::nullopt;
1390 if (
auto A = findEnumAttribute(Attribute::StackAlignment))
1391 return A->getStackAlignment();
1392 return std::nullopt;
1396 if (
auto A = findEnumAttribute(Kind))
1397 return A->getValueAsType();
1402 if (
auto A = findEnumAttribute(Attribute::Dereferenceable))
1403 return A->getDereferenceableBytes();
1408 if (
auto A = findEnumAttribute(Attribute::DeadOnReturn))
1409 return A->getDeadOnReturnInfo();
1414 if (
auto A = findEnumAttribute(Attribute::DereferenceableOrNull))
1415 return A->getDereferenceableOrNullBytes();
1419std::optional<std::pair<unsigned, std::optional<unsigned>>>
1421 if (
auto A = findEnumAttribute(Attribute::AllocSize))
1422 return A->getAllocSizeArgs();
1423 return std::nullopt;
1427 if (
auto A = findEnumAttribute(Attribute::VScaleRange))
1428 return A->getVScaleRangeMin();
1433 if (
auto A = findEnumAttribute(Attribute::VScaleRange))
1434 return A->getVScaleRangeMax();
1435 return std::nullopt;
1439 if (
auto A = findEnumAttribute(Attribute::UWTable))
1440 return A->getUWTableKind();
1445 if (
auto A = findEnumAttribute(Attribute::AllocKind))
1446 return A->getAllocKind();
1451 if (
auto A = findEnumAttribute(Attribute::Memory))
1452 return A->getMemoryEffects();
1457 if (
auto A = findEnumAttribute(Attribute::Captures))
1458 return A->getCaptureInfo();
1463 if (
auto A = findEnumAttribute(Attribute::NoFPClass))
1464 return A->getNoFPClass();
1473 Str +=
I->getAsString(InAttrGrp);
1489 : NumAttrSets(Sets.
size()) {
1490 assert(!Sets.
empty() &&
"pointless AttributeListImpl");
1498 if (!
I.isStringAttribute())
1499 AvailableFunctionAttrs.addAttribute(
I.getKindAsEnum());
1501 for (
const auto &Set : Sets)
1502 for (
const auto &
I : Set)
1503 if (!
I.isStringAttribute())
1504 AvailableSomewhereAttrs.addAttribute(
I.getKindAsEnum());
1508 unsigned *Index)
const {
1509 if (!AvailableSomewhereAttrs.hasAttribute(Kind))
1513 for (
unsigned I = 0, E = NumAttrSets;
I != E; ++
I) {
1514 if (
begin()[
I].hasAttribute(Kind)) {
1525#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1537 assert(!AttrSets.
empty() &&
"pointless AttributeListImpl");
1547 void *Mem = pImpl->
Alloc.Allocate(
1560 ArrayRef<std::pair<unsigned, Attribute>> Attrs) {
1566 "Misordered Attributes list!");
1568 [](
const std::pair<unsigned, Attribute> &Pair) {
1569 return Pair.second.isValid();
1571 "Pointless attribute!");
1576 for (
ArrayRef<std::pair<unsigned, Attribute>>::iterator
I =
Attrs.begin(),
1578 unsigned Index =
I->first;
1580 while (
I !=
E &&
I->first == Index) {
1588 return get(
C, AttrPairVec);
1593 ArrayRef<std::pair<unsigned, AttributeSet>> Attrs) {
1599 "Misordered Attributes list!");
1601 [](
const std::pair<unsigned, AttributeSet> &Pair) {
1602 return !Pair.second.hasAttributes();
1604 "Pointless attribute!");
1606 unsigned MaxIndex =
Attrs.back().first;
1609 if (MaxIndex == FunctionIndex &&
Attrs.size() > 1)
1613 for (
const auto &Pair : Attrs)
1616 return getImpl(
C, AttrVec);
1625 unsigned NumSets = 0;
1626 for (
size_t I = ArgAttrs.
size();
I != 0; --
I) {
1627 if (ArgAttrs[
I - 1].hasAttributes()) {
1657 return getImpl(
C, AttrSets);
1660AttributeList AttributeList::get(
LLVMContext &
C,
unsigned Index,
1662 if (!
Attrs.hasAttributes())
1667 return getImpl(
C, AttrSets);
1670AttributeList AttributeList::get(
LLVMContext &
C,
unsigned Index,
1671 const AttrBuilder &
B) {
1675AttributeList AttributeList::get(
LLVMContext &
C,
unsigned Index,
1678 for (
const auto K : Kinds)
1680 return get(
C, Attrs);
1683AttributeList AttributeList::get(
LLVMContext &
C,
unsigned Index,
1689 for (
const auto K : Kinds)
1691 return get(
C, Attrs);
1694AttributeList AttributeList::get(
LLVMContext &
C,
unsigned Index,
1697 for (
const auto &K : Kinds)
1699 return get(
C, Attrs);
1706 if (
Attrs.size() == 1)
1709 unsigned MaxSize = 0;
1710 for (
const auto &
List : Attrs)
1711 MaxSize = std::max(MaxSize,
List.getNumAttrSets());
1718 for (
unsigned I = 0;
I < MaxSize; ++
I) {
1719 AttrBuilder CurBuilder(
C);
1720 for (
const auto &
List : Attrs)
1721 CurBuilder.merge(AttrBuilder(
C,
List.getAttributes(
I - 1)));
1725 return getImpl(
C, NewAttrSets);
1729AttributeList::addAttributeAtIndex(
LLVMContext &
C,
unsigned Index,
1732 if (
Attrs.hasAttribute(Kind))
1740AttributeList AttributeList::addAttributeAtIndex(
LLVMContext &
C,
unsigned Index,
1744 B.addAttribute(Kind,
Value);
1745 return addAttributesAtIndex(
C, Index,
B);
1748AttributeList AttributeList::addAttributeAtIndex(
LLVMContext &
C,
unsigned Index,
1752 return addAttributesAtIndex(
C, Index,
B);
1755AttributeList AttributeList::setAttributesAtIndex(
LLVMContext &
C,
1760 if (Index >= AttrSets.
size())
1761 AttrSets.
resize(Index + 1);
1765 while (!AttrSets.
empty() && !AttrSets.
back().hasAttributes())
1767 if (AttrSets.
empty())
1769 return AttributeList::getImpl(
C, AttrSets);
1772AttributeList AttributeList::addAttributesAtIndex(
LLVMContext &
C,
1774 const AttrBuilder &
B)
const {
1775 if (!
B.hasAttributes())
1786AttributeList AttributeList::addParamAttribute(
LLVMContext &
C,
1793 if (MaxIndex >= AttrSets.
size())
1794 AttrSets.
resize(MaxIndex + 1);
1796 for (
unsigned ArgNo : ArgNos) {
1798 AttrBuilder
B(
C, AttrSets[Index]);
1803 return getImpl(
C, AttrSets);
1807AttributeList::removeAttributeAtIndex(
LLVMContext &
C,
unsigned Index,
1811 if (Attrs == NewAttrs)
1813 return setAttributesAtIndex(
C, Index, NewAttrs);
1816AttributeList AttributeList::removeAttributeAtIndex(
LLVMContext &
C,
1821 if (Attrs == NewAttrs)
1823 return setAttributesAtIndex(
C, Index, NewAttrs);
1826AttributeList AttributeList::removeAttributesAtIndex(
1831 if (Attrs == NewAttrs)
1833 return setAttributesAtIndex(
C, Index, NewAttrs);
1838 unsigned WithoutIndex)
const {
1843 return setAttributesAtIndex(
C, WithoutIndex,
AttributeSet());
1846AttributeList AttributeList::addDereferenceableRetAttr(
LLVMContext &
C,
1849 B.addDereferenceableAttr(Bytes);
1850 return addRetAttributes(
C,
B);
1853AttributeList AttributeList::addDereferenceableParamAttr(
LLVMContext &
C,
1857 B.addDereferenceableAttr(Bytes);
1858 return addParamAttributes(
C, Index,
B);
1862AttributeList::addDereferenceableOrNullParamAttr(
LLVMContext &
C,
unsigned Index,
1865 B.addDereferenceableOrNullAttr(Bytes);
1866 return addParamAttributes(
C, Index,
B);
1869AttributeList AttributeList::addRangeRetAttr(
LLVMContext &
C,
1873 return addRetAttributes(
C,
B);
1876AttributeList AttributeList::addAllocSizeParamAttr(
1878 const std::optional<unsigned> &NumElemsArg)
const {
1880 B.addAllocSizeAttr(ElemSizeArg, NumElemsArg);
1881 return addParamAttributes(
C, Index,
B);
1884std::optional<AttributeList>
1892 index_iterator(std::max(getNumAttrSets(),
Other.getNumAttrSets()));
1893 for (
unsigned Idx : IndexIt) {
1894 auto IntersectedAS =
1898 return std::nullopt;
1899 if (!IntersectedAS->hasAttributes())
1901 IntersectedAttrs.
push_back(std::make_pair(Idx, *IntersectedAS));
1905 return AttributeList::get(
C, IntersectedAttrs);
1912AttributeSet AttributeList::getParamAttrs(
unsigned ArgNo)
const {
1924bool AttributeList::hasAttributeAtIndex(
unsigned Index,
1929bool AttributeList::hasAttributeAtIndex(
unsigned Index,
StringRef Kind)
const {
1933bool AttributeList::hasAttributesAtIndex(
unsigned Index)
const {
1938 return pImpl && pImpl->hasFnAttribute(Kind);
1941bool AttributeList::hasFnAttr(
StringRef Kind)
const {
1942 return hasAttributeAtIndex(AttributeList::FunctionIndex, Kind);
1946 unsigned *Index)
const {
1947 return pImpl && pImpl->hasAttrSomewhere(Attr, Index);
1950Attribute AttributeList::getAttributeAtIndex(
unsigned Index,
1955Attribute AttributeList::getAttributeAtIndex(
unsigned Index,
1960MaybeAlign AttributeList::getRetAlignment()
const {
1964MaybeAlign AttributeList::getParamAlignment(
unsigned ArgNo)
const {
1968MaybeAlign AttributeList::getParamStackAlignment(
unsigned ArgNo)
const {
1969 return getAttributes(ArgNo + FirstArgIndex).getStackAlignment();
1972Type *AttributeList::getParamByValType(
unsigned Index)
const {
1976Type *AttributeList::getParamStructRetType(
unsigned Index)
const {
1977 return getAttributes(Index + FirstArgIndex).getStructRetType();
1980Type *AttributeList::getParamByRefType(
unsigned Index)
const {
1984Type *AttributeList::getParamPreallocatedType(
unsigned Index)
const {
1985 return getAttributes(Index + FirstArgIndex).getPreallocatedType();
1988Type *AttributeList::getParamInAllocaType(
unsigned Index)
const {
1989 return getAttributes(Index + FirstArgIndex).getInAllocaType();
1992Type *AttributeList::getParamElementType(
unsigned Index)
const {
1993 return getAttributes(Index + FirstArgIndex).getElementType();
1996MaybeAlign AttributeList::getFnStackAlignment()
const {
1997 return getFnAttrs().getStackAlignment();
2000MaybeAlign AttributeList::getRetStackAlignment()
const {
2001 return getRetAttrs().getStackAlignment();
2004uint64_t AttributeList::getRetDereferenceableBytes()
const {
2005 return getRetAttrs().getDereferenceableBytes();
2008uint64_t AttributeList::getParamDereferenceableBytes(
unsigned Index)
const {
2009 return getParamAttrs(Index).getDereferenceableBytes();
2012uint64_t AttributeList::getRetDereferenceableOrNullBytes()
const {
2013 return getRetAttrs().getDereferenceableOrNullBytes();
2017 return getParamAttrs(Index).getDeadOnReturnInfo();
2021AttributeList::getParamDereferenceableOrNullBytes(
unsigned Index)
const {
2022 return getParamAttrs(Index).getDereferenceableOrNullBytes();
2025std::optional<ConstantRange>
2026AttributeList::getParamRange(
unsigned ArgNo)
const {
2027 auto RangeAttr = getParamAttrs(ArgNo).getAttribute(Attribute::Range);
2028 if (RangeAttr.isValid())
2029 return RangeAttr.getRange();
2030 return std::nullopt;
2033FPClassTest AttributeList::getRetNoFPClass()
const {
2034 return getRetAttrs().getNoFPClass();
2037FPClassTest AttributeList::getParamNoFPClass(
unsigned Index)
const {
2038 return getParamAttrs(Index).getNoFPClass();
2041UWTableKind AttributeList::getUWTableKind()
const {
2042 return getFnAttrs().getUWTableKind();
2046 return getFnAttrs().getAllocKind();
2050 return getFnAttrs().getMemoryEffects();
2053std::string AttributeList::getAsString(
unsigned Index,
bool InAttrGrp)
const {
2057AttributeSet AttributeList::getAttributes(
unsigned Index)
const {
2059 if (!pImpl || Index >= getNumAttrSets())
2061 return pImpl->begin()[
Index];
2064bool AttributeList::hasParentContext(
LLVMContext &
C)
const {
2065 assert(!isEmpty() &&
"an empty attribute list has no parent context");
2067 return C.pImpl->AttrsLists.lookup(pImpl->getKey(), Token) == pImpl;
2070AttributeList::iterator AttributeList::begin()
const {
2071 return pImpl ? pImpl->begin() :
nullptr;
2074AttributeList::iterator AttributeList::end()
const {
2075 return pImpl ? pImpl->end() :
nullptr;
2082unsigned AttributeList::getNumAttrSets()
const {
2083 return pImpl ? pImpl->NumAttrSets : 0;
2087 O <<
"AttributeList[\n";
2089 for (
unsigned i : indexes()) {
2094 case AttrIndex::ReturnIndex:
2097 case AttrIndex::FunctionIndex:
2101 O <<
"arg(" << i - AttrIndex::FirstArgIndex <<
")";
2103 O <<
" => " << getAsString(i) <<
" }\n";
2109#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2122void AttrBuilder::clear() {
Attrs.clear(); }
2152template <
typename K>
2156 if (It != Attrs.end() && It->hasAttribute(Kind))
2159 Attrs.insert(It, Attr);
2162AttrBuilder &AttrBuilder::addAttribute(
Attribute Attr) {
2182 auto It =
lower_bound(Attrs, Val, AttributeComparator());
2183 if (It !=
Attrs.end() && It->hasAttribute(Val))
2188AttrBuilder &AttrBuilder::removeAttribute(
StringRef A) {
2189 auto It =
lower_bound(Attrs,
A, AttributeComparator());
2190 if (It !=
Attrs.end() && It->hasAttribute(
A))
2195std::optional<uint64_t>
2200 return A.getValueAsInt();
2201 return std::nullopt;
2209std::optional<std::pair<unsigned, std::optional<unsigned>>>
2210AttrBuilder::getAllocSizeArgs()
const {
2211 Attribute A = getAttribute(Attribute::AllocSize);
2213 return A.getAllocSizeArgs();
2214 return std::nullopt;
2222 return addRawIntAttr(Attribute::Alignment,
Align->
value());
2230 assert(*
Align <= 0x100 &&
"Alignment too large.");
2231 return addRawIntAttr(Attribute::StackAlignment,
Align->
value());
2234AttrBuilder &AttrBuilder::addDereferenceableAttr(
uint64_t Bytes) {
2235 if (Bytes == 0)
return *
this;
2237 return addRawIntAttr(Attribute::Dereferenceable, Bytes);
2241 if (
Info.isZeroSized())
2244 return addRawIntAttr(Attribute::DeadOnReturn,
Info.toIntValue());
2247AttrBuilder &AttrBuilder::addDereferenceableOrNullAttr(
uint64_t Bytes) {
2251 return addRawIntAttr(Attribute::DereferenceableOrNull, Bytes);
2255AttrBuilder::addAllocSizeAttr(
unsigned ElemSize,
2256 const std::optional<unsigned> &NumElems) {
2260AttrBuilder &AttrBuilder::addAllocSizeAttrFromRawRepr(
uint64_t RawArgs) {
2262 assert(RawArgs &&
"Invalid allocsize arguments -- given allocsize(0, 0)");
2263 return addRawIntAttr(Attribute::AllocSize, RawArgs);
2266AttrBuilder &AttrBuilder::addVScaleRangeAttr(
unsigned MinValue,
2267 std::optional<unsigned> MaxValue) {
2271AttrBuilder &AttrBuilder::addVScaleRangeAttrFromRawRepr(
uint64_t RawArgs) {
2276 return addRawIntAttr(Attribute::VScaleRange, RawArgs);
2279AttrBuilder &AttrBuilder::addUWTableAttr(
UWTableKind Kind) {
2282 return addRawIntAttr(Attribute::UWTable,
uint64_t(Kind));
2286 return addRawIntAttr(Attribute::Memory, ME.
toIntValue());
2289AttrBuilder &AttrBuilder::addCapturesAttr(
CaptureInfo CI) {
2290 return addRawIntAttr(Attribute::Captures, CI.
toIntValue());
2293AttrBuilder &AttrBuilder::addDenormalFPEnvAttr(
DenormalFPEnv FPEnv) {
2294 return addRawIntAttr(Attribute::DenormalFPEnv, FPEnv.
toIntValue());
2297AttrBuilder &AttrBuilder::addNoFPClassAttr(
FPClassTest Mask) {
2301 return addRawIntAttr(Attribute::NoFPClass, Mask);
2304AttrBuilder &AttrBuilder::addAllocKindAttr(
AllocFnKind Kind) {
2305 return addRawIntAttr(Attribute::AllocKind,
static_cast<uint64_t>(Kind));
2311 return A.isValid() ?
A.getValueAsType() :
nullptr;
2318AttrBuilder &AttrBuilder::addByValAttr(
Type *Ty) {
2319 return addTypeAttr(Attribute::ByVal, Ty);
2322AttrBuilder &AttrBuilder::addStructRetAttr(
Type *Ty) {
2323 return addTypeAttr(Attribute::StructRet, Ty);
2326AttrBuilder &AttrBuilder::addByRefAttr(
Type *Ty) {
2327 return addTypeAttr(Attribute::ByRef, Ty);
2330AttrBuilder &AttrBuilder::addPreallocatedAttr(
Type *Ty) {
2331 return addTypeAttr(Attribute::Preallocated, Ty);
2334AttrBuilder &AttrBuilder::addInAllocaAttr(
Type *Ty) {
2335 return addTypeAttr(Attribute::InAlloca, Ty);
2346AttrBuilder &AttrBuilder::addRangeAttr(
const ConstantRange &CR) {
2347 return addConstantRangeAttr(Attribute::Range, CR);
2357 return addConstantRangeListAttr(Attribute::Initializes, CRL.
rangesRef());
2360AttrBuilder &AttrBuilder::addFromEquivalentMetadata(
const Instruction &
I) {
2361 if (
I.hasMetadata(LLVMContext::MD_nonnull))
2362 addAttribute(Attribute::NonNull);
2364 if (
I.hasMetadata(LLVMContext::MD_noundef))
2365 addAttribute(Attribute::NoUndef);
2367 if (
const MDNode *
Align =
I.getMetadata(LLVMContext::MD_align)) {
2372 if (
const MDNode *Dereferenceable =
2373 I.getMetadata(LLVMContext::MD_dereferenceable)) {
2379 if (
const MDNode *DereferenceableOrNull =
2380 I.getMetadata(LLVMContext::MD_dereferenceable_or_null)) {
2386 if (
const MDNode *
Range =
I.getMetadata(LLVMContext::MD_range))
2389 if (
const MDNode *NoFPClass =
I.getMetadata(LLVMContext::MD_nofpclass)) {
2397AttrBuilder &AttrBuilder::merge(
const AttrBuilder &
B) {
2399 for (
const auto &
I :
B.attrs())
2416 auto It =
lower_bound(Attrs,
A, AttributeComparator());
2417 if (It !=
Attrs.end() && It->hasAttribute(
A))
2423 auto It =
lower_bound(Attrs,
A, AttributeComparator());
2424 if (It !=
Attrs.end() && It->hasAttribute(
A))
2429std::optional<ConstantRange> AttrBuilder::getRange()
const {
2430 const Attribute RangeAttr = getAttribute(Attribute::Range);
2433 return std::nullopt;
2437 return getAttribute(
A).isValid();
2440bool AttrBuilder::contains(
StringRef A)
const {
2441 return getAttribute(
A).isValid();
2444bool AttrBuilder::operator==(
const AttrBuilder &
B)
const {
2454bool AttributeFuncs::isNoFPClassCompatibleType(
Type *Ty) {
2460 AttributeSafetyKind ASK) {
2463 if (!Ty->isIntegerTy()) {
2465 if (ASK & ASK_SAFE_TO_DROP)
2469 if (!Ty->isIntegerTy() && !Ty->isByteTy()) {
2471 if (ASK & ASK_UNSAFE_TO_DROP)
2475 if (!Ty->isIntOrIntVectorTy()) {
2477 if (ASK & ASK_SAFE_TO_DROP)
2486 if (!Ty->isPointerTy()) {
2488 if (ASK & ASK_SAFE_TO_DROP)
2502 if (ASK & ASK_UNSAFE_TO_DROP)
2515 if (!Ty->isPtrOrPtrVectorTy()) {
2516 if (ASK & ASK_SAFE_TO_DROP)
2520 if (ASK & ASK_SAFE_TO_DROP) {
2521 if (!isNoFPClassCompatibleType(Ty))
2526 if (Ty->isVoidTy()) {
2527 if (ASK & ASK_SAFE_TO_DROP)
2531 return Incompatible;
2580 return !Callee.getAttributes().hasFnAttr(Attribute::StrictFP) ||
2581 Caller.getAttributes().hasFnAttr(Attribute::StrictFP);
2584template<
typename AttrClass>
2586 return Caller.getFnAttribute(AttrClass::getKind()) ==
2587 Callee.getFnAttribute(AttrClass::getKind());
2592 return Caller.getFnAttribute(AttrName) == Callee.getFnAttribute(AttrName);
2600template<
typename AttrClass>
2602 if (AttrClass::isSet(Caller, AttrClass::getKind()) &&
2603 !AttrClass::isSet(Callee, AttrClass::getKind()))
2604 AttrClass::set(Caller, AttrClass::getKind(),
false);
2612template<
typename AttrClass>
2614 if (!AttrClass::isSet(Caller, AttrClass::getKind()) &&
2615 AttrClass::isSet(Callee, AttrClass::getKind()))
2616 AttrClass::set(Caller, AttrClass::getKind(),
true);
2625 if (!Caller.hasStackProtectorFnAttr())
2636 if (Callee.hasFnAttribute(Attribute::StackProtectReq)) {
2637 Caller.removeFnAttrs(OldSSPAttr);
2638 Caller.addFnAttr(Attribute::StackProtectReq);
2639 }
else if (Callee.hasFnAttribute(Attribute::StackProtectStrong) &&
2640 !Caller.hasFnAttribute(Attribute::StackProtectReq)) {
2641 Caller.removeFnAttrs(OldSSPAttr);
2642 Caller.addFnAttr(Attribute::StackProtectStrong);
2643 }
else if (Callee.hasFnAttribute(Attribute::StackProtect) &&
2644 !Caller.hasFnAttribute(Attribute::StackProtectReq) &&
2645 !Caller.hasFnAttribute(Attribute::StackProtectStrong))
2646 Caller.addFnAttr(Attribute::StackProtect);
2652 if (!Caller.hasFnAttribute(
"probe-stack") &&
2653 Callee.hasFnAttribute(
"probe-stack")) {
2654 Caller.addFnAttr(Callee.getFnAttribute(
"probe-stack"));
2663 Attribute CalleeAttr = Callee.getFnAttribute(
"stack-probe-size");
2665 Attribute CallerAttr = Caller.getFnAttribute(
"stack-probe-size");
2667 uint64_t CallerStackProbeSize, CalleeStackProbeSize;
2671 if (CallerStackProbeSize > CalleeStackProbeSize) {
2672 Caller.addFnAttr(CalleeAttr);
2675 Caller.addFnAttr(CalleeAttr);
2691 Attribute CallerAttr = Caller.getFnAttribute(
"min-legal-vector-width");
2693 Attribute CalleeAttr = Callee.getFnAttribute(
"min-legal-vector-width");
2695 uint64_t CallerVectorWidth, CalleeVectorWidth;
2698 if (CallerVectorWidth < CalleeVectorWidth)
2699 Caller.addFnAttr(CalleeAttr);
2703 Caller.removeFnAttr(
"min-legal-vector-width");
2712 if (Callee.nullPointerIsDefined() && !Caller.nullPointerIsDefined()) {
2713 Caller.addFnAttr(Attribute::NullPointerIsValid);
2736 return A.getValueAsString() ==
"true";
2741 Fn.
addFnAttr(Kind, Val ?
"true" :
"false");
2745#define GET_ATTR_NAMES
2746#define ATTRIBUTE_ENUM(ENUM_NAME, DISPLAY_NAME) \
2747 struct ENUM_NAME##Attr : EnumAttr { \
2748 static enum Attribute::AttrKind getKind() { \
2749 return llvm::Attribute::ENUM_NAME; \
2752#define ATTRIBUTE_STRBOOL(ENUM_NAME, DISPLAY_NAME) \
2753 struct ENUM_NAME##Attr : StrBoolAttr { \
2754 static StringRef getKind() { return #DISPLAY_NAME; } \
2756#include "llvm/IR/Attributes.inc"
2758#define GET_ATTR_COMPAT_FUNC
2759#include "llvm/IR/Attributes.inc"
2761bool AttributeFuncs::areInlineCompatible(
const Function &Caller,
2763 return hasCompatibleFnAttrs(Caller, Callee);
2766bool AttributeFuncs::isStrictFPInlineCompatible(
const Function &Caller,
2773 return hasCompatibleFnAttrs(
A,
B);
2776void AttributeFuncs::mergeAttributesForInlining(
Function &Caller,
2778 mergeFnAttrs(Caller, Callee);
2791 mergeFnAttrs(
Base, ToMerge);
2794void AttributeFuncs::updateMinLegalVectorWidthAttr(
Function &Fn,
2800 if (Width > OldWidth)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file defines various helper methods and classes used by LLVMContextImpl for creating and managin...
static void addAttributeImpl(SmallVectorImpl< Attribute > &Attrs, K Kind, Attribute Attr)
static void setAND(Function &Caller, const Function &Callee)
Compute the logical AND of the attributes of the caller and the callee.
static void adjustCallerStackProbes(Function &Caller, const Function &Callee)
If the inlined function required stack probes, then ensure that the calling function has those too.
static std::pair< unsigned, std::optional< unsigned > > unpackVScaleRangeArgs(uint64_t Value)
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...
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)
static uint64_t packVScaleRangeArgs(unsigned MinValue, std::optional< unsigned > MaxValue)
static bool hasIntersectProperty(Attribute::AttrKind Kind, AttributeProperty Prop)
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
static std::pair< unsigned, std::optional< unsigned > > unpackAllocSizeArgs(uint64_t Num)
static bool checkDenormMode(const Function &Caller, const Function &Callee)
static unsigned getAttributeProperties(Attribute::AttrKind Kind)
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)
static const char * getModRefStr(ModRefInfo MR)
This file contains the simple types necessary to represent the attributes associated with functions a...
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
This file defines a hash set that can be used to remove duplication of nodes in a graph.
static constexpr Value * getValue(Ty &ValueOrUse)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
This file defines the SmallVector class.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
LLVM_ABI void Profile(FoldingSetNodeID &id) const
Used to insert APInt objects, or objects that contain APInt objects, into FoldingSets.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
const T & back() const
Get the last element.
ArrayRef< T > take_front(size_t N=1) const
Return a copy of *this with only the first N elements.
size_t size() const
Get the array size.
bool empty() const
Check if the array is empty.
This class represents a single, uniqued attribute.
int cmp(const AttributeImpl &AI, bool KindOnly) const
Used to sort attributes.
bool isConstantRangeAttribute() const
bool hasAttribute(Attribute::AttrKind A) const
Type * getValueAsType() const
Attribute::AttrKind getKindAsEnum() const
bool operator<(const AttributeImpl &AI) const
Used when sorting the attributes.
uint64_t getValueAsInt() const
bool isIntAttribute() const
bool isTypeAttribute() const
AttributeImpl(AttrEntryKind KindID)
bool getValueAsBool() const
StringRef getKindAsString() const
StringRef getValueAsString() const
bool isEnumAttribute() const
ArrayRef< ConstantRange > getValueAsConstantRangeList() const
bool isConstantRangeListAttribute() const
bool isStringAttribute() const
const ConstantRange & getValueAsConstantRange() const
This class represents a set of attributes that apply to the function, return type,...
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.
AttributeListImpl(ArrayRef< AttributeSet > Sets)
friend class AttributeList
This class stores enough information to efficiently remove some attributes from an existing AttrBuild...
AttributeMask & addAttribute(Attribute::AttrKind Val)
Add an attribute to the mask.
bool contains(Attribute::AttrKind A) const
Return true if the builder has the specified attribute.
This class represents a group of attributes that apply to one element: function, return type,...
MaybeAlign getStackAlignment() const
uint64_t getDereferenceableOrNullBytes() const
std::optional< unsigned > getVScaleRangeMax() const
bool hasAttribute(Attribute::AttrKind Kind) const
Type * getAttributeType(Attribute::AttrKind Kind) const
AllocFnKind getAllocKind() const
CaptureInfo getCaptureInfo() const
unsigned getVScaleRangeMin() const
MaybeAlign getAlignment() const
MemoryEffects getMemoryEffects() const
UWTableKind getUWTableKind() const
std::optional< std::pair< unsigned, std::optional< unsigned > > > getAllocSizeArgs() const
DeadOnReturnInfo getDeadOnReturnInfo() const
const Attribute * iterator
uint64_t getDereferenceableBytes() const
std::string getAsString(bool InAttrGrp) const
static AttributeSetNode * get(LLVMContext &C, const AttrBuilder &B)
FPClassTest getNoFPClass() const
Attribute getAttribute(Attribute::AttrKind Kind) const
This class holds the attributes for a particular argument, parameter, function, or return value.
LLVM_ABI AllocFnKind getAllocKind() const
bool hasAttributes() const
Return true if attributes exists in this set.
const Attribute * iterator
LLVM_ABI AttributeSet removeAttribute(LLVMContext &C, Attribute::AttrKind Kind) const
Remove the specified attribute from this set.
LLVM_ABI Type * getInAllocaType() const
LLVM_ABI Type * getByValType() const
LLVM_ABI DeadOnReturnInfo getDeadOnReturnInfo() const
LLVM_ABI AttributeSet addAttributes(LLVMContext &C, AttributeSet AS) const
Add attributes to the attribute set.
LLVM_ABI MemoryEffects getMemoryEffects() const
LLVM_ABI bool hasAttribute(Attribute::AttrKind Kind) const
Return true if the attribute exists in this set.
LLVM_ABI std::optional< AttributeSet > intersectWith(LLVMContext &C, AttributeSet Other) const
Try to intersect this AttributeSet with Other.
LLVM_ABI Type * getStructRetType() const
LLVM_ABI std::string getAsString(bool InAttrGrp=false) const
LLVM_ABI unsigned getVScaleRangeMin() const
LLVM_ABI std::optional< std::pair< unsigned, std::optional< unsigned > > > getAllocSizeArgs() const
LLVM_ABI UWTableKind getUWTableKind() const
LLVM_ABI bool hasParentContext(LLVMContext &C) const
Return true if this attribute set belongs to the LLVMContext.
LLVM_ABI iterator begin() const
LLVM_ABI iterator end() const
LLVM_ABI AttributeSet removeAttributes(LLVMContext &C, const AttributeMask &AttrsToRemove) const
Remove the specified attributes from this set.
LLVM_ABI std::optional< unsigned > getVScaleRangeMax() const
LLVM_ABI MaybeAlign getStackAlignment() const
LLVM_ABI Attribute getAttribute(Attribute::AttrKind Kind) const
Return the attribute object.
LLVM_ABI Type * getPreallocatedType() const
LLVM_ABI uint64_t getDereferenceableBytes() const
LLVM_ABI MaybeAlign getAlignment() const
LLVM_ABI FPClassTest getNoFPClass() const
LLVM_ABI Type * getElementType() const
LLVM_ABI Type * getByRefType() const
LLVM_ABI CaptureInfo getCaptureInfo() const
AttributeSet()=default
AttributeSet is a trivially copyable value type.
static LLVM_ABI AttributeSet get(LLVMContext &C, const AttrBuilder &B)
LLVM_ABI uint64_t getDereferenceableOrNullBytes() const
LLVM_ABI unsigned getNumAttributes() const
Return the number of attributes in this set.
LLVM_ABI AttributeSet addAttribute(LLVMContext &C, Attribute::AttrKind Kind) const
Add an argument attribute.
Functions, function parameters, and return types can have attributes to indicate how they should be t...
LLVM_ABI bool isStringAttribute() const
Return true if the attribute is a string (target-dependent) attribute.
static LLVM_ABI Attribute getWithStructRetType(LLVMContext &Context, Type *Ty)
static LLVM_ABI bool isABIAttr(AttrKind Kind)
Whether this is an ABI attribute (for returns or arguments).
static LLVM_ABI Attribute::AttrKind getAttrKindFromName(StringRef AttrName)
LLVM_ABI bool isEnumAttribute() const
Return true if the attribute is an Attribute::AttrKind type.
static LLVM_ABI Attribute getWithStackAlignment(LLVMContext &Context, Align Alignment)
LLVM_ABI const ConstantRange & getRange() const
Returns the value of the range attribute.
static LLVM_ABI bool intersectWithCustom(AttrKind Kind)
LLVM_ABI bool isIntAttribute() const
Return true if the attribute is an integer attribute.
static LLVM_ABI Attribute getWithByRefType(LLVMContext &Context, Type *Ty)
LLVM_ABI struct DenormalFPEnv getDenormalFPEnv() const
Returns denormal_fpenv.
LLVM_ABI std::optional< unsigned > getVScaleRangeMax() const
Returns the maximum value for the vscale_range attribute or std::nullopt when unknown.
LLVM_ABI uint64_t getValueAsInt() const
Return the attribute's value as an integer.
LLVM_ABI unsigned getVScaleRangeMin() const
Returns the minimum value for the vscale_range attribute.
LLVM_ABI AllocFnKind getAllocKind() const
LLVM_ABI bool isConstantRangeAttribute() const
Return true if the attribute is a ConstantRange attribute.
static LLVM_ABI Attribute getWithAllocKind(LLVMContext &Context, AllocFnKind Kind)
LLVM_ABI StringRef getKindAsString() const
Return the attribute's kind as a string.
static LLVM_ABI Attribute getWithPreallocatedType(LLVMContext &Context, Type *Ty)
static LLVM_ABI bool intersectWithMin(AttrKind Kind)
static LLVM_ABI Attribute getWithDeadOnReturnInfo(LLVMContext &Context, DeadOnReturnInfo DI)
static LLVM_ABI Attribute get(LLVMContext &Context, AttrKind Kind, uint64_t Val=0)
Return a uniquified Attribute object.
static LLVM_ABI bool canUseAsRetAttr(AttrKind Kind)
static bool isTypeAttrKind(AttrKind Kind)
LLVM_ABI std::string getAsString(bool InAttrGrp=false) const
The Attribute is converted to a string of equivalent mnemonic.
LLVM_ABI uint64_t getDereferenceableOrNullBytes() const
Returns the number of dereferenceable_or_null bytes from the dereferenceable_or_null attribute.
static LLVM_ABI Attribute getWithDereferenceableBytes(LLVMContext &Context, uint64_t Bytes)
LLVM_ABI std::pair< unsigned, std::optional< unsigned > > getAllocSizeArgs() const
Returns the argument numbers for the allocsize attribute.
static LLVM_ABI Attribute getWithUWTableKind(LLVMContext &Context, UWTableKind Kind)
LLVM_ABI FPClassTest getNoFPClass() const
Return the FPClassTest for nofpclass.
static LLVM_ABI Attribute getWithAllocSizeArgs(LLVMContext &Context, unsigned ElemSizeArg, const std::optional< unsigned > &NumElemsArg)
LLVM_ABI Attribute::AttrKind getKindAsEnum() const
Return the attribute's kind as an enum (Attribute::AttrKind).
LLVM_ABI bool getValueAsBool() const
Return the attribute's value as a boolean.
LLVM_ABI ArrayRef< ConstantRange > getInitializes() const
Returns the value of the initializes attribute.
LLVM_ABI const ConstantRange & getValueAsConstantRange() const
Return the attribute's value as a ConstantRange.
LLVM_ABI uint64_t getDereferenceableBytes() const
Returns the number of dereferenceable bytes from the dereferenceable attribute.
static LLVM_ABI Attribute getWithVScaleRangeArgs(LLVMContext &Context, unsigned MinValue, unsigned MaxValue)
LLVM_ABI MemoryEffects getMemoryEffects() const
Returns memory effects.
LLVM_ABI UWTableKind getUWTableKind() const
static LLVM_ABI Attribute getWithDereferenceableOrNullBytes(LLVMContext &Context, uint64_t Bytes)
LLVM_ABI ArrayRef< ConstantRange > getValueAsConstantRangeList() const
Return the attribute's value as a ConstantRange array.
LLVM_ABI StringRef getValueAsString() const
Return the attribute's value as a string.
static LLVM_ABI bool isExistingAttribute(StringRef Name)
Return true if the provided string matches the IR name of an attribute.
bool hasKindAsEnum() const
Returns true if the attribute's kind can be represented as an enum (Enum, Integer,...
static LLVM_ABI StringRef getNameFromAttrKind(Attribute::AttrKind AttrKind)
static LLVM_ABI bool canUseAsFnAttr(AttrKind Kind)
static LLVM_ABI bool intersectWithAnd(AttrKind Kind)
static LLVM_ABI Attribute getWithNoFPClass(LLVMContext &Context, FPClassTest Mask)
AttrKind
This enumeration lists the attributes that can be associated with parameters, function results,...
@ None
No attributes have been set.
@ EndAttrKinds
Sentinel value useful for loops.
static bool isConstantRangeAttrKind(AttrKind Kind)
LLVM_ABI bool hasParentContext(LLVMContext &C) const
Return true if this attribute belongs to the LLVMContext.
LLVM_ABI bool isTypeAttribute() const
Return true if the attribute is a type attribute.
static LLVM_ABI Attribute getWithCaptureInfo(LLVMContext &Context, CaptureInfo CI)
static LLVM_ABI Attribute getWithInAllocaType(LLVMContext &Context, Type *Ty)
static bool isIntAttrKind(AttrKind Kind)
static bool isConstantRangeListAttrKind(AttrKind Kind)
LLVM_ABI bool isConstantRangeListAttribute() const
Return true if the attribute is a ConstantRangeList attribute.
static LLVM_ABI Attribute getWithByValType(LLVMContext &Context, Type *Ty)
LLVM_ABI bool hasAttribute(AttrKind Val) const
Return true if the attribute is present.
static bool isEnumAttrKind(AttrKind Kind)
static LLVM_ABI Attribute getWithMemoryEffects(LLVMContext &Context, MemoryEffects ME)
static LLVM_ABI bool canUseAsParamAttr(AttrKind Kind)
bool isValid() const
Return true if the attribute is any kind of attribute.
LLVM_ABI MaybeAlign getStackAlignment() const
Returns the stack alignment field of an attribute as a byte alignment value.
LLVM_ABI MaybeAlign getAlignment() const
Returns the alignment field of an attribute as a byte alignment value.
LLVM_ABI CaptureInfo getCaptureInfo() const
Returns information from captures attribute.
static LLVM_ABI bool intersectMustPreserve(AttrKind Kind)
LLVM_ABI int cmpKind(Attribute A) const
Used to sort attribute by kind.
LLVM_ABI bool operator<(Attribute A) const
Less-than operator. Useful for sorting the attributes list.
static LLVM_ABI Attribute getWithAlignment(LLVMContext &Context, Align Alignment)
Return a uniquified Attribute object that has the specific alignment set.
LLVM_ABI DeadOnReturnInfo getDeadOnReturnInfo() const
Returns the number of dead_on_return bytes from the dead_on_return attribute, or std::nullopt if all ...
LLVM_ABI Type * getValueAsType() const
Return the attribute's value as a Type.
Represents which components of the pointer may be captured in which location.
static CaptureInfo createFromIntValue(uint32_t Data)
static CaptureInfo all()
Create CaptureInfo that may capture all components of the pointer.
uint32_t toIntValue() const
Convert CaptureInfo into an encoded integer value (used by captures attribute).
This is the shared class of boolean and integer constants.
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
static size_t totalSizeToAlloc(ArrayRef< ConstantRange > Val)
This class represents a list of constant ranges.
ArrayRef< ConstantRange > rangesRef() const
LLVM_ABI void print(raw_ostream &OS) const
Print out the ranges to a stream.
This class represents a range of values.
const APInt & getLower() const
Return the lower value for this range.
LLVM_ABI bool isFullSet() const
Return true if this set contains all of the elements possible for this data-type.
const APInt & getUpper() const
Return the upper value for this range.
LLVM_ABI ConstantRange unionWith(const ConstantRange &CR, PreferredRangeType Type=Smallest) const
Return the range that results from the union of this range with another range.
uint32_t getBitWidth() const
Get the bit width of this ConstantRange.
static DeadOnReturnInfo createFromIntValue(uint64_t Data)
uint64_t toIntValue() const
A set of classes that contain the value of the attribute object.
static bool isSupportedFloatingPointType(Type *Ty)
Returns true if Ty is a supported floating-point type for phi, select, or call FPMathOperators.
Insertion token: a failed lookup fills it in, the matching insert consumes it.
This class is used to gather all the unique data bits of a node.
void AddInteger(signed I)
void addFnAttr(Attribute::AttrKind Kind)
Add function attributes to this function.
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
void removeFnAttr(Attribute::AttrKind Kind)
Remove function attributes from this function.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
UniquingSet< TypeAttributeImpl > TypeAttrs
EnumAttributeImpl * EnumAttrs[Attribute::NumEnumAttrKinds]
UniquingSet< IntAttributeImpl > IntAttrs
FoldingSet< AttributeImpl > AttrsSet
UniquingSet< StringAttributeImpl > StringAttrs
UniquingSet< AttributeListImpl > AttrsLists
This is an important class for using LLVM in a threaded context.
bool isTargetMemLocSameForAll() const
Whether the target memory locations are all the same.
bool isTargetMemLoc(IRMemLocation Loc) const
Whether location is target memory location.
ModRefInfo getModRef(Location Loc) const
Get ModRefInfo for the given Location.
static MemoryEffectsBase createFromIntValue(uint32_t Data)
uint32_t toIntValue() const
Convert MemoryEffectsBase into an encoded integer value (used by memory attribute).
static MemoryEffectsBase unknown()
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void reserve(size_type N)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
static size_t totalSizeToAlloc(StringRef Kind, StringRef Val)
Represent a constant reference to a string, i.e.
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
std::string str() const
Get the contents as an std::string.
int compare(StringRef RHS) const
Compare two strings; the result is negative, zero, or positive if this string is lexicographically le...
A switch()-like statement whose cases are string literals.
static constexpr std::enable_if_t< std::is_same_v< Foo< TrailingTys... >, Foo< Tys... > >, size_t > totalSizeToAlloc(typename trailing_objects_internal::ExtractSecondType< TrailingTys, size_t >::type... Counts)
const T * getTrailingObjects() const
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM_ABI void print(raw_ostream &O, bool IsForDebug=false, bool NoDetails=false) const
Print the current type.
LLVM Value Representation.
static constexpr uint64_t MaximumAlignment
This class implements an extremely fast bulk output stream that can only output to a stream.
A raw_ostream that writes to an std::string.
This class provides various memory handling functions that manipulate MemoryBlock instances.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Attrs[]
Key for Kernel::Metadata::mAttrs.
LLVM_ABI AttributeList getAttributes(LLVMContext &C, ID id, FunctionType *FT)
Return the attributes for an intrinsic.
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > extract(Y &&MD)
Extract a Value from Metadata.
LLVM_ABI iterator begin() const
This is an optimization pass for GlobalISel generic memory operations.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
bool isEqual(const GCNRPTracker::LiveRegSet &S1, const GCNRPTracker::LiveRegSet &S2)
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
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.
RelativeUniformCounterPtr Values
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
std::string utostr(uint64_t X, bool isNeg=false)
MemoryEffectsBase< IRMemLocation > MemoryEffects
Summary of how a function affects memory in the program.
LLVM_ABI void printEscapedString(StringRef Name, raw_ostream &Out)
Print each character of the specified string, escaping it if it is not printable or if it is an escap...
LLVM_ABI ConstantRange getConstantRangeFromMetadata(const MDNode &RangeMD)
Parse out a conservative ConstantRange from !range metadata.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
@ None
No unwind table requested.
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
void sort(IteratorTy Start, IteratorTy End)
FPClassTest
Floating-point class tests, supported by 'is_fpclass' intrinsic.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
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...
ModRefInfo
Flags indicating whether a memory access modifies or references memory.
@ 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.
@ TargetMem0
Represents target specific state.
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
@ InaccessibleMem
Memory that is inaccessible via LLVM IR.
std::string join(IteratorT Begin, IteratorT End, StringRef Separator)
Joins the strings in the range [Begin, End), adding Separator between the elements.
auto lower_bound(R &&Range, T &&Value)
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
OutputIt copy(R &&Range, OutputIt Out)
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
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.
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
Represents the full denormal controls for a function, including the default mode and the f32 specific...
static constexpr DenormalFPEnv createFromIntValue(uint32_t Data)
LLVM_ABI void print(raw_ostream &OS, bool OmitIfSame=true) const
constexpr uint32_t toIntValue() const
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.
Align valueOrOne() const
For convenience, returns a valid alignment or 1 if undefined.
Function object to check whether the first component of a container supported by std::get (like std::...