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");
107 assert(Val == 0 &&
"Value must be zero for enum attributes");
110 AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(
ID, InsertPoint);
119 pImpl->AttrsSet.InsertNode(PA, InsertPoint);
130 if (!Val.
empty())
ID.AddString(Val);
133 AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(
ID, InsertPoint);
142 pImpl->AttrsSet.InsertNode(PA, InsertPoint);
158 AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(
ID, InsertPoint);
164 pImpl->AttrsSet.InsertNode(PA, InsertPoint);
174 "Not a ConstantRange attribute");
183 AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(
ID, InsertPoint);
188 PA =
new (pImpl->ConstantRangeAttributeAlloc.Allocate())
190 pImpl->AttrsSet.InsertNode(PA, InsertPoint);
200 "Not a ConstantRangeList attribute");
204 ID.AddInteger(Val.
size());
205 for (
auto &CR : Val) {
206 CR.getLower().Profile(
ID);
207 CR.getUpper().Profile(
ID);
211 AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(
ID, InsertPoint);
221 void *Mem = pImpl->Alloc.Allocate(
225 pImpl->AttrsSet.InsertNode(PA, InsertPoint);
226 pImpl->ConstantRangeListAttributes.push_back(
236 return get(Context, Alignment,
A.value());
240 assert(
A <= 0x100 &&
"Alignment too large.");
241 return get(Context, StackAlignment,
A.value());
246 assert(Bytes &&
"Bytes must be non-zero.");
247 return get(Context, Dereferenceable, Bytes);
252 assert(Bytes &&
"Bytes must be non-zero.");
253 return get(Context, DereferenceableOrNull, Bytes);
257 return get(Context, ByVal, Ty);
261 return get(Context, StructRet, Ty);
265 return get(Context, ByRef, Ty);
269 return get(Context, Preallocated, Ty);
273 return get(Context, InAlloca, Ty);
288 return get(Context, NoFPClass, ClassMask);
297 const std::optional<unsigned> &NumElemsArg) {
298 assert(!(ElemSizeArg == 0 && NumElemsArg == 0) &&
299 "Invalid allocsize arguments -- given allocsize(0, 0)");
304 return get(Context, AllocKind,
static_cast<uint64_t>(Kind));
315#define GET_ATTR_NAMES
316#define ATTRIBUTE_ENUM(ENUM_NAME, DISPLAY_NAME) \
317 .Case(#DISPLAY_NAME, Attribute::ENUM_NAME)
318#include "llvm/IR/Attributes.inc"
324#define GET_ATTR_NAMES
325#define ATTRIBUTE_ENUM(ENUM_NAME, DISPLAY_NAME) \
326 case Attribute::ENUM_NAME: \
327 return #DISPLAY_NAME;
328#include "llvm/IR/Attributes.inc"
338#define GET_ATTR_NAMES
339#define ATTRIBUTE_ALL(ENUM_NAME, DISPLAY_NAME) .Case(#DISPLAY_NAME, true)
340#include "llvm/IR/Attributes.inc"
349 return pImpl && pImpl->isEnumAttribute();
353 return pImpl && pImpl->isIntAttribute();
357 return pImpl && pImpl->isStringAttribute();
361 return pImpl && pImpl->isTypeAttribute();
365 return pImpl && pImpl->isConstantRangeAttribute();
369 return pImpl && pImpl->isConstantRangeListAttribute();
373 if (!pImpl)
return None;
375 "Invalid attribute type to get the kind as an enum!");
376 return pImpl->getKindAsEnum();
380 if (!pImpl)
return 0;
382 "Expected the attribute to be an integer attribute!");
383 return pImpl->getValueAsInt();
387 if (!pImpl)
return false;
389 "Expected the attribute to be a string attribute!");
390 return pImpl->getValueAsBool();
394 if (!pImpl)
return {};
396 "Invalid attribute type to get the kind as a string!");
397 return pImpl->getKindAsString();
401 if (!pImpl)
return {};
403 "Invalid attribute type to get the value as a string!");
404 return pImpl->getValueAsString();
408 if (!pImpl)
return {};
410 "Invalid attribute type to get the value as a type!");
411 return pImpl->getValueAsType();
416 "Invalid attribute type to get the value as a ConstantRange!");
417 return pImpl->getValueAsConstantRange();
422 "Invalid attribute type to get the value as a ConstantRangeList!");
423 return pImpl->getValueAsConstantRangeList();
427 return (pImpl && pImpl->hasAttribute(Kind)) || (!pImpl && Kind ==
None);
432 return pImpl && pImpl->hasAttribute(Kind);
437 "Trying to get alignment from non-alignment attribute!");
443 "Trying to get alignment from non-alignment attribute!");
449 "Trying to get dereferenceable bytes from "
450 "non-dereferenceable attribute!");
451 return pImpl->getValueAsInt();
456 "Trying to get dereferenceable bytes from "
457 "non-dereferenceable attribute!");
458 return pImpl->getValueAsInt();
461std::pair<unsigned, std::optional<unsigned>>
464 "Trying to get allocsize args from non-allocsize attribute");
470 "Trying to get vscale args from non-vscale attribute");
476 "Trying to get vscale args from non-vscale attribute");
482 "Trying to get unwind table kind from non-uwtable attribute");
488 "Trying to get allockind value from non-allockind attribute");
494 "Can only call getMemoryEffects() on memory attribute");
500 "Can only call getCaptureInfo() on captures attribute");
506 "Can only call getNoFPClass() on nofpclass attribute");
507 return static_cast<FPClassTest>(pImpl->getValueAsInt());
512 "Trying to get range args from non-range attribute");
513 return pImpl->getValueAsConstantRange();
518 "Trying to get initializes attr from non-ConstantRangeList attribute");
519 return pImpl->getValueAsConstantRangeList();
537 if (!pImpl)
return {};
562 auto AttrWithBytesToString = [&](
const char *Name) {
569 return AttrWithBytesToString(
"alignstack");
572 return AttrWithBytesToString(
"dereferenceable");
575 return AttrWithBytesToString(
"dereferenceable_or_null");
579 std::optional<unsigned> NumElems;
583 ?
"allocsize(" +
Twine(ElemSize) +
"," +
Twine(*NumElems) +
")"
584 :
"allocsize(" +
Twine(ElemSize) +
")")
591 return (
"vscale_range(" +
Twine(MinValue) +
"," +
592 Twine(MaxValue.value_or(0)) +
")")
617 return (
"allockind(\"" +
652 OS <<
"inaccessiblemem: ";
660 OS <<
"target_mem0: ";
663 OS <<
"target_mem1: ";
681 std::string Result =
"nofpclass";
703 OS <<
"initializes(";
724 const auto &AttrVal = pImpl->getValueAsString();
725 if (!AttrVal.empty()) {
738 assert(
isValid() &&
"invalid Attribute doesn't refer to any context");
742 return C.pImpl->AttrsSet.FindNodeOrInsertPos(
ID, Unused) == pImpl;
746 if (!pImpl && !
A.pImpl)
752 return pImpl->cmp(*
A.pImpl,
true);
756 if (!pImpl && !
A.pImpl)
return false;
757 if (!pImpl)
return true;
758 if (!
A.pImpl)
return false;
759 return *pImpl < *
A.pImpl;
763 ID.AddPointer(pImpl);
777#define GET_ATTR_PROP_TABLE
778#include "llvm/IR/Attributes.inc"
781 unsigned Index = Kind - 1;
782 assert(Index < std::size(AttrPropTable) &&
"Invalid attribute kind");
783 return AttrPropTable[Index];
809 "Unknown intersect property");
875 ->getConstantRangeValue();
881 ->getConstantRangeListValue();
903 "Unclear how to compare range list");
920 return cmp(AI,
false) < 0;
939 B.addAttribute(Kind);
946 B.addAttribute(Kind,
Value);
951 const AttributeSet AS)
const {
958 AttrBuilder
B(
C, *
this);
959 B.merge(AttrBuilder(
C, AS));
964 const AttrBuilder &
B)
const {
968 if (!
B.hasAttributes())
971 AttrBuilder Merged(
C, *
this);
973 return get(
C, Merged);
979 AttrBuilder
B(
C, *
this);
980 B.removeAttribute(Kind);
987 AttrBuilder
B(
C, *
this);
988 B.removeAttribute(Kind);
994 AttrBuilder
B(
C, *
this);
996 if (!
B.overlaps(Attrs))
1003std::optional<AttributeSet>
1008 AttrBuilder Intersected(
C);
1010 auto ItBegin0 =
begin();
1011 auto ItEnd0 =
end();
1012 auto ItBegin1 =
Other.begin();
1013 auto ItEnd1 =
Other.end();
1015 while (ItBegin0 != ItEnd0 || ItBegin1 != ItEnd1) {
1020 if (ItBegin1 == ItEnd1)
1021 Attr0 = *ItBegin0++;
1022 else if (ItBegin0 == ItEnd0)
1023 Attr0 = *ItBegin1++;
1025 int Cmp = ItBegin0->cmpKind(*ItBegin1);
1027 Attr0 = *ItBegin0++;
1028 Attr1 = *ItBegin1++;
1030 Attr0 = *ItBegin0++;
1032 Attr0 = *ItBegin1++;
1034 assert(Attr0.
isValid() &&
"Iteration should always yield a valid attr");
1036 auto IntersectEq = [&]() {
1041 Intersected.addAttribute(Attr0);
1049 return std::nullopt;
1058 return std::nullopt;
1064 "Iterator picked up two different attributes in the same iteration");
1069 "Invalid attr type of intersectAnd");
1070 Intersected.addAttribute(Kind);
1077 "Invalid attr type of intersectMin");
1079 Intersected.addRawIntAttr(Kind, NewVal);
1085 case Attribute::Alignment:
1088 Intersected.addAlignmentAttr(
1092 case Attribute::Memory:
1096 case Attribute::Captures:
1100 case Attribute::NoFPClass:
1104 case Attribute::Range: {
1109 Intersected.addRangeAttr(NewRange);
1120 return std::nullopt;
1124 if (Kind == Attribute::ByVal &&
1126 Other.getAttribute(Attribute::Alignment))
1127 return std::nullopt;
1130 return get(
C, Intersected);
1134 return SetNode ? SetNode->getNumAttributes() : 0;
1138 return SetNode ? SetNode->hasAttribute(Kind) :
false;
1142 return SetNode ? SetNode->hasAttribute(Kind) :
false;
1146 return SetNode ? SetNode->getAttribute(Kind) :
Attribute();
1150 return SetNode ? SetNode->getAttribute(Kind) :
Attribute();
1154 return SetNode ? SetNode->getAlignment() : std::nullopt;
1158 return SetNode ? SetNode->getStackAlignment() : std::nullopt;
1162 return SetNode ? SetNode->getDereferenceableBytes() : 0;
1166 return SetNode ? SetNode->getDereferenceableOrNullBytes() : 0;
1170 return SetNode ? SetNode->getAttributeType(Attribute::ByRef) :
nullptr;
1174 return SetNode ? SetNode->getAttributeType(Attribute::ByVal) :
nullptr;
1178 return SetNode ? SetNode->getAttributeType(Attribute::StructRet) :
nullptr;
1182 return SetNode ? SetNode->getAttributeType(Attribute::Preallocated) :
nullptr;
1186 return SetNode ? SetNode->getAttributeType(Attribute::InAlloca) :
nullptr;
1190 return SetNode ? SetNode->getAttributeType(Attribute::ElementType) :
nullptr;
1193std::optional<std::pair<unsigned, std::optional<unsigned>>>
1196 return SetNode->getAllocSizeArgs();
1197 return std::nullopt;
1201 return SetNode ? SetNode->getVScaleRangeMin() : 1;
1205 return SetNode ? SetNode->getVScaleRangeMax() : std::nullopt;
1225 return SetNode ? SetNode->getNoFPClass() :
fcNone;
1229 return SetNode ? SetNode->getAsString(InAttrGrp) :
"";
1235 SetNode->Profile(
ID);
1237 return C.pImpl->AttrsSetNodes.FindNodeOrInsertPos(
ID, Unused) == SetNode;
1241 return SetNode ? SetNode->begin() :
nullptr;
1245 return SetNode ? SetNode->end() :
nullptr;
1248#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1261 : NumAttrs(Attrs.
size()) {
1265 for (
const auto &
I : *
this) {
1266 if (
I.isStringAttribute())
1267 StringAttrs.insert({
I.getKindAsString(),
I });
1269 AvailableAttrs.addAttribute(
I.getKindAsEnum());
1277 return getSorted(
C, SortedAttrs);
1282 if (SortedAttrs.
empty())
1290 for (
const auto &Attr : SortedAttrs)
1311 return getSorted(
C,
B.attrs());
1315 return StringAttrs.count(Kind);
1318std::optional<Attribute>
1322 return std::nullopt;
1327 std::lower_bound(
begin(),
end() - StringAttrs.size(), Kind,
1329 return A.getKindAsEnum() < Kind;
1331 assert(
I !=
end() &&
I->hasAttribute(Kind) &&
"Presence check failed?");
1336 if (
auto A = findEnumAttribute(Kind))
1342 return StringAttrs.lookup(Kind);
1346 if (
auto A = findEnumAttribute(Attribute::Alignment))
1347 return A->getAlignment();
1348 return std::nullopt;
1352 if (
auto A = findEnumAttribute(Attribute::StackAlignment))
1353 return A->getStackAlignment();
1354 return std::nullopt;
1358 if (
auto A = findEnumAttribute(Kind))
1359 return A->getValueAsType();
1364 if (
auto A = findEnumAttribute(Attribute::Dereferenceable))
1365 return A->getDereferenceableBytes();
1370 if (
auto A = findEnumAttribute(Attribute::DereferenceableOrNull))
1371 return A->getDereferenceableOrNullBytes();
1375std::optional<std::pair<unsigned, std::optional<unsigned>>>
1377 if (
auto A = findEnumAttribute(Attribute::AllocSize))
1378 return A->getAllocSizeArgs();
1379 return std::nullopt;
1383 if (
auto A = findEnumAttribute(Attribute::VScaleRange))
1384 return A->getVScaleRangeMin();
1389 if (
auto A = findEnumAttribute(Attribute::VScaleRange))
1390 return A->getVScaleRangeMax();
1391 return std::nullopt;
1395 if (
auto A = findEnumAttribute(Attribute::UWTable))
1396 return A->getUWTableKind();
1401 if (
auto A = findEnumAttribute(Attribute::AllocKind))
1402 return A->getAllocKind();
1407 if (
auto A = findEnumAttribute(Attribute::Memory))
1408 return A->getMemoryEffects();
1413 if (
auto A = findEnumAttribute(Attribute::Captures))
1414 return A->getCaptureInfo();
1419 if (
auto A = findEnumAttribute(Attribute::NoFPClass))
1420 return A->getNoFPClass();
1429 Str +=
I->getAsString(InAttrGrp);
1445 : NumAttrSets(Sets.
size()) {
1446 assert(!Sets.
empty() &&
"pointless AttributeListImpl");
1454 if (!
I.isStringAttribute())
1455 AvailableFunctionAttrs.addAttribute(
I.getKindAsEnum());
1457 for (
const auto &Set : Sets)
1458 for (
const auto &
I : Set)
1459 if (!
I.isStringAttribute())
1460 AvailableSomewhereAttrs.addAttribute(
I.getKindAsEnum());
1469 for (
const auto &Set : Sets)
1470 ID.AddPointer(Set.SetNode);
1474 unsigned *Index)
const {
1475 if (!AvailableSomewhereAttrs.hasAttribute(Kind))
1479 for (
unsigned I = 0, E = NumAttrSets;
I != E; ++
I) {
1480 if (
begin()[
I].hasAttribute(Kind)) {
1491#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1503 assert(!AttrSets.
empty() &&
"pointless AttributeListImpl");
1511 pImpl->
AttrsLists.FindNodeOrInsertPos(
ID, InsertPoint);
1517 void *Mem = pImpl->
Alloc.Allocate(
1521 pImpl->
AttrsLists.InsertNode(PA, InsertPoint);
1525 return AttributeList(PA);
1530 ArrayRef<std::pair<unsigned, Attribute>> Attrs) {
1536 "Misordered Attributes list!");
1538 [](
const std::pair<unsigned, Attribute> &Pair) {
1539 return Pair.second.isValid();
1541 "Pointless attribute!");
1546 for (
ArrayRef<std::pair<unsigned, Attribute>>::iterator
I =
Attrs.begin(),
1548 unsigned Index =
I->first;
1550 while (
I !=
E &&
I->first == Index) {
1558 return get(
C, AttrPairVec);
1563 ArrayRef<std::pair<unsigned, AttributeSet>> Attrs) {
1569 "Misordered Attributes list!");
1571 [](
const std::pair<unsigned, AttributeSet> &Pair) {
1572 return !Pair.second.hasAttributes();
1574 "Pointless attribute!");
1576 unsigned MaxIndex =
Attrs.back().first;
1579 if (MaxIndex == FunctionIndex &&
Attrs.size() > 1)
1583 for (
const auto &Pair : Attrs)
1586 return getImpl(
C, AttrVec);
1595 unsigned NumSets = 0;
1596 for (
size_t I = ArgAttrs.
size();
I != 0; --
I) {
1597 if (ArgAttrs[
I - 1].hasAttributes()) {
1627 return getImpl(
C, AttrSets);
1630AttributeList AttributeList::get(
LLVMContext &
C,
unsigned Index,
1632 if (!
Attrs.hasAttributes())
1637 return getImpl(
C, AttrSets);
1640AttributeList AttributeList::get(
LLVMContext &
C,
unsigned Index,
1641 const AttrBuilder &
B) {
1645AttributeList AttributeList::get(
LLVMContext &
C,
unsigned Index,
1648 for (
const auto K : Kinds)
1650 return get(
C, Attrs);
1653AttributeList AttributeList::get(
LLVMContext &
C,
unsigned Index,
1656 assert(Kinds.
size() == Values.
size() &&
"Mismatched attribute values.");
1659 for (
const auto K : Kinds)
1661 return get(
C, Attrs);
1664AttributeList AttributeList::get(
LLVMContext &
C,
unsigned Index,
1667 for (
const auto &K : Kinds)
1669 return get(
C, Attrs);
1676 if (
Attrs.size() == 1)
1679 unsigned MaxSize = 0;
1680 for (
const auto &
List : Attrs)
1681 MaxSize = std::max(MaxSize,
List.getNumAttrSets());
1688 for (
unsigned I = 0;
I < MaxSize; ++
I) {
1689 AttrBuilder CurBuilder(
C);
1690 for (
const auto &
List : Attrs)
1691 CurBuilder.merge(AttrBuilder(
C,
List.getAttributes(
I - 1)));
1695 return getImpl(
C, NewAttrSets);
1699AttributeList::addAttributeAtIndex(
LLVMContext &
C,
unsigned Index,
1702 if (
Attrs.hasAttribute(Kind))
1710AttributeList AttributeList::addAttributeAtIndex(
LLVMContext &
C,
unsigned Index,
1714 B.addAttribute(Kind,
Value);
1715 return addAttributesAtIndex(
C, Index,
B);
1718AttributeList AttributeList::addAttributeAtIndex(
LLVMContext &
C,
unsigned Index,
1722 return addAttributesAtIndex(
C, Index,
B);
1725AttributeList AttributeList::setAttributesAtIndex(
LLVMContext &
C,
1730 if (Index >= AttrSets.
size())
1731 AttrSets.
resize(Index + 1);
1735 while (!AttrSets.
empty() && !AttrSets.
back().hasAttributes())
1737 if (AttrSets.
empty())
1739 return AttributeList::getImpl(
C, AttrSets);
1742AttributeList AttributeList::addAttributesAtIndex(
LLVMContext &
C,
1744 const AttrBuilder &
B)
const {
1745 if (!
B.hasAttributes())
1756AttributeList AttributeList::addParamAttribute(
LLVMContext &
C,
1763 if (MaxIndex >= AttrSets.
size())
1764 AttrSets.
resize(MaxIndex + 1);
1766 for (
unsigned ArgNo : ArgNos) {
1768 AttrBuilder
B(
C, AttrSets[Index]);
1773 return getImpl(
C, AttrSets);
1777AttributeList::removeAttributeAtIndex(
LLVMContext &
C,
unsigned Index,
1781 if (Attrs == NewAttrs)
1783 return setAttributesAtIndex(
C, Index, NewAttrs);
1786AttributeList AttributeList::removeAttributeAtIndex(
LLVMContext &
C,
1791 if (Attrs == NewAttrs)
1793 return setAttributesAtIndex(
C, Index, NewAttrs);
1796AttributeList AttributeList::removeAttributesAtIndex(
1801 if (Attrs == NewAttrs)
1803 return setAttributesAtIndex(
C, Index, NewAttrs);
1808 unsigned WithoutIndex)
const {
1813 return setAttributesAtIndex(
C, WithoutIndex,
AttributeSet());
1816AttributeList AttributeList::addDereferenceableRetAttr(
LLVMContext &
C,
1817 uint64_t Bytes)
const {
1819 B.addDereferenceableAttr(Bytes);
1820 return addRetAttributes(
C,
B);
1823AttributeList AttributeList::addDereferenceableParamAttr(
LLVMContext &
C,
1825 uint64_t Bytes)
const {
1827 B.addDereferenceableAttr(Bytes);
1828 return addParamAttributes(
C, Index,
B);
1832AttributeList::addDereferenceableOrNullParamAttr(
LLVMContext &
C,
unsigned Index,
1833 uint64_t Bytes)
const {
1835 B.addDereferenceableOrNullAttr(Bytes);
1836 return addParamAttributes(
C, Index,
B);
1839AttributeList AttributeList::addRangeRetAttr(
LLVMContext &
C,
1843 return addRetAttributes(
C,
B);
1846AttributeList AttributeList::addAllocSizeParamAttr(
1848 const std::optional<unsigned> &NumElemsArg)
const {
1850 B.addAllocSizeAttr(ElemSizeArg, NumElemsArg);
1851 return addParamAttributes(
C, Index,
B);
1854std::optional<AttributeList>
1862 index_iterator(std::max(getNumAttrSets(),
Other.getNumAttrSets()));
1863 for (
unsigned Idx : IndexIt) {
1864 auto IntersectedAS =
1868 return std::nullopt;
1869 if (!IntersectedAS->hasAttributes())
1871 IntersectedAttrs.
push_back(std::make_pair(Idx, *IntersectedAS));
1875 return AttributeList::get(
C, IntersectedAttrs);
1882AttributeSet AttributeList::getParamAttrs(
unsigned ArgNo)
const {
1894bool AttributeList::hasAttributeAtIndex(
unsigned Index,
1899bool AttributeList::hasAttributeAtIndex(
unsigned Index,
StringRef Kind)
const {
1903bool AttributeList::hasAttributesAtIndex(
unsigned Index)
const {
1908 return pImpl && pImpl->hasFnAttribute(Kind);
1911bool AttributeList::hasFnAttr(
StringRef Kind)
const {
1912 return hasAttributeAtIndex(AttributeList::FunctionIndex, Kind);
1916 unsigned *Index)
const {
1917 return pImpl && pImpl->hasAttrSomewhere(Attr, Index);
1920Attribute AttributeList::getAttributeAtIndex(
unsigned Index,
1925Attribute AttributeList::getAttributeAtIndex(
unsigned Index,
1930MaybeAlign AttributeList::getRetAlignment()
const {
1934MaybeAlign AttributeList::getParamAlignment(
unsigned ArgNo)
const {
1938MaybeAlign AttributeList::getParamStackAlignment(
unsigned ArgNo)
const {
1939 return getAttributes(ArgNo + FirstArgIndex).getStackAlignment();
1942Type *AttributeList::getParamByValType(
unsigned Index)
const {
1946Type *AttributeList::getParamStructRetType(
unsigned Index)
const {
1947 return getAttributes(Index + FirstArgIndex).getStructRetType();
1950Type *AttributeList::getParamByRefType(
unsigned Index)
const {
1954Type *AttributeList::getParamPreallocatedType(
unsigned Index)
const {
1955 return getAttributes(Index + FirstArgIndex).getPreallocatedType();
1958Type *AttributeList::getParamInAllocaType(
unsigned Index)
const {
1959 return getAttributes(Index + FirstArgIndex).getInAllocaType();
1962Type *AttributeList::getParamElementType(
unsigned Index)
const {
1963 return getAttributes(Index + FirstArgIndex).getElementType();
1966MaybeAlign AttributeList::getFnStackAlignment()
const {
1967 return getFnAttrs().getStackAlignment();
1970MaybeAlign AttributeList::getRetStackAlignment()
const {
1971 return getRetAttrs().getStackAlignment();
1974uint64_t AttributeList::getRetDereferenceableBytes()
const {
1975 return getRetAttrs().getDereferenceableBytes();
1978uint64_t AttributeList::getParamDereferenceableBytes(
unsigned Index)
const {
1979 return getParamAttrs(Index).getDereferenceableBytes();
1982uint64_t AttributeList::getRetDereferenceableOrNullBytes()
const {
1983 return getRetAttrs().getDereferenceableOrNullBytes();
1987AttributeList::getParamDereferenceableOrNullBytes(
unsigned Index)
const {
1988 return getParamAttrs(Index).getDereferenceableOrNullBytes();
1991std::optional<ConstantRange>
1992AttributeList::getParamRange(
unsigned ArgNo)
const {
1993 auto RangeAttr = getParamAttrs(ArgNo).getAttribute(Attribute::Range);
1994 if (RangeAttr.isValid())
1995 return RangeAttr.getRange();
1996 return std::nullopt;
1999FPClassTest AttributeList::getRetNoFPClass()
const {
2000 return getRetAttrs().getNoFPClass();
2003FPClassTest AttributeList::getParamNoFPClass(
unsigned Index)
const {
2004 return getParamAttrs(Index).getNoFPClass();
2007UWTableKind AttributeList::getUWTableKind()
const {
2008 return getFnAttrs().getUWTableKind();
2012 return getFnAttrs().getAllocKind();
2016 return getFnAttrs().getMemoryEffects();
2019std::string AttributeList::getAsString(
unsigned Index,
bool InAttrGrp)
const {
2023AttributeSet AttributeList::getAttributes(
unsigned Index)
const {
2025 if (!pImpl || Index >= getNumAttrSets())
2027 return pImpl->begin()[
Index];
2030bool AttributeList::hasParentContext(
LLVMContext &
C)
const {
2031 assert(!isEmpty() &&
"an empty attribute list has no parent context");
2035 return C.pImpl->AttrsLists.FindNodeOrInsertPos(
ID, Unused) == pImpl;
2038AttributeList::iterator AttributeList::begin()
const {
2039 return pImpl ? pImpl->begin() :
nullptr;
2042AttributeList::iterator AttributeList::end()
const {
2043 return pImpl ? pImpl->end() :
nullptr;
2050unsigned AttributeList::getNumAttrSets()
const {
2051 return pImpl ? pImpl->NumAttrSets : 0;
2055 O <<
"AttributeList[\n";
2057 for (
unsigned i : indexes()) {
2062 case AttrIndex::ReturnIndex:
2065 case AttrIndex::FunctionIndex:
2069 O <<
"arg(" << i - AttrIndex::FirstArgIndex <<
")";
2071 O <<
" => " << getAsString(i) <<
" }\n";
2077#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2090void AttrBuilder::clear() {
Attrs.clear(); }
2120template <
typename K>
2124 if (It != Attrs.end() && It->hasAttribute(Kind))
2127 Attrs.insert(It, Attr);
2130AttrBuilder &AttrBuilder::addAttribute(
Attribute Attr) {
2150 auto It =
lower_bound(Attrs, Val, AttributeComparator());
2151 if (It !=
Attrs.end() && It->hasAttribute(Val))
2156AttrBuilder &AttrBuilder::removeAttribute(
StringRef A) {
2157 auto It =
lower_bound(Attrs,
A, AttributeComparator());
2158 if (It !=
Attrs.end() && It->hasAttribute(
A))
2163std::optional<uint64_t>
2168 return A.getValueAsInt();
2169 return std::nullopt;
2177std::optional<std::pair<unsigned, std::optional<unsigned>>>
2178AttrBuilder::getAllocSizeArgs()
const {
2179 Attribute A = getAttribute(Attribute::AllocSize);
2181 return A.getAllocSizeArgs();
2182 return std::nullopt;
2190 return addRawIntAttr(Attribute::Alignment,
Align->
value());
2198 assert(*
Align <= 0x100 &&
"Alignment too large.");
2199 return addRawIntAttr(Attribute::StackAlignment,
Align->
value());
2202AttrBuilder &AttrBuilder::addDereferenceableAttr(uint64_t Bytes) {
2203 if (Bytes == 0)
return *
this;
2205 return addRawIntAttr(Attribute::Dereferenceable, Bytes);
2208AttrBuilder &AttrBuilder::addDereferenceableOrNullAttr(uint64_t Bytes) {
2212 return addRawIntAttr(Attribute::DereferenceableOrNull, Bytes);
2216AttrBuilder::addAllocSizeAttr(
unsigned ElemSize,
2217 const std::optional<unsigned> &NumElems) {
2221AttrBuilder &AttrBuilder::addAllocSizeAttrFromRawRepr(uint64_t RawArgs) {
2223 assert(RawArgs &&
"Invalid allocsize arguments -- given allocsize(0, 0)");
2224 return addRawIntAttr(Attribute::AllocSize, RawArgs);
2227AttrBuilder &AttrBuilder::addVScaleRangeAttr(
unsigned MinValue,
2228 std::optional<unsigned> MaxValue) {
2232AttrBuilder &AttrBuilder::addVScaleRangeAttrFromRawRepr(uint64_t RawArgs) {
2237 return addRawIntAttr(Attribute::VScaleRange, RawArgs);
2240AttrBuilder &AttrBuilder::addUWTableAttr(
UWTableKind Kind) {
2243 return addRawIntAttr(Attribute::UWTable, uint64_t(Kind));
2247 return addRawIntAttr(Attribute::Memory, ME.
toIntValue());
2250AttrBuilder &AttrBuilder::addCapturesAttr(
CaptureInfo CI) {
2251 return addRawIntAttr(Attribute::Captures, CI.
toIntValue());
2254AttrBuilder &AttrBuilder::addNoFPClassAttr(
FPClassTest Mask) {
2258 return addRawIntAttr(Attribute::NoFPClass, Mask);
2261AttrBuilder &AttrBuilder::addAllocKindAttr(
AllocFnKind Kind) {
2262 return addRawIntAttr(Attribute::AllocKind,
static_cast<uint64_t
>(Kind));
2268 return A.isValid() ?
A.getValueAsType() :
nullptr;
2275AttrBuilder &AttrBuilder::addByValAttr(
Type *Ty) {
2276 return addTypeAttr(Attribute::ByVal, Ty);
2279AttrBuilder &AttrBuilder::addStructRetAttr(
Type *Ty) {
2280 return addTypeAttr(Attribute::StructRet, Ty);
2283AttrBuilder &AttrBuilder::addByRefAttr(
Type *Ty) {
2284 return addTypeAttr(Attribute::ByRef, Ty);
2287AttrBuilder &AttrBuilder::addPreallocatedAttr(
Type *Ty) {
2288 return addTypeAttr(Attribute::Preallocated, Ty);
2291AttrBuilder &AttrBuilder::addInAllocaAttr(
Type *Ty) {
2292 return addTypeAttr(Attribute::InAlloca, Ty);
2303AttrBuilder &AttrBuilder::addRangeAttr(
const ConstantRange &CR) {
2304 return addConstantRangeAttr(Attribute::Range, CR);
2314 return addConstantRangeListAttr(Attribute::Initializes, CRL.
rangesRef());
2317AttrBuilder &AttrBuilder::addFromEquivalentMetadata(
const Instruction &
I) {
2318 if (
I.hasMetadata(LLVMContext::MD_nonnull))
2319 addAttribute(Attribute::NonNull);
2321 if (
I.hasMetadata(LLVMContext::MD_noundef))
2322 addAttribute(Attribute::NoUndef);
2324 if (
const MDNode *
Align =
I.getMetadata(LLVMContext::MD_align)) {
2329 if (
const MDNode *Dereferenceable =
2330 I.getMetadata(LLVMContext::MD_dereferenceable)) {
2336 if (
const MDNode *DereferenceableOrNull =
2337 I.getMetadata(LLVMContext::MD_dereferenceable_or_null)) {
2343 if (
const MDNode *
Range =
I.getMetadata(LLVMContext::MD_range))
2349AttrBuilder &AttrBuilder::merge(
const AttrBuilder &
B) {
2351 for (
const auto &
I :
B.attrs())
2368 auto It =
lower_bound(Attrs,
A, AttributeComparator());
2369 if (It !=
Attrs.end() && It->hasAttribute(
A))
2375 auto It =
lower_bound(Attrs,
A, AttributeComparator());
2376 if (It !=
Attrs.end() && It->hasAttribute(
A))
2381std::optional<ConstantRange> AttrBuilder::getRange()
const {
2382 const Attribute RangeAttr = getAttribute(Attribute::Range);
2385 return std::nullopt;
2389 return getAttribute(
A).isValid();
2392bool AttrBuilder::contains(
StringRef A)
const {
2393 return getAttribute(
A).isValid();
2396bool AttrBuilder::operator==(
const AttrBuilder &
B)
const {
2406bool AttributeFuncs::isNoFPClassCompatibleType(
Type *Ty) {
2412 AttributeSafetyKind ASK) {
2415 if (!Ty->isIntegerTy()) {
2417 if (ASK & ASK_SAFE_TO_DROP)
2419 if (ASK & ASK_UNSAFE_TO_DROP)
2423 if (!Ty->isIntOrIntVectorTy()) {
2425 if (ASK & ASK_SAFE_TO_DROP)
2434 if (!Ty->isPointerTy()) {
2436 if (ASK & ASK_SAFE_TO_DROP)
2448 if (ASK & ASK_UNSAFE_TO_DROP)
2461 if (!Ty->isPtrOrPtrVectorTy()) {
2462 if (ASK & ASK_SAFE_TO_DROP)
2466 if (ASK & ASK_SAFE_TO_DROP) {
2467 if (!isNoFPClassCompatibleType(Ty))
2472 if (Ty->isVoidTy()) {
2473 if (ASK & ASK_SAFE_TO_DROP)
2477 return Incompatible;
2511 DenormalMode CallerModeF32 = Caller.getDenormalModeF32Raw();
2512 DenormalMode CalleeModeF32 = Callee.getDenormalModeF32Raw();
2514 CallerModeF32 = CallerMode;
2516 CalleeModeF32 = CalleeMode;
2526 return !Callee.getAttributes().hasFnAttr(Attribute::StrictFP) ||
2527 Caller.getAttributes().hasFnAttr(Attribute::StrictFP);
2530template<
typename AttrClass>
2532 return Caller.getFnAttribute(AttrClass::getKind()) ==
2533 Callee.getFnAttribute(AttrClass::getKind());
2538 return Caller.getFnAttribute(AttrName) == Callee.getFnAttribute(AttrName);
2546template<
typename AttrClass>
2548 if (AttrClass::isSet(Caller, AttrClass::getKind()) &&
2549 !AttrClass::isSet(Callee, AttrClass::getKind()))
2550 AttrClass::set(Caller, AttrClass::getKind(),
false);
2558template<
typename AttrClass>
2560 if (!AttrClass::isSet(Caller, AttrClass::getKind()) &&
2561 AttrClass::isSet(Callee, AttrClass::getKind()))
2562 AttrClass::set(Caller, AttrClass::getKind(),
true);
2571 if (!Caller.hasStackProtectorFnAttr())
2582 if (Callee.hasFnAttribute(Attribute::StackProtectReq)) {
2583 Caller.removeFnAttrs(OldSSPAttr);
2584 Caller.addFnAttr(Attribute::StackProtectReq);
2585 }
else if (Callee.hasFnAttribute(Attribute::StackProtectStrong) &&
2586 !Caller.hasFnAttribute(Attribute::StackProtectReq)) {
2587 Caller.removeFnAttrs(OldSSPAttr);
2588 Caller.addFnAttr(Attribute::StackProtectStrong);
2589 }
else if (Callee.hasFnAttribute(Attribute::StackProtect) &&
2590 !Caller.hasFnAttribute(Attribute::StackProtectReq) &&
2591 !Caller.hasFnAttribute(Attribute::StackProtectStrong))
2592 Caller.addFnAttr(Attribute::StackProtect);
2598 if (!Caller.hasFnAttribute(
"probe-stack") &&
2599 Callee.hasFnAttribute(
"probe-stack")) {
2600 Caller.addFnAttr(Callee.getFnAttribute(
"probe-stack"));
2609 Attribute CalleeAttr = Callee.getFnAttribute(
"stack-probe-size");
2611 Attribute CallerAttr = Caller.getFnAttribute(
"stack-probe-size");
2613 uint64_t CallerStackProbeSize, CalleeStackProbeSize;
2617 if (CallerStackProbeSize > CalleeStackProbeSize) {
2618 Caller.addFnAttr(CalleeAttr);
2621 Caller.addFnAttr(CalleeAttr);
2637 Attribute CallerAttr = Caller.getFnAttribute(
"min-legal-vector-width");
2639 Attribute CalleeAttr = Callee.getFnAttribute(
"min-legal-vector-width");
2641 uint64_t CallerVectorWidth, CalleeVectorWidth;
2644 if (CallerVectorWidth < CalleeVectorWidth)
2645 Caller.addFnAttr(CalleeAttr);
2649 Caller.removeFnAttr(
"min-legal-vector-width");
2658 if (Callee.nullPointerIsDefined() && !Caller.nullPointerIsDefined()) {
2659 Caller.addFnAttr(Attribute::NullPointerIsValid);
2682 return A.getValueAsString() ==
"true";
2687 Fn.
addFnAttr(Kind, Val ?
"true" :
"false");
2691#define GET_ATTR_NAMES
2692#define ATTRIBUTE_ENUM(ENUM_NAME, DISPLAY_NAME) \
2693 struct ENUM_NAME##Attr : EnumAttr { \
2694 static enum Attribute::AttrKind getKind() { \
2695 return llvm::Attribute::ENUM_NAME; \
2698#define ATTRIBUTE_STRBOOL(ENUM_NAME, DISPLAY_NAME) \
2699 struct ENUM_NAME##Attr : StrBoolAttr { \
2700 static StringRef getKind() { return #DISPLAY_NAME; } \
2702#include "llvm/IR/Attributes.inc"
2704#define GET_ATTR_COMPAT_FUNC
2705#include "llvm/IR/Attributes.inc"
2707bool AttributeFuncs::areInlineCompatible(
const Function &Caller,
2709 return hasCompatibleFnAttrs(Caller, Callee);
2714 return hasCompatibleFnAttrs(
A,
B);
2717void AttributeFuncs::mergeAttributesForInlining(
Function &Caller,
2719 mergeFnAttrs(Caller, Callee);
2732 mergeFnAttrs(
Base, ToMerge);
2735void AttributeFuncs::updateMinLegalVectorWidthAttr(
Function &Fn,
2741 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< 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.
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.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
const T & back() const
back - 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
size - Get the array size.
bool empty() const
empty - 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.
void Profile(FoldingSetNodeID &ID) const
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
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 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 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 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 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 void Profile(FoldingSetNodeID &ID) const
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 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.
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.
FoldingSetNodeID - This class is used to gather all the unique data bits of a node.
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.
FoldingSet< AttributeSetNode > AttrsSetNodes
FoldingSet< AttributeListImpl > AttrsLists
This is an important class for using LLVM in a threaded context.
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)
StringRef - 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
str - Get the contents as an std::string.
constexpr bool empty() const
empty - Check if the string is empty.
int compare(StringRef RHS) const
compare - Compare two strings; the result is negative, zero, or positive if this string is lexicograp...
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.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
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.
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...
ArrayRef(const T &OneElt) -> ArrayRef< T >
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.
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::...