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");
130 if (!Val.
empty())
ID.AddString(Val);
174 "Not a ConstantRange attribute");
188 PA =
new (pImpl->ConstantRangeAttributeAlloc.Allocate())
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);
221 void *Mem = pImpl->Alloc.Allocate(
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);
302 const std::optional<unsigned> &NumElemsArg) {
303 assert(!(ElemSizeArg == 0 && NumElemsArg == 0) &&
304 "Invalid allocsize arguments -- given allocsize(0, 0)");
309 return get(Context, AllocKind,
static_cast<uint64_t>(Kind));
320#define GET_ATTR_NAMES
321#define ATTRIBUTE_ENUM(ENUM_NAME, DISPLAY_NAME) \
322 .Case(#DISPLAY_NAME, Attribute::ENUM_NAME)
323#include "llvm/IR/Attributes.inc"
329#define GET_ATTR_NAMES
330#define ATTRIBUTE_ENUM(ENUM_NAME, DISPLAY_NAME) \
331 case Attribute::ENUM_NAME: \
332 return #DISPLAY_NAME;
333#include "llvm/IR/Attributes.inc"
343#define GET_ATTR_NAMES
344#define ATTRIBUTE_ALL(ENUM_NAME, DISPLAY_NAME) .Case(#DISPLAY_NAME, true)
345#include "llvm/IR/Attributes.inc"
354 return pImpl && pImpl->isEnumAttribute();
358 return pImpl && pImpl->isIntAttribute();
362 return pImpl && pImpl->isStringAttribute();
366 return pImpl && pImpl->isTypeAttribute();
370 return pImpl && pImpl->isConstantRangeAttribute();
374 return pImpl && pImpl->isConstantRangeListAttribute();
378 if (!pImpl)
return None;
380 "Invalid attribute type to get the kind as an enum!");
381 return pImpl->getKindAsEnum();
385 if (!pImpl)
return 0;
387 "Expected the attribute to be an integer attribute!");
388 return pImpl->getValueAsInt();
392 if (!pImpl)
return false;
394 "Expected the attribute to be a string attribute!");
395 return pImpl->getValueAsBool();
399 if (!pImpl)
return {};
401 "Invalid attribute type to get the kind as a string!");
402 return pImpl->getKindAsString();
406 if (!pImpl)
return {};
408 "Invalid attribute type to get the value as a string!");
409 return pImpl->getValueAsString();
413 if (!pImpl)
return {};
415 "Invalid attribute type to get the value as a type!");
416 return pImpl->getValueAsType();
421 "Invalid attribute type to get the value as a ConstantRange!");
422 return pImpl->getValueAsConstantRange();
427 "Invalid attribute type to get the value as a ConstantRangeList!");
428 return pImpl->getValueAsConstantRangeList();
432 return (pImpl && pImpl->hasAttribute(Kind)) || (!pImpl && Kind ==
None);
437 return pImpl && pImpl->hasAttribute(Kind);
442 "Trying to get alignment from non-alignment attribute!");
448 "Trying to get alignment from non-alignment attribute!");
454 "Trying to get dereferenceable bytes from "
455 "non-dereferenceable attribute!");
456 return pImpl->getValueAsInt();
461 "Trying to get dead_on_return bytes from"
462 "a parameter without such an attribute!");
468 "Trying to get dereferenceable bytes from "
469 "non-dereferenceable attribute!");
470 return pImpl->getValueAsInt();
473std::pair<unsigned, std::optional<unsigned>>
476 "Trying to get allocsize args from non-allocsize attribute");
482 "Trying to get vscale args from non-vscale attribute");
488 "Trying to get vscale args from non-vscale attribute");
494 "Trying to get unwind table kind from non-uwtable attribute");
500 "Trying to get allockind value from non-allockind attribute");
506 "Can only call getMemoryEffects() on memory attribute");
512 "Can only call getCaptureInfo() on captures attribute");
522 "Can only call getNoFPClass() on nofpclass attribute");
523 return static_cast<FPClassTest>(pImpl->getValueAsInt());
528 "Trying to get range args from non-range attribute");
529 return pImpl->getValueAsConstantRange();
534 "Trying to get initializes attr from non-ConstantRangeList attribute");
535 return pImpl->getValueAsConstantRangeList();
553 if (!pImpl)
return {};
577 auto AttrWithBytesToString = [&](
const char *Name) {
584 return AttrWithBytesToString(
"alignstack");
587 return AttrWithBytesToString(
"dereferenceable");
590 return AttrWithBytesToString(
"dereferenceable_or_null");
594 if (DeadBytes == std::numeric_limits<uint64_t>::max())
595 return "dead_on_return";
596 return AttrWithBytesToString(
"dead_on_return");
601 std::optional<unsigned> NumElems;
605 ?
"allocsize(" +
Twine(ElemSize) +
"," +
Twine(*NumElems) +
")"
606 :
"allocsize(" +
Twine(ElemSize) +
")")
613 return (
"vscale_range(" +
Twine(MinValue) +
"," +
614 Twine(MaxValue.value_or(0)) +
")")
639 return (
"allockind(\"" +
660 bool TargetPrintedForAll =
false;
666 if (!
First && !TargetPrintedForAll)
674 if (!TargetPrintedForAll) {
675 OS <<
"target_mem: ";
677 TargetPrintedForAll =
true;
688 OS <<
"inaccessiblemem: ";
696 OS <<
"target_mem0: ";
699 OS <<
"target_mem1: ";
715 std::string Result =
"denormal_fpenv(";
719 FPEnv.
print(OS,
true);
726 std::string Result =
"nofpclass";
746 OS <<
"initializes(";
766 const auto &AttrVal = pImpl->getValueAsString();
767 if (!AttrVal.empty()) {
780 assert(
isValid() &&
"invalid Attribute doesn't refer to any context");
784 return C.pImpl->AttrsSet.FindNodeOrInsertPos(
ID, Unused) == pImpl;
788 if (!pImpl && !
A.pImpl)
794 return pImpl->cmp(*
A.pImpl,
true);
798 if (!pImpl && !
A.pImpl)
return false;
799 if (!pImpl)
return true;
800 if (!
A.pImpl)
return false;
801 return *pImpl < *
A.pImpl;
805 ID.AddPointer(pImpl);
819#define GET_ATTR_PROP_TABLE
820#include "llvm/IR/Attributes.inc"
823 unsigned Index = Kind - 1;
824 assert(Index < std::size(AttrPropTable) &&
"Invalid attribute kind");
825 return AttrPropTable[Index];
851 "Unknown intersect property");
917 ->getConstantRangeValue();
923 ->getConstantRangeListValue();
945 "Unclear how to compare range list");
962 return cmp(AI,
false) < 0;
981 B.addAttribute(Kind);
988 B.addAttribute(Kind,
Value);
993 const AttributeSet AS)
const {
1000 AttrBuilder
B(
C, *
this);
1001 B.merge(AttrBuilder(
C, AS));
1006 const AttrBuilder &
B)
const {
1010 if (!
B.hasAttributes())
1013 AttrBuilder Merged(
C, *
this);
1015 return get(
C, Merged);
1021 AttrBuilder
B(
C, *
this);
1022 B.removeAttribute(Kind);
1029 AttrBuilder
B(
C, *
this);
1030 B.removeAttribute(Kind);
1036 AttrBuilder
B(
C, *
this);
1038 if (!
B.overlaps(Attrs))
1045std::optional<AttributeSet>
1050 AttrBuilder Intersected(
C);
1052 auto ItBegin0 =
begin();
1053 auto ItEnd0 =
end();
1054 auto ItBegin1 =
Other.begin();
1055 auto ItEnd1 =
Other.end();
1057 while (ItBegin0 != ItEnd0 || ItBegin1 != ItEnd1) {
1062 if (ItBegin1 == ItEnd1)
1063 Attr0 = *ItBegin0++;
1064 else if (ItBegin0 == ItEnd0)
1065 Attr0 = *ItBegin1++;
1067 int Cmp = ItBegin0->cmpKind(*ItBegin1);
1069 Attr0 = *ItBegin0++;
1070 Attr1 = *ItBegin1++;
1072 Attr0 = *ItBegin0++;
1074 Attr0 = *ItBegin1++;
1076 assert(Attr0.
isValid() &&
"Iteration should always yield a valid attr");
1078 auto IntersectEq = [&]() {
1083 Intersected.addAttribute(Attr0);
1091 return std::nullopt;
1100 return std::nullopt;
1106 "Iterator picked up two different attributes in the same iteration");
1111 "Invalid attr type of intersectAnd");
1112 Intersected.addAttribute(Kind);
1119 "Invalid attr type of intersectMin");
1121 Intersected.addRawIntAttr(Kind, NewVal);
1127 case Attribute::Alignment:
1130 Intersected.addAlignmentAttr(
1134 case Attribute::Memory:
1138 case Attribute::Captures:
1142 case Attribute::NoFPClass:
1146 case Attribute::Range: {
1151 Intersected.addRangeAttr(NewRange);
1162 return std::nullopt;
1166 if (Kind == Attribute::ByVal &&
1168 Other.getAttribute(Attribute::Alignment))
1169 return std::nullopt;
1172 return get(
C, Intersected);
1176 return SetNode ? SetNode->getNumAttributes() : 0;
1180 return SetNode ? SetNode->hasAttribute(Kind) :
false;
1184 return SetNode ? SetNode->hasAttribute(Kind) :
false;
1188 return SetNode ? SetNode->getAttribute(Kind) :
Attribute();
1192 return SetNode ? SetNode->getAttribute(Kind) :
Attribute();
1196 return SetNode ? SetNode->getAlignment() : std::nullopt;
1200 return SetNode ? SetNode->getStackAlignment() : std::nullopt;
1204 return SetNode ? SetNode->getDereferenceableBytes() : 0;
1212 return SetNode ? SetNode->getDereferenceableOrNullBytes() : 0;
1216 return SetNode ? SetNode->getAttributeType(Attribute::ByRef) :
nullptr;
1220 return SetNode ? SetNode->getAttributeType(Attribute::ByVal) :
nullptr;
1224 return SetNode ? SetNode->getAttributeType(Attribute::StructRet) :
nullptr;
1228 return SetNode ? SetNode->getAttributeType(Attribute::Preallocated) :
nullptr;
1232 return SetNode ? SetNode->getAttributeType(Attribute::InAlloca) :
nullptr;
1236 return SetNode ? SetNode->getAttributeType(Attribute::ElementType) :
nullptr;
1239std::optional<std::pair<unsigned, std::optional<unsigned>>>
1242 return SetNode->getAllocSizeArgs();
1243 return std::nullopt;
1247 return SetNode ? SetNode->getVScaleRangeMin() : 1;
1251 return SetNode ? SetNode->getVScaleRangeMax() : std::nullopt;
1271 return SetNode ? SetNode->getNoFPClass() :
fcNone;
1275 return SetNode ? SetNode->getAsString(InAttrGrp) :
"";
1281 SetNode->Profile(
ID);
1283 return C.pImpl->AttrsSetNodes.FindNodeOrInsertPos(
ID, Unused) == 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);
1328 if (SortedAttrs.
empty())
1336 for (
const auto &Attr : SortedAttrs)
1357 return getSorted(
C,
B.attrs());
1361 return StringAttrs.count(Kind);
1364std::optional<Attribute>
1368 return std::nullopt;
1373 std::lower_bound(
begin(),
end() - StringAttrs.size(), Kind,
1375 return A.getKindAsEnum() < Kind;
1377 assert(
I !=
end() &&
I->hasAttribute(Kind) &&
"Presence check failed?");
1382 if (
auto A = findEnumAttribute(Kind))
1388 return StringAttrs.lookup(Kind);
1392 if (
auto A = findEnumAttribute(Attribute::Alignment))
1393 return A->getAlignment();
1394 return std::nullopt;
1398 if (
auto A = findEnumAttribute(Attribute::StackAlignment))
1399 return A->getStackAlignment();
1400 return std::nullopt;
1404 if (
auto A = findEnumAttribute(Kind))
1405 return A->getValueAsType();
1410 if (
auto A = findEnumAttribute(Attribute::Dereferenceable))
1411 return A->getDereferenceableBytes();
1416 if (
auto A = findEnumAttribute(Attribute::DeadOnReturn))
1417 return A->getDeadOnReturnInfo();
1422 if (
auto A = findEnumAttribute(Attribute::DereferenceableOrNull))
1423 return A->getDereferenceableOrNullBytes();
1427std::optional<std::pair<unsigned, std::optional<unsigned>>>
1429 if (
auto A = findEnumAttribute(Attribute::AllocSize))
1430 return A->getAllocSizeArgs();
1431 return std::nullopt;
1435 if (
auto A = findEnumAttribute(Attribute::VScaleRange))
1436 return A->getVScaleRangeMin();
1441 if (
auto A = findEnumAttribute(Attribute::VScaleRange))
1442 return A->getVScaleRangeMax();
1443 return std::nullopt;
1447 if (
auto A = findEnumAttribute(Attribute::UWTable))
1448 return A->getUWTableKind();
1453 if (
auto A = findEnumAttribute(Attribute::AllocKind))
1454 return A->getAllocKind();
1459 if (
auto A = findEnumAttribute(Attribute::Memory))
1460 return A->getMemoryEffects();
1465 if (
auto A = findEnumAttribute(Attribute::Captures))
1466 return A->getCaptureInfo();
1471 if (
auto A = findEnumAttribute(Attribute::NoFPClass))
1472 return A->getNoFPClass();
1481 Str +=
I->getAsString(InAttrGrp);
1497 : NumAttrSets(Sets.
size()) {
1498 assert(!Sets.
empty() &&
"pointless AttributeListImpl");
1506 if (!
I.isStringAttribute())
1507 AvailableFunctionAttrs.addAttribute(
I.getKindAsEnum());
1509 for (
const auto &Set : Sets)
1510 for (
const auto &
I : Set)
1511 if (!
I.isStringAttribute())
1512 AvailableSomewhereAttrs.addAttribute(
I.getKindAsEnum());
1521 for (
const auto &Set : Sets)
1522 ID.AddPointer(Set.SetNode);
1526 unsigned *Index)
const {
1527 if (!AvailableSomewhereAttrs.hasAttribute(Kind))
1531 for (
unsigned I = 0, E = NumAttrSets;
I != E; ++
I) {
1532 if (
begin()[
I].hasAttribute(Kind)) {
1543#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1555 assert(!AttrSets.
empty() &&
"pointless AttributeListImpl");
1569 void *Mem = pImpl->
Alloc.Allocate(
1577 return AttributeList(PA);
1582 ArrayRef<std::pair<unsigned, Attribute>> Attrs) {
1588 "Misordered Attributes list!");
1590 [](
const std::pair<unsigned, Attribute> &Pair) {
1591 return Pair.second.isValid();
1593 "Pointless attribute!");
1598 for (
ArrayRef<std::pair<unsigned, Attribute>>::iterator
I =
Attrs.begin(),
1600 unsigned Index =
I->first;
1602 while (
I !=
E &&
I->first == Index) {
1610 return get(
C, AttrPairVec);
1615 ArrayRef<std::pair<unsigned, AttributeSet>> Attrs) {
1621 "Misordered Attributes list!");
1623 [](
const std::pair<unsigned, AttributeSet> &Pair) {
1624 return !Pair.second.hasAttributes();
1626 "Pointless attribute!");
1628 unsigned MaxIndex =
Attrs.back().first;
1631 if (MaxIndex == FunctionIndex &&
Attrs.size() > 1)
1635 for (
const auto &Pair : Attrs)
1638 return getImpl(
C, AttrVec);
1647 unsigned NumSets = 0;
1648 for (
size_t I = ArgAttrs.
size();
I != 0; --
I) {
1649 if (ArgAttrs[
I - 1].hasAttributes()) {
1679 return getImpl(
C, AttrSets);
1682AttributeList AttributeList::get(
LLVMContext &
C,
unsigned Index,
1684 if (!
Attrs.hasAttributes())
1689 return getImpl(
C, AttrSets);
1692AttributeList AttributeList::get(
LLVMContext &
C,
unsigned Index,
1693 const AttrBuilder &
B) {
1697AttributeList AttributeList::get(
LLVMContext &
C,
unsigned Index,
1700 for (
const auto K : Kinds)
1702 return get(
C, Attrs);
1705AttributeList AttributeList::get(
LLVMContext &
C,
unsigned Index,
1708 assert(Kinds.
size() == Values.
size() &&
"Mismatched attribute values.");
1711 for (
const auto K : Kinds)
1713 return get(
C, Attrs);
1716AttributeList AttributeList::get(
LLVMContext &
C,
unsigned Index,
1719 for (
const auto &K : Kinds)
1721 return get(
C, Attrs);
1728 if (
Attrs.size() == 1)
1731 unsigned MaxSize = 0;
1732 for (
const auto &
List : Attrs)
1733 MaxSize = std::max(MaxSize,
List.getNumAttrSets());
1740 for (
unsigned I = 0;
I < MaxSize; ++
I) {
1741 AttrBuilder CurBuilder(
C);
1742 for (
const auto &
List : Attrs)
1743 CurBuilder.merge(AttrBuilder(
C,
List.getAttributes(
I - 1)));
1747 return getImpl(
C, NewAttrSets);
1751AttributeList::addAttributeAtIndex(
LLVMContext &
C,
unsigned Index,
1754 if (
Attrs.hasAttribute(Kind))
1762AttributeList AttributeList::addAttributeAtIndex(
LLVMContext &
C,
unsigned Index,
1766 B.addAttribute(Kind,
Value);
1767 return addAttributesAtIndex(
C, Index,
B);
1770AttributeList AttributeList::addAttributeAtIndex(
LLVMContext &
C,
unsigned Index,
1774 return addAttributesAtIndex(
C, Index,
B);
1777AttributeList AttributeList::setAttributesAtIndex(
LLVMContext &
C,
1782 if (Index >= AttrSets.
size())
1783 AttrSets.
resize(Index + 1);
1787 while (!AttrSets.
empty() && !AttrSets.
back().hasAttributes())
1789 if (AttrSets.
empty())
1791 return AttributeList::getImpl(
C, AttrSets);
1794AttributeList AttributeList::addAttributesAtIndex(
LLVMContext &
C,
1796 const AttrBuilder &
B)
const {
1797 if (!
B.hasAttributes())
1808AttributeList AttributeList::addParamAttribute(
LLVMContext &
C,
1815 if (MaxIndex >= AttrSets.
size())
1816 AttrSets.
resize(MaxIndex + 1);
1818 for (
unsigned ArgNo : ArgNos) {
1820 AttrBuilder
B(
C, AttrSets[Index]);
1825 return getImpl(
C, AttrSets);
1829AttributeList::removeAttributeAtIndex(
LLVMContext &
C,
unsigned Index,
1833 if (Attrs == NewAttrs)
1835 return setAttributesAtIndex(
C, Index, NewAttrs);
1838AttributeList AttributeList::removeAttributeAtIndex(
LLVMContext &
C,
1843 if (Attrs == NewAttrs)
1845 return setAttributesAtIndex(
C, Index, NewAttrs);
1848AttributeList AttributeList::removeAttributesAtIndex(
1853 if (Attrs == NewAttrs)
1855 return setAttributesAtIndex(
C, Index, NewAttrs);
1860 unsigned WithoutIndex)
const {
1865 return setAttributesAtIndex(
C, WithoutIndex,
AttributeSet());
1868AttributeList AttributeList::addDereferenceableRetAttr(
LLVMContext &
C,
1869 uint64_t Bytes)
const {
1871 B.addDereferenceableAttr(Bytes);
1872 return addRetAttributes(
C,
B);
1875AttributeList AttributeList::addDereferenceableParamAttr(
LLVMContext &
C,
1877 uint64_t Bytes)
const {
1879 B.addDereferenceableAttr(Bytes);
1880 return addParamAttributes(
C, Index,
B);
1884AttributeList::addDereferenceableOrNullParamAttr(
LLVMContext &
C,
unsigned Index,
1885 uint64_t Bytes)
const {
1887 B.addDereferenceableOrNullAttr(Bytes);
1888 return addParamAttributes(
C, Index,
B);
1891AttributeList AttributeList::addRangeRetAttr(
LLVMContext &
C,
1895 return addRetAttributes(
C,
B);
1898AttributeList AttributeList::addAllocSizeParamAttr(
1900 const std::optional<unsigned> &NumElemsArg)
const {
1902 B.addAllocSizeAttr(ElemSizeArg, NumElemsArg);
1903 return addParamAttributes(
C, Index,
B);
1906std::optional<AttributeList>
1914 index_iterator(std::max(getNumAttrSets(),
Other.getNumAttrSets()));
1915 for (
unsigned Idx : IndexIt) {
1916 auto IntersectedAS =
1920 return std::nullopt;
1921 if (!IntersectedAS->hasAttributes())
1923 IntersectedAttrs.
push_back(std::make_pair(Idx, *IntersectedAS));
1927 return AttributeList::get(
C, IntersectedAttrs);
1934AttributeSet AttributeList::getParamAttrs(
unsigned ArgNo)
const {
1946bool AttributeList::hasAttributeAtIndex(
unsigned Index,
1951bool AttributeList::hasAttributeAtIndex(
unsigned Index,
StringRef Kind)
const {
1955bool AttributeList::hasAttributesAtIndex(
unsigned Index)
const {
1960 return pImpl && pImpl->hasFnAttribute(Kind);
1963bool AttributeList::hasFnAttr(
StringRef Kind)
const {
1964 return hasAttributeAtIndex(AttributeList::FunctionIndex, Kind);
1968 unsigned *Index)
const {
1969 return pImpl && pImpl->hasAttrSomewhere(Attr, Index);
1972Attribute AttributeList::getAttributeAtIndex(
unsigned Index,
1977Attribute AttributeList::getAttributeAtIndex(
unsigned Index,
1982MaybeAlign AttributeList::getRetAlignment()
const {
1986MaybeAlign AttributeList::getParamAlignment(
unsigned ArgNo)
const {
1990MaybeAlign AttributeList::getParamStackAlignment(
unsigned ArgNo)
const {
1991 return getAttributes(ArgNo + FirstArgIndex).getStackAlignment();
1994Type *AttributeList::getParamByValType(
unsigned Index)
const {
1998Type *AttributeList::getParamStructRetType(
unsigned Index)
const {
1999 return getAttributes(Index + FirstArgIndex).getStructRetType();
2002Type *AttributeList::getParamByRefType(
unsigned Index)
const {
2006Type *AttributeList::getParamPreallocatedType(
unsigned Index)
const {
2007 return getAttributes(Index + FirstArgIndex).getPreallocatedType();
2010Type *AttributeList::getParamInAllocaType(
unsigned Index)
const {
2011 return getAttributes(Index + FirstArgIndex).getInAllocaType();
2014Type *AttributeList::getParamElementType(
unsigned Index)
const {
2015 return getAttributes(Index + FirstArgIndex).getElementType();
2018MaybeAlign AttributeList::getFnStackAlignment()
const {
2019 return getFnAttrs().getStackAlignment();
2022MaybeAlign AttributeList::getRetStackAlignment()
const {
2023 return getRetAttrs().getStackAlignment();
2026uint64_t AttributeList::getRetDereferenceableBytes()
const {
2027 return getRetAttrs().getDereferenceableBytes();
2030uint64_t AttributeList::getParamDereferenceableBytes(
unsigned Index)
const {
2031 return getParamAttrs(Index).getDereferenceableBytes();
2034uint64_t AttributeList::getRetDereferenceableOrNullBytes()
const {
2035 return getRetAttrs().getDereferenceableOrNullBytes();
2039 return getParamAttrs(Index).getDeadOnReturnInfo();
2043AttributeList::getParamDereferenceableOrNullBytes(
unsigned Index)
const {
2044 return getParamAttrs(Index).getDereferenceableOrNullBytes();
2047std::optional<ConstantRange>
2048AttributeList::getParamRange(
unsigned ArgNo)
const {
2049 auto RangeAttr = getParamAttrs(ArgNo).getAttribute(Attribute::Range);
2050 if (RangeAttr.isValid())
2051 return RangeAttr.getRange();
2052 return std::nullopt;
2055FPClassTest AttributeList::getRetNoFPClass()
const {
2056 return getRetAttrs().getNoFPClass();
2059FPClassTest AttributeList::getParamNoFPClass(
unsigned Index)
const {
2060 return getParamAttrs(Index).getNoFPClass();
2063UWTableKind AttributeList::getUWTableKind()
const {
2064 return getFnAttrs().getUWTableKind();
2068 return getFnAttrs().getAllocKind();
2072 return getFnAttrs().getMemoryEffects();
2075std::string AttributeList::getAsString(
unsigned Index,
bool InAttrGrp)
const {
2079AttributeSet AttributeList::getAttributes(
unsigned Index)
const {
2081 if (!pImpl || Index >= getNumAttrSets())
2083 return pImpl->begin()[
Index];
2086bool AttributeList::hasParentContext(
LLVMContext &
C)
const {
2087 assert(!isEmpty() &&
"an empty attribute list has no parent context");
2091 return C.pImpl->AttrsLists.FindNodeOrInsertPos(
ID, Unused) == pImpl;
2094AttributeList::iterator AttributeList::begin()
const {
2095 return pImpl ? pImpl->begin() :
nullptr;
2098AttributeList::iterator AttributeList::end()
const {
2099 return pImpl ? pImpl->end() :
nullptr;
2106unsigned AttributeList::getNumAttrSets()
const {
2107 return pImpl ? pImpl->NumAttrSets : 0;
2111 O <<
"AttributeList[\n";
2113 for (
unsigned i : indexes()) {
2118 case AttrIndex::ReturnIndex:
2121 case AttrIndex::FunctionIndex:
2125 O <<
"arg(" << i - AttrIndex::FirstArgIndex <<
")";
2127 O <<
" => " << getAsString(i) <<
" }\n";
2133#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2146void AttrBuilder::clear() {
Attrs.clear(); }
2176template <
typename K>
2180 if (It != Attrs.end() && It->hasAttribute(Kind))
2183 Attrs.insert(It, Attr);
2186AttrBuilder &AttrBuilder::addAttribute(
Attribute Attr) {
2206 auto It =
lower_bound(Attrs, Val, AttributeComparator());
2207 if (It !=
Attrs.end() && It->hasAttribute(Val))
2212AttrBuilder &AttrBuilder::removeAttribute(
StringRef A) {
2213 auto It =
lower_bound(Attrs,
A, AttributeComparator());
2214 if (It !=
Attrs.end() && It->hasAttribute(
A))
2219std::optional<uint64_t>
2224 return A.getValueAsInt();
2225 return std::nullopt;
2233std::optional<std::pair<unsigned, std::optional<unsigned>>>
2234AttrBuilder::getAllocSizeArgs()
const {
2235 Attribute A = getAttribute(Attribute::AllocSize);
2237 return A.getAllocSizeArgs();
2238 return std::nullopt;
2246 return addRawIntAttr(Attribute::Alignment,
Align->
value());
2254 assert(*
Align <= 0x100 &&
"Alignment too large.");
2255 return addRawIntAttr(Attribute::StackAlignment,
Align->
value());
2258AttrBuilder &AttrBuilder::addDereferenceableAttr(uint64_t Bytes) {
2259 if (Bytes == 0)
return *
this;
2261 return addRawIntAttr(Attribute::Dereferenceable, Bytes);
2265 if (
Info.isZeroSized())
2268 return addRawIntAttr(Attribute::DeadOnReturn,
Info.toIntValue());
2271AttrBuilder &AttrBuilder::addDereferenceableOrNullAttr(uint64_t Bytes) {
2275 return addRawIntAttr(Attribute::DereferenceableOrNull, Bytes);
2279AttrBuilder::addAllocSizeAttr(
unsigned ElemSize,
2280 const std::optional<unsigned> &NumElems) {
2284AttrBuilder &AttrBuilder::addAllocSizeAttrFromRawRepr(uint64_t RawArgs) {
2286 assert(RawArgs &&
"Invalid allocsize arguments -- given allocsize(0, 0)");
2287 return addRawIntAttr(Attribute::AllocSize, RawArgs);
2290AttrBuilder &AttrBuilder::addVScaleRangeAttr(
unsigned MinValue,
2291 std::optional<unsigned> MaxValue) {
2295AttrBuilder &AttrBuilder::addVScaleRangeAttrFromRawRepr(uint64_t RawArgs) {
2300 return addRawIntAttr(Attribute::VScaleRange, RawArgs);
2303AttrBuilder &AttrBuilder::addUWTableAttr(
UWTableKind Kind) {
2306 return addRawIntAttr(Attribute::UWTable, uint64_t(Kind));
2310 return addRawIntAttr(Attribute::Memory, ME.
toIntValue());
2313AttrBuilder &AttrBuilder::addCapturesAttr(
CaptureInfo CI) {
2314 return addRawIntAttr(Attribute::Captures, CI.
toIntValue());
2317AttrBuilder &AttrBuilder::addDenormalFPEnvAttr(
DenormalFPEnv FPEnv) {
2318 return addRawIntAttr(Attribute::DenormalFPEnv, FPEnv.
toIntValue());
2321AttrBuilder &AttrBuilder::addNoFPClassAttr(
FPClassTest Mask) {
2325 return addRawIntAttr(Attribute::NoFPClass, Mask);
2328AttrBuilder &AttrBuilder::addAllocKindAttr(
AllocFnKind Kind) {
2329 return addRawIntAttr(Attribute::AllocKind,
static_cast<uint64_t
>(Kind));
2335 return A.isValid() ?
A.getValueAsType() :
nullptr;
2342AttrBuilder &AttrBuilder::addByValAttr(
Type *Ty) {
2343 return addTypeAttr(Attribute::ByVal, Ty);
2346AttrBuilder &AttrBuilder::addStructRetAttr(
Type *Ty) {
2347 return addTypeAttr(Attribute::StructRet, Ty);
2350AttrBuilder &AttrBuilder::addByRefAttr(
Type *Ty) {
2351 return addTypeAttr(Attribute::ByRef, Ty);
2354AttrBuilder &AttrBuilder::addPreallocatedAttr(
Type *Ty) {
2355 return addTypeAttr(Attribute::Preallocated, Ty);
2358AttrBuilder &AttrBuilder::addInAllocaAttr(
Type *Ty) {
2359 return addTypeAttr(Attribute::InAlloca, Ty);
2370AttrBuilder &AttrBuilder::addRangeAttr(
const ConstantRange &CR) {
2371 return addConstantRangeAttr(Attribute::Range, CR);
2381 return addConstantRangeListAttr(Attribute::Initializes, CRL.
rangesRef());
2384AttrBuilder &AttrBuilder::addFromEquivalentMetadata(
const Instruction &
I) {
2385 if (
I.hasMetadata(LLVMContext::MD_nonnull))
2386 addAttribute(Attribute::NonNull);
2388 if (
I.hasMetadata(LLVMContext::MD_noundef))
2389 addAttribute(Attribute::NoUndef);
2391 if (
const MDNode *
Align =
I.getMetadata(LLVMContext::MD_align)) {
2396 if (
const MDNode *Dereferenceable =
2397 I.getMetadata(LLVMContext::MD_dereferenceable)) {
2403 if (
const MDNode *DereferenceableOrNull =
2404 I.getMetadata(LLVMContext::MD_dereferenceable_or_null)) {
2410 if (
const MDNode *
Range =
I.getMetadata(LLVMContext::MD_range))
2413 if (
const MDNode *NoFPClass =
I.getMetadata(LLVMContext::MD_nofpclass)) {
2421AttrBuilder &AttrBuilder::merge(
const AttrBuilder &
B) {
2423 for (
const auto &
I :
B.attrs())
2440 auto It =
lower_bound(Attrs,
A, AttributeComparator());
2441 if (It !=
Attrs.end() && It->hasAttribute(
A))
2447 auto It =
lower_bound(Attrs,
A, AttributeComparator());
2448 if (It !=
Attrs.end() && It->hasAttribute(
A))
2453std::optional<ConstantRange> AttrBuilder::getRange()
const {
2454 const Attribute RangeAttr = getAttribute(Attribute::Range);
2457 return std::nullopt;
2461 return getAttribute(
A).isValid();
2464bool AttrBuilder::contains(
StringRef A)
const {
2465 return getAttribute(
A).isValid();
2468bool AttrBuilder::operator==(
const AttrBuilder &
B)
const {
2478bool AttributeFuncs::isNoFPClassCompatibleType(
Type *Ty) {
2484 AttributeSafetyKind ASK) {
2487 if (!Ty->isIntegerTy()) {
2489 if (ASK & ASK_SAFE_TO_DROP)
2493 if (!Ty->isIntegerTy() && !Ty->isByteTy()) {
2495 if (ASK & ASK_UNSAFE_TO_DROP)
2499 if (!Ty->isIntOrIntVectorTy()) {
2501 if (ASK & ASK_SAFE_TO_DROP)
2510 if (!Ty->isPointerTy()) {
2512 if (ASK & ASK_SAFE_TO_DROP)
2524 if (ASK & ASK_UNSAFE_TO_DROP)
2537 if (!Ty->isPtrOrPtrVectorTy()) {
2538 if (ASK & ASK_SAFE_TO_DROP)
2542 if (ASK & ASK_SAFE_TO_DROP) {
2543 if (!isNoFPClassCompatibleType(Ty))
2548 if (Ty->isVoidTy()) {
2549 if (ASK & ASK_SAFE_TO_DROP)
2553 return Incompatible;
2602 return !Callee.getAttributes().hasFnAttr(Attribute::StrictFP) ||
2603 Caller.getAttributes().hasFnAttr(Attribute::StrictFP);
2606template<
typename AttrClass>
2608 return Caller.getFnAttribute(AttrClass::getKind()) ==
2609 Callee.getFnAttribute(AttrClass::getKind());
2614 return Caller.getFnAttribute(AttrName) == Callee.getFnAttribute(AttrName);
2622template<
typename AttrClass>
2624 if (AttrClass::isSet(Caller, AttrClass::getKind()) &&
2625 !AttrClass::isSet(Callee, AttrClass::getKind()))
2626 AttrClass::set(Caller, AttrClass::getKind(),
false);
2634template<
typename AttrClass>
2636 if (!AttrClass::isSet(Caller, AttrClass::getKind()) &&
2637 AttrClass::isSet(Callee, AttrClass::getKind()))
2638 AttrClass::set(Caller, AttrClass::getKind(),
true);
2647 if (!Caller.hasStackProtectorFnAttr())
2658 if (Callee.hasFnAttribute(Attribute::StackProtectReq)) {
2659 Caller.removeFnAttrs(OldSSPAttr);
2660 Caller.addFnAttr(Attribute::StackProtectReq);
2661 }
else if (Callee.hasFnAttribute(Attribute::StackProtectStrong) &&
2662 !Caller.hasFnAttribute(Attribute::StackProtectReq)) {
2663 Caller.removeFnAttrs(OldSSPAttr);
2664 Caller.addFnAttr(Attribute::StackProtectStrong);
2665 }
else if (Callee.hasFnAttribute(Attribute::StackProtect) &&
2666 !Caller.hasFnAttribute(Attribute::StackProtectReq) &&
2667 !Caller.hasFnAttribute(Attribute::StackProtectStrong))
2668 Caller.addFnAttr(Attribute::StackProtect);
2674 if (!Caller.hasFnAttribute(
"probe-stack") &&
2675 Callee.hasFnAttribute(
"probe-stack")) {
2676 Caller.addFnAttr(Callee.getFnAttribute(
"probe-stack"));
2685 Attribute CalleeAttr = Callee.getFnAttribute(
"stack-probe-size");
2687 Attribute CallerAttr = Caller.getFnAttribute(
"stack-probe-size");
2689 uint64_t CallerStackProbeSize, CalleeStackProbeSize;
2693 if (CallerStackProbeSize > CalleeStackProbeSize) {
2694 Caller.addFnAttr(CalleeAttr);
2697 Caller.addFnAttr(CalleeAttr);
2713 Attribute CallerAttr = Caller.getFnAttribute(
"min-legal-vector-width");
2715 Attribute CalleeAttr = Callee.getFnAttribute(
"min-legal-vector-width");
2717 uint64_t CallerVectorWidth, CalleeVectorWidth;
2720 if (CallerVectorWidth < CalleeVectorWidth)
2721 Caller.addFnAttr(CalleeAttr);
2725 Caller.removeFnAttr(
"min-legal-vector-width");
2734 if (Callee.nullPointerIsDefined() && !Caller.nullPointerIsDefined()) {
2735 Caller.addFnAttr(Attribute::NullPointerIsValid);
2758 return A.getValueAsString() ==
"true";
2763 Fn.
addFnAttr(Kind, Val ?
"true" :
"false");
2767#define GET_ATTR_NAMES
2768#define ATTRIBUTE_ENUM(ENUM_NAME, DISPLAY_NAME) \
2769 struct ENUM_NAME##Attr : EnumAttr { \
2770 static enum Attribute::AttrKind getKind() { \
2771 return llvm::Attribute::ENUM_NAME; \
2774#define ATTRIBUTE_STRBOOL(ENUM_NAME, DISPLAY_NAME) \
2775 struct ENUM_NAME##Attr : StrBoolAttr { \
2776 static StringRef getKind() { return #DISPLAY_NAME; } \
2778#include "llvm/IR/Attributes.inc"
2780#define GET_ATTR_COMPAT_FUNC
2781#include "llvm/IR/Attributes.inc"
2783bool AttributeFuncs::areInlineCompatible(
const Function &Caller,
2785 return hasCompatibleFnAttrs(Caller, Callee);
2790 return hasCompatibleFnAttrs(
A,
B);
2793void AttributeFuncs::mergeAttributesForInlining(
Function &Caller,
2795 mergeFnAttrs(Caller, Callee);
2808 mergeFnAttrs(
Base, ToMerge);
2811void AttributeFuncs::updateMinLegalVectorWidthAttr(
Function &Fn,
2817 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
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 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 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 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.
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.
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)
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.
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::...