LLVM: lib/IR/Attributes.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
25#include "llvm/Config/llvm-config.h"
37#include
38#include
39#include
40#include
41#include
42#include
43#include
44#include
45#include
46
47using namespace llvm;
48
49
50
51
52
53
54
55
56
57
58
60
62 const std::optional &NumElemsArg) {
64 "Attempting to pack a reserved value");
65
66 return uint64_t(ElemSizeArg) << 32 |
68}
69
70static std::pair<unsigned, std::optional>
72 unsigned NumElems = Num & std::numeric_limits::max();
73 unsigned ElemSizeArg = Num >> 32;
74
75 std::optional NumElemsArg;
77 NumElemsArg = NumElems;
78 return std::make_pair(ElemSizeArg, NumElemsArg);
79}
80
82 std::optional MaxValue) {
83 return uint64_t(MinValue) << 32 | MaxValue.value_or(0);
84}
85
86static std::pair<unsigned, std::optional>
88 unsigned MaxValue = Value & std::numeric_limits::max();
89 unsigned MinValue = Value >> 32;
90
91 return std::make_pair(MinValue,
92 MaxValue > 0 ? MaxValue : std::optional());
93}
94
99 "Not an enum or int attribute");
100
103 ID.AddInteger(Kind);
104 if (IsIntAttr)
105 ID.AddInteger(Val);
106 else
107 assert(Val == 0 && "Value must be zero for enum attributes");
108
109 void *InsertPoint;
110 AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);
111
112 if (!PA) {
113
114
115 if (!IsIntAttr)
117 else
119 pImpl->AttrsSet.InsertNode(PA, InsertPoint);
120 }
121
122
124}
125
129 ID.AddString(Kind);
130 if (!Val.empty()) ID.AddString(Val);
131
132 void *InsertPoint;
133 AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);
134
135 if (!PA) {
136
137
138 void *Mem =
142 pImpl->AttrsSet.InsertNode(PA, InsertPoint);
143 }
144
145
147}
148
154 ID.AddInteger(Kind);
155 ID.AddPointer(Ty);
156
157 void *InsertPoint;
158 AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);
159
160 if (!PA) {
161
162
164 pImpl->AttrsSet.InsertNode(PA, InsertPoint);
165 }
166
167
169}
170
174 "Not a ConstantRange attribute");
175 assert(!CR.isFullSet() && "ConstantRange attribute must not be full");
178 ID.AddInteger(Kind);
181
182 void *InsertPoint;
183 AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);
184
185 if (!PA) {
186
187
188 PA = new (pImpl->ConstantRangeAttributeAlloc.Allocate())
190 pImpl->AttrsSet.InsertNode(PA, InsertPoint);
191 }
192
193
195}
196
200 "Not a ConstantRangeList attribute");
203 ID.AddInteger(Kind);
204 ID.AddInteger(Val.size());
205 for (auto &CR : Val) {
206 CR.getLower().Profile(ID);
207 CR.getUpper().Profile(ID);
208 }
209
210 void *InsertPoint;
211 AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);
212
213 if (!PA) {
214
215
216
217
218
219
220
221 void *Mem = pImpl->Alloc.Allocate(
225 pImpl->AttrsSet.InsertNode(PA, InsertPoint);
226 pImpl->ConstantRangeListAttributes.push_back(
228 }
229
230
232}
233
236 return get(Context, Alignment, A.value());
237}
238
240 assert(A <= 0x100 && "Alignment too large.");
241 return get(Context, StackAlignment, A.value());
242}
243
246 assert(Bytes && "Bytes must be non-zero.");
247 return get(Context, Dereferenceable, Bytes);
248}
249
252 assert(Bytes && "Bytes must be non-zero.");
253 return get(Context, DereferenceableOrNull, Bytes);
254}
255
257 return get(Context, ByVal, Ty);
258}
259
261 return get(Context, StructRet, Ty);
262}
263
265 return get(Context, ByRef, Ty);
266}
267
269 return get(Context, Preallocated, Ty);
270}
271
273 return get(Context, InAlloca, Ty);
274}
275
280
285
288 return get(Context, NoFPClass, ClassMask);
289}
290
294
297 const std::optional &NumElemsArg) {
298 assert(!(ElemSizeArg == 0 && NumElemsArg == 0) &&
299 "Invalid allocsize arguments -- given allocsize(0, 0)");
301}
302
304 return get(Context, AllocKind, static_cast<uint64_t>(Kind));
305}
306
308 unsigned MinValue,
309 unsigned MaxValue) {
311}
312
315#define GET_ATTR_NAMES
316#define ATTRIBUTE_ENUM(ENUM_NAME, DISPLAY_NAME) \
317 .Case(#DISPLAY_NAME, Attribute::ENUM_NAME)
318#include "llvm/IR/Attributes.inc"
320}
321
324#define GET_ATTR_NAMES
325#define ATTRIBUTE_ENUM(ENUM_NAME, DISPLAY_NAME) \
326 case Attribute::ENUM_NAME: \
327 return #DISPLAY_NAME;
328#include "llvm/IR/Attributes.inc"
330 return "none";
331 default:
333 }
334}
335
338#define GET_ATTR_NAMES
339#define ATTRIBUTE_ALL(ENUM_NAME, DISPLAY_NAME) .Case(#DISPLAY_NAME, true)
340#include "llvm/IR/Attributes.inc"
342}
343
344
345
346
347
349 return pImpl && pImpl->isEnumAttribute();
350}
351
353 return pImpl && pImpl->isIntAttribute();
354}
355
357 return pImpl && pImpl->isStringAttribute();
358}
359
361 return pImpl && pImpl->isTypeAttribute();
362}
363
365 return pImpl && pImpl->isConstantRangeAttribute();
366}
367
369 return pImpl && pImpl->isConstantRangeListAttribute();
370}
371
373 if (!pImpl) return None;
375 "Invalid attribute type to get the kind as an enum!");
376 return pImpl->getKindAsEnum();
377}
378
380 if (!pImpl) return 0;
382 "Expected the attribute to be an integer attribute!");
383 return pImpl->getValueAsInt();
384}
385
387 if (!pImpl) return false;
389 "Expected the attribute to be a string attribute!");
390 return pImpl->getValueAsBool();
391}
392
394 if (!pImpl) return {};
396 "Invalid attribute type to get the kind as a string!");
397 return pImpl->getKindAsString();
398}
399
401 if (!pImpl) return {};
403 "Invalid attribute type to get the value as a string!");
404 return pImpl->getValueAsString();
405}
406
408 if (!pImpl) return {};
410 "Invalid attribute type to get the value as a type!");
411 return pImpl->getValueAsType();
412}
413
416 "Invalid attribute type to get the value as a ConstantRange!");
417 return pImpl->getValueAsConstantRange();
418}
419
422 "Invalid attribute type to get the value as a ConstantRangeList!");
423 return pImpl->getValueAsConstantRangeList();
424}
425
427 return (pImpl && pImpl->hasAttribute(Kind)) || (!pImpl && Kind == None);
428}
429
432 return pImpl && pImpl->hasAttribute(Kind);
433}
434
437 "Trying to get alignment from non-alignment attribute!");
438 return MaybeAlign(pImpl->getValueAsInt());
439}
440
443 "Trying to get alignment from non-alignment attribute!");
444 return MaybeAlign(pImpl->getValueAsInt());
445}
446
449 "Trying to get dereferenceable bytes from "
450 "non-dereferenceable attribute!");
451 return pImpl->getValueAsInt();
452}
453
456 "Trying to get dereferenceable bytes from "
457 "non-dereferenceable attribute!");
458 return pImpl->getValueAsInt();
459}
460
461std::pair<unsigned, std::optional>
464 "Trying to get allocsize args from non-allocsize attribute");
466}
467
470 "Trying to get vscale args from non-vscale attribute");
472}
473
476 "Trying to get vscale args from non-vscale attribute");
478}
479
482 "Trying to get unwind table kind from non-uwtable attribute");
483 return UWTableKind(pImpl->getValueAsInt());
484}
485
488 "Trying to get allockind value from non-allockind attribute");
489 return AllocFnKind(pImpl->getValueAsInt());
490}
491
494 "Can only call getMemoryEffects() on memory attribute");
496}
497
500 "Can only call getCaptureInfo() on captures attribute");
502}
503
506 "Can only call getNoFPClass() on nofpclass attribute");
507 return static_cast<FPClassTest>(pImpl->getValueAsInt());
508}
509
512 "Trying to get range args from non-range attribute");
513 return pImpl->getValueAsConstantRange();
514}
515
518 "Trying to get initializes attr from non-ConstantRangeList attribute");
519 return pImpl->getValueAsConstantRangeList();
520}
521
523 switch (MR) {
525 return "none";
527 return "read";
529 return "write";
531 return "readwrite";
532 }
534}
535
537 if (!pImpl) return {};
538
541
544 Result += '(';
548 Result += ')';
549 return Result;
550 }
551
552
553
554
555
556
560 .str();
561
562 auto AttrWithBytesToString = [&](const char *Name) {
565 .str();
566 };
567
569 return AttrWithBytesToString("alignstack");
570
571 if (hasAttribute(Attribute::Dereferenceable))
572 return AttrWithBytesToString("dereferenceable");
573
574 if (hasAttribute(Attribute::DereferenceableOrNull))
575 return AttrWithBytesToString("dereferenceable_or_null");
576
578 unsigned ElemSize;
579 std::optional NumElems;
581
582 return (NumElems
583 ? "allocsize(" + Twine(ElemSize) + "," + Twine(*NumElems) + ")"
584 : "allocsize(" + Twine(ElemSize) + ")")
585 .str();
586 }
587
591 return ("vscale_range(" + Twine(MinValue) + "," +
592 Twine(MaxValue.value_or(0)) + ")")
593 .str();
594 }
595
600 }
601
612 parts.push_back("uninitialized");
617 return ("allockind(\"" +
619 .str();
620 }
621
623 std::string Result;
625 bool First = true;
626 OS << "memory(";
627
629
630
631
636 }
637
640 if (MR == OtherMR)
641 continue;
642
644 OS << ", ";
646
647 switch (Loc) {
649 OS << "argmem: ";
650 break;
652 OS << "inaccessiblemem: ";
653 break;
655 OS << "errnomem: ";
656 break;
658 llvm_unreachable("This is represented as the default access kind");
660 OS << "target_mem0: ";
661 break;
663 OS << "target_mem1: ";
664 break;
665 }
667 }
668 OS << ")";
670 return Result;
671 }
672
674 std::string Result;
677 return Result;
678 }
679
681 std::string Result = "nofpclass";
684 return Result;
685 }
686
688 std::string Result;
691 OS << "range(";
694 OS << ")";
696 return Result;
697 }
698
700 std::string Result;
703 OS << "initializes(";
705 OS << ")";
707 return Result;
708 }
709
710
711
712
713
714
716 std::string Result;
717 {
720
721
722
723
724 const auto &AttrVal = pImpl->getValueAsString();
725 if (!AttrVal.empty()) {
726 OS << "=\"";
728 OS << "\"";
729 }
730 }
731 return Result;
732 }
733
735}
736
738 assert(isValid() && "invalid Attribute doesn't refer to any context");
740 pImpl->Profile(ID);
741 void *Unused;
742 return C.pImpl->AttrsSet.FindNodeOrInsertPos(ID, Unused) == pImpl;
743}
744
746 if (!pImpl && .pImpl)
747 return 0;
748 if (!pImpl)
749 return 1;
750 if (.pImpl)
751 return -1;
752 return pImpl->cmp(*A.pImpl, true);
753}
754
756 if (!pImpl && .pImpl) return false;
757 if (!pImpl) return true;
758 if (.pImpl) return false;
759 return *pImpl < *A.pImpl;
760}
761
763 ID.AddPointer(pImpl);
764}
765
776
777#define GET_ATTR_PROP_TABLE
778#include "llvm/IR/Attributes.inc"
779
781 unsigned Index = Kind - 1;
782 assert(Index < std::size(AttrPropTable) && "Invalid attribute kind");
783 return AttrPropTable[Index];
784}
785
790
794
798
802
809 "Unknown intersect property");
812}
813
826
827
828
829
830
835
840
846
851
856
861
866
871
875 ->getConstantRangeValue();
876}
877
881 ->getConstantRangeListValue();
882}
883
885 if (this == &AI)
886 return 0;
887
888
889
892 return -1;
893
896 else if (KindOnly)
897 return 0;
898
903 "Unclear how to compare range list");
904
907 return -1;
909 }
911 return 1;
912 if (KindOnly)
917}
918
920 return cmp(AI, false) < 0;
921}
922
923
924
925
926
930
934
939 B.addAttribute(Kind);
941}
942
946 B.addAttribute(Kind, Value);
948}
949
951 const AttributeSet AS) const {
953 return AS;
954
956 return *this;
957
959 B.merge(AttrBuilder(C, AS));
961}
962
964 const AttrBuilder &B) const {
967
968 if (.hasAttributes())
969 return *this;
970
971 AttrBuilder Merged(C, *this);
972 Merged.merge(B);
974}
975
980 B.removeAttribute(Kind);
982}
983
988 B.removeAttribute(Kind);
990}
991
995
996 if (.overlaps(Attrs))
997 return *this;
998
999 B.remove(Attrs);
1001}
1002
1003std::optional
1005 if (*this == Other)
1006 return *this;
1007
1008 AttrBuilder Intersected(C);
1009
1010 auto ItBegin0 = begin();
1011 auto ItEnd0 = end();
1012 auto ItBegin1 = Other.begin();
1013 auto ItEnd1 = Other.end();
1014
1015 while (ItBegin0 != ItEnd0 || ItBegin1 != ItEnd1) {
1016
1017
1018
1020 if (ItBegin1 == ItEnd1)
1021 Attr0 = *ItBegin0++;
1022 else if (ItBegin0 == ItEnd0)
1023 Attr0 = *ItBegin1++;
1024 else {
1025 int Cmp = ItBegin0->cmpKind(*ItBegin1);
1026 if (Cmp == 0) {
1027 Attr0 = *ItBegin0++;
1028 Attr1 = *ItBegin1++;
1029 } else if (Cmp < 0)
1030 Attr0 = *ItBegin0++;
1031 else
1032 Attr0 = *ItBegin1++;
1033 }
1034 assert(Attr0.isValid() && "Iteration should always yield a valid attr");
1035
1036 auto IntersectEq = [&]() {
1038 return false;
1039 if (Attr0 != Attr1)
1040 return false;
1041 Intersected.addAttribute(Attr0);
1042 return true;
1043 };
1044
1045
1046
1048 if (!IntersectEq())
1049 return std::nullopt;
1050 continue;
1051 }
1052
1054
1055
1058 return std::nullopt;
1059 continue;
1060 }
1061
1062
1064 "Iterator picked up two different attributes in the same iteration");
1065
1066
1069 "Invalid attr type of intersectAnd");
1070 Intersected.addAttribute(Kind);
1071 continue;
1072 }
1073
1074
1077 "Invalid attr type of intersectMin");
1079 Intersected.addRawIntAttr(Kind, NewVal);
1080 continue;
1081 }
1082
1084 switch (Kind) {
1085 case Attribute::Alignment:
1086
1087
1088 Intersected.addAlignmentAttr(
1091 break;
1092 case Attribute::Memory:
1095 break;
1096 case Attribute::Captures:
1097 Intersected.addCapturesAttr(Attr0.getCaptureInfo() |
1099 break;
1100 case Attribute::NoFPClass:
1101 Intersected.addNoFPClassAttr(Attr0.getNoFPClass() &
1103 break;
1104 case Attribute::Range: {
1109 Intersected.addRangeAttr(NewRange);
1110 } break;
1111 default:
1112 llvm_unreachable("Unknown attribute with custom intersection rule");
1113 }
1114 continue;
1115 }
1116
1117
1118
1119 if (!IntersectEq())
1120 return std::nullopt;
1121
1122
1123
1124 if (Kind == Attribute::ByVal &&
1126 Other.getAttribute(Attribute::Alignment))
1127 return std::nullopt;
1128 }
1129
1130 return get(C, Intersected);
1131}
1132
1134 return SetNode ? SetNode->getNumAttributes() : 0;
1135}
1136
1138 return SetNode ? SetNode->hasAttribute(Kind) : false;
1139}
1140
1142 return SetNode ? SetNode->hasAttribute(Kind) : false;
1143}
1144
1146 return SetNode ? SetNode->getAttribute(Kind) : Attribute();
1147}
1148
1150 return SetNode ? SetNode->getAttribute(Kind) : Attribute();
1151}
1152
1154 return SetNode ? SetNode->getAlignment() : std::nullopt;
1155}
1156
1158 return SetNode ? SetNode->getStackAlignment() : std::nullopt;
1159}
1160
1162 return SetNode ? SetNode->getDereferenceableBytes() : 0;
1163}
1164
1166 return SetNode ? SetNode->getDereferenceableOrNullBytes() : 0;
1167}
1168
1170 return SetNode ? SetNode->getAttributeType(Attribute::ByRef) : nullptr;
1171}
1172
1174 return SetNode ? SetNode->getAttributeType(Attribute::ByVal) : nullptr;
1175}
1176
1178 return SetNode ? SetNode->getAttributeType(Attribute::StructRet) : nullptr;
1179}
1180
1182 return SetNode ? SetNode->getAttributeType(Attribute::Preallocated) : nullptr;
1183}
1184
1186 return SetNode ? SetNode->getAttributeType(Attribute::InAlloca) : nullptr;
1187}
1188
1190 return SetNode ? SetNode->getAttributeType(Attribute::ElementType) : nullptr;
1191}
1192
1193std::optional<std::pair<unsigned, std::optional>>
1195 if (SetNode)
1196 return SetNode->getAllocSizeArgs();
1197 return std::nullopt;
1198}
1199
1201 return SetNode ? SetNode->getVScaleRangeMin() : 1;
1202}
1203
1205 return SetNode ? SetNode->getVScaleRangeMax() : std::nullopt;
1206}
1207
1211
1215
1219
1223
1225 return SetNode ? SetNode->getNoFPClass() : fcNone;
1226}
1227
1229 return SetNode ? SetNode->getAsString(InAttrGrp) : "";
1230}
1231
1233 assert(hasAttributes() && "empty AttributeSet doesn't refer to any context");
1235 SetNode->Profile(ID);
1236 void *Unused;
1237 return C.pImpl->AttrsSetNodes.FindNodeOrInsertPos(ID, Unused) == SetNode;
1238}
1239
1241 return SetNode ? SetNode->begin() : nullptr;
1242}
1243
1245 return SetNode ? SetNode->end() : nullptr;
1246}
1247
1248#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1250 dbgs() << "AS =\n";
1251 dbgs() << " { ";
1253}
1254#endif
1255
1256
1257
1258
1259
1261 : NumAttrs(Attrs.size()) {
1262
1263 llvm::copy(Attrs, getTrailingObjects());
1264
1265 for (const auto &I : *this) {
1266 if (I.isStringAttribute())
1267 StringAttrs.insert({ I.getKindAsString(), I });
1268 else
1269 AvailableAttrs.addAttribute(I.getKindAsEnum());
1270 }
1271}
1272
1277 return getSorted(C, SortedAttrs);
1278}
1279
1282 if (SortedAttrs.empty())
1283 return nullptr;
1284
1285
1288
1290 for (const auto &Attr : SortedAttrs)
1291 Attr.Profile(ID);
1292
1293 void *InsertPoint;
1295 pImpl->AttrsSetNodes.FindNodeOrInsertPos(ID, InsertPoint);
1296
1297
1298
1299 if (!PA) {
1300
1303 pImpl->AttrsSetNodes.InsertNode(PA, InsertPoint);
1304 }
1305
1306
1307 return PA;
1308}
1309
1311 return getSorted(C, B.attrs());
1312}
1313
1315 return StringAttrs.count(Kind);
1316}
1317
1318std::optional
1320
1322 return std::nullopt;
1323
1324
1325
1327 std::lower_bound(begin(), end() - StringAttrs.size(), Kind,
1329 return A.getKindAsEnum() < Kind;
1330 });
1331 assert(I != end() && I->hasAttribute(Kind) && "Presence check failed?");
1332 return *I;
1333}
1334
1336 if (auto A = findEnumAttribute(Kind))
1337 return *A;
1338 return {};
1339}
1340
1342 return StringAttrs.lookup(Kind);
1343}
1344
1346 if (auto A = findEnumAttribute(Attribute::Alignment))
1347 return A->getAlignment();
1348 return std::nullopt;
1349}
1350
1352 if (auto A = findEnumAttribute(Attribute::StackAlignment))
1353 return A->getStackAlignment();
1354 return std::nullopt;
1355}
1356
1358 if (auto A = findEnumAttribute(Kind))
1359 return A->getValueAsType();
1360 return nullptr;
1361}
1362
1364 if (auto A = findEnumAttribute(Attribute::Dereferenceable))
1365 return A->getDereferenceableBytes();
1366 return 0;
1367}
1368
1370 if (auto A = findEnumAttribute(Attribute::DereferenceableOrNull))
1371 return A->getDereferenceableOrNullBytes();
1372 return 0;
1373}
1374
1375std::optional<std::pair<unsigned, std::optional>>
1377 if (auto A = findEnumAttribute(Attribute::AllocSize))
1378 return A->getAllocSizeArgs();
1379 return std::nullopt;
1380}
1381
1383 if (auto A = findEnumAttribute(Attribute::VScaleRange))
1384 return A->getVScaleRangeMin();
1385 return 1;
1386}
1387
1389 if (auto A = findEnumAttribute(Attribute::VScaleRange))
1390 return A->getVScaleRangeMax();
1391 return std::nullopt;
1392}
1393
1395 if (auto A = findEnumAttribute(Attribute::UWTable))
1396 return A->getUWTableKind();
1398}
1399
1401 if (auto A = findEnumAttribute(Attribute::AllocKind))
1402 return A->getAllocKind();
1404}
1405
1407 if (auto A = findEnumAttribute(Attribute::Memory))
1408 return A->getMemoryEffects();
1410}
1411
1413 if (auto A = findEnumAttribute(Attribute::Captures))
1414 return A->getCaptureInfo();
1416}
1417
1419 if (auto A = findEnumAttribute(Attribute::NoFPClass))
1420 return A->getNoFPClass();
1422}
1423
1425 std::string Str;
1428 Str += ' ';
1429 Str += I->getAsString(InAttrGrp);
1430 }
1431 return Str;
1432}
1433
1434
1435
1436
1437
1438
1439
1441 return Index + 1;
1442}
1443
1445 : NumAttrSets(Sets.size()) {
1446 assert(!Sets.empty() && "pointless AttributeListImpl");
1447
1448
1450
1451
1452
1453 for (const auto &I : Sets[attrIdxToArrayIdx(AttributeList::FunctionIndex)])
1454 if (.isStringAttribute())
1455 AvailableFunctionAttrs.addAttribute(I.getKindAsEnum());
1456
1457 for (const auto &Set : Sets)
1458 for (const auto &I : Set)
1459 if (.isStringAttribute())
1460 AvailableSomewhereAttrs.addAttribute(I.getKindAsEnum());
1461}
1462
1466
1469 for (const auto &Set : Sets)
1470 ID.AddPointer(Set.SetNode);
1471}
1472
1474 unsigned *Index) const {
1475 if (!AvailableSomewhereAttrs.hasAttribute(Kind))
1476 return false;
1477
1478 if (Index) {
1479 for (unsigned I = 0, E = NumAttrSets; I != E; ++I) {
1480 if (begin()[I].hasAttribute(Kind)) {
1481 *Index = I - 1;
1482 break;
1483 }
1484 }
1485 }
1486
1487 return true;
1488}
1489
1490
1491#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1495#endif
1496
1497
1498
1499
1500
1501AttributeList AttributeList::getImpl(LLVMContext &C,
1503 assert(!AttrSets.empty() && "pointless AttributeListImpl");
1504
1508
1509 void *InsertPoint;
1511 pImpl->AttrsLists.FindNodeOrInsertPos(ID, InsertPoint);
1512
1513
1514
1515 if (!PA) {
1516
1517 void *Mem = pImpl->Alloc.Allocate(
1521 pImpl->AttrsLists.InsertNode(PA, InsertPoint);
1522 }
1523
1524
1525 return AttributeList(PA);
1526}
1527
1528AttributeList
1530 ArrayRef<std::pair<unsigned, Attribute>> Attrs) {
1531
1532 if (Attrs.empty())
1533 return {};
1534
1536 "Misordered Attributes list!");
1538 [](const std::pair<unsigned, Attribute> &Pair) {
1539 return Pair.second.isValid();
1540 }) &&
1541 "Pointless attribute!");
1542
1543
1544
1546 for (ArrayRef<std::pair<unsigned, Attribute>>::iterator I = Attrs.begin(),
1547 E = Attrs.end(); I != E; ) {
1548 unsigned Index = I->first;
1550 while (I != E && I->first == Index) {
1552 ++I;
1553 }
1554
1556 }
1557
1558 return get(C, AttrPairVec);
1559}
1560
1561AttributeList
1563 ArrayRef<std::pair<unsigned, AttributeSet>> Attrs) {
1564
1565 if (Attrs.empty())
1566 return {};
1567
1569 "Misordered Attributes list!");
1571 [](const std::pair<unsigned, AttributeSet> &Pair) {
1572 return !Pair.second.hasAttributes();
1573 }) &&
1574 "Pointless attribute!");
1575
1576 unsigned MaxIndex = Attrs.back().first;
1577
1578
1579 if (MaxIndex == FunctionIndex && Attrs.size() > 1)
1580 MaxIndex = Attrs[Attrs.size() - 2].first;
1581
1583 for (const auto &Pair : Attrs)
1585
1586 return getImpl(C, AttrVec);
1587}
1588
1592
1593
1594
1595 unsigned NumSets = 0;
1596 for (size_t I = ArgAttrs.size(); I != 0; --I) {
1597 if (ArgAttrs[I - 1].hasAttributes()) {
1598 NumSets = I + 2;
1599 break;
1600 }
1601 }
1602 if (NumSets == 0) {
1603
1604
1606 NumSets = 2;
1608 NumSets = 1;
1609 }
1610
1611
1612 if (NumSets == 0)
1613 return {};
1614
1616 AttrSets.reserve(NumSets);
1617
1619 if (NumSets > 1)
1621 if (NumSets > 2) {
1622
1623 ArgAttrs = ArgAttrs.take_front(NumSets - 2);
1625 }
1626
1627 return getImpl(C, AttrSets);
1628}
1629
1630AttributeList AttributeList::get(LLVMContext &C, unsigned Index,
1632 if (.hasAttributes())
1633 return {};
1637 return getImpl(C, AttrSets);
1638}
1639
1640AttributeList AttributeList::get(LLVMContext &C, unsigned Index,
1641 const AttrBuilder &B) {
1643}
1644
1645AttributeList AttributeList::get(LLVMContext &C, unsigned Index,
1648 for (const auto K : Kinds)
1651}
1652
1653AttributeList AttributeList::get(LLVMContext &C, unsigned Index,
1656 assert(Kinds.size() == Values.size() && "Mismatched attribute values.");
1658 auto VI = Values.begin();
1659 for (const auto K : Kinds)
1662}
1663
1664AttributeList AttributeList::get(LLVMContext &C, unsigned Index,
1667 for (const auto &K : Kinds)
1670}
1671
1672AttributeList AttributeList::get(LLVMContext &C,
1674 if (Attrs.empty())
1675 return {};
1676 if (Attrs.size() == 1)
1677 return Attrs[0];
1678
1679 unsigned MaxSize = 0;
1680 for (const auto &List : Attrs)
1681 MaxSize = std::max(MaxSize, List.getNumAttrSets());
1682
1683
1684 if (MaxSize == 0)
1685 return {};
1686
1688 for (unsigned I = 0; I < MaxSize; ++I) {
1689 AttrBuilder CurBuilder(C);
1690 for (const auto &List : Attrs)
1691 CurBuilder.merge(AttrBuilder(C, List.getAttributes(I - 1)));
1693 }
1694
1695 return getImpl(C, NewAttrSets);
1696}
1697
1698AttributeList
1699AttributeList::addAttributeAtIndex(LLVMContext &C, unsigned Index,
1702 if (Attrs.hasAttribute(Kind))
1703 return *this;
1704
1708}
1709
1710AttributeList AttributeList::addAttributeAtIndex(LLVMContext &C, unsigned Index,
1714 B.addAttribute(Kind, Value);
1715 return addAttributesAtIndex(C, Index, B);
1716}
1717
1718AttributeList AttributeList::addAttributeAtIndex(LLVMContext &C, unsigned Index,
1722 return addAttributesAtIndex(C, Index, B);
1723}
1724
1725AttributeList AttributeList::setAttributesAtIndex(LLVMContext &C,
1726 unsigned Index,
1730 if (Index >= AttrSets.size())
1731 AttrSets.resize(Index + 1);
1733
1734
1735 while (!AttrSets.empty() && !AttrSets.back().hasAttributes())
1737 if (AttrSets.empty())
1738 return {};
1739 return AttributeList::getImpl(C, AttrSets);
1740}
1741
1742AttributeList AttributeList::addAttributesAtIndex(LLVMContext &C,
1743 unsigned Index,
1744 const AttrBuilder &B) const {
1745 if (.hasAttributes())
1746 return *this;
1747
1748 if (!pImpl)
1750
1752 Merged.merge(B);
1754}
1755
1756AttributeList AttributeList::addParamAttribute(LLVMContext &C,
1760
1763 if (MaxIndex >= AttrSets.size())
1764 AttrSets.resize(MaxIndex + 1);
1765
1766 for (unsigned ArgNo : ArgNos) {
1768 AttrBuilder B(C, AttrSets[Index]);
1771 }
1772
1773 return getImpl(C, AttrSets);
1774}
1775
1776AttributeList
1777AttributeList::removeAttributeAtIndex(LLVMContext &C, unsigned Index,
1781 if (Attrs == NewAttrs)
1782 return *this;
1783 return setAttributesAtIndex(C, Index, NewAttrs);
1784}
1785
1786AttributeList AttributeList::removeAttributeAtIndex(LLVMContext &C,
1787 unsigned Index,
1791 if (Attrs == NewAttrs)
1792 return *this;
1793 return setAttributesAtIndex(C, Index, NewAttrs);
1794}
1795
1796AttributeList AttributeList::removeAttributesAtIndex(
1800
1801 if (Attrs == NewAttrs)
1802 return *this;
1803 return setAttributesAtIndex(C, Index, NewAttrs);
1804}
1805
1806AttributeList
1807AttributeList::removeAttributesAtIndex(LLVMContext &C,
1808 unsigned WithoutIndex) const {
1809 if (!pImpl)
1810 return {};
1812 return *this;
1813 return setAttributesAtIndex(C, WithoutIndex, AttributeSet());
1814}
1815
1816AttributeList AttributeList::addDereferenceableRetAttr(LLVMContext &C,
1817 uint64_t Bytes) const {
1819 B.addDereferenceableAttr(Bytes);
1820 return addRetAttributes(C, B);
1821}
1822
1823AttributeList AttributeList::addDereferenceableParamAttr(LLVMContext &C,
1824 unsigned Index,
1825 uint64_t Bytes) const {
1827 B.addDereferenceableAttr(Bytes);
1828 return addParamAttributes(C, Index, B);
1829}
1830
1831AttributeList
1832AttributeList::addDereferenceableOrNullParamAttr(LLVMContext &C, unsigned Index,
1833 uint64_t Bytes) const {
1835 B.addDereferenceableOrNullAttr(Bytes);
1836 return addParamAttributes(C, Index, B);
1837}
1838
1839AttributeList AttributeList::addRangeRetAttr(LLVMContext &C,
1842 B.addRangeAttr(CR);
1843 return addRetAttributes(C, B);
1844}
1845
1846AttributeList AttributeList::addAllocSizeParamAttr(
1847 LLVMContext &C, unsigned Index, unsigned ElemSizeArg,
1848 const std::optional &NumElemsArg) const {
1850 B.addAllocSizeAttr(ElemSizeArg, NumElemsArg);
1851 return addParamAttributes(C, Index, B);
1852}
1853
1854std::optional
1855AttributeList::intersectWith(LLVMContext &C, AttributeList Other) const {
1856
1857 if (*this == Other)
1858 return *this;
1859
1861 auto IndexIt =
1862 index_iterator(std::max(getNumAttrSets(), Other.getNumAttrSets()));
1863 for (unsigned Idx : IndexIt) {
1864 auto IntersectedAS =
1866
1867 if (!IntersectedAS)
1868 return std::nullopt;
1869 if (!IntersectedAS->hasAttributes())
1870 continue;
1871 IntersectedAttrs.push_back(std::make_pair(Idx, *IntersectedAS));
1872 }
1873
1875 return AttributeList::get(C, IntersectedAttrs);
1876}
1877
1878
1879
1880
1881
1882AttributeSet AttributeList::getParamAttrs(unsigned ArgNo) const {
1884}
1885
1886AttributeSet AttributeList::getRetAttrs() const {
1888}
1889
1890AttributeSet AttributeList::getFnAttrs() const {
1892}
1893
1894bool AttributeList::hasAttributeAtIndex(unsigned Index,
1897}
1898
1899bool AttributeList::hasAttributeAtIndex(unsigned Index, StringRef Kind) const {
1901}
1902
1903bool AttributeList::hasAttributesAtIndex(unsigned Index) const {
1905}
1906
1908 return pImpl && pImpl->hasFnAttribute(Kind);
1909}
1910
1911bool AttributeList::hasFnAttr(StringRef Kind) const {
1912 return hasAttributeAtIndex(AttributeList::FunctionIndex, Kind);
1913}
1914
1916 unsigned *Index) const {
1917 return pImpl && pImpl->hasAttrSomewhere(Attr, Index);
1918}
1919
1920Attribute AttributeList::getAttributeAtIndex(unsigned Index,
1923}
1924
1925Attribute AttributeList::getAttributeAtIndex(unsigned Index,
1928}
1929
1930MaybeAlign AttributeList::getRetAlignment() const {
1931 return getAttributes(ReturnIndex).getAlignment();
1932}
1933
1934MaybeAlign AttributeList::getParamAlignment(unsigned ArgNo) const {
1935 return getAttributes(ArgNo + FirstArgIndex).getAlignment();
1936}
1937
1938MaybeAlign AttributeList::getParamStackAlignment(unsigned ArgNo) const {
1939 return getAttributes(ArgNo + FirstArgIndex).getStackAlignment();
1940}
1941
1942Type *AttributeList::getParamByValType(unsigned Index) const {
1943 return getAttributes(Index+FirstArgIndex).getByValType();
1944}
1945
1946Type *AttributeList::getParamStructRetType(unsigned Index) const {
1947 return getAttributes(Index + FirstArgIndex).getStructRetType();
1948}
1949
1950Type *AttributeList::getParamByRefType(unsigned Index) const {
1951 return getAttributes(Index + FirstArgIndex).getByRefType();
1952}
1953
1954Type *AttributeList::getParamPreallocatedType(unsigned Index) const {
1955 return getAttributes(Index + FirstArgIndex).getPreallocatedType();
1956}
1957
1958Type *AttributeList::getParamInAllocaType(unsigned Index) const {
1959 return getAttributes(Index + FirstArgIndex).getInAllocaType();
1960}
1961
1962Type *AttributeList::getParamElementType(unsigned Index) const {
1963 return getAttributes(Index + FirstArgIndex).getElementType();
1964}
1965
1966MaybeAlign AttributeList::getFnStackAlignment() const {
1967 return getFnAttrs().getStackAlignment();
1968}
1969
1970MaybeAlign AttributeList::getRetStackAlignment() const {
1971 return getRetAttrs().getStackAlignment();
1972}
1973
1974uint64_t AttributeList::getRetDereferenceableBytes() const {
1975 return getRetAttrs().getDereferenceableBytes();
1976}
1977
1978uint64_t AttributeList::getParamDereferenceableBytes(unsigned Index) const {
1979 return getParamAttrs(Index).getDereferenceableBytes();
1980}
1981
1982uint64_t AttributeList::getRetDereferenceableOrNullBytes() const {
1983 return getRetAttrs().getDereferenceableOrNullBytes();
1984}
1985
1986uint64_t
1987AttributeList::getParamDereferenceableOrNullBytes(unsigned Index) const {
1988 return getParamAttrs(Index).getDereferenceableOrNullBytes();
1989}
1990
1991std::optional
1992AttributeList::getParamRange(unsigned ArgNo) const {
1993 auto RangeAttr = getParamAttrs(ArgNo).getAttribute(Attribute::Range);
1994 if (RangeAttr.isValid())
1995 return RangeAttr.getRange();
1996 return std::nullopt;
1997}
1998
1999FPClassTest AttributeList::getRetNoFPClass() const {
2000 return getRetAttrs().getNoFPClass();
2001}
2002
2003FPClassTest AttributeList::getParamNoFPClass(unsigned Index) const {
2004 return getParamAttrs(Index).getNoFPClass();
2005}
2006
2007UWTableKind AttributeList::getUWTableKind() const {
2008 return getFnAttrs().getUWTableKind();
2009}
2010
2011AllocFnKind AttributeList::getAllocKind() const {
2012 return getFnAttrs().getAllocKind();
2013}
2014
2015MemoryEffects AttributeList::getMemoryEffects() const {
2016 return getFnAttrs().getMemoryEffects();
2017}
2018
2019std::string AttributeList::getAsString(unsigned Index, bool InAttrGrp) const {
2020 return getAttributes(Index).getAsString(InAttrGrp);
2021}
2022
2023AttributeSet AttributeList::getAttributes(unsigned Index) const {
2025 if (!pImpl || Index >= getNumAttrSets())
2026 return {};
2027 return pImpl->begin()[Index];
2028}
2029
2030bool AttributeList::hasParentContext(LLVMContext &C) const {
2031 assert(!isEmpty() && "an empty attribute list has no parent context");
2033 pImpl->Profile(ID);
2035 return C.pImpl->AttrsLists.FindNodeOrInsertPos(ID, Unused) == pImpl;
2036}
2037
2038AttributeList::iterator AttributeList::begin() const {
2039 return pImpl ? pImpl->begin() : nullptr;
2040}
2041
2042AttributeList::iterator AttributeList::end() const {
2043 return pImpl ? pImpl->end() : nullptr;
2044}
2045
2046
2047
2048
2049
2050unsigned AttributeList::getNumAttrSets() const {
2051 return pImpl ? pImpl->NumAttrSets : 0;
2052}
2053
2054void AttributeList::print(raw_ostream &O) const {
2055 O << "AttributeList[\n";
2056
2057 for (unsigned i : indexes()) {
2059 continue;
2060 O << " { ";
2061 switch (i) {
2062 case AttrIndex::ReturnIndex:
2063 O << "return";
2064 break;
2065 case AttrIndex::FunctionIndex:
2066 O << "function";
2067 break;
2068 default:
2069 O << "arg(" << i - AttrIndex::FirstArgIndex << ")";
2070 }
2071 O << " => " << getAsString(i) << " }\n";
2072 }
2073
2074 O << "]\n";
2075}
2076
2077#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2079#endif
2080
2081
2082
2083
2084
2087 assert(is_sorted(Attrs) && "AttributeSet should be sorted");
2088}
2089
2090void AttrBuilder::clear() { Attrs.clear(); }
2091
2092
2093
2098 if (A0IsString) {
2099 if (A1IsString)
2101 else
2102 return false;
2103 }
2104 if (A1IsString)
2105 return true;
2107 }
2110 return false;
2112 }
2118};
2119
2120template
2124 if (It != Attrs.end() && It->hasAttribute(Kind))
2126 else
2127 Attrs.insert(It, Attr);
2128}
2129
2130AttrBuilder &AttrBuilder::addAttribute(Attribute Attr) {
2133 else
2135 return *this;
2136}
2137
2140 return *this;
2141}
2142
2145 return *this;
2146}
2147
2150 auto It = lower_bound(Attrs, Val, AttributeComparator());
2151 if (It != Attrs.end() && It->hasAttribute(Val))
2152 Attrs.erase(It);
2153 return *this;
2154}
2155
2156AttrBuilder &AttrBuilder::removeAttribute(StringRef A) {
2157 auto It = lower_bound(Attrs, A, AttributeComparator());
2158 if (It != Attrs.end() && It->hasAttribute(A))
2159 Attrs.erase(It);
2160 return *this;
2161}
2162
2163std::optional<uint64_t>
2167 if (A.isValid())
2168 return A.getValueAsInt();
2169 return std::nullopt;
2170}
2171
2173 uint64_t Value) {
2175}
2176
2177std::optional<std::pair<unsigned, std::optional>>
2178AttrBuilder::getAllocSizeArgs() const {
2179 Attribute A = getAttribute(Attribute::AllocSize);
2180 if (A.isValid())
2181 return A.getAllocSizeArgs();
2182 return std::nullopt;
2183}
2184
2185AttrBuilder &AttrBuilder::addAlignmentAttr(MaybeAlign Align) {
2187 return *this;
2188
2190 return addRawIntAttr(Attribute::Alignment, Align->value());
2191}
2192
2193AttrBuilder &AttrBuilder::addStackAlignmentAttr(MaybeAlign Align) {
2194
2196 return *this;
2197
2198 assert(*Align <= 0x100 && "Alignment too large.");
2199 return addRawIntAttr(Attribute::StackAlignment, Align->value());
2200}
2201
2202AttrBuilder &AttrBuilder::addDereferenceableAttr(uint64_t Bytes) {
2203 if (Bytes == 0) return *this;
2204
2205 return addRawIntAttr(Attribute::Dereferenceable, Bytes);
2206}
2207
2208AttrBuilder &AttrBuilder::addDereferenceableOrNullAttr(uint64_t Bytes) {
2209 if (Bytes == 0)
2210 return *this;
2211
2212 return addRawIntAttr(Attribute::DereferenceableOrNull, Bytes);
2213}
2214
2215AttrBuilder &
2216AttrBuilder::addAllocSizeAttr(unsigned ElemSize,
2217 const std::optional &NumElems) {
2218 return addAllocSizeAttrFromRawRepr(packAllocSizeArgs(ElemSize, NumElems));
2219}
2220
2221AttrBuilder &AttrBuilder::addAllocSizeAttrFromRawRepr(uint64_t RawArgs) {
2222
2223 assert(RawArgs && "Invalid allocsize arguments -- given allocsize(0, 0)");
2224 return addRawIntAttr(Attribute::AllocSize, RawArgs);
2225}
2226
2227AttrBuilder &AttrBuilder::addVScaleRangeAttr(unsigned MinValue,
2228 std::optional MaxValue) {
2229 return addVScaleRangeAttrFromRawRepr(packVScaleRangeArgs(MinValue, MaxValue));
2230}
2231
2232AttrBuilder &AttrBuilder::addVScaleRangeAttrFromRawRepr(uint64_t RawArgs) {
2233
2234 if (RawArgs == 0)
2235 return *this;
2236
2237 return addRawIntAttr(Attribute::VScaleRange, RawArgs);
2238}
2239
2240AttrBuilder &AttrBuilder::addUWTableAttr(UWTableKind Kind) {
2242 return *this;
2243 return addRawIntAttr(Attribute::UWTable, uint64_t(Kind));
2244}
2245
2246AttrBuilder &AttrBuilder::addMemoryAttr(MemoryEffects ME) {
2247 return addRawIntAttr(Attribute::Memory, ME.toIntValue());
2248}
2249
2250AttrBuilder &AttrBuilder::addCapturesAttr(CaptureInfo CI) {
2251 return addRawIntAttr(Attribute::Captures, CI.toIntValue());
2252}
2253
2254AttrBuilder &AttrBuilder::addNoFPClassAttr(FPClassTest Mask) {
2256 return *this;
2257
2258 return addRawIntAttr(Attribute::NoFPClass, Mask);
2259}
2260
2261AttrBuilder &AttrBuilder::addAllocKindAttr(AllocFnKind Kind) {
2262 return addRawIntAttr(Attribute::AllocKind, static_cast<uint64_t>(Kind));
2263}
2264
2268 return A.isValid() ? A.getValueAsType() : nullptr;
2269}
2270
2273}
2274
2275AttrBuilder &AttrBuilder::addByValAttr(Type *Ty) {
2276 return addTypeAttr(Attribute::ByVal, Ty);
2277}
2278
2279AttrBuilder &AttrBuilder::addStructRetAttr(Type *Ty) {
2280 return addTypeAttr(Attribute::StructRet, Ty);
2281}
2282
2283AttrBuilder &AttrBuilder::addByRefAttr(Type *Ty) {
2284 return addTypeAttr(Attribute::ByRef, Ty);
2285}
2286
2287AttrBuilder &AttrBuilder::addPreallocatedAttr(Type *Ty) {
2288 return addTypeAttr(Attribute::Preallocated, Ty);
2289}
2290
2291AttrBuilder &AttrBuilder::addInAllocaAttr(Type *Ty) {
2292 return addTypeAttr(Attribute::InAlloca, Ty);
2293}
2294
2298 return *this;
2299
2301}
2302
2303AttrBuilder &AttrBuilder::addRangeAttr(const ConstantRange &CR) {
2304 return addConstantRangeAttr(Attribute::Range, CR);
2305}
2306
2307AttrBuilder &
2310 return addAttribute(Attribute::get(Ctx, Kind, Val));
2311}
2312
2313AttrBuilder &AttrBuilder::addInitializesAttr(const ConstantRangeList &CRL) {
2314 return addConstantRangeListAttr(Attribute::Initializes, CRL.rangesRef());
2315}
2316
2317AttrBuilder &AttrBuilder::addFromEquivalentMetadata(const Instruction &I) {
2318 if (I.hasMetadata(LLVMContext::MD_nonnull))
2319 addAttribute(Attribute::NonNull);
2320
2321 if (I.hasMetadata(LLVMContext::MD_noundef))
2322 addAttribute(Attribute::NoUndef);
2323
2324 if (const MDNode *Align = I.getMetadata(LLVMContext::MD_align)) {
2327 }
2328
2329 if (const MDNode *Dereferenceable =
2330 I.getMetadata(LLVMContext::MD_dereferenceable)) {
2334 }
2335
2336 if (const MDNode *DereferenceableOrNull =
2337 I.getMetadata(LLVMContext::MD_dereferenceable_or_null)) {
2341 }
2342
2343 if (const MDNode *Range = I.getMetadata(LLVMContext::MD_range))
2345
2346 return *this;
2347}
2348
2349AttrBuilder &AttrBuilder::merge(const AttrBuilder &B) {
2350
2351 for (const auto &I : B.attrs())
2352 addAttribute(I);
2353
2354 return *this;
2355}
2356
2357AttrBuilder &AttrBuilder::remove(const AttributeMask &AM) {
2359 return *this;
2360}
2361
2362bool AttrBuilder::overlaps(const AttributeMask &AM) const {
2364}
2365
2368 auto It = lower_bound(Attrs, A, AttributeComparator());
2369 if (It != Attrs.end() && It->hasAttribute(A))
2370 return *It;
2371 return {};
2372}
2373
2375 auto It = lower_bound(Attrs, A, AttributeComparator());
2376 if (It != Attrs.end() && It->hasAttribute(A))
2377 return *It;
2378 return {};
2379}
2380
2381std::optional AttrBuilder::getRange() const {
2382 const Attribute RangeAttr = getAttribute(Attribute::Range);
2383 if (RangeAttr.isValid())
2384 return RangeAttr.getRange();
2385 return std::nullopt;
2386}
2387
2389 return getAttribute(A).isValid();
2390}
2391
2392bool AttrBuilder::contains(StringRef A) const {
2393 return getAttribute(A).isValid();
2394}
2395
2396bool AttrBuilder::operator==(const AttrBuilder &B) const {
2398}
2399
2400
2401
2402
2403
2404
2405
2406bool AttributeFuncs::isNoFPClassCompatibleType(Type *Ty) {
2408}
2409
2410
2412 AttributeSafetyKind ASK) {
2414
2415 if (!Ty->isIntegerTy()) {
2416
2417 if (ASK & ASK_SAFE_TO_DROP)
2418 Incompatible.addAttribute(Attribute::AllocAlign);
2419 if (ASK & ASK_UNSAFE_TO_DROP)
2421 }
2422
2423 if (!Ty->isIntOrIntVectorTy()) {
2424
2425 if (ASK & ASK_SAFE_TO_DROP)
2426 Incompatible.addAttribute(Attribute::Range);
2427 } else {
2429 if (RangeAttr.isValid() &&
2431 Incompatible.addAttribute(Attribute::Range);
2432 }
2433
2434 if (!Ty->isPointerTy()) {
2435
2436 if (ASK & ASK_SAFE_TO_DROP)
2437 Incompatible.addAttribute(Attribute::NoAlias)
2442 .addAttribute(Attribute::DereferenceableOrNull)
2448 if (ASK & ASK_UNSAFE_TO_DROP)
2458 }
2459
2460
2461 if (!Ty->isPtrOrPtrVectorTy()) {
2462 if (ASK & ASK_SAFE_TO_DROP)
2463 Incompatible.addAttribute(Attribute::Alignment);
2464 }
2465
2466 if (ASK & ASK_SAFE_TO_DROP) {
2467 if (!isNoFPClassCompatibleType(Ty))
2468 Incompatible.addAttribute(Attribute::NoFPClass);
2469 }
2470
2471
2472 if (Ty->isVoidTy()) {
2473 if (ASK & ASK_SAFE_TO_DROP)
2474 Incompatible.addAttribute(Attribute::NoUndef);
2475 }
2476
2477 return Incompatible;
2478}
2479
2483 AM.addAttribute(Attribute::Dereferenceable);
2484 AM.addAttribute(Attribute::DereferenceableOrNull);
2485 return AM;
2486}
2487
2488
2492 return true;
2493
2494
2495
2496 if (CalleeMode.Input == CallerMode.Input &&
2498 return true;
2499
2500 if (CalleeMode.Output == CallerMode.Output &&
2502 return true;
2503 return false;
2504}
2505
2507 DenormalMode CallerMode = Caller.getDenormalModeRaw();
2508 DenormalMode CalleeMode = Callee.getDenormalModeRaw();
2509
2511 DenormalMode CallerModeF32 = Caller.getDenormalModeF32Raw();
2512 DenormalMode CalleeModeF32 = Callee.getDenormalModeF32Raw();
2514 CallerModeF32 = CallerMode;
2516 CalleeModeF32 = CalleeMode;
2518 }
2519
2520 return false;
2521}
2522
2524
2525
2526 return !Callee.getAttributes().hasFnAttr(Attribute::StrictFP) ||
2527 Caller.getAttributes().hasFnAttr(Attribute::StrictFP);
2528}
2529
2530template
2532 return Caller.getFnAttribute(AttrClass::getKind()) ==
2533 Callee.getFnAttribute(AttrClass::getKind());
2534}
2535
2538 return Caller.getFnAttribute(AttrName) == Callee.getFnAttribute(AttrName);
2539}
2540
2541
2542
2543
2544
2545
2546template
2548 if (AttrClass::isSet(Caller, AttrClass::getKind()) &&
2549 !AttrClass::isSet(Callee, AttrClass::getKind()))
2550 AttrClass::set(Caller, AttrClass::getKind(), false);
2551}
2552
2553
2554
2555
2556
2557
2558template
2560 if (!AttrClass::isSet(Caller, AttrClass::getKind()) &&
2561 AttrClass::isSet(Callee, AttrClass::getKind()))
2562 AttrClass::set(Caller, AttrClass::getKind(), true);
2563}
2564
2565
2566
2568
2569
2570
2571 if (!Caller.hasStackProtectorFnAttr())
2572 return;
2573
2574
2575
2576
2578 OldSSPAttr.addAttribute(Attribute::StackProtect)
2579 .addAttribute(Attribute::StackProtectStrong)
2581
2582 if (Callee.hasFnAttribute(Attribute::StackProtectReq)) {
2583 Caller.removeFnAttrs(OldSSPAttr);
2584 Caller.addFnAttr(Attribute::StackProtectReq);
2585 } else if (Callee.hasFnAttribute(Attribute::StackProtectStrong) &&
2586 !Caller.hasFnAttribute(Attribute::StackProtectReq)) {
2587 Caller.removeFnAttrs(OldSSPAttr);
2588 Caller.addFnAttr(Attribute::StackProtectStrong);
2589 } else if (Callee.hasFnAttribute(Attribute::StackProtect) &&
2590 !Caller.hasFnAttribute(Attribute::StackProtectReq) &&
2591 !Caller.hasFnAttribute(Attribute::StackProtectStrong))
2592 Caller.addFnAttr(Attribute::StackProtect);
2593}
2594
2595
2596
2598 if (!Caller.hasFnAttribute("probe-stack") &&
2599 Callee.hasFnAttribute("probe-stack")) {
2600 Caller.addFnAttr(Callee.getFnAttribute("probe-stack"));
2601 }
2602}
2603
2604
2605
2606
2607static void
2609 Attribute CalleeAttr = Callee.getFnAttribute("stack-probe-size");
2610 if (CalleeAttr.isValid()) {
2611 Attribute CallerAttr = Caller.getFnAttribute("stack-probe-size");
2612 if (CallerAttr.isValid()) {
2613 uint64_t CallerStackProbeSize, CalleeStackProbeSize;
2616
2617 if (CallerStackProbeSize > CalleeStackProbeSize) {
2618 Caller.addFnAttr(CalleeAttr);
2619 }
2620 } else {
2621 Caller.addFnAttr(CalleeAttr);
2622 }
2623 }
2624}
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635static void
2637 Attribute CallerAttr = Caller.getFnAttribute("min-legal-vector-width");
2638 if (CallerAttr.isValid()) {
2639 Attribute CalleeAttr = Callee.getFnAttribute("min-legal-vector-width");
2640 if (CalleeAttr.isValid()) {
2641 uint64_t CallerVectorWidth, CalleeVectorWidth;
2644 if (CallerVectorWidth < CalleeVectorWidth)
2645 Caller.addFnAttr(CalleeAttr);
2646 } else {
2647
2648
2649 Caller.removeFnAttr("min-legal-vector-width");
2650 }
2651 }
2652}
2653
2654
2655
2656static void
2658 if (Callee.nullPointerIsDefined() && !Caller.nullPointerIsDefined()) {
2659 Caller.addFnAttr(Attribute::NullPointerIsValid);
2660 }
2661}
2662
2668
2671 if (Val)
2673 else
2675 }
2676};
2677
2682 return A.getValueAsString() == "true";
2683 }
2684
2687 Fn.addFnAttr(Kind, Val ? "true" : "false");
2688 }
2689};
2690
2691#define GET_ATTR_NAMES
2692#define ATTRIBUTE_ENUM(ENUM_NAME, DISPLAY_NAME) \
2693 struct ENUM_NAME##Attr : EnumAttr { \
2694 static enum Attribute::AttrKind getKind() { \
2695 return llvm::Attribute::ENUM_NAME; \
2696 } \
2697 };
2698#define ATTRIBUTE_STRBOOL(ENUM_NAME, DISPLAY_NAME) \
2699 struct ENUM_NAME##Attr : StrBoolAttr { \
2700 static StringRef getKind() { return #DISPLAY_NAME; } \
2701 };
2702#include "llvm/IR/Attributes.inc"
2703
2704#define GET_ATTR_COMPAT_FUNC
2705#include "llvm/IR/Attributes.inc"
2706
2707bool AttributeFuncs::areInlineCompatible(const Function &Caller,
2709 return hasCompatibleFnAttrs(Caller, Callee);
2710}
2711
2712bool AttributeFuncs::areOutlineCompatible(const Function &A,
2714 return hasCompatibleFnAttrs(A, B);
2715}
2716
2717void AttributeFuncs::mergeAttributesForInlining(Function &Caller,
2719 mergeFnAttrs(Caller, Callee);
2720}
2721
2722void AttributeFuncs::mergeAttributesForOutlining(Function &Base,
2724
2725
2726
2727
2728
2729
2730
2731
2732 mergeFnAttrs(Base, ToMerge);
2733}
2734
2735void AttributeFuncs::updateMinLegalVectorWidthAttr(Function &Fn,
2741 if (Width > OldWidth)
2743 }
2744}
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)
Definition Attributes.cpp:2121
static void setAND(Function &Caller, const Function &Callee)
Compute the logical AND of the attributes of the caller and the callee.
Definition Attributes.cpp:2547
static void adjustCallerStackProbes(Function &Caller, const Function &Callee)
If the inlined function required stack probes, then ensure that the calling function has those too.
Definition Attributes.cpp:2597
static std::pair< unsigned, std::optional< unsigned > > unpackVScaleRangeArgs(uint64_t Value)
Definition Attributes.cpp:87
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...
Definition Attributes.cpp:2636
AttributeProperty
Definition Attributes.cpp:766
@ RetAttr
Definition Attributes.cpp:769
@ IntersectPreserve
Definition Attributes.cpp:770
@ IntersectMin
Definition Attributes.cpp:772
@ IntersectCustom
Definition Attributes.cpp:773
@ ParamAttr
Definition Attributes.cpp:768
@ FnAttr
Definition Attributes.cpp:767
@ IntersectPropertyMask
Definition Attributes.cpp:774
@ IntersectAnd
Definition Attributes.cpp:771
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...
Definition Attributes.cpp:2608
static void adjustCallerSSPLevel(Function &Caller, const Function &Callee)
If the inlined function had a higher stack protection level than the calling function,...
Definition Attributes.cpp:2567
static bool checkStrictFP(const Function &Caller, const Function &Callee)
Definition Attributes.cpp:2523
static uint64_t packAllocSizeArgs(unsigned ElemSizeArg, const std::optional< unsigned > &NumElemsArg)
Definition Attributes.cpp:61
static uint64_t packVScaleRangeArgs(unsigned MinValue, std::optional< unsigned > MaxValue)
Definition Attributes.cpp:81
static bool hasIntersectProperty(Attribute::AttrKind Kind, AttributeProperty Prop)
Definition Attributes.cpp:803
static unsigned attrIdxToArrayIdx(unsigned Index)
Map from AttributeList index to the internal array index.
Definition Attributes.cpp:1440
static bool denormModeCompatible(DenormalMode CallerMode, DenormalMode CalleeMode)
Callees with dynamic denormal modes are compatible with any caller mode.
Definition Attributes.cpp:2489
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...
Definition Attributes.cpp:2657
static const unsigned AllocSizeNumElemsNotPresent
Definition Attributes.cpp:59
static std::pair< unsigned, std::optional< unsigned > > unpackAllocSizeArgs(uint64_t Num)
Definition Attributes.cpp:71
static bool checkDenormMode(const Function &Caller, const Function &Callee)
Definition Attributes.cpp:2506
static unsigned getAttributeProperties(Attribute::AttrKind Kind)
Definition Attributes.cpp:780
static void setOR(Function &Caller, const Function &Callee)
Compute the logical OR of the attributes of the caller and the callee.
Definition Attributes.cpp:2559
static bool hasAttributeProperty(Attribute::AttrKind Kind, AttributeProperty Prop)
Definition Attributes.cpp:786
static const char * getModRefStr(ModRefInfo MR)
Definition Attributes.cpp:522
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.
Definition Attributes.cpp:884
bool isConstantRangeAttribute() const
bool hasAttribute(Attribute::AttrKind A) const
Definition Attributes.cpp:831
Type * getValueAsType() const
Definition Attributes.cpp:867
Attribute::AttrKind getKindAsEnum() const
Definition Attributes.cpp:841
bool operator<(const AttributeImpl &AI) const
Used when sorting the attributes.
Definition Attributes.cpp:919
uint64_t getValueAsInt() const
Definition Attributes.cpp:847
bool isIntAttribute() const
bool isTypeAttribute() const
AttributeImpl(AttrEntryKind KindID)
bool getValueAsBool() const
Definition Attributes.cpp:852
StringRef getKindAsString() const
Definition Attributes.cpp:857
StringRef getValueAsString() const
Definition Attributes.cpp:862
bool isEnumAttribute() const
ArrayRef< ConstantRange > getValueAsConstantRangeList() const
Definition Attributes.cpp:878
bool isConstantRangeListAttribute() const
bool isStringAttribute() const
const ConstantRange & getValueAsConstantRange() const
Definition Attributes.cpp:872
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.
Definition Attributes.cpp:1473
void Profile(FoldingSetNodeID &ID) const
Definition Attributes.cpp:1463
AttributeListImpl(ArrayRef< AttributeSet > Sets)
Definition Attributes.cpp:1444
friend class AttributeList
void dump() const
Definition Attributes.cpp:1492
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
Definition Attributes.cpp:1351
uint64_t getDereferenceableOrNullBytes() const
Definition Attributes.cpp:1369
std::optional< unsigned > getVScaleRangeMax() const
Definition Attributes.cpp:1388
bool hasAttribute(Attribute::AttrKind Kind) const
Type * getAttributeType(Attribute::AttrKind Kind) const
Definition Attributes.cpp:1357
AllocFnKind getAllocKind() const
Definition Attributes.cpp:1400
CaptureInfo getCaptureInfo() const
Definition Attributes.cpp:1412
unsigned getVScaleRangeMin() const
Definition Attributes.cpp:1382
MaybeAlign getAlignment() const
Definition Attributes.cpp:1345
MemoryEffects getMemoryEffects() const
Definition Attributes.cpp:1406
UWTableKind getUWTableKind() const
Definition Attributes.cpp:1394
std::optional< std::pair< unsigned, std::optional< unsigned > > > getAllocSizeArgs() const
Definition Attributes.cpp:1376
const Attribute * iterator
uint64_t getDereferenceableBytes() const
Definition Attributes.cpp:1363
std::string getAsString(bool InAttrGrp) const
Definition Attributes.cpp:1424
static AttributeSetNode * get(LLVMContext &C, const AttrBuilder &B)
Definition Attributes.cpp:1310
FPClassTest getNoFPClass() const
Definition Attributes.cpp:1418
Attribute getAttribute(Attribute::AttrKind Kind) const
Definition Attributes.cpp:1335
This class holds the attributes for a particular argument, parameter, function, or return value.
LLVM_ABI AllocFnKind getAllocKind() const
Definition Attributes.cpp:1212
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.
Definition Attributes.cpp:976
LLVM_ABI Type * getInAllocaType() const
Definition Attributes.cpp:1185
LLVM_ABI Type * getByValType() const
Definition Attributes.cpp:1173
LLVM_ABI AttributeSet addAttributes(LLVMContext &C, AttributeSet AS) const
Add attributes to the attribute set.
Definition Attributes.cpp:950
LLVM_ABI MemoryEffects getMemoryEffects() const
Definition Attributes.cpp:1216
LLVM_ABI bool hasAttribute(Attribute::AttrKind Kind) const
Return true if the attribute exists in this set.
Definition Attributes.cpp:1137
LLVM_ABI std::optional< AttributeSet > intersectWith(LLVMContext &C, AttributeSet Other) const
Try to intersect this AttributeSet with Other.
Definition Attributes.cpp:1004
LLVM_ABI Type * getStructRetType() const
Definition Attributes.cpp:1177
LLVM_ABI std::string getAsString(bool InAttrGrp=false) const
Definition Attributes.cpp:1228
LLVM_ABI unsigned getVScaleRangeMin() const
Definition Attributes.cpp:1200
LLVM_ABI std::optional< std::pair< unsigned, std::optional< unsigned > > > getAllocSizeArgs() const
Definition Attributes.cpp:1194
LLVM_ABI UWTableKind getUWTableKind() const
Definition Attributes.cpp:1208
LLVM_ABI bool hasParentContext(LLVMContext &C) const
Return true if this attribute set belongs to the LLVMContext.
Definition Attributes.cpp:1232
LLVM_ABI iterator begin() const
Definition Attributes.cpp:1240
LLVM_ABI iterator end() const
Definition Attributes.cpp:1244
LLVM_ABI AttributeSet removeAttributes(LLVMContext &C, const AttributeMask &AttrsToRemove) const
Remove the specified attributes from this set.
Definition Attributes.cpp:992
LLVM_ABI std::optional< unsigned > getVScaleRangeMax() const
Definition Attributes.cpp:1204
LLVM_ABI MaybeAlign getStackAlignment() const
Definition Attributes.cpp:1157
LLVM_ABI Attribute getAttribute(Attribute::AttrKind Kind) const
Return the attribute object.
Definition Attributes.cpp:1145
LLVM_ABI Type * getPreallocatedType() const
Definition Attributes.cpp:1181
LLVM_ABI uint64_t getDereferenceableBytes() const
Definition Attributes.cpp:1161
LLVM_ABI MaybeAlign getAlignment() const
Definition Attributes.cpp:1153
LLVM_ABI FPClassTest getNoFPClass() const
Definition Attributes.cpp:1224
LLVM_ABI Type * getElementType() const
Definition Attributes.cpp:1189
LLVM_ABI Type * getByRefType() const
Definition Attributes.cpp:1169
LLVM_ABI CaptureInfo getCaptureInfo() const
Definition Attributes.cpp:1220
AttributeSet()=default
AttributeSet is a trivially copyable value type.
static LLVM_ABI AttributeSet get(LLVMContext &C, const AttrBuilder &B)
Definition Attributes.cpp:927
LLVM_ABI uint64_t getDereferenceableOrNullBytes() const
Definition Attributes.cpp:1165
LLVM_ABI unsigned getNumAttributes() const
Return the number of attributes in this set.
Definition Attributes.cpp:1133
LLVM_ABI AttributeSet addAttribute(LLVMContext &C, Attribute::AttrKind Kind) const
Add an argument attribute.
Definition Attributes.cpp:935
void dump() const
Definition Attributes.cpp:1249
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.
Definition Attributes.cpp:356
static LLVM_ABI Attribute getWithStructRetType(LLVMContext &Context, Type *Ty)
Definition Attributes.cpp:260
static LLVM_ABI Attribute::AttrKind getAttrKindFromName(StringRef AttrName)
Definition Attributes.cpp:313
LLVM_ABI bool isEnumAttribute() const
Return true if the attribute is an Attribute::AttrKind type.
Definition Attributes.cpp:348
static LLVM_ABI Attribute getWithStackAlignment(LLVMContext &Context, Align Alignment)
Definition Attributes.cpp:239
LLVM_ABI const ConstantRange & getRange() const
Returns the value of the range attribute.
Definition Attributes.cpp:510
static LLVM_ABI bool intersectWithCustom(AttrKind Kind)
Definition Attributes.cpp:823
LLVM_ABI bool isIntAttribute() const
Return true if the attribute is an integer attribute.
Definition Attributes.cpp:352
static LLVM_ABI Attribute getWithByRefType(LLVMContext &Context, Type *Ty)
Definition Attributes.cpp:264
LLVM_ABI std::optional< unsigned > getVScaleRangeMax() const
Returns the maximum value for the vscale_range attribute or std::nullopt when unknown.
Definition Attributes.cpp:474
LLVM_ABI uint64_t getValueAsInt() const
Return the attribute's value as an integer.
Definition Attributes.cpp:379
LLVM_ABI unsigned getVScaleRangeMin() const
Returns the minimum value for the vscale_range attribute.
Definition Attributes.cpp:468
LLVM_ABI AllocFnKind getAllocKind() const
Definition Attributes.cpp:486
LLVM_ABI bool isConstantRangeAttribute() const
Return true if the attribute is a ConstantRange attribute.
Definition Attributes.cpp:364
static LLVM_ABI Attribute getWithAllocKind(LLVMContext &Context, AllocFnKind Kind)
Definition Attributes.cpp:303
LLVM_ABI StringRef getKindAsString() const
Return the attribute's kind as a string.
Definition Attributes.cpp:393
static LLVM_ABI Attribute getWithPreallocatedType(LLVMContext &Context, Type *Ty)
Definition Attributes.cpp:268
static LLVM_ABI bool intersectWithMin(AttrKind Kind)
Definition Attributes.cpp:820
static LLVM_ABI Attribute get(LLVMContext &Context, AttrKind Kind, uint64_t Val=0)
Return a uniquified Attribute object.
Definition Attributes.cpp:95
static LLVM_ABI bool canUseAsRetAttr(AttrKind Kind)
Definition Attributes.cpp:799
static bool isTypeAttrKind(AttrKind Kind)
LLVM_ABI std::string getAsString(bool InAttrGrp=false) const
The Attribute is converted to a string of equivalent mnemonic.
Definition Attributes.cpp:536
LLVM_ABI uint64_t getDereferenceableOrNullBytes() const
Returns the number of dereferenceable_or_null bytes from the dereferenceable_or_null attribute.
Definition Attributes.cpp:454
static LLVM_ABI Attribute getWithDereferenceableBytes(LLVMContext &Context, uint64_t Bytes)
Definition Attributes.cpp:244
LLVM_ABI std::pair< unsigned, std::optional< unsigned > > getAllocSizeArgs() const
Returns the argument numbers for the allocsize attribute.
Definition Attributes.cpp:462
static LLVM_ABI Attribute getWithUWTableKind(LLVMContext &Context, UWTableKind Kind)
Definition Attributes.cpp:276
LLVM_ABI FPClassTest getNoFPClass() const
Return the FPClassTest for nofpclass.
Definition Attributes.cpp:504
static LLVM_ABI Attribute getWithAllocSizeArgs(LLVMContext &Context, unsigned ElemSizeArg, const std::optional< unsigned > &NumElemsArg)
Definition Attributes.cpp:296
LLVM_ABI Attribute::AttrKind getKindAsEnum() const
Return the attribute's kind as an enum (Attribute::AttrKind).
Definition Attributes.cpp:372
LLVM_ABI bool getValueAsBool() const
Return the attribute's value as a boolean.
Definition Attributes.cpp:386
LLVM_ABI ArrayRef< ConstantRange > getInitializes() const
Returns the value of the initializes attribute.
Definition Attributes.cpp:516
LLVM_ABI const ConstantRange & getValueAsConstantRange() const
Return the attribute's value as a ConstantRange.
Definition Attributes.cpp:414
LLVM_ABI uint64_t getDereferenceableBytes() const
Returns the number of dereferenceable bytes from the dereferenceable attribute.
Definition Attributes.cpp:447
static LLVM_ABI Attribute getWithVScaleRangeArgs(LLVMContext &Context, unsigned MinValue, unsigned MaxValue)
Definition Attributes.cpp:307
LLVM_ABI MemoryEffects getMemoryEffects() const
Returns memory effects.
Definition Attributes.cpp:492
LLVM_ABI void Profile(FoldingSetNodeID &ID) const
Definition Attributes.cpp:762
LLVM_ABI UWTableKind getUWTableKind() const
Definition Attributes.cpp:480
static LLVM_ABI Attribute getWithDereferenceableOrNullBytes(LLVMContext &Context, uint64_t Bytes)
Definition Attributes.cpp:250
LLVM_ABI ArrayRef< ConstantRange > getValueAsConstantRangeList() const
Return the attribute's value as a ConstantRange array.
Definition Attributes.cpp:420
LLVM_ABI StringRef getValueAsString() const
Return the attribute's value as a string.
Definition Attributes.cpp:400
static LLVM_ABI bool isExistingAttribute(StringRef Name)
Return true if the provided string matches the IR name of an attribute.
Definition Attributes.cpp:336
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)
Definition Attributes.cpp:322
static LLVM_ABI bool canUseAsFnAttr(AttrKind Kind)
Definition Attributes.cpp:791
static LLVM_ABI bool intersectWithAnd(AttrKind Kind)
Definition Attributes.cpp:817
static LLVM_ABI Attribute getWithNoFPClass(LLVMContext &Context, FPClassTest Mask)
Definition Attributes.cpp:286
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.
Definition Attributes.cpp:737
LLVM_ABI bool isTypeAttribute() const
Return true if the attribute is a type attribute.
Definition Attributes.cpp:360
static LLVM_ABI Attribute getWithCaptureInfo(LLVMContext &Context, CaptureInfo CI)
Definition Attributes.cpp:291
static LLVM_ABI Attribute getWithInAllocaType(LLVMContext &Context, Type *Ty)
Definition Attributes.cpp:272
static bool isIntAttrKind(AttrKind Kind)
static bool isConstantRangeListAttrKind(AttrKind Kind)
LLVM_ABI bool isConstantRangeListAttribute() const
Return true if the attribute is a ConstantRangeList attribute.
Definition Attributes.cpp:368
static LLVM_ABI Attribute getWithByValType(LLVMContext &Context, Type *Ty)
Definition Attributes.cpp:256
LLVM_ABI bool hasAttribute(AttrKind Val) const
Return true if the attribute is present.
Definition Attributes.cpp:426
static bool isEnumAttrKind(AttrKind Kind)
static LLVM_ABI Attribute getWithMemoryEffects(LLVMContext &Context, MemoryEffects ME)
Definition Attributes.cpp:281
static LLVM_ABI bool canUseAsParamAttr(AttrKind Kind)
Definition Attributes.cpp:795
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.
Definition Attributes.cpp:441
LLVM_ABI MaybeAlign getAlignment() const
Returns the alignment field of an attribute as a byte alignment value.
Definition Attributes.cpp:435
LLVM_ABI CaptureInfo getCaptureInfo() const
Returns information from captures attribute.
Definition Attributes.cpp:498
static LLVM_ABI bool intersectMustPreserve(AttrKind Kind)
Definition Attributes.cpp:814
LLVM_ABI int cmpKind(Attribute A) const
Used to sort attribute by kind.
Definition Attributes.cpp:745
LLVM_ABI bool operator<(Attribute A) const
Less-than operator. Useful for sorting the attributes list.
Definition Attributes.cpp:755
static LLVM_ABI Attribute getWithAlignment(LLVMContext &Context, Align Alignment)
Return a uniquified Attribute object that has the specific alignment set.
Definition Attributes.cpp:234
LLVM_ABI Type * getValueAsType() const
Return the attribute's value as a Type.
Definition Attributes.cpp:407
Represents which components of the pointer may be captured in which location.
static CaptureInfo createFromIntValue(uint32_t Data)
static CaptureInfo all()
Create CaptureInfo that may capture all components of the pointer.
uint32_t toIntValue() const
Convert CaptureInfo into an encoded integer value (used by captures attribute).
This is the shared class of boolean and integer constants.
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
static size_t totalSizeToAlloc(ArrayRef< ConstantRange > Val)
This class represents a list of constant ranges.
ArrayRef< ConstantRange > rangesRef() const
LLVM_ABI void print(raw_ostream &OS) const
Print out the ranges to a stream.
This class represents a range of values.
const APInt & getLower() const
Return the lower value for this range.
LLVM_ABI bool isFullSet() const
Return true if this set contains all of the elements possible for this data-type.
const APInt & getUpper() const
Return the upper value for this range.
LLVM_ABI ConstantRange unionWith(const ConstantRange &CR, PreferredRangeType Type=Smallest) const
Return the range that results from the union of this range with another range.
uint32_t getBitWidth() const
Get the bit width of this ConstantRange.
A set of classes that contain the value of the attribute object.
static bool isSupportedFloatingPointType(Type *Ty)
Returns true if Ty is a supported floating-point type for phi, select, or call FPMathOperators.
FoldingSetNodeID - This class is used to gather all the unique data bits of a node.
void addFnAttr(Attribute::AttrKind Kind)
Add function attributes to this function.
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
void removeFnAttr(Attribute::AttrKind Kind)
Remove function attributes from this function.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
FoldingSet< AttributeSetNode > AttrsSetNodes
FoldingSet< AttributeListImpl > AttrsLists
This is an important class for using LLVM in a threaded context.
ModRefInfo getModRef(Location Loc) const
Get ModRefInfo for the given Location.
static MemoryEffectsBase createFromIntValue(uint32_t Data)
uint32_t toIntValue() const
Convert MemoryEffectsBase into an encoded integer value (used by memory attribute).
static MemoryEffectsBase unknown()
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void reserve(size_type N)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
static size_t totalSizeToAlloc(StringRef Kind, StringRef Val)
StringRef - Represent a constant reference to a string, i.e.
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
std::string str() const
str - Get the contents as an std::string.
constexpr bool empty() const
empty - Check if the string is empty.
int compare(StringRef RHS) const
compare - Compare two strings; the result is negative, zero, or positive if this string is lexicograp...
A switch()-like statement whose cases are string literals.
static constexpr std::enable_if_t< std::is_same_v< Foo< TrailingTys... >, Foo< Tys... > >, size_t > totalSizeToAlloc(typename trailing_objects_internal::ExtractSecondType< TrailingTys, size_t >::type... Counts)
const T * getTrailingObjects() const
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM_ABI void print(raw_ostream &O, bool IsForDebug=false, bool NoDetails=false) const
Print the current type.
LLVM Value Representation.
static constexpr uint64_t MaximumAlignment
This class implements an extremely fast bulk output stream that can only output to a stream.
A raw_ostream that writes to an std::string.
This class provides various memory handling functions that manipulate MemoryBlock instances.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Attrs[]
Key for Kernel::Metadata::mAttrs.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
LLVM_ABI AttributeList getAttributes(LLVMContext &C, ID id, FunctionType *FT)
Return the attributes for an intrinsic.
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > extract(Y &&MD)
Extract a Value from Metadata.
LLVM_ABI iterator begin() const
This is an optimization pass for GlobalISel generic memory operations.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
bool isEqual(const GCNRPTracker::LiveRegSet &S1, const GCNRPTracker::LiveRegSet &S2)
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
std::string utostr(uint64_t X, bool isNeg=false)
MemoryEffectsBase< IRMemLocation > MemoryEffects
Summary of how a function affects memory in the program.
LLVM_ABI void printEscapedString(StringRef Name, raw_ostream &Out)
Print each character of the specified string, escaping it if it is not printable or if it is an escap...
LLVM_ABI ConstantRange getConstantRangeFromMetadata(const MDNode &RangeMD)
Parse out a conservative ConstantRange from !range metadata.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
@ None
No unwind table requested.
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
void sort(IteratorTy Start, IteratorTy End)
FPClassTest
Floating-point class tests, supported by 'is_fpclass' intrinsic.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
bool is_sorted(R &&Range, Compare C)
Wrapper function around std::is_sorted to check if elements in a range R are sorted with respect to a...
ModRefInfo
Flags indicating whether a memory access modifies or references memory.
@ Ref
The access may reference the value stored in memory.
@ ModRef
The access may reference and may modify the value stored in memory.
@ Mod
The access may modify the value stored in memory.
@ NoModRef
The access neither references nor modifies the value stored in memory.
@ ArgMem
Access to memory via argument pointers.
@ TargetMem0
Represents target specific state.
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
@ InaccessibleMem
Memory that is inaccessible via LLVM IR.
std::string join(IteratorT Begin, IteratorT End, StringRef Separator)
Joins the strings in the range [Begin, End), adding Separator between the elements.
auto lower_bound(R &&Range, T &&Value)
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
ArrayRef(const T &OneElt) -> ArrayRef< T >
OutputIt copy(R &&Range, OutputIt Out)
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Attribute comparator that only compares attribute keys.
Definition Attributes.cpp:2094
bool operator()(Attribute A0, StringRef Kind) const
Definition Attributes.cpp:2113
bool operator()(Attribute A0, Attribute A1) const
Definition Attributes.cpp:2095
bool operator()(Attribute A0, Attribute::AttrKind Kind) const
Definition Attributes.cpp:2108
Definition Attributes.cpp:2663
static void set(Function &Fn, Attribute::AttrKind Kind, bool Val)
Definition Attributes.cpp:2669
static bool isSet(const Function &Fn, Attribute::AttrKind Kind)
Definition Attributes.cpp:2664
Definition Attributes.cpp:2678
static bool isSet(const Function &Fn, StringRef Kind)
Definition Attributes.cpp:2679
static void set(Function &Fn, StringRef Kind, bool Val)
Definition Attributes.cpp:2685
This struct is a compact representation of a valid (non-zero power of two) alignment.
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
Represent subnormal handling kind for floating point instruction inputs and outputs.
DenormalModeKind Input
Denormal treatment kind for floating point instruction inputs in the default floating-point environme...
@ Dynamic
Denormals have unknown treatment.
static constexpr DenormalMode getInvalid()
DenormalModeKind Output
Denormal flushing mode for floating point instruction results in the default floating point environme...
static constexpr DenormalMode getDynamic()
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Align valueOrOne() const
For convenience, returns a valid alignment or 1 if undefined.
Function object to check whether the first component of a container supported by std::get (like std::...