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;

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;

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;

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;

184

185 if (!PA) {

186

187

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;

212

213 if (!PA) {

214

215

216

217

218

219

220

225 pImpl->AttrsSet.InsertNode(PA, InsertPoint);

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

278 return get(Context, UWTable, uint64_t(Kind));

279}

280

284}

285

288 return get(Context, NoFPClass, ClassMask);

289}

290

293 const std::optional &NumElemsArg) {

294 assert(!(ElemSizeArg == 0 && NumElemsArg && *NumElemsArg == 0) &&

295 "Invalid allocsize arguments -- given allocsize(0, 0)");

297}

298

300 unsigned MinValue,

301 unsigned MaxValue) {

303}

304

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"

312}

313

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"

322 return "none";

323 default:

325 }

326}

327

330#define GET_ATTR_NAMES

331#define ATTRIBUTE_ALL(ENUM_NAME, DISPLAY_NAME) .Case(#DISPLAY_NAME, true)

332#include "llvm/IR/Attributes.inc"

334}

335

336

337

338

339

342}

343

346}

347

350}

351

354}

355

358}

359

362}

363

365 if (!pImpl) return None;

367 "Invalid attribute type to get the kind as an enum!");

369}

370

372 if (!pImpl) return 0;

374 "Expected the attribute to be an integer attribute!");

376}

377

379 if (!pImpl) return false;

381 "Expected the attribute to be a string attribute!");

383}

384

386 if (!pImpl) return {};

388 "Invalid attribute type to get the kind as a string!");

390}

391

393 if (!pImpl) return {};

395 "Invalid attribute type to get the value as a string!");

397}

398

400 if (!pImpl) return {};

402 "Invalid attribute type to get the value as a type!");

404}

405

408 "Invalid attribute type to get the value as a ConstantRange!");

410}

411

414 "Invalid attribute type to get the value as a ConstantRangeList!");

416}

417

419 return (pImpl && pImpl->hasAttribute(Kind)) || (!pImpl && Kind == None);

420}

421

425}

426

429 "Trying to get alignment from non-alignment attribute!");

431}

432

435 "Trying to get alignment from non-alignment attribute!");

437}

438

441 "Trying to get dereferenceable bytes from "

442 "non-dereferenceable attribute!");

444}

445

448 "Trying to get dereferenceable bytes from "

449 "non-dereferenceable attribute!");

451}

452

453std::pair<unsigned, std::optional>

456 "Trying to get allocsize args from non-allocsize attribute");

458}

459

462 "Trying to get vscale args from non-vscale attribute");

464}

465

468 "Trying to get vscale args from non-vscale attribute");

470}

471

474 "Trying to get unwind table kind from non-uwtable attribute");

476}

477

480 "Trying to get allockind value from non-allockind attribute");

482}

483

486 "Can only call getMemoryEffects() on memory attribute");

488}

489

492 "Can only call getCaptureInfo() on captures attribute");

494}

495

498 "Can only call getNoFPClass() on nofpclass attribute");

500}

501

504 "Trying to get range args from non-range attribute");

506}

507

510 "Trying to get initializes attr from non-ConstantRangeList attribute");

512}

513

515 switch (MR) {

517 return "none";

519 return "read";

521 return "write";

523 return "readwrite";

524 }

526}

527

529 if (!pImpl) return {};

530

533

536 Result += '(';

540 Result += ')';

541 return Result;

542 }

543

544

545

546

547

548

552 .str();

553

554 auto AttrWithBytesToString = [&](const char *Name) {

557 .str();

558 };

559

561 return AttrWithBytesToString("alignstack");

562

563 if (hasAttribute(Attribute::Dereferenceable))

564 return AttrWithBytesToString("dereferenceable");

565

566 if (hasAttribute(Attribute::DereferenceableOrNull))

567 return AttrWithBytesToString("dereferenceable_or_null");

568

570 unsigned ElemSize;

571 std::optional NumElems;

573

574 return (NumElems

575 ? "allocsize(" + Twine(ElemSize) + "," + Twine(*NumElems) + ")"

576 : "allocsize(" + Twine(ElemSize) + ")")

577 .str();

578 }

579

583 return ("vscale_range(" + Twine(MinValue) + "," +

584 Twine(MaxValue.value_or(0)) + ")")

585 .str();

586 }

587

592 }

593

604 parts.push_back("uninitialized");

609 return ("allockind(\"" +

610 Twine(llvm::join(parts.begin(), parts.end(), ",")) + "\")")

611 .str();

612 }

613

615 std::string Result;

617 bool First = true;

618 OS << "memory(";

619

621

622

623

628 }

629

632 if (MR == OtherMR)

633 continue;

634

636 OS << ", ";

638

639 switch (Loc) {

641 OS << "argmem: ";

642 break;

644 OS << "inaccessiblemem: ";

645 break;

647 llvm_unreachable("This is represented as the default access kind");

648 }

650 }

651 OS << ")";

653 return Result;

654 }

655

657 std::string Result;

660 return Result;

661 }

662

664 std::string Result = "nofpclass";

667 return Result;

668 }

669

671 std::string Result;

674 OS << "range(";

677 OS << ")";

679 return Result;

680 }

681

683 std::string Result;

686 OS << "initializes(";

688 OS << ")";

690 return Result;

691 }

692

693

694

695

696

697

699 std::string Result;

700 {

703

704

705

706

708 if (!AttrVal.empty()) {

709 OS << "=\"";

710 printEscapedString(AttrVal, OS);

711 OS << "\"";

712 }

713 }

714 return Result;

715 }

716

718}

719

721 assert(isValid() && "invalid Attribute doesn't refer to any context");

724 void *Unused;

725 return C.pImpl->AttrsSet.FindNodeOrInsertPos(ID, Unused) == pImpl;

726}

727

729 if (!pImpl && A.pImpl)

730 return 0;

731 if (!pImpl)

732 return 1;

733 if (A.pImpl)

734 return -1;

735 return pImpl->cmp(*A.pImpl, true);

736}

737

739 if (!pImpl && A.pImpl) return false;

740 if (!pImpl) return true;

741 if (A.pImpl) return false;

742 return *pImpl < *A.pImpl;

743}

744

746 ID.AddPointer(pImpl);

747}

748

758};

759

760#define GET_ATTR_PROP_TABLE

761#include "llvm/IR/Attributes.inc"

762

764 unsigned Index = Kind - 1;

765 assert(Index < std::size(AttrPropTable) && "Invalid attribute kind");

766 return AttrPropTable[Index];

767}

768

772}

773

776}

777

780}

781

784}

785

788 assert((Prop == AttributeProperty::IntersectPreserve ||

789 Prop == AttributeProperty::IntersectAnd ||

790 Prop == AttributeProperty::IntersectMin ||

791 Prop == AttributeProperty::IntersectCustom) &&

792 "Unknown intersect property");

794 AttributeProperty::IntersectPropertyMask) == Prop;

795}

796

799}

802}

805}

808}

809

810

811

812

813

817}

818

822}

823

827 return static_cast<const EnumAttributeImpl *>(this)->getEnumKind();

828}

829

832 return static_cast<const IntAttributeImpl *>(this)->getValue();

833}

834

838}

839

843}

844

848}

849

852 return static_cast<const TypeAttributeImpl *>(this)->getTypeValue();

853}

854

858 ->getConstantRangeValue();

859}

860

864 ->getConstantRangeListValue();

865}

866

868 if (this == &AI)

869 return 0;

870

871

872

875 return -1;

876

879 else if (KindOnly)

880 return 0;

881

886 "Unclear how to compare range list");

887

890 return -1;

892 }

894 return 1;

895 if (KindOnly)

900}

901

903 return cmp(AI, false) < 0;

904}

905

906

907

908

909

912}

913

916}

917

922 B.addAttribute(Kind);

924}

925

929 B.addAttribute(Kind, Value);

931}

932

936 return AS;

937

939 return *this;

940

943 return get(C, B);

944}

945

950 B.removeAttribute(Kind);

951 return get(C, B);

952}

953

958 B.removeAttribute(Kind);

959 return get(C, B);

960}

961

965

966 if (B.overlaps(Attrs))

967 return *this;

968

969 B.remove(Attrs);

970 return get(C, B);

971}

972

973std::optional

975 if (*this == Other)

976 return *this;

977

979

980 auto ItBegin0 = begin();

981 auto ItEnd0 = end();

982 auto ItBegin1 = Other.begin();

983 auto ItEnd1 = Other.end();

984

985 while (ItBegin0 != ItEnd0 || ItBegin1 != ItEnd1) {

986

987

988

990 if (ItBegin1 == ItEnd1)

991 Attr0 = *ItBegin0++;

992 else if (ItBegin0 == ItEnd0)

993 Attr0 = *ItBegin1++;

994 else {

995 int Cmp = ItBegin0->cmpKind(*ItBegin1);

996 if (Cmp == 0) {

997 Attr0 = *ItBegin0++;

998 Attr1 = *ItBegin1++;

999 } else if (Cmp < 0)

1000 Attr0 = *ItBegin0++;

1001 else

1002 Attr0 = *ItBegin1++;

1003 }

1004 assert(Attr0.isValid() && "Iteration should always yield a valid attr");

1005

1006 auto IntersectEq = [&]() {

1008 return false;

1009 if (Attr0 != Attr1)

1010 return false;

1012 return true;

1013 };

1014

1015

1016

1018 if (!IntersectEq())

1019 return std::nullopt;

1020 continue;

1021 }

1022

1024

1025

1028 return std::nullopt;

1029 continue;

1030 }

1031

1032

1034 "Iterator picked up two different attributes in the same iteration");

1035

1036

1039 "Invalid attr type of intersectAnd");

1041 continue;

1042 }

1043

1044

1047 "Invalid attr type of intersectMin");

1050 continue;

1051 }

1052

1054 switch (Kind) {

1055 case Attribute::Alignment:

1056

1057

1061 break;

1062 case Attribute::Memory:

1065 break;

1066 case Attribute::Captures:

1069 break;

1070 case Attribute::NoFPClass:

1073 break;

1074 case Attribute::Range: {

1080 } break;

1081 default:

1082 llvm_unreachable("Unknown attribute with custom intersection rule");

1083 }

1084 continue;

1085 }

1086

1087

1088

1089 if (!IntersectEq())

1090 return std::nullopt;

1091

1092

1093

1094 if (Kind == Attribute::ByVal &&

1096 Other.getAttribute(Attribute::Alignment))

1097 return std::nullopt;

1098 }

1099

1100 return get(C, Intersected);

1101}

1102

1105}

1106

1108 return SetNode ? SetNode->hasAttribute(Kind) : false;

1109}

1110

1112 return SetNode ? SetNode->hasAttribute(Kind) : false;

1113}

1114

1117}

1118

1121}

1122

1124 return SetNode ? SetNode->getAlignment() : std::nullopt;

1125}

1126

1129}

1130

1133}

1134

1137}

1138

1140 return SetNode ? SetNode->getAttributeType(Attribute::ByRef) : nullptr;

1141}

1142

1144 return SetNode ? SetNode->getAttributeType(Attribute::ByVal) : nullptr;

1145}

1146

1148 return SetNode ? SetNode->getAttributeType(Attribute::StructRet) : nullptr;

1149}

1150

1152 return SetNode ? SetNode->getAttributeType(Attribute::Preallocated) : nullptr;

1153}

1154

1156 return SetNode ? SetNode->getAttributeType(Attribute::InAlloca) : nullptr;

1157}

1158

1160 return SetNode ? SetNode->getAttributeType(Attribute::ElementType) : nullptr;

1161}

1162

1163std::optional<std::pair<unsigned, std::optional>>

1165 if (SetNode)

1167 return std::nullopt;

1168}

1169

1172}

1173

1176}

1177

1180}

1181

1184}

1185

1188}

1189

1192}

1193

1196}

1197

1199 return SetNode ? SetNode->getAsString(InAttrGrp) : "";

1200}

1201

1203 assert(hasAttributes() && "empty AttributeSet doesn't refer to any context");

1206 void *Unused;

1207 return C.pImpl->AttrsSetNodes.FindNodeOrInsertPos(ID, Unused) == SetNode;

1208}

1209

1211 return SetNode ? SetNode->begin() : nullptr;

1212}

1213

1215 return SetNode ? SetNode->end() : nullptr;

1216}

1217

1218#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)

1220 dbgs() << "AS =\n";

1221 dbgs() << " { ";

1223}

1224#endif

1225

1226

1227

1228

1229

1231 : NumAttrs(Attrs.size()) {

1232

1233 llvm::copy(Attrs, getTrailingObjects());

1234

1235 for (const auto &I : *this) {

1236 if (I.isStringAttribute())

1237 StringAttrs.insert({ I.getKindAsString(), I });

1238 else

1239 AvailableAttrs.addAttribute(I.getKindAsEnum());

1240 }

1241}

1242

1247 return getSorted(C, SortedAttrs);

1248}

1249

1252 if (SortedAttrs.empty())

1253 return nullptr;

1254

1255

1258

1260 for (const auto &Attr : SortedAttrs)

1261 Attr.Profile(ID);

1262

1263 void *InsertPoint;

1265 pImpl->AttrsSetNodes.FindNodeOrInsertPos(ID, InsertPoint);

1266

1267

1268

1269 if (!PA) {

1270

1271 void *Mem = ::operator new(totalSizeToAlloc(SortedAttrs.size()));

1273 pImpl->AttrsSetNodes.InsertNode(PA, InsertPoint);

1274 }

1275

1276

1277 return PA;

1278}

1279

1281 return getSorted(C, B.attrs());

1282}

1283

1285 return StringAttrs.count(Kind);

1286}

1287

1288std::optional

1290

1292 return std::nullopt;

1293

1294

1295

1297 std::lower_bound(begin(), end() - StringAttrs.size(), Kind,

1299 return A.getKindAsEnum() < Kind;

1300 });

1301 assert(I != end() && I->hasAttribute(Kind) && "Presence check failed?");

1302 return *I;

1303}

1304

1306 if (auto A = findEnumAttribute(Kind))

1307 return *A;

1308 return {};

1309}

1310

1312 return StringAttrs.lookup(Kind);

1313}

1314

1316 if (auto A = findEnumAttribute(Attribute::Alignment))

1317 return A->getAlignment();

1318 return std::nullopt;

1319}

1320

1322 if (auto A = findEnumAttribute(Attribute::StackAlignment))

1323 return A->getStackAlignment();

1324 return std::nullopt;

1325}

1326

1328 if (auto A = findEnumAttribute(Kind))

1329 return A->getValueAsType();

1330 return nullptr;

1331}

1332

1334 if (auto A = findEnumAttribute(Attribute::Dereferenceable))

1335 return A->getDereferenceableBytes();

1336 return 0;

1337}

1338

1340 if (auto A = findEnumAttribute(Attribute::DereferenceableOrNull))

1341 return A->getDereferenceableOrNullBytes();

1342 return 0;

1343}

1344

1345std::optional<std::pair<unsigned, std::optional>>

1347 if (auto A = findEnumAttribute(Attribute::AllocSize))

1348 return A->getAllocSizeArgs();

1349 return std::nullopt;

1350}

1351

1353 if (auto A = findEnumAttribute(Attribute::VScaleRange))

1354 return A->getVScaleRangeMin();

1355 return 1;

1356}

1357

1359 if (auto A = findEnumAttribute(Attribute::VScaleRange))

1360 return A->getVScaleRangeMax();

1361 return std::nullopt;

1362}

1363

1365 if (auto A = findEnumAttribute(Attribute::UWTable))

1366 return A->getUWTableKind();

1368}

1369

1371 if (auto A = findEnumAttribute(Attribute::AllocKind))

1372 return A->getAllocKind();

1374}

1375

1377 if (auto A = findEnumAttribute(Attribute::Memory))

1378 return A->getMemoryEffects();

1380}

1381

1383 if (auto A = findEnumAttribute(Attribute::Captures))

1384 return A->getCaptureInfo();

1386}

1387

1389 if (auto A = findEnumAttribute(Attribute::NoFPClass))

1390 return A->getNoFPClass();

1392}

1393

1395 std::string Str;

1398 Str += ' ';

1399 Str += I->getAsString(InAttrGrp);

1400 }

1401 return Str;

1402}

1403

1404

1405

1406

1407

1408

1409

1411 return Index + 1;

1412}

1413

1415 : NumAttrSets(Sets.size()) {

1416 assert(!Sets.empty() && "pointless AttributeListImpl");

1417

1418

1419 llvm::copy(Sets, getTrailingObjects());

1420

1421

1422

1424 if (I.isStringAttribute())

1425 AvailableFunctionAttrs.addAttribute(I.getKindAsEnum());

1426

1427 for (const auto &Set : Sets)

1428 for (const auto &I : Set)

1429 if (I.isStringAttribute())

1430 AvailableSomewhereAttrs.addAttribute(I.getKindAsEnum());

1431}

1432

1435}

1436

1439 for (const auto &Set : Sets)

1440 ID.AddPointer(Set.SetNode);

1441}

1442

1444 unsigned *Index) const {

1445 if (!AvailableSomewhereAttrs.hasAttribute(Kind))

1446 return false;

1447

1448 if (Index) {

1449 for (unsigned I = 0, E = NumAttrSets; I != E; ++I) {

1450 if (begin()[I].hasAttribute(Kind)) {

1451 *Index = I - 1;

1452 break;

1453 }

1454 }

1455 }

1456

1457 return true;

1458}

1459

1460

1461#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)

1464}

1465#endif

1466

1467

1468

1469

1470

1473 assert(!AttrSets.empty() && "pointless AttributeListImpl");

1474

1478

1479 void *InsertPoint;

1481 pImpl->AttrsLists.FindNodeOrInsertPos(ID, InsertPoint);

1482

1483

1484

1485 if (!PA) {

1486

1488 AttributeListImpl::totalSizeToAlloc(AttrSets.size()),

1491 pImpl->AttrsLists.InsertNode(PA, InsertPoint);

1492 }

1493

1494

1496}

1497

1500 ArrayRef<std::pair<unsigned, Attribute>> Attrs) {

1501

1502 if (Attrs.empty())

1503 return {};

1504

1506 "Misordered Attributes list!");

1508 [](const std::pair<unsigned, Attribute> &Pair) {

1509 return Pair.second.isValid();

1510 }) &&

1511 "Pointless attribute!");

1512

1513

1514

1516 for (ArrayRef<std::pair<unsigned, Attribute>>::iterator I = Attrs.begin(),

1517 E = Attrs.end(); I != E; ) {

1518 unsigned Index = I->first;

1520 while (I != E && I->first == Index) {

1522 ++I;

1523 }

1524

1526 }

1527

1528 return get(C, AttrPairVec);

1529}

1530

1533 ArrayRef<std::pair<unsigned, AttributeSet>> Attrs) {

1534

1535 if (Attrs.empty())

1536 return {};

1537

1539 "Misordered Attributes list!");

1541 [](const std::pair<unsigned, AttributeSet> &Pair) {

1542 return !Pair.second.hasAttributes();

1543 }) &&

1544 "Pointless attribute!");

1545

1546 unsigned MaxIndex = Attrs.back().first;

1547

1548

1549 if (MaxIndex == FunctionIndex && Attrs.size() > 1)

1550 MaxIndex = Attrs[Attrs.size() - 2].first;

1551

1553 for (const auto &Pair : Attrs)

1555

1556 return getImpl(C, AttrVec);

1557}

1558

1562

1563

1564

1565 unsigned NumSets = 0;

1566 for (size_t I = ArgAttrs.size(); I != 0; --I) {

1567 if (ArgAttrs[I - 1].hasAttributes()) {

1568 NumSets = I + 2;

1569 break;

1570 }

1571 }

1572 if (NumSets == 0) {

1573

1574

1576 NumSets = 2;

1578 NumSets = 1;

1579 }

1580

1581

1582 if (NumSets == 0)

1583 return {};

1584

1586 AttrSets.reserve(NumSets);

1587

1589 if (NumSets > 1)

1591 if (NumSets > 2) {

1592

1593 ArgAttrs = ArgAttrs.take_front(NumSets - 2);

1595 }

1596

1597 return getImpl(C, AttrSets);

1598}

1599

1602 if (!Attrs.hasAttributes())

1603 return {};

1606 AttrSets[Index] = Attrs;

1607 return getImpl(C, AttrSets);

1608}

1609

1613}

1614

1618 for (const auto K : Kinds)

1620 return get(C, Attrs);

1621}

1622

1626 assert(Kinds.size() == Values.size() && "Mismatched attribute values.");

1628 auto VI = Values.begin();

1629 for (const auto K : Kinds)

1631 return get(C, Attrs);

1632}

1633

1637 for (const auto &K : Kinds)

1639 return get(C, Attrs);

1640}

1641

1644 if (Attrs.empty())

1645 return {};

1646 if (Attrs.size() == 1)

1647 return Attrs[0];

1648

1649 unsigned MaxSize = 0;

1650 for (const auto &List : Attrs)

1651 MaxSize = std::max(MaxSize, List.getNumAttrSets());

1652

1653

1654 if (MaxSize == 0)

1655 return {};

1656

1658 for (unsigned I = 0; I < MaxSize; ++I) {

1660 for (const auto &List : Attrs)

1663 }

1664

1665 return getImpl(C, NewAttrSets);

1666}

1667

1672 if (Attrs.hasAttribute(Kind))

1673 return *this;

1674

1678}

1679

1684 B.addAttribute(Kind, Value);

1686}

1687

1691 B.addAttribute(A);

1693}

1694

1696 unsigned Index,

1700 if (Index >= AttrSets.size())

1701 AttrSets.resize(Index + 1);

1702 AttrSets[Index] = Attrs;

1703

1704

1705 while (!AttrSets.empty() && !AttrSets.back().hasAttributes())

1706 AttrSets.pop_back();

1707 if (AttrSets.empty())

1708 return {};

1709 return AttributeList::getImpl(C, AttrSets);

1710}

1711

1713 unsigned Index,

1715 if (B.hasAttributes())

1716 return *this;

1717

1718 if (!pImpl)

1720

1722 Merged.merge(B);

1724}

1725

1730

1733 if (MaxIndex >= AttrSets.size())

1734 AttrSets.resize(MaxIndex + 1);

1735

1736 for (unsigned ArgNo : ArgNos) {

1739 B.addAttribute(A);

1741 }

1742

1743 return getImpl(C, AttrSets);

1744}

1745

1750 AttributeSet NewAttrs = Attrs.removeAttribute(C, Kind);

1751 if (Attrs == NewAttrs)

1752 return *this;

1753 return setAttributesAtIndex(C, Index, NewAttrs);

1754}

1755

1757 unsigned Index,

1760 AttributeSet NewAttrs = Attrs.removeAttribute(C, Kind);

1761 if (Attrs == NewAttrs)

1762 return *this;

1763 return setAttributesAtIndex(C, Index, NewAttrs);

1764}

1765

1769 AttributeSet NewAttrs = Attrs.removeAttributes(C, AttrsToRemove);

1770

1771 if (Attrs == NewAttrs)

1772 return *this;

1773 return setAttributesAtIndex(C, Index, NewAttrs);

1774}

1775

1778 unsigned WithoutIndex) const {

1779 if (!pImpl)

1780 return {};

1782 return *this;

1783 return setAttributesAtIndex(C, WithoutIndex, AttributeSet());

1784}

1785

1789 B.addDereferenceableAttr(Bytes);

1791}

1792

1794 unsigned Index,

1797 B.addDereferenceableAttr(Bytes);

1799}

1800

1805 B.addDereferenceableOrNullAttr(Bytes);

1807}

1808

1812 B.addRangeAttr(CR);

1814}

1815

1817 LLVMContext &C, unsigned Index, unsigned ElemSizeArg,

1818 const std::optional &NumElemsArg) const {

1820 B.addAllocSizeAttr(ElemSizeArg, NumElemsArg);

1822}

1823

1824std::optional

1826

1827 if (*this == Other)

1828 return *this;

1829

1831 auto IndexIt =

1833 for (unsigned Idx : IndexIt) {

1834 auto IntersectedAS =

1836

1837 if (!IntersectedAS)

1838 return std::nullopt;

1839 if (!IntersectedAS->hasAttributes())

1840 continue;

1841 IntersectedAttrs.push_back(std::make_pair(Idx, *IntersectedAS));

1842 }

1843

1846}

1847

1848

1849

1850

1851

1854}

1855

1858}

1859

1862}

1863

1867}

1868

1871}

1872

1875}

1876

1878 return pImpl && pImpl->hasFnAttribute(Kind);

1879}

1880

1883}

1884

1886 unsigned *Index) const {

1887 return pImpl && pImpl->hasAttrSomewhere(Attr, Index);

1888}

1889

1893}

1894

1898}

1899

1902}

1903

1906}

1907

1910}

1911

1914}

1915

1918}

1919

1922}

1923

1926}

1927

1930}

1931

1934}

1935

1938}

1939

1942}

1943

1946}

1947

1950}

1951

1954}

1955

1959}

1960

1961std::optional

1964 if (RangeAttr.isValid())

1965 return RangeAttr.getRange();

1966 return std::nullopt;

1967}

1968

1971}

1972

1975}

1976

1979}

1980

1983}

1984

1987}

1988

1991}

1992

1996 return {};

1997 return pImpl->begin()[Index];

1998}

1999

2001 assert(isEmpty() && "an empty attribute list has no parent context");

2003 pImpl->Profile(ID);

2004 void *Unused;

2005 return C.pImpl->AttrsLists.FindNodeOrInsertPos(ID, Unused) == pImpl;

2006}

2007

2009 return pImpl ? pImpl->begin() : nullptr;

2010}

2011

2013 return pImpl ? pImpl->end() : nullptr;

2014}

2015

2016

2017

2018

2019

2021 return pImpl ? pImpl->NumAttrSets : 0;

2022}

2023

2025 O << "AttributeList[\n";

2026

2027 for (unsigned i : indexes()) {

2029 continue;

2030 O << " { ";

2031 switch (i) {

2033 O << "return";

2034 break;

2036 O << "function";

2037 break;

2038 default:

2040 }

2041 O << " => " << getAsString(i) << " }\n";

2042 }

2043

2044 O << "]\n";

2045}

2046

2047#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)

2049#endif

2050

2051

2052

2053

2054

2057 assert(is_sorted(Attrs) && "AttributeSet should be sorted");

2058}

2059

2061

2062

2063

2068 if (A0IsString) {

2069 if (A1IsString)

2071 else

2072 return false;

2073 }

2074 if (A1IsString)

2075 return true;

2077 }

2080 return false;

2082 }

2086 return true;

2087 }

2088};

2089

2090template

2094 if (It != Attrs.end() && It->hasAttribute(Kind))

2096 else

2097 Attrs.insert(It, Attr);

2098}

2099

2103 else

2105 return *this;

2106}

2107

2110 return *this;

2111}

2112

2115 return *this;

2116}

2117

2121 if (It != Attrs.end() && It->hasAttribute(Val))

2122 Attrs.erase(It);

2123 return *this;

2124}

2125

2128 if (It != Attrs.end() && It->hasAttribute(A))

2129 Attrs.erase(It);

2130 return *this;

2131}

2132

2133std::optional<uint64_t>

2137 if (A.isValid())

2138 return A.getValueAsInt();

2139 return std::nullopt;

2140}

2141

2145}

2146

2147std::optional<std::pair<unsigned, std::optional>>

2150 if (A.isValid())

2151 return A.getAllocSizeArgs();

2152 return std::nullopt;

2153}

2154

2157 return *this;

2158

2161}

2162

2164

2166 return *this;

2167

2168 assert(*Align <= 0x100 && "Alignment too large.");

2170}

2171

2173 if (Bytes == 0) return *this;

2174

2175 return addRawIntAttr(Attribute::Dereferenceable, Bytes);

2176}

2177

2179 if (Bytes == 0)

2180 return *this;

2181

2182 return addRawIntAttr(Attribute::DereferenceableOrNull, Bytes);

2183}

2184

2187 const std::optional &NumElems) {

2189}

2190

2192

2193 assert(RawArgs && "Invalid allocsize arguments -- given allocsize(0, 0)");

2194 return addRawIntAttr(Attribute::AllocSize, RawArgs);

2195}

2196

2198 std::optional MaxValue) {

2200}

2201

2203

2204 if (RawArgs == 0)

2205 return *this;

2206

2207 return addRawIntAttr(Attribute::VScaleRange, RawArgs);

2208}

2209

2212 return *this;

2214}

2215

2218}

2219

2222}

2223

2226 return *this;

2227

2228 return addRawIntAttr(Attribute::NoFPClass, Mask);

2229}

2230

2233}

2234

2238 return A.isValid() ? A.getValueAsType() : nullptr;

2239}

2240

2243}

2244

2246 return addTypeAttr(Attribute::ByVal, Ty);

2247}

2248

2250 return addTypeAttr(Attribute::StructRet, Ty);

2251}

2252

2254 return addTypeAttr(Attribute::ByRef, Ty);

2255}

2256

2258 return addTypeAttr(Attribute::Preallocated, Ty);

2259}

2260

2262 return addTypeAttr(Attribute::InAlloca, Ty);

2263}

2264

2268 return *this;

2269

2271}

2272

2275}

2276

2281}

2282

2285}

2286

2288

2289 for (const auto &I : B.attrs())

2291

2292 return *this;

2293}

2294

2297 return *this;

2298}

2299

2302}

2303

2307 if (It != Attrs.end() && It->hasAttribute(A))

2308 return *It;

2309 return {};

2310}

2311

2314 if (It != Attrs.end() && It->hasAttribute(A))

2315 return *It;

2316 return {};

2317}

2318

2321 if (RangeAttr.isValid())

2322 return RangeAttr.getRange();

2323 return std::nullopt;

2324}

2325

2328}

2329

2332}

2333

2335 return Attrs == B.Attrs;

2336}

2337

2338

2339

2340

2341

2342

2343

2346}

2347

2348

2352

2354

2356 Incompatible.addAttribute(Attribute::AllocAlign);

2359 }

2360

2362

2364 Incompatible.addAttribute(Attribute::Range);

2365 } else {

2367 if (RangeAttr.isValid() &&

2369 Incompatible.addAttribute(Attribute::Range);

2370 }

2371

2373

2375 Incompatible.addAttribute(Attribute::NoAlias)

2381 .addAttribute(Attribute::DereferenceableOrNull)

2396 }

2397

2398

2401 Incompatible.addAttribute(Attribute::Alignment);

2402 }

2403

2406 Incompatible.addAttribute(Attribute::NoFPClass);

2407 }

2408

2409

2412 Incompatible.addAttribute(Attribute::NoUndef);

2413 }

2414

2415 return Incompatible;

2416}

2417

2421 AM.addAttribute(Attribute::Dereferenceable);

2422 AM.addAttribute(Attribute::DereferenceableOrNull);

2423 return AM;

2424}

2425

2426

2430 return true;

2431

2432

2433

2434 if (CalleeMode.Input == CallerMode.Input &&

2436 return true;

2437

2438 if (CalleeMode.Output == CallerMode.Output &&

2440 return true;

2441 return false;

2442}

2443

2445 DenormalMode CallerMode = Caller.getDenormalModeRaw();

2446 DenormalMode CalleeMode = Callee.getDenormalModeRaw();

2447

2449 DenormalMode CallerModeF32 = Caller.getDenormalModeF32Raw();

2450 DenormalMode CalleeModeF32 = Callee.getDenormalModeF32Raw();

2452 CallerModeF32 = CallerMode;

2454 CalleeModeF32 = CalleeMode;

2456 }

2457

2458 return false;

2459}

2460

2462

2463

2464 return !Callee.getAttributes().hasFnAttr(Attribute::StrictFP) ||

2465 Caller.getAttributes().hasFnAttr(Attribute::StrictFP);

2466}

2467

2468template

2470 return Caller.getFnAttribute(AttrClass::getKind()) ==

2471 Callee.getFnAttribute(AttrClass::getKind());

2472}

2473

2476 return Caller.getFnAttribute(AttrName) == Callee.getFnAttribute(AttrName);

2477}

2478

2479

2480

2481

2482

2483

2484template

2486 if (AttrClass::isSet(Caller, AttrClass::getKind()) &&

2487 !AttrClass::isSet(Callee, AttrClass::getKind()))

2488 AttrClass::set(Caller, AttrClass::getKind(), false);

2489}

2490

2491

2492

2493

2494

2495

2496template

2498 if (!AttrClass::isSet(Caller, AttrClass::getKind()) &&

2499 AttrClass::isSet(Callee, AttrClass::getKind()))

2500 AttrClass::set(Caller, AttrClass::getKind(), true);

2501}

2502

2503

2504

2506

2507

2508

2509 if (!Caller.hasStackProtectorFnAttr())

2510 return;

2511

2512

2513

2514

2516 OldSSPAttr.addAttribute(Attribute::StackProtect)

2517 .addAttribute(Attribute::StackProtectStrong)

2519

2520 if (Callee.hasFnAttribute(Attribute::StackProtectReq)) {

2521 Caller.removeFnAttrs(OldSSPAttr);

2522 Caller.addFnAttr(Attribute::StackProtectReq);

2523 } else if (Callee.hasFnAttribute(Attribute::StackProtectStrong) &&

2524 !Caller.hasFnAttribute(Attribute::StackProtectReq)) {

2525 Caller.removeFnAttrs(OldSSPAttr);

2526 Caller.addFnAttr(Attribute::StackProtectStrong);

2527 } else if (Callee.hasFnAttribute(Attribute::StackProtect) &&

2528 !Caller.hasFnAttribute(Attribute::StackProtectReq) &&

2529 !Caller.hasFnAttribute(Attribute::StackProtectStrong))

2530 Caller.addFnAttr(Attribute::StackProtect);

2531}

2532

2533

2534

2536 if (!Caller.hasFnAttribute("probe-stack") &&

2537 Callee.hasFnAttribute("probe-stack")) {

2538 Caller.addFnAttr(Callee.getFnAttribute("probe-stack"));

2539 }

2540}

2541

2542

2543

2544

2545static void

2547 Attribute CalleeAttr = Callee.getFnAttribute("stack-probe-size");

2548 if (CalleeAttr.isValid()) {

2549 Attribute CallerAttr = Caller.getFnAttribute("stack-probe-size");

2550 if (CallerAttr.isValid()) {

2551 uint64_t CallerStackProbeSize, CalleeStackProbeSize;

2554

2555 if (CallerStackProbeSize > CalleeStackProbeSize) {

2556 Caller.addFnAttr(CalleeAttr);

2557 }

2558 } else {

2559 Caller.addFnAttr(CalleeAttr);

2560 }

2561 }

2562}

2563

2564

2565

2566

2567

2568

2569

2570

2571

2572

2573static void

2575 Attribute CallerAttr = Caller.getFnAttribute("min-legal-vector-width");

2576 if (CallerAttr.isValid()) {

2577 Attribute CalleeAttr = Callee.getFnAttribute("min-legal-vector-width");

2578 if (CalleeAttr.isValid()) {

2579 uint64_t CallerVectorWidth, CalleeVectorWidth;

2582 if (CallerVectorWidth < CalleeVectorWidth)

2583 Caller.addFnAttr(CalleeAttr);

2584 } else {

2585

2586

2587 Caller.removeFnAttr("min-legal-vector-width");

2588 }

2589 }

2590}

2591

2592

2593

2594static void

2596 if (Callee.nullPointerIsDefined() && !Caller.nullPointerIsDefined()) {

2597 Caller.addFnAttr(Attribute::NullPointerIsValid);

2598 }

2599}

2600

2605 }

2606

2609 if (Val)

2611 else

2613 }

2614};

2615

2620 return A.getValueAsString() == "true";

2621 }

2622

2625 Fn.addFnAttr(Kind, Val ? "true" : "false");

2626 }

2627};

2628

2629#define GET_ATTR_NAMES

2630#define ATTRIBUTE_ENUM(ENUM_NAME, DISPLAY_NAME) \

2631 struct ENUM_NAME##Attr : EnumAttr { \

2632 static enum Attribute::AttrKind getKind() { \

2633 return llvm::Attribute::ENUM_NAME; \

2634 } \

2635 };

2636#define ATTRIBUTE_STRBOOL(ENUM_NAME, DISPLAY_NAME) \

2637 struct ENUM_NAME##Attr : StrBoolAttr { \

2638 static StringRef getKind() { return #DISPLAY_NAME; } \

2639 };

2640#include "llvm/IR/Attributes.inc"

2641

2642#define GET_ATTR_COMPAT_FUNC

2643#include "llvm/IR/Attributes.inc"

2644

2647 return hasCompatibleFnAttrs(Caller, Callee);

2648}

2649

2652 return hasCompatibleFnAttrs(A, B);

2653}

2654

2657 mergeFnAttrs(Caller, Callee);

2658}

2659

2662

2663

2664

2665

2666

2667

2668

2669

2670 mergeFnAttrs(Base, ToMerge);

2671}

2672

2679 if (Width > OldWidth)

2680 Fn.addFnAttr("min-legal-vector-width", llvm::utostr(Width));

2681 }

2682}

This file defines various helper methods and classes used by LLVMContextImpl for creating and managin...

static void addAttributeImpl(SmallVectorImpl< Attribute > &Attrs, K Kind, Attribute Attr)

static void setAND(Function &Caller, const Function &Callee)

Compute the logical AND of the attributes of the caller and the callee.

static void adjustCallerStackProbes(Function &Caller, const Function &Callee)

If the inlined function required stack probes, then ensure that the calling function has those too.

static std::pair< unsigned, std::optional< unsigned > > unpackVScaleRangeArgs(uint64_t Value)

static void adjustMinLegalVectorWidth(Function &Caller, const Function &Callee)

If the inlined function defines a min legal vector width, then ensure the calling function has the sa...

static void adjustCallerStackProbeSize(Function &Caller, const Function &Callee)

If the inlined function defines the size of guard region on the stack, then ensure that the calling f...

static void adjustCallerSSPLevel(Function &Caller, const Function &Callee)

If the inlined function had a higher stack protection level than the calling function,...

static bool checkStrictFP(const Function &Caller, const Function &Callee)

static uint64_t packAllocSizeArgs(unsigned ElemSizeArg, const std::optional< unsigned > &NumElemsArg)

static uint64_t packVScaleRangeArgs(unsigned MinValue, std::optional< unsigned > MaxValue)

static bool hasIntersectProperty(Attribute::AttrKind Kind, AttributeProperty Prop)

static unsigned attrIdxToArrayIdx(unsigned Index)

Map from AttributeList index to the internal array index.

static bool denormModeCompatible(DenormalMode CallerMode, DenormalMode CalleeMode)

Callees with dynamic denormal modes are compatible with any caller mode.

static void adjustNullPointerValidAttr(Function &Caller, const Function &Callee)

If the inlined function has null_pointer_is_valid attribute, set this attribute in the caller post in...

static const unsigned AllocSizeNumElemsNotPresent

static std::pair< unsigned, std::optional< unsigned > > unpackAllocSizeArgs(uint64_t Num)

static bool checkDenormMode(const Function &Caller, const Function &Callee)

static unsigned getAttributeProperties(Attribute::AttrKind Kind)

static void setOR(Function &Caller, const Function &Callee)

Compute the logical OR of the attributes of the caller and the callee.

static bool hasAttributeProperty(Attribute::AttrKind Kind, AttributeProperty Prop)

static const char * getModRefStr(ModRefInfo MR)

This file contains the simple types necessary to represent the attributes associated with functions a...

static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")

static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")

#define LLVM_DUMP_METHOD

Mark debug helper function definitions like dump() that should not be stripped from debug builds.

Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx

This file defines a hash set that can be used to remove duplication of nodes in a graph.

assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())

This file defines the SmallVector class.

This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...

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.

AttrBuilder & addStructRetAttr(Type *Ty)

This turns a sret type into the form used internally in Attribute.

AttrBuilder & addAlignmentAttr(MaybeAlign Align)

This turns an alignment into the form used internally in Attribute.

AttrBuilder & addVScaleRangeAttrFromRawRepr(uint64_t RawVScaleRangeRepr)

Add a vscale_range attribute, using the representation returned by Attribute.getIntValue().

std::optional< uint64_t > getRawIntAttr(Attribute::AttrKind Kind) const

Return raw (possibly packed/encoded) value of integer attribute or std::nullopt if not set.

AttrBuilder & addAllocKindAttr(AllocFnKind Kind)

Attribute getAttribute(Attribute::AttrKind Kind) const

Return Attribute with the given Kind.

AttrBuilder & addByRefAttr(Type *Ty)

This turns a byref type into the form used internally in Attribute.

AttrBuilder & addNoFPClassAttr(FPClassTest NoFPClassMask)

AttrBuilder & addCapturesAttr(CaptureInfo CI)

Add captures attribute.

bool overlaps(const AttributeMask &AM) const

Return true if the builder has any attribute that's in the specified builder.

AttrBuilder & merge(const AttrBuilder &B)

Add the attributes from the builder.

AttrBuilder & addVScaleRangeAttr(unsigned MinValue, std::optional< unsigned > MaxValue)

This turns two ints into the form used internally in Attribute.

AttrBuilder(LLVMContext &Ctx)

AttrBuilder & addRawIntAttr(Attribute::AttrKind Kind, uint64_t Value)

Add integer attribute with raw value (packed/encoded if necessary).

AttrBuilder & addAttribute(Attribute::AttrKind Val)

Add an attribute to the builder.

AttrBuilder & addByValAttr(Type *Ty)

This turns a byval type into the form used internally in Attribute.

AttrBuilder & addDereferenceableAttr(uint64_t Bytes)

This turns the number of dereferenceable bytes into the form used internally in Attribute.

AttrBuilder & addInitializesAttr(const ConstantRangeList &CRL)

Add initializes attribute.

bool contains(Attribute::AttrKind A) const

Return true if the builder has the specified attribute.

AttrBuilder & addMemoryAttr(MemoryEffects ME)

Add memory effect attribute.

AttrBuilder & addConstantRangeListAttr(Attribute::AttrKind Kind, ArrayRef< ConstantRange > Val)

Add a ConstantRangeList attribute with the given ranges.

AttrBuilder & addConstantRangeAttr(Attribute::AttrKind Kind, const ConstantRange &CR)

Add a ConstantRange attribute with the given range.

AttrBuilder & addAllocSizeAttrFromRawRepr(uint64_t RawAllocSizeRepr)

Add an allocsize attribute, using the representation returned by Attribute.getIntValue().

AttrBuilder & addPreallocatedAttr(Type *Ty)

This turns a preallocated type into the form used internally in Attribute.

AttrBuilder & addStackAlignmentAttr(MaybeAlign Align)

This turns a stack alignment into the form used internally in Attribute.

AttrBuilder & addInAllocaAttr(Type *Ty)

This turns an inalloca type into the form used internally in Attribute.

AttrBuilder & removeAttribute(Attribute::AttrKind Val)

Remove an attribute from the builder.

bool operator==(const AttrBuilder &B) const

Type * getTypeAttr(Attribute::AttrKind Kind) const

Retrieve type for the given type attribute.

AttrBuilder & remove(const AttributeMask &AM)

Remove the attributes from the builder.

std::optional< ConstantRange > getRange() const

Retrieve the range if the attribute exists (std::nullopt is returned otherwise).

AttrBuilder & addDereferenceableOrNullAttr(uint64_t Bytes)

This turns the number of dereferenceable_or_null bytes into the form used internally in Attribute.

AttrBuilder & addTypeAttr(Attribute::AttrKind Kind, Type *Ty)

Add a type attribute with the given type.

std::optional< std::pair< unsigned, std::optional< unsigned > > > getAllocSizeArgs() const

Retrieve the allocsize args, or std::nullopt if the attribute does not exist.

AttrBuilder & addAllocSizeAttr(unsigned ElemSizeArg, const std::optional< unsigned > &NumElemsArg)

This turns one (or two) ints into the form used internally in Attribute.

AttrBuilder & addRangeAttr(const ConstantRange &CR)

Add range attribute.

AttrBuilder & addUWTableAttr(UWTableKind Kind)

This turns the unwind table kind into the form used internally in Attribute.

void addAttribute(Attribute::AttrKind Kind)

bool hasAttribute(Attribute::AttrKind Kind) const

int cmp(const AttributeImpl &AI, bool KindOnly) const

Used to sort attributes.

bool isConstantRangeAttribute() const

bool hasAttribute(Attribute::AttrKind A) const

void Profile(FoldingSetNodeID &ID) 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

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

bool hasAttrSomewhere(Attribute::AttrKind Kind, unsigned *Index=nullptr) const

Return true if the specified attribute is set for at least one parameter or for the return value.

void Profile(FoldingSetNodeID &ID) const

AttributeListImpl(ArrayRef< AttributeSet > Sets)

friend class AttributeList

bool hasAttributeAtIndex(unsigned Index, Attribute::AttrKind Kind) const

Return true if the attribute exists at the given index.

Type * getParamStructRetType(unsigned ArgNo) const

Return the sret type for the specified function parameter.

AttributeList addDereferenceableParamAttr(LLVMContext &C, unsigned ArgNo, uint64_t Bytes) const

Add the dereferenceable attribute to the attribute set at the given arg index.

AttributeList removeAttributeAtIndex(LLVMContext &C, unsigned Index, Attribute::AttrKind Kind) const

Remove the specified attribute at the specified index from this attribute list.

AttributeList addRangeRetAttr(LLVMContext &C, const ConstantRange &CR) const

Add the range attribute to the attribute set at the return value index.

bool hasAttributesAtIndex(unsigned Index) const

Return true if attribute exists at the given index.

friend class AttributeListImpl

AttributeSet getFnAttrs() const

The function attributes are returned.

index_iterator indexes() const

Use this to iterate over the valid attribute indexes.

AttributeList removeAttributesAtIndex(LLVMContext &C, unsigned Index, const AttributeMask &AttrsToRemove) const

Remove the specified attributes at the specified index from this attribute list.

friend class AttributeSet

MaybeAlign getRetStackAlignment() const

Get the stack alignment of the return value.

AttributeList addRetAttributes(LLVMContext &C, const AttrBuilder &B) const

Add a return value attribute to the list.

void print(raw_ostream &O) const

AttributeList addDereferenceableRetAttr(LLVMContext &C, uint64_t Bytes) const

Add the dereferenceable attribute to the attribute set at the given index.

static AttributeList get(LLVMContext &C, ArrayRef< std::pair< unsigned, Attribute > > Attrs)

Create an AttributeList with the specified parameters in it.

AllocFnKind getAllocKind() const

bool isEmpty() const

Return true if there are no attributes.

AttributeSet getRetAttrs() const

The attributes for the ret value are returned.

bool hasFnAttr(Attribute::AttrKind Kind) const

Return true if the attribute exists for the function.

uint64_t getParamDereferenceableBytes(unsigned Index) const

Get the number of dereferenceable bytes (or zero if unknown) of an arg.

MaybeAlign getParamAlignment(unsigned ArgNo) const

Return the alignment for the specified function parameter.

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.

Type * getParamInAllocaType(unsigned ArgNo) const

Return the inalloca type for the specified function parameter.

unsigned getNumAttrSets() const

FPClassTest getRetNoFPClass() const

Get the disallowed floating-point classes of the return value.

std::string getAsString(unsigned Index, bool InAttrGrp=false) const

Return the attributes at the index as a string.

UWTableKind getUWTableKind() const

Get the unwind table kind requested for the function.

MaybeAlign getRetAlignment() const

Return the alignment of the return value.

Type * getParamElementType(unsigned ArgNo) const

Return the elementtype type for the specified function parameter.

Attribute getAttributeAtIndex(unsigned Index, Attribute::AttrKind Kind) const

Return the attribute object that exists at the given index.

Type * getParamPreallocatedType(unsigned ArgNo) const

Return the preallocated type for the specified function parameter.

bool hasParentContext(LLVMContext &C) const

Return true if this attribute list belongs to the LLVMContext.

const AttributeSet * iterator

MaybeAlign getFnStackAlignment() const

Get the stack alignment of the function.

AttributeList addAttributesAtIndex(LLVMContext &C, unsigned Index, const AttrBuilder &B) const

Add attributes to the attribute set at the given index.

Type * getParamByValType(unsigned ArgNo) const

Return the byval type for the specified function parameter.

MaybeAlign getParamStackAlignment(unsigned ArgNo) const

Return the stack alignment for the specified function parameter.

uint64_t getRetDereferenceableBytes() const

Get the number of dereferenceable bytes (or zero if unknown) of the return value.

AttributeList addAllocSizeParamAttr(LLVMContext &C, unsigned ArgNo, unsigned ElemSizeArg, const std::optional< unsigned > &NumElemsArg) const

Add the allocsize attribute to the attribute set at the given arg index.

uint64_t getParamDereferenceableOrNullBytes(unsigned ArgNo) const

Get the number of dereferenceable_or_null bytes (or zero if unknown) of an arg.

AttributeList addDereferenceableOrNullParamAttr(LLVMContext &C, unsigned ArgNo, uint64_t Bytes) const

Add the dereferenceable_or_null attribute to the attribute set at the given arg index.

AttributeSet getAttributes(unsigned Index) const

The attributes for the specified index are returned.

FPClassTest getParamNoFPClass(unsigned ArgNo) const

Get the disallowed floating-point classes of the argument value.

std::optional< AttributeList > intersectWith(LLVMContext &C, AttributeList Other) const

Try to intersect this AttributeList with Other.

Type * getParamByRefType(unsigned ArgNo) const

Return the byref type for the specified function parameter.

AttributeList addAttributeAtIndex(LLVMContext &C, unsigned Index, Attribute::AttrKind Kind) const

Add an attribute to the attribute set at the given index.

AttributeSet getParamAttrs(unsigned ArgNo) const

The attributes for the argument or parameter at the given index are returned.

AttributeList addParamAttributes(LLVMContext &C, unsigned ArgNo, const AttrBuilder &B) const

Add an argument attribute to the list.

std::optional< ConstantRange > getParamRange(unsigned ArgNo) const

Get range (or std::nullopt if unknown) of an arg.

uint64_t getRetDereferenceableOrNullBytes() const

Get the number of dereferenceable_or_null bytes (or zero if unknown) of the return value.

AttributeList addParamAttribute(LLVMContext &C, unsigned ArgNo, Attribute::AttrKind Kind) const

Add an argument attribute to the list.

MemoryEffects getMemoryEffects() const

Returns memory effects of the function.

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

MaybeAlign getAlignment() const

MemoryEffects getMemoryEffects() const

UWTableKind getUWTableKind() const

std::optional< std::pair< unsigned, std::optional< unsigned > > > getAllocSizeArgs() const

uint64_t getDereferenceableBytes() const

unsigned getNumAttributes() const

Return the number of attributes this AttributeList contains.

void Profile(FoldingSetNodeID &ID) const

std::string getAsString(bool InAttrGrp) const

static AttributeSetNode * get(LLVMContext &C, const AttrBuilder &B)

FPClassTest getNoFPClass() const

Attribute getAttribute(Attribute::AttrKind Kind) const

AllocFnKind getAllocKind() const

bool hasAttributes() const

Return true if attributes exists in this set.

AttributeSet removeAttribute(LLVMContext &C, Attribute::AttrKind Kind) const

Remove the specified attribute from this set.

Type * getInAllocaType() const

Type * getByValType() const

AttributeSet addAttributes(LLVMContext &C, AttributeSet AS) const

Add attributes to the attribute set.

MemoryEffects getMemoryEffects() const

bool hasAttribute(Attribute::AttrKind Kind) const

Return true if the attribute exists in this set.

std::optional< AttributeSet > intersectWith(LLVMContext &C, AttributeSet Other) const

Try to intersect this AttributeSet with Other.

Type * getStructRetType() const

std::string getAsString(bool InAttrGrp=false) const

unsigned getVScaleRangeMin() const

std::optional< std::pair< unsigned, std::optional< unsigned > > > getAllocSizeArgs() const

UWTableKind getUWTableKind() const

bool hasParentContext(LLVMContext &C) const

Return true if this attribute set belongs to the LLVMContext.

AttributeSet removeAttributes(LLVMContext &C, const AttributeMask &AttrsToRemove) const

Remove the specified attributes from this set.

std::optional< unsigned > getVScaleRangeMax() const

MaybeAlign getStackAlignment() const

Attribute getAttribute(Attribute::AttrKind Kind) const

Return the attribute object.

Type * getPreallocatedType() const

uint64_t getDereferenceableBytes() const

MaybeAlign getAlignment() const

FPClassTest getNoFPClass() const

Type * getElementType() const

Type * getByRefType() const

CaptureInfo getCaptureInfo() const

AttributeSet()=default

AttributeSet is a trivially copyable value type.

static AttributeSet get(LLVMContext &C, const AttrBuilder &B)

uint64_t getDereferenceableOrNullBytes() const

unsigned getNumAttributes() const

Return the number of attributes in this set.

AttributeSet addAttribute(LLVMContext &C, Attribute::AttrKind Kind) const

Add an argument attribute.

bool isStringAttribute() const

Return true if the attribute is a string (target-dependent) attribute.

static Attribute getWithStructRetType(LLVMContext &Context, Type *Ty)

static Attribute::AttrKind getAttrKindFromName(StringRef AttrName)

bool isEnumAttribute() const

Return true if the attribute is an Attribute::AttrKind type.

static Attribute getWithStackAlignment(LLVMContext &Context, Align Alignment)

const ConstantRange & getRange() const

Returns the value of the range attribute.

static bool intersectWithCustom(AttrKind Kind)

bool isIntAttribute() const

Return true if the attribute is an integer attribute.

static Attribute getWithByRefType(LLVMContext &Context, Type *Ty)

std::optional< unsigned > getVScaleRangeMax() const

Returns the maximum value for the vscale_range attribute or std::nullopt when unknown.

uint64_t getValueAsInt() const

Return the attribute's value as an integer.

unsigned getVScaleRangeMin() const

Returns the minimum value for the vscale_range attribute.

AllocFnKind getAllocKind() const

bool isConstantRangeAttribute() const

Return true if the attribute is a ConstantRange attribute.

StringRef getKindAsString() const

Return the attribute's kind as a string.

static Attribute getWithPreallocatedType(LLVMContext &Context, Type *Ty)

static bool intersectWithMin(AttrKind Kind)

static Attribute get(LLVMContext &Context, AttrKind Kind, uint64_t Val=0)

Return a uniquified Attribute object.

static bool canUseAsRetAttr(AttrKind Kind)

static bool isTypeAttrKind(AttrKind Kind)

std::string getAsString(bool InAttrGrp=false) const

The Attribute is converted to a string of equivalent mnemonic.

uint64_t getDereferenceableOrNullBytes() const

Returns the number of dereferenceable_or_null bytes from the dereferenceable_or_null attribute.

static Attribute getWithDereferenceableBytes(LLVMContext &Context, uint64_t Bytes)

std::pair< unsigned, std::optional< unsigned > > getAllocSizeArgs() const

Returns the argument numbers for the allocsize attribute.

static Attribute getWithUWTableKind(LLVMContext &Context, UWTableKind Kind)

FPClassTest getNoFPClass() const

Return the FPClassTest for nofpclass.

static Attribute getWithAllocSizeArgs(LLVMContext &Context, unsigned ElemSizeArg, const std::optional< unsigned > &NumElemsArg)

Attribute::AttrKind getKindAsEnum() const

Return the attribute's kind as an enum (Attribute::AttrKind).

bool getValueAsBool() const

Return the attribute's value as a boolean.

ArrayRef< ConstantRange > getInitializes() const

Returns the value of the initializes attribute.

const ConstantRange & getValueAsConstantRange() const

Return the attribute's value as a ConstantRange.

uint64_t getDereferenceableBytes() const

Returns the number of dereferenceable bytes from the dereferenceable attribute.

static Attribute getWithVScaleRangeArgs(LLVMContext &Context, unsigned MinValue, unsigned MaxValue)

MemoryEffects getMemoryEffects() const

Returns memory effects.

void Profile(FoldingSetNodeID &ID) const

UWTableKind getUWTableKind() const

static Attribute getWithDereferenceableOrNullBytes(LLVMContext &Context, uint64_t Bytes)

ArrayRef< ConstantRange > getValueAsConstantRangeList() const

Return the attribute's value as a ConstantRange array.

StringRef getValueAsString() const

Return the attribute's value as a string.

static bool isExistingAttribute(StringRef Name)

Return true if the provided string matches the IR name of an attribute.

bool hasKindAsEnum() const

Returns true if the attribute's kind can be represented as an enum (Enum, Integer,...

static StringRef getNameFromAttrKind(Attribute::AttrKind AttrKind)

static bool canUseAsFnAttr(AttrKind Kind)

static bool intersectWithAnd(AttrKind Kind)

static 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)

bool hasParentContext(LLVMContext &C) const

Return true if this attribute belongs to the LLVMContext.

bool isTypeAttribute() const

Return true if the attribute is a type attribute.

static Attribute getWithInAllocaType(LLVMContext &Context, Type *Ty)

static bool isIntAttrKind(AttrKind Kind)

static bool isConstantRangeListAttrKind(AttrKind Kind)

bool isConstantRangeListAttribute() const

Return true if the attribute is a ConstantRangeList attribute.

static Attribute getWithByValType(LLVMContext &Context, Type *Ty)

bool hasAttribute(AttrKind Val) const

Return true if the attribute is present.

static bool isEnumAttrKind(AttrKind Kind)

static Attribute getWithMemoryEffects(LLVMContext &Context, MemoryEffects ME)

static bool canUseAsParamAttr(AttrKind Kind)

bool isValid() const

Return true if the attribute is any kind of attribute.

MaybeAlign getStackAlignment() const

Returns the stack alignment field of an attribute as a byte alignment value.

MaybeAlign getAlignment() const

Returns the alignment field of an attribute as a byte alignment value.

CaptureInfo getCaptureInfo() const

Returns information from captures attribute.

static bool intersectMustPreserve(AttrKind Kind)

int cmpKind(Attribute A) const

Used to sort attribute by kind.

bool operator<(Attribute A) const

Less-than operator. Useful for sorting the attributes list.

static Attribute getWithAlignment(LLVMContext &Context, Align Alignment)

Return a uniquified Attribute object that has the specific alignment set.

Type * getValueAsType() const

Return the attribute's value as a Type.

LLVM_ATTRIBUTE_RETURNS_NONNULL void * Allocate(size_t Size, Align Alignment)

Allocate space at the specified alignment.

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).

static size_t totalSizeToAlloc(ArrayRef< ConstantRange > Val)

This class represents a list of constant ranges.

ArrayRef< ConstantRange > rangesRef() const

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.

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.

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 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< AttributeImpl > AttrsSet

FoldingSet< AttributeSetNode > AttrsSetNodes

FoldingSet< AttributeListImpl > AttrsLists

SpecificBumpPtrAllocator< ConstantRangeAttributeImpl > ConstantRangeAttributeAlloc

std::vector< ConstantRangeListAttributeImpl * > ConstantRangeListAttributes

This is an important class for using LLVM in a threaded context.

LLVMContextImpl *const pImpl

ModRefInfo getModRef(Location Loc) const

Get ModRefInfo for the given Location.

static MemoryEffectsBase createFromIntValue(uint32_t Data)

Create MemoryEffectsBase from an encoded integer value (used by memory attribute).

static auto locations()

Returns iterator over all supported location kinds.

uint32_t toIntValue() const

Convert MemoryEffectsBase into an encoded integer value (used by memory attribute).

static MemoryEffectsBase unknown()

Create MemoryEffectsBase that can read and write any memory.

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.

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.

bool isIntOrIntVectorTy() const

Return true if this is an integer type or a vector of integer types.

bool isPointerTy() const

True if this is an instance of PointerType.

void print(raw_ostream &O, bool IsForDebug=false, bool NoDetails=false) const

Print the current type.

unsigned getScalarSizeInBits() const LLVM_READONLY

If this is a vector type, return the getPrimitiveSizeInBits value for the element type.

bool isPtrOrPtrVectorTy() const

Return true if this is a pointer type or a vector of pointer types.

bool isIntegerTy() const

True if this is an instance of IntegerType.

bool isVoidTy() const

Return true if this is 'void'.

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.

bool areInlineCompatible(const Function &Caller, const Function &Callee)

AttributeMask getUBImplyingAttributes()

Get param/return attributes which imply immediate undefined behavior if an invalid value is passed.

bool isNoFPClassCompatibleType(Type *Ty)

Returns true if this is a type legal for the 'nofpclass' attribute.

bool areOutlineCompatible(const Function &A, const Function &B)

Checks if there are any incompatible function attributes between A and B.

void updateMinLegalVectorWidthAttr(Function &Fn, uint64_t Width)

Update min-legal-vector-width if it is in Attribute and less than Width.

void mergeAttributesForOutlining(Function &Base, const Function &ToMerge)

Merges the functions attributes from ToMerge into function Base.

AttributeMask typeIncompatible(Type *Ty, AttributeSet AS, AttributeSafetyKind ASK=ASK_ALL)

Which attributes cannot be applied to a type.

void mergeAttributesForInlining(Function &Caller, const Function &Callee)

Merge caller's and callee's attributes.

@ C

The default llvm calling convention, compatible with C.

unsigned ID

LLVM IR allows to use arbitrary numbers as calling convention identifiers.

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)

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.

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.

void sort(IteratorTy Start, IteratorTy End)

FPClassTest

Floating-point class tests, supported by 'is_fpclass' intrinsic.

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.

@ First

Helpers to iterate all locations in the MemoryEffectsBase class.

@ InaccessibleMem

Memory that is inaccessible via LLVM IR.

auto lower_bound(R &&Range, T &&Value)

Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...

OutputIt copy(R &&Range, OutputIt Out)

void erase_if(Container &C, UnaryPredicate P)

Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...

void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)

Implement std::swap in terms of BitVector swap.

Attribute comparator that only compares attribute keys.

bool operator()(Attribute A0, StringRef Kind) const

bool operator()(Attribute A0, Attribute A1) const

bool operator()(Attribute A0, Attribute::AttrKind Kind) const

static void set(Function &Fn, Attribute::AttrKind Kind, bool Val)

static bool isSet(const Function &Fn, Attribute::AttrKind Kind)

static bool isSet(const Function &Fn, StringRef Kind)

static void set(Function &Fn, StringRef Kind, bool Val)

This struct is a compact representation of a valid (non-zero power of two) alignment.

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::...