LLVM: lib/IR/Intrinsics.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

16#include "llvm/IR/IntrinsicsAArch64.h"

17#include "llvm/IR/IntrinsicsAMDGPU.h"

18#include "llvm/IR/IntrinsicsARM.h"

19#include "llvm/IR/IntrinsicsBPF.h"

20#include "llvm/IR/IntrinsicsHexagon.h"

21#include "llvm/IR/IntrinsicsLoongArch.h"

22#include "llvm/IR/IntrinsicsMips.h"

23#include "llvm/IR/IntrinsicsNVPTX.h"

24#include "llvm/IR/IntrinsicsPowerPC.h"

25#include "llvm/IR/IntrinsicsR600.h"

26#include "llvm/IR/IntrinsicsRISCV.h"

27#include "llvm/IR/IntrinsicsS390.h"

28#include "llvm/IR/IntrinsicsVE.h"

29#include "llvm/IR/IntrinsicsX86.h"

30#include "llvm/IR/IntrinsicsXCore.h"

33

34using namespace llvm;

35

36

37#define GET_INTRINSIC_NAME_TABLE

38#include "llvm/IR/IntrinsicImpl.inc"

39#undef GET_INTRINSIC_NAME_TABLE

40

42 assert(id < num_intrinsics && "Invalid intrinsic ID!");

43 return IntrinsicNameTable + IntrinsicNameOffsetTable[id];

44}

45

47 assert(id < num_intrinsics && "Invalid intrinsic ID!");

49 "This version of getName does not support overloading");

51}

52

53

54

55

56

57

58

59

60

61

62

63

64

66 std::string Result;

67 if (PointerType *PTyp = dyn_cast(Ty)) {

68 Result += "p" + utostr(PTyp->getAddressSpace());

69 } else if (ArrayType *ATyp = dyn_cast(Ty)) {

70 Result += "a" + utostr(ATyp->getNumElements()) +

72 } else if (StructType *STyp = dyn_cast(Ty)) {

73 if (!STyp->isLiteral()) {

74 Result += "s_";

75 if (STyp->hasName())

76 Result += STyp->getName();

77 else

78 HasUnnamedType = true;

79 } else {

80 Result += "sl_";

81 for (auto *Elem : STyp->elements())

83 }

84

85 Result += "s";

86 } else if (FunctionType *FT = dyn_cast(Ty)) {

87 Result += "f_" + getMangledTypeStr(FT->getReturnType(), HasUnnamedType);

88 for (size_t i = 0; i < FT->getNumParams(); i++)

90 if (FT->isVarArg())

91 Result += "vararg";

92

93 Result += "f";

94 } else if (VectorType *VTy = dyn_cast(Ty)) {

96 if (EC.isScalable())

97 Result += "nx";

98 Result += "v" + utostr(EC.getKnownMinValue()) +

100 } else if (TargetExtType *TETy = dyn_cast(Ty)) {

101 Result += "t";

102 Result += TETy->getName();

103 for (Type *ParamTy : TETy->type_params())

105 for (unsigned IntParam : TETy->int_params())

106 Result += "_" + utostr(IntParam);

107

108 Result += "t";

109 } else if (Ty) {

111 default:

114 Result += "isVoid";

115 break;

117 Result += "Metadata";

118 break;

120 Result += "f16";

121 break;

123 Result += "bf16";

124 break;

126 Result += "f32";

127 break;

129 Result += "f64";

130 break;

132 Result += "f80";

133 break;

135 Result += "f128";

136 break;

138 Result += "ppcf128";

139 break;

141 Result += "x86amx";

142 break;

144 Result += "i" + utostr(cast(Ty)->getBitWidth());

145 break;

146 }

147 }

148 return Result;

149}

150

153 bool EarlyModuleCheck) {

154

155 assert(Id < Intrinsic::num_intrinsics && "Invalid intrinsic ID!");

157 "This version of getName is for overloaded intrinsics only");

158 (void)EarlyModuleCheck;

159 assert((!EarlyModuleCheck || M ||

160 any\_of(Tys, [](Type *T) { return isa(T); })) &&

161 "Intrinsic overloading on pointer types need to provide a Module");

162 bool HasUnnamedType = false;

164 for (Type *Ty : Tys)

166 if (HasUnnamedType) {

167 assert(M && "unnamed types need a module");

168 if (!FT)

170 else

172 "Provided FunctionType must match arguments");

173 return M->getUniqueIntrinsicName(Result, Id, FT);

174 }

175 return Result;

176}

177

180 assert(M && "We need to have a Module");

182}

183

186}

187

188

189

190

191

193#define GET_INTRINSIC_IITINFO

194#include "llvm/IR/IntrinsicImpl.inc"

195#undef GET_INTRINSIC_IITINFO

196};

197

198static void

202 using namespace Intrinsic;

203

204 bool IsScalableVector = (LastInfo == IIT_SCALABLE_VEC);

205

207 unsigned StructElts = 2;

208

209 switch (Info) {

210 case IIT_Done:

211 OutputTable.push_back(IITDescriptor::get(IITDescriptor::Void, 0));

212 return;

213 case IIT_VARARG:

214 OutputTable.push_back(IITDescriptor::get(IITDescriptor::VarArg, 0));

215 return;

216 case IIT_MMX:

217 OutputTable.push_back(IITDescriptor::get(IITDescriptor::MMX, 0));

218 return;

219 case IIT_AMX:

220 OutputTable.push_back(IITDescriptor::get(IITDescriptor::AMX, 0));

221 return;

222 case IIT_TOKEN:

223 OutputTable.push_back(IITDescriptor::get(IITDescriptor::Token, 0));

224 return;

225 case IIT_METADATA:

226 OutputTable.push_back(IITDescriptor::get(IITDescriptor::Metadata, 0));

227 return;

228 case IIT_F16:

229 OutputTable.push_back(IITDescriptor::get(IITDescriptor::Half, 0));

230 return;

231 case IIT_BF16:

232 OutputTable.push_back(IITDescriptor::get(IITDescriptor::BFloat, 0));

233 return;

234 case IIT_F32:

235 OutputTable.push_back(IITDescriptor::get(IITDescriptor::Float, 0));

236 return;

237 case IIT_F64:

238 OutputTable.push_back(IITDescriptor::get(IITDescriptor::Double, 0));

239 return;

240 case IIT_F128:

241 OutputTable.push_back(IITDescriptor::get(IITDescriptor::Quad, 0));

242 return;

243 case IIT_PPCF128:

244 OutputTable.push_back(IITDescriptor::get(IITDescriptor::PPCQuad, 0));

245 return;

246 case IIT_I1:

247 OutputTable.push_back(IITDescriptor::get(IITDescriptor::Integer, 1));

248 return;

249 case IIT_I2:

250 OutputTable.push_back(IITDescriptor::get(IITDescriptor::Integer, 2));

251 return;

252 case IIT_I4:

253 OutputTable.push_back(IITDescriptor::get(IITDescriptor::Integer, 4));

254 return;

255 case IIT_AARCH64_SVCOUNT:

256 OutputTable.push_back(IITDescriptor::get(IITDescriptor::AArch64Svcount, 0));

257 return;

258 case IIT_I8:

259 OutputTable.push_back(IITDescriptor::get(IITDescriptor::Integer, 8));

260 return;

261 case IIT_I16:

262 OutputTable.push_back(IITDescriptor::get(IITDescriptor::Integer, 16));

263 return;

264 case IIT_I32:

265 OutputTable.push_back(IITDescriptor::get(IITDescriptor::Integer, 32));

266 return;

267 case IIT_I64:

268 OutputTable.push_back(IITDescriptor::get(IITDescriptor::Integer, 64));

269 return;

270 case IIT_I128:

271 OutputTable.push_back(IITDescriptor::get(IITDescriptor::Integer, 128));

272 return;

273 case IIT_V1:

274 OutputTable.push_back(IITDescriptor::getVector(1, IsScalableVector));

276 return;

277 case IIT_V2:

278 OutputTable.push_back(IITDescriptor::getVector(2, IsScalableVector));

280 return;

281 case IIT_V3:

282 OutputTable.push_back(IITDescriptor::getVector(3, IsScalableVector));

284 return;

285 case IIT_V4:

286 OutputTable.push_back(IITDescriptor::getVector(4, IsScalableVector));

288 return;

289 case IIT_V6:

290 OutputTable.push_back(IITDescriptor::getVector(6, IsScalableVector));

292 return;

293 case IIT_V8:

294 OutputTable.push_back(IITDescriptor::getVector(8, IsScalableVector));

296 return;

297 case IIT_V10:

298 OutputTable.push_back(IITDescriptor::getVector(10, IsScalableVector));

300 return;

301 case IIT_V16:

302 OutputTable.push_back(IITDescriptor::getVector(16, IsScalableVector));

304 return;

305 case IIT_V32:

306 OutputTable.push_back(IITDescriptor::getVector(32, IsScalableVector));

308 return;

309 case IIT_V64:

310 OutputTable.push_back(IITDescriptor::getVector(64, IsScalableVector));

312 return;

313 case IIT_V128:

314 OutputTable.push_back(IITDescriptor::getVector(128, IsScalableVector));

316 return;

317 case IIT_V256:

318 OutputTable.push_back(IITDescriptor::getVector(256, IsScalableVector));

320 return;

321 case IIT_V512:

322 OutputTable.push_back(IITDescriptor::getVector(512, IsScalableVector));

324 return;

325 case IIT_V1024:

326 OutputTable.push_back(IITDescriptor::getVector(1024, IsScalableVector));

328 return;

329 case IIT_EXTERNREF:

330 OutputTable.push_back(IITDescriptor::get(IITDescriptor::Pointer, 10));

331 return;

332 case IIT_FUNCREF:

333 OutputTable.push_back(IITDescriptor::get(IITDescriptor::Pointer, 20));

334 return;

335 case IIT_PTR:

336 OutputTable.push_back(IITDescriptor::get(IITDescriptor::Pointer, 0));

337 return;

338 case IIT_ANYPTR:

340 IITDescriptor::get(IITDescriptor::Pointer, Infos[NextElt++]));

341 return;

342 case IIT_ARG: {

343 unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);

344 OutputTable.push_back(IITDescriptor::get(IITDescriptor::Argument, ArgInfo));

345 return;

346 }

347 case IIT_EXTEND_ARG: {

348 unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);

350 IITDescriptor::get(IITDescriptor::ExtendArgument, ArgInfo));

351 return;

352 }

353 case IIT_TRUNC_ARG: {

354 unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);

356 IITDescriptor::get(IITDescriptor::TruncArgument, ArgInfo));

357 return;

358 }

359 case IIT_HALF_VEC_ARG: {

360 unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);

362 IITDescriptor::get(IITDescriptor::HalfVecArgument, ArgInfo));

363 return;

364 }

365 case IIT_SAME_VEC_WIDTH_ARG: {

366 unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);

368 IITDescriptor::get(IITDescriptor::SameVecWidthArgument, ArgInfo));

369 return;

370 }

371 case IIT_VEC_OF_ANYPTRS_TO_ELT: {

372 unsigned short ArgNo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);

373 unsigned short RefNo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);

375 IITDescriptor::get(IITDescriptor::VecOfAnyPtrsToElt, ArgNo, RefNo));

376 return;

377 }

378 case IIT_EMPTYSTRUCT:

379 OutputTable.push_back(IITDescriptor::get(IITDescriptor::Struct, 0));

380 return;

381 case IIT_STRUCT9:

382 ++StructElts;

383 [[fallthrough]];

384 case IIT_STRUCT8:

385 ++StructElts;

386 [[fallthrough]];

387 case IIT_STRUCT7:

388 ++StructElts;

389 [[fallthrough]];

390 case IIT_STRUCT6:

391 ++StructElts;

392 [[fallthrough]];

393 case IIT_STRUCT5:

394 ++StructElts;

395 [[fallthrough]];

396 case IIT_STRUCT4:

397 ++StructElts;

398 [[fallthrough]];

399 case IIT_STRUCT3:

400 ++StructElts;

401 [[fallthrough]];

402 case IIT_STRUCT2: {

404 IITDescriptor::get(IITDescriptor::Struct, StructElts));

405

406 for (unsigned i = 0; i != StructElts; ++i)

408 return;

409 }

410 case IIT_SUBDIVIDE2_ARG: {

411 unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);

413 IITDescriptor::get(IITDescriptor::Subdivide2Argument, ArgInfo));

414 return;

415 }

416 case IIT_SUBDIVIDE4_ARG: {

417 unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);

419 IITDescriptor::get(IITDescriptor::Subdivide4Argument, ArgInfo));

420 return;

421 }

422 case IIT_VEC_ELEMENT: {

423 unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);

425 IITDescriptor::get(IITDescriptor::VecElementArgument, ArgInfo));

426 return;

427 }

428 case IIT_SCALABLE_VEC: {

430 return;

431 }

432 case IIT_VEC_OF_BITCASTS_TO_INT: {

433 unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);

435 IITDescriptor::get(IITDescriptor::VecOfBitcastsToInt, ArgInfo));

436 return;

437 }

438 }

440}

441

442#define GET_INTRINSIC_GENERATOR_GLOBAL

443#include "llvm/IR/IntrinsicImpl.inc"

444#undef GET_INTRINSIC_GENERATOR_GLOBAL

445

448 static_assert(sizeof(IIT_Table[0]) == 2,

449 "Expect 16-bit entries in IIT_Table");

450

451 uint16_t TableVal = IIT_Table[id - 1];

452

453

456 unsigned NextElt = 0;

457 if (TableVal >> 15) {

458

459 IITEntries = IIT_LongEncodingTable;

460

461

462 NextElt = TableVal & 0x7fff;

463 } else {

464

465

466 do {

467 IITValues.push_back(TableVal & 0xF);

468 TableVal >>= 4;

469 } while (TableVal);

470

471 IITEntries = IITValues;

472 NextElt = 0;

473 }

474

475

477 while (NextElt != IITEntries.size() && IITEntries[NextElt] != 0)

479}

480

483 using namespace Intrinsic;

484

485 IITDescriptor D = Infos.front();

486 Infos = Infos.slice(1);

487

488 switch (D.Kind) {

489 case IITDescriptor::Void:

491 case IITDescriptor::VarArg:

493 case IITDescriptor::MMX:

495 case IITDescriptor::AMX:

497 case IITDescriptor::Token:

499 case IITDescriptor::Metadata:

501 case IITDescriptor::Half:

503 case IITDescriptor::BFloat:

505 case IITDescriptor::Float:

507 case IITDescriptor::Double:

509 case IITDescriptor::Quad:

511 case IITDescriptor::PPCQuad:

513 case IITDescriptor::AArch64Svcount:

515

516 case IITDescriptor::Integer:

518 case IITDescriptor::Vector:

519 return VectorType::get(DecodeFixedType(Infos, Tys, Context),

520 D.Vector_Width);

521 case IITDescriptor::Pointer:

522 return PointerType::get(Context, D.Pointer_AddressSpace);

523 case IITDescriptor::Struct: {

525 for (unsigned i = 0, e = D.Struct_NumElements; i != e; ++i)

528 }

529 case IITDescriptor::Argument:

530 return Tys[D.getArgumentNumber()];

531 case IITDescriptor::ExtendArgument: {

532 Type *Ty = Tys[D.getArgumentNumber()];

533 if (VectorType *VTy = dyn_cast(Ty))

534 return VectorType::getExtendedElementVectorType(VTy);

535

537 }

538 case IITDescriptor::TruncArgument: {

539 Type *Ty = Tys[D.getArgumentNumber()];

540 if (VectorType *VTy = dyn_cast(Ty))

541 return VectorType::getTruncatedElementVectorType(VTy);

542

543 IntegerType *ITy = cast(Ty);

546 }

547 case IITDescriptor::Subdivide2Argument:

548 case IITDescriptor::Subdivide4Argument: {

549 Type *Ty = Tys[D.getArgumentNumber()];

550 VectorType *VTy = dyn_cast(Ty);

551 assert(VTy && "Expected an argument of Vector Type");

552 int SubDivs = D.Kind == IITDescriptor::Subdivide2Argument ? 1 : 2;

553 return VectorType::getSubdividedVectorType(VTy, SubDivs);

554 }

555 case IITDescriptor::HalfVecArgument:

556 return VectorType::getHalfElementsVectorType(

557 cast(Tys[D.getArgumentNumber()]));

558 case IITDescriptor::SameVecWidthArgument: {

560 Type *Ty = Tys[D.getArgumentNumber()];

561 if (auto *VTy = dyn_cast(Ty))

562 return VectorType::get(EltTy, VTy->getElementCount());

563 return EltTy;

564 }

565 case IITDescriptor::VecElementArgument: {

566 Type *Ty = Tys[D.getArgumentNumber()];

567 if (VectorType *VTy = dyn_cast(Ty))

568 return VTy->getElementType();

570 }

571 case IITDescriptor::VecOfBitcastsToInt: {

572 Type *Ty = Tys[D.getArgumentNumber()];

573 VectorType *VTy = dyn_cast(Ty);

574 assert(VTy && "Expected an argument of Vector Type");

575 return VectorType::getInteger(VTy);

576 }

577 case IITDescriptor::VecOfAnyPtrsToElt:

578

579 return Tys[D.getOverloadArgNumber()];

580 }

582}

583

588

591

595

596

597

598

599 if (!ArgTys.empty() && ArgTys.back()->isVoidTy()) {

601 return FunctionType::get(ResultTy, ArgTys, true);

602 }

603 return FunctionType::get(ResultTy, ArgTys, false);

604}

605

607#define GET_INTRINSIC_OVERLOAD_TABLE

608#include "llvm/IR/IntrinsicImpl.inc"

609#undef GET_INTRINSIC_OVERLOAD_TABLE

610}

611

612

613#define GET_INTRINSIC_TARGET_DATA

614#include "llvm/IR/IntrinsicImpl.inc"

615#undef GET_INTRINSIC_TARGET_DATA

616

618 return IID > TargetInfos[0].Count;

619}

620

621

622

623

624

627 assert(Name.starts_with("llvm.") && "Unexpected intrinsic prefix");

628 assert(Name.drop_front(5).starts_with(Target) && "Unexpected target");

629

630

631

632

633

634

635

636

637 size_t CmpEnd = 4;

639 CmpEnd += 1 + Target.size();

640

641 const unsigned *Low = NameOffsetTable.begin();

642 const unsigned *High = NameOffsetTable.end();

643 const unsigned *LastLow = Low;

644 while (CmpEnd < Name.size() && High - Low > 0) {

645 size_t CmpStart = CmpEnd;

646 CmpEnd = Name.find('.', CmpStart + 1);

648 auto Cmp = [CmpStart, CmpEnd](auto LHS, auto RHS) {

649

650

651

652 const char *LHSStr;

653 if constexpr (std::is_integral_v<decltype(LHS)>) {

654 LHSStr = &IntrinsicNameTable[LHS];

655 } else {

656 LHSStr = LHS;

657 }

658 const char *RHSStr;

659 if constexpr (std::is_integral_v<decltype(RHS)>) {

660 RHSStr = &IntrinsicNameTable[RHS];

661 } else {

662 RHSStr = RHS;

663 }

664 return strncmp(LHSStr + CmpStart, RHSStr + CmpStart, CmpEnd - CmpStart) <

665 0;

666 };

667 LastLow = Low;

669 }

671 LastLow = Low;

672

673 if (LastLow == NameOffsetTable.end())

674 return -1;

675 StringRef NameFound = &IntrinsicNameTable[*LastLow];

676 if (Name == NameFound ||

677 (Name.starts_with(NameFound) && Name[NameFound.size()] == '.'))

678 return LastLow - NameOffsetTable.begin();

679 return -1;

680}

681

682

683

684

685

686

687static std::pair<ArrayRef, StringRef>

690

692

693

696 Targets, [=](const IntrinsicTargetInfo &TI) { return TI.Name < Target; });

697

698

699 const auto &TI = It != Targets.end() && It->Name == Target ? *It : Targets[0];

700 return {ArrayRef(&IntrinsicNameOffsetTable[1] + TI.Offset, TI.Count),

701 TI.Name};

702}

703

704

705

709 if (Idx == -1)

711

712

713

714 int Adjust = NameOffsetTable.data() - IntrinsicNameOffsetTable;

716

717

718

719 const auto MatchSize = strlen(&IntrinsicNameTable[NameOffsetTable[Idx]]);

720 assert(Name.size() >= MatchSize && "Expected either exact or prefix match");

721 bool IsExactMatch = Name.size() == MatchSize;

724}

725

726

727#define GET_INTRINSIC_ATTRIBUTES

728#include "llvm/IR/IntrinsicImpl.inc"

729#undef GET_INTRINSIC_ATTRIBUTES

730

733

734

735 auto *FT = getType(M->getContext(), id, Tys);

736 return cast(

737 M->getOrInsertFunction(

739 .getCallee());

740}

741

743 return M->getFunction(getName(id));

744}

745

749 return M->getFunction(getName(id, Tys, M, FT));

750}

751

752

753#define GET_LLVM_INTRINSIC_FOR_CLANG_BUILTIN

754#include "llvm/IR/IntrinsicImpl.inc"

755#undef GET_LLVM_INTRINSIC_FOR_CLANG_BUILTIN

756

757

758#define GET_LLVM_INTRINSIC_FOR_MS_BUILTIN

759#include "llvm/IR/IntrinsicImpl.inc"

760#undef GET_LLVM_INTRINSIC_FOR_MS_BUILTIN

761

763 switch (QID) {

764#define INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC) \

765 case Intrinsic::INTRINSIC:

766#include "llvm/IR/ConstrainedOps.def"

767#undef INSTRUCTION

768 return true;

769 default:

770 return false;

771 }

772}

773

775 switch (QID) {

776#define INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC) \

777 case Intrinsic::INTRINSIC: \

778 return ROUND_MODE == 1;

779#include "llvm/IR/ConstrainedOps.def"

780#undef INSTRUCTION

781 default:

782 return false;

783 }

784}

785

787 std::pair<Type *, ArrayRefIntrinsic::IITDescriptor>;

788

789static bool

793 bool IsDeferredCheck) {

794 using namespace Intrinsic;

795

796

797 if (Infos.empty())

798 return true;

799

800

801 auto InfosRef = Infos;

802 auto DeferCheck = [&DeferredChecks, &InfosRef](Type *T) {

804 return false;

805 };

806

807 IITDescriptor D = Infos.front();

808 Infos = Infos.slice(1);

809

810 switch (D.Kind) {

811 case IITDescriptor::Void:

813 case IITDescriptor::VarArg:

814 return true;

815 case IITDescriptor::MMX: {

819 }

820 case IITDescriptor::AMX:

822 case IITDescriptor::Token:

824 case IITDescriptor::Metadata:

826 case IITDescriptor::Half:

828 case IITDescriptor::BFloat:

830 case IITDescriptor::Float:

832 case IITDescriptor::Double:

834 case IITDescriptor::Quad:

836 case IITDescriptor::PPCQuad:

838 case IITDescriptor::Integer:

840 case IITDescriptor::AArch64Svcount:

841 return !isa(Ty) ||

842 cast(Ty)->getName() != "aarch64.svcount";

843 case IITDescriptor::Vector: {

844 VectorType *VT = dyn_cast(Ty);

845 return !VT || VT->getElementCount() != D.Vector_Width ||

847 DeferredChecks, IsDeferredCheck);

848 }

849 case IITDescriptor::Pointer: {

850 PointerType *PT = dyn_cast(Ty);

851 return !PT || PT->getAddressSpace() != D.Pointer_AddressSpace;

852 }

853

854 case IITDescriptor::Struct: {

855 StructType *ST = dyn_cast(Ty);

856 if (!ST || !ST->isLiteral() || ST->isPacked() ||

857 ST->getNumElements() != D.Struct_NumElements)

858 return true;

859

860 for (unsigned i = 0, e = D.Struct_NumElements; i != e; ++i)

862 DeferredChecks, IsDeferredCheck))

863 return true;

864 return false;

865 }

866

867 case IITDescriptor::Argument:

868

869

870 if (D.getArgumentNumber() < ArgTys.size())

871 return Ty != ArgTys[D.getArgumentNumber()];

872

873 if (D.getArgumentNumber() > ArgTys.size() ||

874 D.getArgumentKind() == IITDescriptor::AK_MatchType)

875 return IsDeferredCheck || DeferCheck(Ty);

876

877 assert(D.getArgumentNumber() == ArgTys.size() && !IsDeferredCheck &&

878 "Table consistency error");

880

881 switch (D.getArgumentKind()) {

882 case IITDescriptor::AK_Any:

883 return false;

884 case IITDescriptor::AK_AnyInteger:

886 case IITDescriptor::AK_AnyFloat:

888 case IITDescriptor::AK_AnyVector:

889 return !isa(Ty);

890 case IITDescriptor::AK_AnyPointer:

891 return !isa(Ty);

892 default:

893 break;

894 }

896

897 case IITDescriptor::ExtendArgument: {

898

899 if (D.getArgumentNumber() >= ArgTys.size())

900 return IsDeferredCheck || DeferCheck(Ty);

901

902 Type *NewTy = ArgTys[D.getArgumentNumber()];

903 if (VectorType *VTy = dyn_cast(NewTy))

904 NewTy = VectorType::getExtendedElementVectorType(VTy);

905 else if (IntegerType *ITy = dyn_cast(NewTy))

906 NewTy = IntegerType::get(ITy->getContext(), 2 * ITy->getBitWidth());

907 else

908 return true;

909

910 return Ty != NewTy;

911 }

912 case IITDescriptor::TruncArgument: {

913

914 if (D.getArgumentNumber() >= ArgTys.size())

915 return IsDeferredCheck || DeferCheck(Ty);

916

917 Type *NewTy = ArgTys[D.getArgumentNumber()];

918 if (VectorType *VTy = dyn_cast(NewTy))

919 NewTy = VectorType::getTruncatedElementVectorType(VTy);

920 else if (IntegerType *ITy = dyn_cast(NewTy))

921 NewTy = IntegerType::get(ITy->getContext(), ITy->getBitWidth() / 2);

922 else

923 return true;

924

925 return Ty != NewTy;

926 }

927 case IITDescriptor::HalfVecArgument:

928

929 if (D.getArgumentNumber() >= ArgTys.size())

930 return IsDeferredCheck || DeferCheck(Ty);

931 return !isa(ArgTys[D.getArgumentNumber()]) ||

932 VectorType::getHalfElementsVectorType(

933 cast(ArgTys[D.getArgumentNumber()])) != Ty;

934 case IITDescriptor::SameVecWidthArgument: {

935 if (D.getArgumentNumber() >= ArgTys.size()) {

936

937 Infos = Infos.slice(1);

938 return IsDeferredCheck || DeferCheck(Ty);

939 }

940 auto *ReferenceType = dyn_cast(ArgTys[D.getArgumentNumber()]);

941 auto *ThisArgType = dyn_cast(Ty);

942

943 if ((ReferenceType != nullptr) != (ThisArgType != nullptr))

944 return true;

945 Type *EltTy = Ty;

946 if (ThisArgType) {

947 if (ReferenceType->getElementCount() != ThisArgType->getElementCount())

948 return true;

949 EltTy = ThisArgType->getElementType();

950 }

952 IsDeferredCheck);

953 }

954 case IITDescriptor::VecOfAnyPtrsToElt: {

955 unsigned RefArgNumber = D.getRefArgNumber();

956 if (RefArgNumber >= ArgTys.size()) {

957 if (IsDeferredCheck)

958 return true;

959

960

962 return DeferCheck(Ty);

963 }

964

965 if (!IsDeferredCheck) {

966 assert(D.getOverloadArgNumber() == ArgTys.size() &&

967 "Table consistency error");

969 }

970

971

972

973

974 auto *ReferenceType = dyn_cast(ArgTys[RefArgNumber]);

975 auto *ThisArgVecTy = dyn_cast(Ty);

977 (ReferenceType->getElementCount() != ThisArgVecTy->getElementCount()))

978 return true;

979 return !ThisArgVecTy->getElementType()->isPointerTy();

980 }

981 case IITDescriptor::VecElementArgument: {

982 if (D.getArgumentNumber() >= ArgTys.size())

983 return IsDeferredCheck ? true : DeferCheck(Ty);

984 auto *ReferenceType = dyn_cast(ArgTys[D.getArgumentNumber()]);

986 }

987 case IITDescriptor::Subdivide2Argument:

988 case IITDescriptor::Subdivide4Argument: {

989

990 if (D.getArgumentNumber() >= ArgTys.size())

991 return IsDeferredCheck || DeferCheck(Ty);

992

993 Type *NewTy = ArgTys[D.getArgumentNumber()];

994 if (auto *VTy = dyn_cast(NewTy)) {

995 int SubDivs = D.Kind == IITDescriptor::Subdivide2Argument ? 1 : 2;

996 NewTy = VectorType::getSubdividedVectorType(VTy, SubDivs);

997 return Ty != NewTy;

998 }

999 return true;

1000 }

1001 case IITDescriptor::VecOfBitcastsToInt: {

1002 if (D.getArgumentNumber() >= ArgTys.size())

1003 return IsDeferredCheck || DeferCheck(Ty);

1004 auto *ReferenceType = dyn_cast(ArgTys[D.getArgumentNumber()]);

1005 auto *ThisArgVecTy = dyn_cast(Ty);

1007 return true;

1008 return ThisArgVecTy != VectorType::getInteger(ReferenceType);

1009 }

1010 }

1012}

1013

1020 false))

1022

1023 unsigned NumDeferredReturnChecks = DeferredChecks.size();

1024

1025 for (auto *Ty : FTy->params())

1028

1029 for (unsigned I = 0, E = DeferredChecks.size(); I != E; ++I) {

1032 true))

1035 }

1036

1038}

1039

1042

1043 if (Infos.empty())

1044 return isVarArg;

1045

1046

1047 if (Infos.size() != 1)

1048 return true;

1049

1050

1052 Infos = Infos.slice(1);

1053 if (D.Kind == IITDescriptor::VarArg)

1054 return !isVarArg;

1055

1056 return true;

1057}

1058

1061 if (ID)

1062 return false;

1063

1067

1069 Intrinsic::MatchIntrinsicTypesResult::MatchIntrinsicTypes_Match) {

1070 return false;

1071 }

1073 return false;

1074 return true;

1075}

1076

1080 ArgTys);

1081}

1082

1086 return std::nullopt;

1087

1090 std::string WantedName =

1092 if (Name == WantedName)

1093 return std::nullopt;

1094

1096 if (auto *ExistingGV = F->getParent()->getNamedValue(WantedName)) {

1097 if (auto *ExistingF = dyn_cast(ExistingGV))

1098 if (ExistingF->getFunctionType() == F->getFunctionType())

1099 return ExistingF;

1100

1101

1102

1103

1104

1105 ExistingGV->setName(WantedName + ".renamed");

1106 }

1108 }();

1109

1112 "Shouldn't change the signature");

1113 return NewDecl;

1114}

static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")

Analysis containing CSE Info

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

Module.h This file contains the declarations for the Module class.

static bool matchIntrinsicType(Type *Ty, ArrayRef< Intrinsic::IITDescriptor > &Infos, SmallVectorImpl< Type * > &ArgTys, SmallVectorImpl< DeferredIntrinsicMatchPair > &DeferredChecks, bool IsDeferredCheck)

static std::string getIntrinsicNameImpl(Intrinsic::ID Id, ArrayRef< Type * > Tys, Module *M, FunctionType *FT, bool EarlyModuleCheck)

std::pair< Type *, ArrayRef< Intrinsic::IITDescriptor > > DeferredIntrinsicMatchPair

static std::pair< ArrayRef< unsigned >, StringRef > findTargetSubtable(StringRef Name)

Find the segment of IntrinsicNameOffsetTable for intrinsics with the same target as Name,...

static void DecodeIITType(unsigned &NextElt, ArrayRef< unsigned char > Infos, IIT_Info LastInfo, SmallVectorImpl< Intrinsic::IITDescriptor > &OutputTable)

IIT_Info

IIT_Info - These are enumerators that describe the entries returned by the getIntrinsicInfoTableEntri...

static Type * DecodeFixedType(ArrayRef< Intrinsic::IITDescriptor > &Infos, ArrayRef< Type * > Tys, LLVMContext &Context)

static int lookupLLVMIntrinsicByName(ArrayRef< unsigned > NameOffsetTable, StringRef Name, StringRef Target="")

Looks up Name in NameTable via binary search.

static std::string getMangledTypeStr(Type *Ty, bool &HasUnnamedType)

Returns a stable mangling for the type specified for use in the name mangling scheme used by 'any' ty...

static StringRef getName(Value *V)

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

static SymbolRef::Type getType(const Symbol *Sym)

static unsigned getBitWidth(Type *Ty, const DataLayout &DL)

Returns the bitwidth of the given scalar or pointer type.

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

const T & front() const

front - Get the first element.

size_t size() const

size - Get the array size.

bool empty() const

empty - Check if the array is empty.

ArrayRef< T > slice(size_t N, size_t M) const

slice(n, m) - Chop off the first N elements of the array, and keep M elements in the array.

Class to represent fixed width SIMD vectors.

unsigned getNumElements() const

static FixedVectorType * get(Type *ElementType, unsigned NumElts)

Class to represent function types.

ArrayRef< Type * > params() const

Type * getReturnType() const

FunctionType * getFunctionType() const

Returns the FunctionType for me.

void setCallingConv(CallingConv::ID CC)

Class to represent integer types.

static IntegerType * get(LLVMContext &C, unsigned NumBits)

This static method is the primary way of constructing an IntegerType.

unsigned getBitWidth() const

Get the number of bits in this IntegerType.

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

A Module instance is used to store all the information related to an LLVM module.

This class consists of common code factored out of the SmallVector class to reduce code duplication b...

reference emplace_back(ArgTypes &&... Args)

void push_back(const T &Elt)

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

StringRef - Represent a constant reference to a string, i.e.

constexpr size_t size() const

size - Get the string size.

static constexpr size_t npos

Class to represent struct types.

static StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)

This static method is the primary way to create a literal StructType.

Class to represent target extensions types, which are generally unintrospectable from target-independ...

static TargetExtType * get(LLVMContext &Context, StringRef Name, ArrayRef< Type * > Types={}, ArrayRef< unsigned > Ints={})

Return a target extension type having the specified name and optional type and integer parameters.

Target - Wrapper for Target specific information.

The instances of the Type class are immutable: once they are created, they are never changed.

static Type * getHalfTy(LLVMContext &C)

static Type * getDoubleTy(LLVMContext &C)

static Type * getBFloatTy(LLVMContext &C)

bool isIntOrIntVectorTy() const

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

bool isFloatTy() const

Return true if this is 'float', a 32-bit IEEE fp type.

static Type * getX86_AMXTy(LLVMContext &C)

bool isBFloatTy() const

Return true if this is 'bfloat', a 16-bit bfloat type.

static Type * getMetadataTy(LLVMContext &C)

@ X86_AMXTyID

AMX vectors (8192 bits, X86 specific)

@ HalfTyID

16-bit floating point type

@ VoidTyID

type with no size

@ FloatTyID

32-bit floating point type

@ IntegerTyID

Arbitrary bit width integers.

@ BFloatTyID

16-bit floating point type (7-bit significand)

@ DoubleTyID

64-bit floating point type

@ X86_FP80TyID

80-bit floating point type (X87)

@ PPC_FP128TyID

128-bit floating point type (two 64-bits, PowerPC)

@ FP128TyID

128-bit floating point type (112-bit significand)

bool isPPC_FP128Ty() const

Return true if this is powerpc long double.

bool isFP128Ty() const

Return true if this is 'fp128'.

static Type * getVoidTy(LLVMContext &C)

static Type * getFP128Ty(LLVMContext &C)

bool isHalfTy() const

Return true if this is 'half', a 16-bit IEEE fp type.

bool isDoubleTy() const

Return true if this is 'double', a 64-bit IEEE fp type.

static Type * getTokenTy(LLVMContext &C)

bool isX86_AMXTy() const

Return true if this is X86 AMX.

static Type * getFloatTy(LLVMContext &C)

bool isIntegerTy() const

True if this is an instance of IntegerType.

TypeID getTypeID() const

Return the type id for the type.

bool isTokenTy() const

Return true if this is 'token'.

bool isFPOrFPVectorTy() const

Return true if this is a FP type or a vector of FP.

static Type * getPPC_FP128Ty(LLVMContext &C)

bool isVoidTy() const

Return true if this is 'void'.

bool isMetadataTy() const

Return true if this is 'metadata'.

void setName(const Twine &Name)

Change the name of the value.

Type * getElementType() const

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

unsigned ID

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

ID ArrayRef< Type * > Tys

Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > Tys={})

Look up the Function declaration of the intrinsic id in the Module M.

MatchIntrinsicTypesResult matchIntrinsicSignature(FunctionType *FTy, ArrayRef< IITDescriptor > &Infos, SmallVectorImpl< Type * > &ArgTys)

Match the specified function type with the type constraints specified by the .td file.

void getIntrinsicInfoTableEntries(ID id, SmallVectorImpl< IITDescriptor > &T)

Return the IIT table descriptor for the specified intrinsic into an array of IITDescriptors.

MatchIntrinsicTypesResult

@ MatchIntrinsicTypes_Match

@ MatchIntrinsicTypes_NoMatchRet

@ MatchIntrinsicTypes_NoMatchArg

std::string getNameNoUnnamedTypes(ID Id, ArrayRef< Type * > Tys)

Return the LLVM name for an intrinsic.

std::optional< Function * > remangleIntrinsicFunction(Function *F)

bool hasConstrainedFPRoundingModeOperand(ID QID)

Returns true if the intrinsic ID is for one of the "Constrained Floating-Point Intrinsics" that take ...

StringRef getName(ID id)

Return the LLVM name for an intrinsic, such as "llvm.ppc.altivec.lvx".

bool isConstrainedFPIntrinsic(ID QID)

Returns true if the intrinsic ID is for one of the "Constrained Floating-Point Intrinsics".

ID lookupIntrinsicID(StringRef Name)

This does the actual lookup of an intrinsic ID which matches the given function name.

Function * getDeclarationIfExists(Module *M, ID id, ArrayRef< Type * > Tys, FunctionType *FT=nullptr)

This version supports overloaded intrinsics.

StringRef getBaseName(ID id)

Return the LLVM name for an intrinsic, without encoded types for overloading, such as "llvm....

bool isOverloaded(ID id)

Returns true if the intrinsic can be overloaded.

FunctionType * getType(LLVMContext &Context, ID id, ArrayRef< Type * > Tys={})

Return the function type for an intrinsic.

bool getIntrinsicSignature(Intrinsic::ID, FunctionType *FT, SmallVectorImpl< Type * > &ArgTys)

Gets the type arguments of an intrinsic call by matching type contraints specified by the ....

bool isTargetIntrinsic(ID IID)

isTargetIntrinsic - Returns true if IID is an intrinsic specific to a certain target.

bool matchIntrinsicVarArg(bool isVarArg, ArrayRef< IITDescriptor > &Infos)

Verify if the intrinsic has variable arguments.

This is an optimization pass for GlobalISel generic memory operations.

@ Low

Lower the current thread's priority such that it does not affect foreground tasks significantly.

auto partition_point(R &&Range, Predicate P)

Binary search for the first iterator in a range where a predicate is false.

bool any_of(R &&range, UnaryPredicate P)

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

Helper struct shared between Function Specialization and SCCP Solver.

This is a type descriptor which explains the type requirements of an intrinsic.