25#include "llvm/Config/llvm-config.h"
62 const std::optional<unsigned> &NumElemsArg) {
64 "Attempting to pack a reserved value");
70static std::pair<unsigned, std::optional<unsigned>>
72 unsigned NumElems = Num & std::numeric_limits<unsigned>::max();
73 unsigned ElemSizeArg = Num >> 32;
75 std::optional<unsigned> NumElemsArg;
77 NumElemsArg = NumElems;
78 return std::make_pair(ElemSizeArg, NumElemsArg);
82 std::optional<unsigned> MaxValue) {
83 return uint64_t(MinValue) << 32 | MaxValue.value_or(0);
86static std::pair<unsigned, std::optional<unsigned>>
88 unsigned MaxValue =
Value & std::numeric_limits<unsigned>::max();
89 unsigned MinValue =
Value >> 32;
91 return std::make_pair(MinValue,
92 MaxValue > 0 ? MaxValue : std::optional<unsigned>());
99 "Not an enum or int attribute");
103 assert(Val == 0 &&
"Value must be zero for enum attributes");
116 pImpl->IntAttrs.insert(PA, Token);
134 pImpl->StringAttrs.insert(PA, Token);
151 pImpl->TypeAttrs.insert(PA, Token);
161 "Not a ConstantRange attribute");
175 PA =
new (pImpl->ConstantRangeAttributeAlloc.Allocate())
177 pImpl->AttrsSet.insert(PA, Token);
187 "Not a ConstantRangeList attribute");
191 ID.AddInteger(Val.
size());
192 for (
auto &CR : Val) {
193 CR.getLower().Profile(ID);
194 CR.getUpper().Profile(ID);
208 void *Mem = pImpl->Alloc.Allocate(
212 pImpl->AttrsSet.insert(PA, Token);
213 pImpl->ConstantRangeListAttributes.push_back(
223 return get(Context, Alignment,
A.value());
227 assert(
A <= 0x100 &&
"Alignment too large.");
228 return get(Context, StackAlignment,
A.value());
233 assert(Bytes &&
"Bytes must be non-zero.");
234 return get(Context, Dereferenceable, Bytes);
239 assert(Bytes &&
"Bytes must be non-zero.");
240 return get(Context, DereferenceableOrNull, Bytes);
244 return get(Context, ByVal, Ty);
248 return get(Context, StructRet, Ty);
252 return get(Context, ByRef, Ty);
256 return get(Context, Preallocated, Ty);
260 return get(Context, InAlloca, Ty);
275 return get(Context, NoFPClass, ClassMask);
289 const std::optional<unsigned> &NumElemsArg) {
290 assert(!(ElemSizeArg == 0 && NumElemsArg == 0) &&
291 "Invalid allocsize arguments -- given allocsize(0, 0)");
296 return get(Context, AllocKind,
static_cast<uint64_t
>(Kind));
307#define GET_ATTR_NAMES
308#define ATTRIBUTE_ENUM(ENUM_NAME, DISPLAY_NAME) \
309 .Case(#DISPLAY_NAME, Attribute::ENUM_NAME)
310#include "llvm/IR/Attributes.inc"
316#define GET_ATTR_NAMES
317#define ATTRIBUTE_ENUM(ENUM_NAME, DISPLAY_NAME) \
318 case Attribute::ENUM_NAME: \
319 return #DISPLAY_NAME;
320#include "llvm/IR/Attributes.inc"
333 return pImpl && pImpl->isEnumAttribute();
337 return pImpl && pImpl->isIntAttribute();
341 return pImpl && pImpl->isStringAttribute();
345 return pImpl && pImpl->isTypeAttribute();
349 return pImpl && pImpl->isConstantRangeAttribute();
353 return pImpl && pImpl->isConstantRangeListAttribute();
357 if (!pImpl)
return None;
359 "Invalid attribute type to get the kind as an enum!");
360 return pImpl->getKindAsEnum();
364 if (!pImpl)
return 0;
366 "Expected the attribute to be an integer attribute!");
367 return pImpl->getValueAsInt();
371 if (!pImpl)
return false;
373 "Expected the attribute to be a string attribute!");
374 return pImpl->getValueAsBool();
378 if (!pImpl)
return {};
380 "Invalid attribute type to get the kind as a string!");
381 return pImpl->getKindAsString();
385 if (!pImpl)
return {};
387 "Invalid attribute type to get the value as a string!");
388 return pImpl->getValueAsString();
392 if (!pImpl)
return {};
394 "Invalid attribute type to get the value as a type!");
395 return pImpl->getValueAsType();
400 "Invalid attribute type to get the value as a ConstantRange!");
401 return pImpl->getValueAsConstantRange();
406 "Invalid attribute type to get the value as a ConstantRangeList!");
407 return pImpl->getValueAsConstantRangeList();
411 return (pImpl && pImpl->hasAttribute(Kind)) || (!pImpl && Kind ==
None);
416 return pImpl && pImpl->hasAttribute(Kind);
421 "Trying to get alignment from non-alignment attribute!");
427 "Trying to get alignment from non-alignment attribute!");
433 "Trying to get dereferenceable bytes from "
434 "non-dereferenceable attribute!");
435 return pImpl->getValueAsInt();
440 "Trying to get dead_on_return bytes from"
441 "a parameter without such an attribute!");
447 "Trying to get dereferenceable bytes from "
448 "non-dereferenceable attribute!");
449 return pImpl->getValueAsInt();
452std::pair<unsigned, std::optional<unsigned>>
455 "Trying to get allocsize args from non-allocsize attribute");
461 "Trying to get vscale args from non-vscale attribute");
467 "Trying to get vscale args from non-vscale attribute");
473 "Trying to get unwind table kind from non-uwtable attribute");
479 "Trying to get allockind value from non-allockind attribute");
485 "Can only call getMemoryEffects() on memory attribute");
491 "Can only call getCaptureInfo() on captures attribute");
501 "Can only call getNoFPClass() on nofpclass attribute");
502 return static_cast<FPClassTest>(pImpl->getValueAsInt());
507 "Trying to get range args from non-range attribute");
508 return pImpl->getValueAsConstantRange();
513 "Trying to get initializes attr from non-ConstantRangeList attribute");
514 return pImpl->getValueAsConstantRangeList();
532 if (!pImpl)
return {};
556 auto AttrWithBytesToString = [&](
const char *Name) {
563 return AttrWithBytesToString(
"alignstack");
566 return AttrWithBytesToString(
"dereferenceable");
569 return AttrWithBytesToString(
"dereferenceable_or_null");
573 if (DeadBytes == std::numeric_limits<uint64_t>::max())
574 return "dead_on_return";
575 return AttrWithBytesToString(
"dead_on_return");
580 std::optional<unsigned> NumElems;
584 ?
"allocsize(" +
Twine(ElemSize) +
"," +
Twine(*NumElems) +
")"
585 :
"allocsize(" +
Twine(ElemSize) +
")")
592 return (
"vscale_range(" +
Twine(MinValue) +
"," +
593 Twine(MaxValue.value_or(0)) +
")")
618 return (
"allockind(\"" +
639 bool TargetPrintedForAll =
false;
645 if (!
First && !TargetPrintedForAll)
653 if (!TargetPrintedForAll) {
654 OS <<
"target_mem: ";
656 TargetPrintedForAll =
true;
667 OS <<
"inaccessiblemem: ";
675 OS <<
"target_mem0: ";
678 OS <<
"target_mem1: ";
694 std::string Result =
"denormal_fpenv(";
698 FPEnv.
print(OS,
true);
705 std::string Result =
"nofpclass";
725 OS <<
"initializes(";
745 const auto &AttrVal = pImpl->getValueAsString();
746 if (!AttrVal.empty()) {
759 assert(
isValid() &&
"invalid Attribute doesn't refer to any context");
762 if (pImpl->isEnumAttribute())
763 return pI->
EnumAttrs[pImpl->getKindAsEnum() - FirstEnumAttr] == pImpl;
764 if (pImpl->isIntAttribute())
765 return pI->
IntAttrs.lookup({pImpl->getKindAsEnum(), pImpl->getValueAsInt()},
767 if (pImpl->isStringAttribute())
769 {pImpl->getKindAsString(), pImpl->getValueAsString()}, Token) ==
771 if (pImpl->isTypeAttribute())
773 {pImpl->getKindAsEnum(), pImpl->getValueAsType()}, Token) ==
777 return pI->
AttrsSet.lookup(ID, Token) == pImpl;
781 if (!pImpl && !
A.pImpl)
787 return pImpl->cmp(*
A.pImpl,
true);
791 if (!pImpl && !
A.pImpl)
return false;
792 if (!pImpl)
return true;
793 if (!
A.pImpl)
return false;
794 return *pImpl < *
A.pImpl;
809#define GET_ATTR_PROP_TABLE
810#include "llvm/IR/Attributes.inc"
813 unsigned Index = Kind - 1;
814 assert(Index < std::size(AttrPropTable) &&
"Invalid attribute kind");
815 return AttrPropTable[Index];
845 "Unknown intersect property");
911 ->getConstantRangeValue();
917 ->getConstantRangeListValue();
939 "Unclear how to compare range list");
956 return cmp(AI,
false) < 0;
975 B.addAttribute(Kind);
982 B.addAttribute(Kind,
Value);
987 const AttributeSet AS)
const {
994 AttrBuilder
B(
C, *
this);
995 B.merge(AttrBuilder(
C, AS));
1000 const AttrBuilder &
B)
const {
1004 if (!
B.hasAttributes())
1007 AttrBuilder Merged(
C, *
this);
1009 return get(
C, Merged);
1015 AttrBuilder
B(
C, *
this);
1016 B.removeAttribute(Kind);
1023 AttrBuilder
B(
C, *
this);
1024 B.removeAttribute(Kind);
1030 AttrBuilder
B(
C, *
this);
1032 if (!
B.overlaps(Attrs))
1039std::optional<AttributeSet>
1044 AttrBuilder Intersected(
C);
1046 auto ItBegin0 =
begin();
1047 auto ItEnd0 =
end();
1048 auto ItBegin1 =
Other.begin();
1049 auto ItEnd1 =
Other.end();
1051 while (ItBegin0 != ItEnd0 || ItBegin1 != ItEnd1) {
1056 if (ItBegin1 == ItEnd1)
1057 Attr0 = *ItBegin0++;
1058 else if (ItBegin0 == ItEnd0)
1059 Attr0 = *ItBegin1++;
1061 int Cmp = ItBegin0->cmpKind(*ItBegin1);
1063 Attr0 = *ItBegin0++;
1064 Attr1 = *ItBegin1++;
1066 Attr0 = *ItBegin0++;
1068 Attr0 = *ItBegin1++;
1070 assert(Attr0.
isValid() &&
"Iteration should always yield a valid attr");
1072 auto IntersectEq = [&]() {
1077 Intersected.addAttribute(Attr0);
1085 return std::nullopt;
1094 return std::nullopt;
1100 "Iterator picked up two different attributes in the same iteration");
1105 "Invalid attr type of intersectAnd");
1106 Intersected.addAttribute(Kind);
1113 "Invalid attr type of intersectMin");
1115 Intersected.addRawIntAttr(Kind, NewVal);
1121 case Attribute::Alignment:
1124 Intersected.addAlignmentAttr(
1128 case Attribute::Memory:
1132 case Attribute::Captures:
1136 case Attribute::NoFPClass:
1140 case Attribute::Range: {
1145 Intersected.addRangeAttr(NewRange);
1156 return std::nullopt;
1160 if (Kind == Attribute::ByVal &&
1162 Other.getAttribute(Attribute::Alignment))
1163 return std::nullopt;
1166 return get(
C, Intersected);
1170 return SetNode ? SetNode->getNumAttributes() : 0;
1174 return SetNode ? SetNode->hasAttribute(Kind) :
false;
1178 return SetNode ? SetNode->hasAttribute(Kind) :
false;
1182 return SetNode ? SetNode->getAttribute(Kind) :
Attribute();
1186 return SetNode ? SetNode->getAttribute(Kind) :
Attribute();
1190 return SetNode ? SetNode->getAlignment() : std::nullopt;
1194 return SetNode ? SetNode->getStackAlignment() : std::nullopt;
1198 return SetNode ? SetNode->getDereferenceableBytes() : 0;
1206 return SetNode ? SetNode->getDereferenceableOrNullBytes() : 0;
1210 return SetNode ? SetNode->getAttributeType(Attribute::ByRef) :
nullptr;
1214 return SetNode ? SetNode->getAttributeType(Attribute::ByVal) :
nullptr;
1218 return SetNode ? SetNode->getAttributeType(Attribute::StructRet) :
nullptr;
1222 return SetNode ? SetNode->getAttributeType(Attribute::Preallocated) :
nullptr;
1226 return SetNode ? SetNode->getAttributeType(Attribute::InAlloca) :
nullptr;
1230 return SetNode ? SetNode->getAttributeType(Attribute::ElementType) :
nullptr;
1233std::optional<std::pair<unsigned, std::optional<unsigned>>>
1236 return SetNode->getAllocSizeArgs();
1237 return std::nullopt;
1241 return SetNode ? SetNode->getVScaleRangeMin() : 1;
1245 return SetNode ? SetNode->getVScaleRangeMax() : std::nullopt;
1265 return SetNode ? SetNode->getNoFPClass() :
fcNone;
1269 return SetNode ? SetNode->getAsString(InAttrGrp) :
"";
1275 return C.pImpl->AttrsSetNodes.lookup(SetNode->getKey(), Token) == SetNode;
1279 return SetNode ? SetNode->begin() :
nullptr;
1283 return SetNode ? SetNode->end() :
nullptr;
1286#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1299 : NumAttrs(Attrs.
size()) {
1303 for (
const auto &
I : *
this) {
1304 if (
I.isStringAttribute())
1305 StringAttrs.insert({
I.getKindAsString(),
I });
1307 AvailableAttrs.addAttribute(
I.getKindAsEnum());
1357 if (SortedAttrs.
empty())
1361 "expected sorted and unique attributes!");
1364 AttributeSetNode *PA =
C.pImpl->AttrsSetNodes.lookup(SortedAttrs, Token);
1371 PA =
new (Mem) AttributeSetNode(SortedAttrs);
1372 C.pImpl->AttrsSetNodes.insert(PA, Token);
1384 return StringAttrs.count(Kind);
1387std::optional<Attribute>
1391 return std::nullopt;
1396 std::lower_bound(
begin(),
end() - StringAttrs.size(), Kind,
1398 return A.getKindAsEnum() < Kind;
1400 assert(
I !=
end() &&
I->hasAttribute(Kind) &&
"Presence check failed?");
1405 if (
auto A = findEnumAttribute(Kind))
1411 return StringAttrs.lookup(Kind);
1415 if (
auto A = findEnumAttribute(Attribute::Alignment))
1416 return A->getAlignment();
1417 return std::nullopt;
1421 if (
auto A = findEnumAttribute(Attribute::StackAlignment))
1422 return A->getStackAlignment();
1423 return std::nullopt;
1427 if (
auto A = findEnumAttribute(Kind))
1428 return A->getValueAsType();
1433 if (
auto A = findEnumAttribute(Attribute::Dereferenceable))
1434 return A->getDereferenceableBytes();
1439 if (
auto A = findEnumAttribute(Attribute::DeadOnReturn))
1440 return A->getDeadOnReturnInfo();
1445 if (
auto A = findEnumAttribute(Attribute::DereferenceableOrNull))
1446 return A->getDereferenceableOrNullBytes();
1450std::optional<std::pair<unsigned, std::optional<unsigned>>>
1452 if (
auto A = findEnumAttribute(Attribute::AllocSize))
1453 return A->getAllocSizeArgs();
1454 return std::nullopt;
1458 if (
auto A = findEnumAttribute(Attribute::VScaleRange))
1459 return A->getVScaleRangeMin();
1464 if (
auto A = findEnumAttribute(Attribute::VScaleRange))
1465 return A->getVScaleRangeMax();
1466 return std::nullopt;
1470 if (
auto A = findEnumAttribute(Attribute::UWTable))
1471 return A->getUWTableKind();
1476 if (
auto A = findEnumAttribute(Attribute::AllocKind))
1477 return A->getAllocKind();
1482 if (
auto A = findEnumAttribute(Attribute::Memory))
1483 return A->getMemoryEffects();
1488 if (
auto A = findEnumAttribute(Attribute::Captures))
1489 return A->getCaptureInfo();
1494 if (
auto A = findEnumAttribute(Attribute::NoFPClass))
1495 return A->getNoFPClass();
1504 Str +=
I->getAsString(InAttrGrp);
1520 : NumAttrSets(Sets.
size()) {
1521 assert(!Sets.
empty() &&
"pointless AttributeListImpl");
1529 if (!
I.isStringAttribute())
1530 AvailableFunctionAttrs.addAttribute(
I.getKindAsEnum());
1532 for (
const auto &Set : Sets)
1533 for (
const auto &
I : Set)
1534 if (!
I.isStringAttribute())
1535 AvailableSomewhereAttrs.addAttribute(
I.getKindAsEnum());
1539 unsigned *Index)
const {
1540 if (!AvailableSomewhereAttrs.hasAttribute(Kind))
1544 for (
unsigned I = 0, E = NumAttrSets;
I != E; ++
I) {
1545 if (
begin()[
I].hasAttribute(Kind)) {
1556#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1568 assert(!AttrSets.
empty() &&
"pointless AttributeListImpl");
1578 void *Mem = pImpl->
Alloc.Allocate(
1591 ArrayRef<std::pair<unsigned, Attribute>> Attrs) {
1597 "Misordered Attributes list!");
1599 [](
const std::pair<unsigned, Attribute> &Pair) {
1600 return Pair.second.isValid();
1602 "Pointless attribute!");
1607 for (
ArrayRef<std::pair<unsigned, Attribute>>::iterator
I =
Attrs.begin(),
1609 unsigned Index =
I->first;
1611 while (
I !=
E &&
I->first == Index) {
1619 return get(
C, AttrPairVec);
1624 ArrayRef<std::pair<unsigned, AttributeSet>> Attrs) {
1630 "Misordered Attributes list!");
1632 [](
const std::pair<unsigned, AttributeSet> &Pair) {
1633 return !Pair.second.hasAttributes();
1635 "Pointless attribute!");
1637 unsigned MaxIndex =
Attrs.back().first;
1640 if (MaxIndex == FunctionIndex &&
Attrs.size() > 1)
1644 for (
const auto &Pair : Attrs)
1647 return getImpl(
C, AttrVec);
1656 unsigned NumSets = 0;
1657 for (
size_t I = ArgAttrs.
size();
I != 0; --
I) {
1658 if (ArgAttrs[
I - 1].hasAttributes()) {
1688 return getImpl(
C, AttrSets);
1691AttributeList AttributeList::get(
LLVMContext &
C,
unsigned Index,
1693 if (!
Attrs.hasAttributes())
1698 return getImpl(
C, AttrSets);
1701AttributeList AttributeList::get(
LLVMContext &
C,
unsigned Index,
1702 const AttrBuilder &
B) {
1706AttributeList AttributeList::get(
LLVMContext &
C,
unsigned Index,
1709 for (
const auto K : Kinds)
1711 return get(
C, Attrs);
1714AttributeList AttributeList::get(
LLVMContext &
C,
unsigned Index,
1720 for (
const auto K : Kinds)
1722 return get(
C, Attrs);
1725AttributeList AttributeList::get(
LLVMContext &
C,
unsigned Index,
1728 for (
const auto &K : Kinds)
1730 return get(
C, Attrs);
1737 if (
Attrs.size() == 1)
1740 unsigned MaxSize = 0;
1741 for (
const auto &
List : Attrs)
1742 MaxSize = std::max(MaxSize,
List.getNumAttrSets());
1749 for (
unsigned I = 0;
I < MaxSize; ++
I) {
1750 AttrBuilder CurBuilder(
C);
1751 for (
const auto &
List : Attrs)
1752 CurBuilder.merge(AttrBuilder(
C,
List.getAttributes(
I - 1)));
1756 return getImpl(
C, NewAttrSets);
1760AttributeList::addAttributeAtIndex(
LLVMContext &
C,
unsigned Index,
1763 if (
Attrs.hasAttribute(Kind))
1771AttributeList AttributeList::addAttributeAtIndex(
LLVMContext &
C,
unsigned Index,
1775 B.addAttribute(Kind,
Value);
1776 return addAttributesAtIndex(
C, Index,
B);
1779AttributeList AttributeList::addAttributeAtIndex(
LLVMContext &
C,
unsigned Index,
1783 return addAttributesAtIndex(
C, Index,
B);
1786AttributeList AttributeList::setAttributesAtIndex(
LLVMContext &
C,
1791 if (Index >= AttrSets.
size())
1792 AttrSets.
resize(Index + 1);
1796 while (!AttrSets.
empty() && !AttrSets.
back().hasAttributes())
1798 if (AttrSets.
empty())
1800 return AttributeList::getImpl(
C, AttrSets);
1803AttributeList AttributeList::addAttributesAtIndex(
LLVMContext &
C,
1805 const AttrBuilder &
B)
const {
1806 if (!
B.hasAttributes())
1818AttributeList::addSortedAttributesAtIndex(
LLVMContext &
C,
unsigned Index,
1822 return setAttributesAtIndex(
1826AttributeList AttributeList::addParamAttribute(
LLVMContext &
C,
1833 if (MaxIndex >= AttrSets.
size())
1834 AttrSets.
resize(MaxIndex + 1);
1836 for (
unsigned ArgNo : ArgNos) {
1838 AttrBuilder
B(
C, AttrSets[Index]);
1843 return getImpl(
C, AttrSets);
1847AttributeList::removeAttributeAtIndex(
LLVMContext &
C,
unsigned Index,
1851 if (Attrs == NewAttrs)
1853 return setAttributesAtIndex(
C, Index, NewAttrs);
1856AttributeList AttributeList::removeAttributeAtIndex(
LLVMContext &
C,
1861 if (Attrs == NewAttrs)
1863 return setAttributesAtIndex(
C, Index, NewAttrs);
1866AttributeList AttributeList::removeAttributesAtIndex(
1871 if (Attrs == NewAttrs)
1873 return setAttributesAtIndex(
C, Index, NewAttrs);
1878 unsigned WithoutIndex)
const {
1883 return setAttributesAtIndex(
C, WithoutIndex,
AttributeSet());
1886AttributeList AttributeList::addDereferenceableRetAttr(
LLVMContext &
C,
1889 B.addDereferenceableAttr(Bytes);
1890 return addRetAttributes(
C,
B);
1893AttributeList AttributeList::addDereferenceableParamAttr(
LLVMContext &
C,
1897 B.addDereferenceableAttr(Bytes);
1898 return addParamAttributes(
C, Index,
B);
1902AttributeList::addDereferenceableOrNullParamAttr(
LLVMContext &
C,
unsigned Index,
1905 B.addDereferenceableOrNullAttr(Bytes);
1906 return addParamAttributes(
C, Index,
B);
1909AttributeList AttributeList::addRangeRetAttr(
LLVMContext &
C,
1913 return addRetAttributes(
C,
B);
1916AttributeList AttributeList::addAllocSizeParamAttr(
1918 const std::optional<unsigned> &NumElemsArg)
const {
1920 B.addAllocSizeAttr(ElemSizeArg, NumElemsArg);
1921 return addParamAttributes(
C, Index,
B);
1924std::optional<AttributeList>
1932 index_iterator(std::max(getNumAttrSets(),
Other.getNumAttrSets()));
1933 for (
unsigned Idx : IndexIt) {
1934 auto IntersectedAS =
1938 return std::nullopt;
1939 if (!IntersectedAS->hasAttributes())
1941 IntersectedAttrs.
push_back(std::make_pair(Idx, *IntersectedAS));
1945 return AttributeList::get(
C, IntersectedAttrs);
1952AttributeSet AttributeList::getParamAttrs(
unsigned ArgNo)
const {
1964bool AttributeList::hasAttributeAtIndex(
unsigned Index,
1969bool AttributeList::hasAttributeAtIndex(
unsigned Index,
StringRef Kind)
const {
1973bool AttributeList::hasAttributesAtIndex(
unsigned Index)
const {
1978 return pImpl && pImpl->hasFnAttribute(Kind);
1981bool AttributeList::hasFnAttr(
StringRef Kind)
const {
1982 return hasAttributeAtIndex(AttributeList::FunctionIndex, Kind);
1986 unsigned *Index)
const {
1987 return pImpl && pImpl->hasAttrSomewhere(Attr, Index);
1990Attribute AttributeList::getAttributeAtIndex(
unsigned Index,
1995Attribute AttributeList::getAttributeAtIndex(
unsigned Index,
2000MaybeAlign AttributeList::getRetAlignment()
const {
2004MaybeAlign AttributeList::getParamAlignment(
unsigned ArgNo)
const {
2008MaybeAlign AttributeList::getParamStackAlignment(
unsigned ArgNo)
const {
2009 return getAttributes(ArgNo + FirstArgIndex).getStackAlignment();
2012Type *AttributeList::getParamByValType(
unsigned Index)
const {
2016Type *AttributeList::getParamStructRetType(
unsigned Index)
const {
2017 return getAttributes(Index + FirstArgIndex).getStructRetType();
2020Type *AttributeList::getParamByRefType(
unsigned Index)
const {
2024Type *AttributeList::getParamPreallocatedType(
unsigned Index)
const {
2025 return getAttributes(Index + FirstArgIndex).getPreallocatedType();
2028Type *AttributeList::getParamInAllocaType(
unsigned Index)
const {
2029 return getAttributes(Index + FirstArgIndex).getInAllocaType();
2032Type *AttributeList::getParamElementType(
unsigned Index)
const {
2033 return getAttributes(Index + FirstArgIndex).getElementType();
2036MaybeAlign AttributeList::getFnStackAlignment()
const {
2037 return getFnAttrs().getStackAlignment();
2040MaybeAlign AttributeList::getRetStackAlignment()
const {
2041 return getRetAttrs().getStackAlignment();
2044uint64_t AttributeList::getRetDereferenceableBytes()
const {
2045 return getRetAttrs().getDereferenceableBytes();
2048uint64_t AttributeList::getParamDereferenceableBytes(
unsigned Index)
const {
2049 return getParamAttrs(Index).getDereferenceableBytes();
2052uint64_t AttributeList::getRetDereferenceableOrNullBytes()
const {
2053 return getRetAttrs().getDereferenceableOrNullBytes();
2057 return getParamAttrs(Index).getDeadOnReturnInfo();
2061AttributeList::getParamDereferenceableOrNullBytes(
unsigned Index)
const {
2062 return getParamAttrs(Index).getDereferenceableOrNullBytes();
2065std::optional<ConstantRange>
2066AttributeList::getParamRange(
unsigned ArgNo)
const {
2067 auto RangeAttr = getParamAttrs(ArgNo).getAttribute(Attribute::Range);
2068 if (RangeAttr.isValid())
2069 return RangeAttr.getRange();
2070 return std::nullopt;
2073FPClassTest AttributeList::getRetNoFPClass()
const {
2074 return getRetAttrs().getNoFPClass();
2077FPClassTest AttributeList::getParamNoFPClass(
unsigned Index)
const {
2078 return getParamAttrs(Index).getNoFPClass();
2081UWTableKind AttributeList::getUWTableKind()
const {
2082 return getFnAttrs().getUWTableKind();
2086 return getFnAttrs().getAllocKind();
2090 return getFnAttrs().getMemoryEffects();
2093std::string AttributeList::getAsString(
unsigned Index,
bool InAttrGrp)
const {
2097AttributeSet AttributeList::getAttributes(
unsigned Index)
const {
2099 if (!pImpl || Index >= getNumAttrSets())
2101 return pImpl->begin()[
Index];
2104bool AttributeList::hasParentContext(
LLVMContext &
C)
const {
2105 assert(!isEmpty() &&
"an empty attribute list has no parent context");
2107 return C.pImpl->AttrsLists.lookup(pImpl->getKey(), Token) == pImpl;
2110AttributeList::iterator AttributeList::begin()
const {
2111 return pImpl ? pImpl->begin() :
nullptr;
2114AttributeList::iterator AttributeList::end()
const {
2115 return pImpl ? pImpl->end() :
nullptr;
2122unsigned AttributeList::getNumAttrSets()
const {
2123 return pImpl ? pImpl->NumAttrSets : 0;
2127 O <<
"AttributeList[\n";
2129 for (
unsigned i : indexes()) {
2134 case AttrIndex::ReturnIndex:
2137 case AttrIndex::FunctionIndex:
2141 O <<
"arg(" << i - AttrIndex::FirstArgIndex <<
")";
2143 O <<
" => " << getAsString(i) <<
" }\n";
2149#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2162void AttrBuilder::clear() {
Attrs.clear(); }
2164template <
typename K>
2168 if (It != Attrs.end() && It->hasAttribute(Kind))
2171 Attrs.insert(It, Attr);
2174AttrBuilder &AttrBuilder::addAttribute(
Attribute Attr) {
2194 auto It =
lower_bound(Attrs, Val, AttributeComparator());
2195 if (It !=
Attrs.end() && It->hasAttribute(Val))
2200AttrBuilder &AttrBuilder::removeAttribute(
StringRef A) {
2201 auto It =
lower_bound(Attrs,
A, AttributeComparator());
2202 if (It !=
Attrs.end() && It->hasAttribute(
A))
2207std::optional<uint64_t>
2212 return A.getValueAsInt();
2213 return std::nullopt;
2221std::optional<std::pair<unsigned, std::optional<unsigned>>>
2222AttrBuilder::getAllocSizeArgs()
const {
2223 Attribute A = getAttribute(Attribute::AllocSize);
2225 return A.getAllocSizeArgs();
2226 return std::nullopt;
2234 return addRawIntAttr(Attribute::Alignment,
Align->
value());
2242 assert(*
Align <= 0x100 &&
"Alignment too large.");
2243 return addRawIntAttr(Attribute::StackAlignment,
Align->
value());
2246AttrBuilder &AttrBuilder::addDereferenceableAttr(
uint64_t Bytes) {
2247 if (Bytes == 0)
return *
this;
2249 return addRawIntAttr(Attribute::Dereferenceable, Bytes);
2253 if (
Info.isZeroSized())
2256 return addRawIntAttr(Attribute::DeadOnReturn,
Info.toIntValue());
2259AttrBuilder &AttrBuilder::addDereferenceableOrNullAttr(
uint64_t Bytes) {
2263 return addRawIntAttr(Attribute::DereferenceableOrNull, Bytes);
2267AttrBuilder::addAllocSizeAttr(
unsigned ElemSize,
2268 const std::optional<unsigned> &NumElems) {
2272AttrBuilder &AttrBuilder::addAllocSizeAttrFromRawRepr(
uint64_t RawArgs) {
2274 assert(RawArgs &&
"Invalid allocsize arguments -- given allocsize(0, 0)");
2275 return addRawIntAttr(Attribute::AllocSize, RawArgs);
2278AttrBuilder &AttrBuilder::addVScaleRangeAttr(
unsigned MinValue,
2279 std::optional<unsigned> MaxValue) {
2283AttrBuilder &AttrBuilder::addVScaleRangeAttrFromRawRepr(
uint64_t RawArgs) {
2288 return addRawIntAttr(Attribute::VScaleRange, RawArgs);
2291AttrBuilder &AttrBuilder::addUWTableAttr(
UWTableKind Kind) {
2294 return addRawIntAttr(Attribute::UWTable,
uint64_t(Kind));
2298 return addRawIntAttr(Attribute::Memory, ME.
toIntValue());
2301AttrBuilder &AttrBuilder::addCapturesAttr(
CaptureInfo CI) {
2302 return addRawIntAttr(Attribute::Captures, CI.
toIntValue());
2305AttrBuilder &AttrBuilder::addDenormalFPEnvAttr(
DenormalFPEnv FPEnv) {
2306 return addRawIntAttr(Attribute::DenormalFPEnv, FPEnv.
toIntValue());
2309AttrBuilder &AttrBuilder::addNoFPClassAttr(
FPClassTest Mask) {
2313 return addRawIntAttr(Attribute::NoFPClass, Mask);
2316AttrBuilder &AttrBuilder::addAllocKindAttr(
AllocFnKind Kind) {
2317 return addRawIntAttr(Attribute::AllocKind,
static_cast<uint64_t>(Kind));
2323 return A.isValid() ?
A.getValueAsType() :
nullptr;
2330AttrBuilder &AttrBuilder::addByValAttr(
Type *Ty) {
2331 return addTypeAttr(Attribute::ByVal, Ty);
2334AttrBuilder &AttrBuilder::addStructRetAttr(
Type *Ty) {
2335 return addTypeAttr(Attribute::StructRet, Ty);
2338AttrBuilder &AttrBuilder::addByRefAttr(
Type *Ty) {
2339 return addTypeAttr(Attribute::ByRef, Ty);
2342AttrBuilder &AttrBuilder::addPreallocatedAttr(
Type *Ty) {
2343 return addTypeAttr(Attribute::Preallocated, Ty);
2346AttrBuilder &AttrBuilder::addInAllocaAttr(
Type *Ty) {
2347 return addTypeAttr(Attribute::InAlloca, Ty);
2358AttrBuilder &AttrBuilder::addRangeAttr(
const ConstantRange &CR) {
2359 return addConstantRangeAttr(Attribute::Range, CR);
2369 return addConstantRangeListAttr(Attribute::Initializes, CRL.
rangesRef());
2372AttrBuilder &AttrBuilder::addFromEquivalentMetadata(
const Instruction &
I) {
2373 if (
I.hasMetadata(LLVMContext::MD_nonnull))
2374 addAttribute(Attribute::NonNull);
2376 if (
I.hasMetadata(LLVMContext::MD_noundef))
2377 addAttribute(Attribute::NoUndef);
2379 if (
const MDNode *
Align =
I.getMetadata(LLVMContext::MD_align)) {
2384 if (
const MDNode *Dereferenceable =
2385 I.getMetadata(LLVMContext::MD_dereferenceable)) {
2391 if (
const MDNode *DereferenceableOrNull =
2392 I.getMetadata(LLVMContext::MD_dereferenceable_or_null)) {
2398 if (
const MDNode *
Range =
I.getMetadata(LLVMContext::MD_range))
2401 if (
const MDNode *NoFPClass =
I.getMetadata(LLVMContext::MD_nofpclass)) {
2415 auto *
I =
A.begin(), *
E =
A.end();
2418 while (
I !=
E &&
Less(*
I, BAttr))
2421 if (
I !=
E && !
Less(BAttr, *
I))
2430AttrBuilder &AttrBuilder::merge(
const AttrBuilder &
B) {
2431 if (
B.Attrs.empty())
2434 if (
Attrs.empty()) {
2442 Attrs = std::move(Merged);
2453 "Expected sorted attributes with distinct kinds!");
2471 auto It =
lower_bound(Attrs,
A, AttributeComparator());
2472 if (It !=
Attrs.end() && It->hasAttribute(
A))
2478 auto It =
lower_bound(Attrs,
A, AttributeComparator());
2479 if (It !=
Attrs.end() && It->hasAttribute(
A))
2484std::optional<ConstantRange> AttrBuilder::getRange()
const {
2485 const Attribute RangeAttr = getAttribute(Attribute::Range);
2488 return std::nullopt;
2492 return getAttribute(
A).isValid();
2495bool AttrBuilder::contains(
StringRef A)
const {
2496 return getAttribute(
A).isValid();
2499bool AttrBuilder::operator==(
const AttrBuilder &
B)
const {
2509bool AttributeFuncs::isNoFPClassCompatibleType(
Type *Ty) {
2515 AttributeSafetyKind ASK) {
2518 if (!Ty->isIntegerTy()) {
2520 if (ASK & ASK_SAFE_TO_DROP)
2524 if (!Ty->isIntegerTy() && !Ty->isByteTy()) {
2526 if (ASK & ASK_UNSAFE_TO_DROP)
2530 if (!Ty->isIntOrIntVectorTy()) {
2532 if (ASK & ASK_SAFE_TO_DROP)
2541 if (!Ty->isPointerTy()) {
2543 if (ASK & ASK_SAFE_TO_DROP)
2557 if (ASK & ASK_UNSAFE_TO_DROP)
2570 if (!Ty->isPtrOrPtrVectorTy()) {
2571 if (ASK & ASK_SAFE_TO_DROP)
2575 if (ASK & ASK_SAFE_TO_DROP) {
2576 if (!isNoFPClassCompatibleType(Ty))
2581 if (Ty->isVoidTy()) {
2582 if (ASK & ASK_SAFE_TO_DROP)
2586 return Incompatible;
2635 return !Callee.getAttributes().hasFnAttr(Attribute::StrictFP) ||
2636 Caller.getAttributes().hasFnAttr(Attribute::StrictFP);
2639template<
typename AttrClass>
2641 return Caller.getFnAttribute(AttrClass::getKind()) ==
2642 Callee.getFnAttribute(AttrClass::getKind());
2647 return Caller.getFnAttribute(AttrName) == Callee.getFnAttribute(AttrName);
2655template<
typename AttrClass>
2657 if (AttrClass::isSet(Caller, AttrClass::getKind()) &&
2658 !AttrClass::isSet(Callee, AttrClass::getKind()))
2659 AttrClass::set(Caller, AttrClass::getKind(),
false);
2667template<
typename AttrClass>
2669 if (!AttrClass::isSet(Caller, AttrClass::getKind()) &&
2670 AttrClass::isSet(Callee, AttrClass::getKind()))
2671 AttrClass::set(Caller, AttrClass::getKind(),
true);
2680 if (!Caller.hasStackProtectorFnAttr())
2691 if (Callee.hasFnAttribute(Attribute::StackProtectReq)) {
2692 Caller.removeFnAttrs(OldSSPAttr);
2693 Caller.addFnAttr(Attribute::StackProtectReq);
2694 }
else if (Callee.hasFnAttribute(Attribute::StackProtectStrong) &&
2695 !Caller.hasFnAttribute(Attribute::StackProtectReq)) {
2696 Caller.removeFnAttrs(OldSSPAttr);
2697 Caller.addFnAttr(Attribute::StackProtectStrong);
2698 }
else if (Callee.hasFnAttribute(Attribute::StackProtect) &&
2699 !Caller.hasFnAttribute(Attribute::StackProtectReq) &&
2700 !Caller.hasFnAttribute(Attribute::StackProtectStrong))
2701 Caller.addFnAttr(Attribute::StackProtect);
2707 if (!Caller.hasFnAttribute(
"probe-stack") &&
2708 Callee.hasFnAttribute(
"probe-stack")) {
2709 Caller.addFnAttr(Callee.getFnAttribute(
"probe-stack"));
2718 Attribute CalleeAttr = Callee.getFnAttribute(
"stack-probe-size");
2720 Attribute CallerAttr = Caller.getFnAttribute(
"stack-probe-size");
2722 uint64_t CallerStackProbeSize, CalleeStackProbeSize;
2726 if (CallerStackProbeSize > CalleeStackProbeSize) {
2727 Caller.addFnAttr(CalleeAttr);
2730 Caller.addFnAttr(CalleeAttr);
2746 Attribute CallerAttr = Caller.getFnAttribute(
"min-legal-vector-width");
2748 Attribute CalleeAttr = Callee.getFnAttribute(
"min-legal-vector-width");
2750 uint64_t CallerVectorWidth, CalleeVectorWidth;
2753 if (CallerVectorWidth < CalleeVectorWidth)
2754 Caller.addFnAttr(CalleeAttr);
2758 Caller.removeFnAttr(
"min-legal-vector-width");
2767 if (Callee.nullPointerIsDefined() && !Caller.nullPointerIsDefined()) {
2768 Caller.addFnAttr(Attribute::NullPointerIsValid);
2791 return A.getValueAsString() ==
"true";
2796 Fn.
addFnAttr(Kind, Val ?
"true" :
"false");
2800#define GET_ATTR_NAMES
2801#define ATTRIBUTE_ENUM(ENUM_NAME, DISPLAY_NAME) \
2802 struct ENUM_NAME##Attr : EnumAttr { \
2803 static enum Attribute::AttrKind getKind() { \
2804 return llvm::Attribute::ENUM_NAME; \
2807#define ATTRIBUTE_STRBOOL(ENUM_NAME, DISPLAY_NAME) \
2808 struct ENUM_NAME##Attr : StrBoolAttr { \
2809 static StringRef getKind() { return #DISPLAY_NAME; } \
2811#include "llvm/IR/Attributes.inc"
2813#define GET_ATTR_COMPAT_FUNC
2814#include "llvm/IR/Attributes.inc"
2816bool AttributeFuncs::areInlineCompatible(
const Function &Caller,
2818 return hasCompatibleFnAttrs(Caller, Callee);
2821bool AttributeFuncs::isStrictFPInlineCompatible(
const Function &Caller,
2828 return hasCompatibleFnAttrs(
A,
B);
2831void AttributeFuncs::mergeAttributesForInlining(
Function &Caller,
2833 mergeFnAttrs(Caller, Callee);
2846 mergeFnAttrs(
Base, ToMerge);
2849void AttributeFuncs::updateMinLegalVectorWidthAttr(
Function &Fn,
2855 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 bool isSortedAndUnique(ArrayRef< Attribute > Attrs)
Return true if Attrs is known sorted with no duplicate entries.
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 void mergeSortedAttrs(ArrayRef< Attribute > A, ArrayRef< Attribute > B, SmallVectorImpl< Attribute > &Merged)
Merge B into A, both sorted by kind, into Merged.
static const char * getModRefStr(ModRefInfo MR)
This file contains the simple types necessary to represent the attributes associated with functions a...
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
This file defines a hash set that can be used to remove duplication of nodes in a graph.
static constexpr Value * getValue(Ty &ValueOrUse)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
This file defines the SmallVector class.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
LLVM_ABI void Profile(FoldingSetNodeID &id) const
Used to insert APInt objects, or objects that contain APInt objects, into FoldingSets.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
const T & back() const
Get the last element.
ArrayRef< T > take_front(size_t N=1) const
Return a copy of *this with only the first N elements.
size_t size() const
Get the array size.
bool empty() const
Check if the array is empty.
This class represents a single, uniqued attribute.
int cmp(const AttributeImpl &AI, bool KindOnly) const
Used to sort attributes.
bool isConstantRangeAttribute() const
bool hasAttribute(Attribute::AttrKind A) const
Type * getValueAsType() const
Attribute::AttrKind getKindAsEnum() const
bool operator<(const AttributeImpl &AI) const
Used when sorting the attributes.
uint64_t getValueAsInt() const
bool isIntAttribute() const
bool isTypeAttribute() const
AttributeImpl(AttrEntryKind KindID)
bool getValueAsBool() const
StringRef getKindAsString() const
StringRef getValueAsString() const
bool isEnumAttribute() const
ArrayRef< ConstantRange > getValueAsConstantRangeList() const
bool isConstantRangeListAttribute() const
bool isStringAttribute() const
const ConstantRange & getValueAsConstantRange() const
This class represents a set of attributes that apply to the function, return type,...
bool hasAttrSomewhere(Attribute::AttrKind Kind, unsigned *Index=nullptr) const
Return true if the specified attribute is set for at least one parameter or for the return value.
AttributeListImpl(ArrayRef< AttributeSet > Sets)
friend class AttributeList
This class stores enough information to efficiently remove some attributes from an existing AttrBuild...
AttributeMask & addAttribute(Attribute::AttrKind Val)
Add an attribute to the mask.
bool contains(Attribute::AttrKind A) const
Return true if the builder has the specified attribute.
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
static AttributeSetNode * getSorted(LLVMContext &C, ArrayRef< Attribute > SortedAttrs)
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 addSortedAttributes(LLVMContext &C, ArrayRef< Attribute > Attrs) const
Add attributes to the attribute set, replacing attributes of the same kind.
LLVM_ABI AttributeSet removeAttributes(LLVMContext &C, const AttributeMask &AttrsToRemove) const
Remove the specified attributes from this set.
LLVM_ABI std::optional< unsigned > getVScaleRangeMax() const
LLVM_ABI MaybeAlign getStackAlignment() const
LLVM_ABI Attribute getAttribute(Attribute::AttrKind Kind) const
Return the attribute object.
LLVM_ABI Type * getPreallocatedType() const
LLVM_ABI uint64_t getDereferenceableBytes() const
LLVM_ABI MaybeAlign getAlignment() const
LLVM_ABI FPClassTest getNoFPClass() const
LLVM_ABI Type * getElementType() const
LLVM_ABI Type * getByRefType() const
LLVM_ABI CaptureInfo getCaptureInfo() const
AttributeSet()=default
AttributeSet is a trivially copyable value type.
static LLVM_ABI AttributeSet get(LLVMContext &C, const AttrBuilder &B)
LLVM_ABI uint64_t getDereferenceableOrNullBytes() const
LLVM_ABI unsigned getNumAttributes() const
Return the number of attributes in this set.
LLVM_ABI AttributeSet addAttribute(LLVMContext &C, Attribute::AttrKind Kind) const
Add an argument attribute.
Functions, function parameters, and return types can have attributes to indicate how they should be t...
LLVM_ABI bool isStringAttribute() const
Return true if the attribute is a string (target-dependent) attribute.
static LLVM_ABI Attribute getWithStructRetType(LLVMContext &Context, Type *Ty)
static LLVM_ABI bool isABIAttr(AttrKind Kind)
Whether this is an ABI attribute (for returns or arguments).
static LLVM_ABI Attribute::AttrKind getAttrKindFromName(StringRef AttrName)
LLVM_ABI bool isEnumAttribute() const
Return true if the attribute is an Attribute::AttrKind type.
static LLVM_ABI Attribute getWithStackAlignment(LLVMContext &Context, Align Alignment)
LLVM_ABI const ConstantRange & getRange() const
Returns the value of the range attribute.
static LLVM_ABI bool intersectWithCustom(AttrKind Kind)
LLVM_ABI bool isIntAttribute() const
Return true if the attribute is an integer attribute.
static LLVM_ABI Attribute getWithByRefType(LLVMContext &Context, Type *Ty)
LLVM_ABI struct DenormalFPEnv getDenormalFPEnv() const
Returns denormal_fpenv.
LLVM_ABI std::optional< unsigned > getVScaleRangeMax() const
Returns the maximum value for the vscale_range attribute or std::nullopt when unknown.
LLVM_ABI uint64_t getValueAsInt() const
Return the attribute's value as an integer.
LLVM_ABI unsigned getVScaleRangeMin() const
Returns the minimum value for the vscale_range attribute.
LLVM_ABI AllocFnKind getAllocKind() const
LLVM_ABI bool isConstantRangeAttribute() const
Return true if the attribute is a ConstantRange attribute.
static LLVM_ABI Attribute getWithAllocKind(LLVMContext &Context, AllocFnKind Kind)
LLVM_ABI StringRef getKindAsString() const
Return the attribute's kind as a string.
static LLVM_ABI Attribute getWithPreallocatedType(LLVMContext &Context, Type *Ty)
static LLVM_ABI bool intersectWithMin(AttrKind Kind)
static LLVM_ABI Attribute getWithDeadOnReturnInfo(LLVMContext &Context, DeadOnReturnInfo DI)
static LLVM_ABI Attribute get(LLVMContext &Context, AttrKind Kind, uint64_t Val=0)
Return a uniquified Attribute object.
static LLVM_ABI bool canUseAsRetAttr(AttrKind Kind)
static bool isTypeAttrKind(AttrKind Kind)
LLVM_ABI std::string getAsString(bool InAttrGrp=false) const
The Attribute is converted to a string of equivalent mnemonic.
LLVM_ABI uint64_t getDereferenceableOrNullBytes() const
Returns the number of dereferenceable_or_null bytes from the dereferenceable_or_null attribute.
static LLVM_ABI Attribute getWithDereferenceableBytes(LLVMContext &Context, uint64_t Bytes)
LLVM_ABI std::pair< unsigned, std::optional< unsigned > > getAllocSizeArgs() const
Returns the argument numbers for the allocsize attribute.
static LLVM_ABI Attribute getWithUWTableKind(LLVMContext &Context, UWTableKind Kind)
LLVM_ABI FPClassTest getNoFPClass() const
Return the FPClassTest for nofpclass.
static LLVM_ABI Attribute getWithAllocSizeArgs(LLVMContext &Context, unsigned ElemSizeArg, const std::optional< unsigned > &NumElemsArg)
LLVM_ABI Attribute::AttrKind getKindAsEnum() const
Return the attribute's kind as an enum (Attribute::AttrKind).
LLVM_ABI bool getValueAsBool() const
Return the attribute's value as a boolean.
LLVM_ABI ArrayRef< ConstantRange > getInitializes() const
Returns the value of the initializes attribute.
LLVM_ABI const ConstantRange & getValueAsConstantRange() const
Return the attribute's value as a ConstantRange.
LLVM_ABI uint64_t getDereferenceableBytes() const
Returns the number of dereferenceable bytes from the dereferenceable attribute.
static LLVM_ABI Attribute getWithVScaleRangeArgs(LLVMContext &Context, unsigned MinValue, unsigned MaxValue)
LLVM_ABI MemoryEffects getMemoryEffects() const
Returns memory effects.
LLVM_ABI UWTableKind getUWTableKind() const
static LLVM_ABI Attribute getWithDereferenceableOrNullBytes(LLVMContext &Context, uint64_t Bytes)
LLVM_ABI ArrayRef< ConstantRange > getValueAsConstantRangeList() const
Return the attribute's value as a ConstantRange array.
LLVM_ABI StringRef getValueAsString() const
Return the attribute's value as a string.
bool hasKindAsEnum() const
Returns true if the attribute's kind can be represented as an enum (Enum, Integer,...
static LLVM_ABI StringRef getNameFromAttrKind(Attribute::AttrKind AttrKind)
static LLVM_ABI bool canUseAsFnAttr(AttrKind Kind)
static LLVM_ABI bool intersectWithAnd(AttrKind Kind)
static LLVM_ABI Attribute getWithNoFPClass(LLVMContext &Context, FPClassTest Mask)
AttrKind
This enumeration lists the attributes that can be associated with parameters, function results,...
@ None
No attributes have been set.
@ EndAttrKinds
Sentinel value useful for loops.
static bool isConstantRangeAttrKind(AttrKind Kind)
LLVM_ABI bool hasParentContext(LLVMContext &C) const
Return true if this attribute belongs to the LLVMContext.
LLVM_ABI bool isTypeAttribute() const
Return true if the attribute is a type attribute.
static LLVM_ABI Attribute getWithCaptureInfo(LLVMContext &Context, CaptureInfo CI)
static LLVM_ABI Attribute getWithInAllocaType(LLVMContext &Context, Type *Ty)
static bool isIntAttrKind(AttrKind Kind)
static bool isConstantRangeListAttrKind(AttrKind Kind)
LLVM_ABI bool isConstantRangeListAttribute() const
Return true if the attribute is a ConstantRangeList attribute.
static LLVM_ABI Attribute getWithByValType(LLVMContext &Context, Type *Ty)
LLVM_ABI bool hasAttribute(AttrKind Val) const
Return true if the attribute is present.
static bool isEnumAttrKind(AttrKind Kind)
static LLVM_ABI Attribute getWithMemoryEffects(LLVMContext &Context, MemoryEffects ME)
static LLVM_ABI bool canUseAsParamAttr(AttrKind Kind)
bool isValid() const
Return true if the attribute is any kind of attribute.
LLVM_ABI MaybeAlign getStackAlignment() const
Returns the stack alignment field of an attribute as a byte alignment value.
LLVM_ABI MaybeAlign getAlignment() const
Returns the alignment field of an attribute as a byte alignment value.
LLVM_ABI CaptureInfo getCaptureInfo() const
Returns information from captures attribute.
static LLVM_ABI bool intersectMustPreserve(AttrKind Kind)
LLVM_ABI int cmpKind(Attribute A) const
Used to sort attribute by kind.
LLVM_ABI bool operator<(Attribute A) const
Less-than operator. Useful for sorting the attributes list.
static LLVM_ABI Attribute getWithAlignment(LLVMContext &Context, Align Alignment)
Return a uniquified Attribute object that has the specific alignment set.
LLVM_ABI DeadOnReturnInfo getDeadOnReturnInfo() const
Returns the number of dead_on_return bytes from the dead_on_return attribute, or std::nullopt if all ...
LLVM_ABI Type * getValueAsType() const
Return the attribute's value as a Type.
Represents which components of the pointer may be captured in which location.
static CaptureInfo createFromIntValue(uint32_t Data)
static CaptureInfo all()
Create CaptureInfo that may capture all components of the pointer.
uint32_t toIntValue() const
Convert CaptureInfo into an encoded integer value (used by captures attribute).
This is the shared class of boolean and integer constants.
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
static size_t totalSizeToAlloc(ArrayRef< ConstantRange > Val)
This class represents a list of constant ranges.
ArrayRef< ConstantRange > rangesRef() const
LLVM_ABI void print(raw_ostream &OS) const
Print out the ranges to a stream.
This class represents a range of values.
const APInt & getLower() const
Return the lower value for this range.
LLVM_ABI bool isFullSet() const
Return true if this set contains all of the elements possible for this data-type.
const APInt & getUpper() const
Return the upper value for this range.
LLVM_ABI ConstantRange unionWith(const ConstantRange &CR, PreferredRangeType Type=Smallest) const
Return the range that results from the union of this range with another range.
uint32_t getBitWidth() const
Get the bit width of this ConstantRange.
static DeadOnReturnInfo createFromIntValue(uint64_t Data)
uint64_t toIntValue() const
A set of classes that contain the value of the attribute object.
static bool isSupportedFloatingPointType(Type *Ty)
Returns true if Ty is a supported floating-point type for phi, select, or call FPMathOperators.
Insertion token: a failed lookup fills it in, the matching insert consumes it.
This class is used to gather all the unique data bits of a node.
void AddInteger(signed I)
void addFnAttr(Attribute::AttrKind Kind)
Add function attributes to this function.
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
void removeFnAttr(Attribute::AttrKind Kind)
Remove function attributes from this function.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
UniquingSet< TypeAttributeImpl > TypeAttrs
EnumAttributeImpl * EnumAttrs[Attribute::NumEnumAttrKinds]
UniquingSet< IntAttributeImpl > IntAttrs
FoldingSet< AttributeImpl > AttrsSet
UniquingSet< StringAttributeImpl > StringAttrs
UniquingSet< AttributeListImpl > AttrsLists
This is an important class for using LLVM in a threaded context.
bool isTargetMemLocSameForAll() const
Whether the target memory locations are all the same.
bool isTargetMemLoc(IRMemLocation Loc) const
Whether location is target memory location.
ModRefInfo getModRef(Location Loc) const
Get ModRefInfo for the given Location.
static MemoryEffectsBase createFromIntValue(uint32_t Data)
uint32_t toIntValue() const
Convert MemoryEffectsBase into an encoded integer value (used by memory attribute).
static MemoryEffectsBase unknown()
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void reserve(size_type N)
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
static size_t totalSizeToAlloc(StringRef Kind, StringRef Val)
Represent a constant reference to a string, i.e.
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
std::string str() const
Get the contents as an std::string.
int compare(StringRef RHS) const
Compare two strings; the result is negative, zero, or positive if this string is lexicographically le...
A switch()-like statement whose cases are string literals.
static constexpr std::enable_if_t< std::is_same_v< Foo< TrailingTys... >, Foo< Tys... > >, size_t > totalSizeToAlloc(typename trailing_objects_internal::ExtractSecondType< TrailingTys, size_t >::type... Counts)
const T * getTrailingObjects() const
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM_ABI void print(raw_ostream &O, bool IsForDebug=false, bool NoDetails=false) const
Print the current type.
LLVM Value Representation.
static constexpr uint64_t MaximumAlignment
This class implements an extremely fast bulk output stream that can only output to a stream.
A raw_ostream that writes to an std::string.
This class provides various memory handling functions that manipulate MemoryBlock instances.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Attrs[]
Key for Kernel::Metadata::mAttrs.
LLVM_ABI AttributeList getAttributes(LLVMContext &C, ID id, FunctionType *FT)
Return the attributes for an intrinsic.
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > extract(Y &&MD)
Extract a Value from Metadata.
LLVM_ABI iterator begin() const
This is an optimization pass for GlobalISel generic memory operations.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
bool isEqual(const GCNRPTracker::LiveRegSet &S1, const GCNRPTracker::LiveRegSet &S2)
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
RelativeUniformCounterPtr Values
auto adjacent_find(R &&Range)
Provide wrappers to std::adjacent_find which finds the first pair of adjacent elements that are equal...
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::...