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 && A.pImpl)

747 return 0;

748 if (!pImpl)

749 return 1;

750 if (A.pImpl)

751 return -1;

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

753}

754

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

757 if (!pImpl) return true;

758 if (A.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

938 AttrBuilder B(C);

939 B.addAttribute(Kind);

941}

942

945 AttrBuilder B(C);

946 B.addAttribute(Kind, Value);

948}

949

951 const AttributeSet AS) const {

953 return AS;

954

956 return *this;

957

958 AttrBuilder B(C, *this);

959 B.merge(AttrBuilder(C, AS));

960 return get(C, B);

961}

962

964 const AttrBuilder &B) const {

966 return get(C, B);

967

968 if (B.hasAttributes())

969 return *this;

970

971 AttrBuilder Merged(C, *this);

972 Merged.merge(B);

973 return get(C, Merged);

974}

975

979 AttrBuilder B(C, *this);

980 B.removeAttribute(Kind);

981 return get(C, B);

982}

983

987 AttrBuilder B(C, *this);

988 B.removeAttribute(Kind);

989 return get(C, B);

990}

991

994 AttrBuilder B(C, *this);

995

996 if (B.overlaps(Attrs))

997 return *this;

998

999 B.remove(Attrs);

1000 return get(C, B);

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 (I.isStringAttribute())

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

1456

1457 for (const auto &Set : Sets)

1458 for (const auto &I : Set)

1459 if (I.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 (Attrs.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)

1650 return get(C, Attrs);

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)

1661 return get(C, Attrs);

1662}

1663

1664AttributeList AttributeList::get(LLVMContext &C, unsigned Index,

1667 for (const auto &K : Kinds)

1669 return get(C, Attrs);

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,

1713 AttrBuilder B(C);

1714 B.addAttribute(Kind, Value);

1715 return addAttributesAtIndex(C, Index, B);

1716}

1717

1718AttributeList AttributeList::addAttributeAtIndex(LLVMContext &C, unsigned Index,

1720 AttrBuilder B(C);

1721 B.addAttribute(A);

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 (B.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]);

1769 B.addAttribute(A);

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 {

1818 AttrBuilder B(C);

1819 B.addDereferenceableAttr(Bytes);

1820 return addRetAttributes(C, B);

1821}

1822

1823AttributeList AttributeList::addDereferenceableParamAttr(LLVMContext &C,

1824 unsigned Index,

1825 uint64_t Bytes) const {

1826 AttrBuilder B(C);

1827 B.addDereferenceableAttr(Bytes);

1828 return addParamAttributes(C, Index, B);

1829}

1830

1831AttributeList

1832AttributeList::addDereferenceableOrNullParamAttr(LLVMContext &C, unsigned Index,

1833 uint64_t Bytes) const {

1834 AttrBuilder B(C);

1835 B.addDereferenceableOrNullAttr(Bytes);

1836 return addParamAttributes(C, Index, B);

1837}

1838

1839AttributeList AttributeList::addRangeRetAttr(LLVMContext &C,

1841 AttrBuilder B(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 {

1849 AttrBuilder B(C);

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 {

2397 return Attrs == B.Attrs;

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