LLVM: lib/CodeGen/SelectionDAG/StatepointLowering.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

47#include

48#include

49#include

50#include

51#include

52#include

53

54using namespace llvm;

55

56#define DEBUG_TYPE "statepoint-lowering"

57

59 "Number of stack slots allocated for statepoints");

60STATISTIC(NumOfStatepoints, "Number of statepoint nodes encountered");

62 "Maximum number of stack slots required for a singe statepoint");

63

66 cl::desc("Allow using registers for non pointer deopt args"));

67

69 "use-registers-for-gc-values-in-landing-pad", cl::Hidden, cl::init(false),

70 cl::desc("Allow using registers for gc pointer in landing pad"));

71

74 cl::desc("Max number of VRegs allowed to pass GC pointer meta args in"));

75

77

82 MVT::i64));

84}

85

87

88 assert(PendingGCRelocateCalls.empty() &&

89 "Trying to visit statepoint before finished processing previous one");

90 Locations.clear();

91 NextSlotToAllocate = 0;

92

93

94

95 AllocatedStackSlots.clear();

97}

98

100 Locations.clear();

101 AllocatedStackSlots.clear();

102 assert(PendingGCRelocateCalls.empty() &&

103 "cleared before statepoint sequence completed");

104}

105

109 NumSlotsAllocatedForStatepoints++;

111

112 unsigned SpillSize = ValueType.getStoreSize();

113 assert((SpillSize * 8) ==

114 (-8u & (7 + ValueType.getSizeInBits())) &&

115 "Size not in bytes?");

116

117

118

119

120

121 const size_t NumSlots = AllocatedStackSlots.size();

122 assert(NextSlotToAllocate <= NumSlots && "Broken invariant");

123

126 "Broken invariant");

127

128 for (; NextSlotToAllocate < NumSlots; NextSlotToAllocate++) {

129 if (!AllocatedStackSlots.test(NextSlotToAllocate)) {

132 AllocatedStackSlots.set(NextSlotToAllocate);

133

135 }

136 }

137 }

138

139

140

142 const unsigned FI = cast(SpillSlot)->getIndex();

144

146 AllocatedStackSlots.resize(AllocatedStackSlots.size()+1, true);

149 "Broken invariant");

150

151 StatepointMaxSlotsRequired.updateMax(

153

154 return SpillSlot;

155}

156

157

158

159

162 int LookUpDepth) {

163

164 if (LookUpDepth <= 0)

165 return std::nullopt;

166

167

168 if (const auto *Relocate = dyn_cast(Val)) {

169 const Value *Statepoint = Relocate->getStatepoint();

170 assert((isa(Statepoint) || isa(Statepoint)) &&

171 "GetStatepoint must return one of two types");

172 if (isa(Statepoint))

173 return std::nullopt;

174

176 [cast(Statepoint)];

177

178 auto It = RelocationMap.find(Relocate);

179 if (It == RelocationMap.end())

180 return std::nullopt;

181

182 auto &Record = It->second;

184 return std::nullopt;

185

186 return Record.payload.FI;

187 }

188

189

190 if (const BitCastInst *Cast = dyn_cast(Val))

192

193

194

195

196 if (const PHINode *Phi = dyn_cast(Val)) {

197 std::optional MergedResult;

198

199 for (const auto &IncomingValue : Phi->incoming_values()) {

200 std::optional SpillSlot =

202 if (!SpillSlot)

203 return std::nullopt;

204

205 if (MergedResult && *MergedResult != *SpillSlot)

206 return std::nullopt;

207

208 MergedResult = SpillSlot;

209 }

210 return MergedResult;

211 }

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241 return std::nullopt;

242}

243

244

245

246

248

249

250 if (isa(Incoming))

251 return true;

252

253

254

255

256

257 if (Incoming.getValueType().getSizeInBits() > 64)

258 return false;

259

261}

262

263

264

265

266

267

271

272

273

275 return;

276

278 if (OldLocation.getNode())

279

280 return;

281

282 const int LookUpDepth = 6;

283 std::optional Index =

285 if (!Index)

286 return;

287

289

290 auto SlotIt = find(StatepointSlots, *Index);

291 assert(SlotIt != StatepointSlots.end() &&

292 "Value spilled to the unknown stack slot");

293

294

295 const int Offset = std::distance(StatepointSlots.begin(), SlotIt);

297

298

299

300

301

302

303 return;

304 }

305

307

308

309

313}

314

315

316

317

321 SDValue ReturnValue, CallEndVal;

322 std::tie(ReturnValue, CallEndVal) =

325

326

327

328

329

330

331

332

333

334

335

336

337

338

339

340

341

344

345 bool HasDef = !SI.CLI.RetTy->isVoidTy();

346 if (HasDef) {

349 else

352 }

353

355 return std::make_pair(ReturnValue, CallEnd->getOperand(0).getNode());

356}

357

365 MFI.getObjectSize(FI.getIndex()),

366 MFI.getObjectAlign(FI.getIndex()));

367}

368

369

370

371

372

373

374

375static std::tuple<SDValue, SDValue, MachineMemOperand*>

380

381

384 Builder);

385 int Index = cast(Loc)->getIndex();

386

388

389

390

391

392

393

396 (-8 & (7 +

397 (int64_t)Incoming.getValueSizeInBits())) &&

398 "Bad spill: stack slot does not match!");

399

400

401

402

405 auto *StoreMMO = MF.getMachineMemOperand(

409 StoreMMO);

410

412

414 }

415

417 return std::make_tuple(Loc, Chain, MMO);

418}

419

420

421

422

423static void

428

431

432

433

435 "Incoming value is a frame index!");

438

442 return;

443 }

444

445 assert(Incoming.getValueType().getSizeInBits() <= 64);

446

448

449

450

451

453 return;

454 }

455

456

457

458

459

462 return;

465 C->getValueAPF().bitcastToAPInt().getZExtValue());

466 return;

467 }

468

470 }

471

472

473

474 if (!RequireSpillSlot) {

475

476

477

478

479

480

481

483 } else {

484

485

486

487

488

492 if (auto *MMO = std::get<2>(Res))

494 Chain = std::get<1>(Res);

496 }

497

498}

499

500

501

503 auto *Ty = V->getType();

504 if (!Ty->isPtrOrPtrVectorTy())

505 return false;

506 if (auto *GFI = Builder.GFI)

507 if (auto IsManaged = GFI->getStrategy().isGCManagedPointer(Ty))

508 return *IsManaged;

509 return true;

510}

511

512

513

514

515

516

517

518

519static void

526

527

528

529

530

531

532

533

534

535

536

537

538

539 const bool LiveInDeopt =

541

542

544

545

546

549 if (const auto *StInvoke =

550 dyn_cast_or_null(SI.StatepointInstr)) {

552 for (const auto *Relocate : SI.GCRelocates)

553 if (Relocate->getOperand(0) == LPI) {

554 LPadPointers.insert(Builder.getValue(Relocate->getBasePtr()));

555 LPadPointers.insert(Builder.getValue(Relocate->getDerivedPtr()));

556 }

557 }

558

559 LLVM_DEBUG(dbgs() << "Deciding how to lower GC Pointers:\n");

560

561

563

565

566 unsigned CurNumVRegs = 0;

567

568 auto canPassGCPtrOnVReg = [&](SDValue SD) {

569 if (SD.getValueType().isVector())

570 return false;

571 if (LPadPointers.count(SD))

572 return false;

574 };

575

576 auto processGCPtr = [&](const Value *V) {

578 if (!LoweredGCPtrs.insert(PtrSD))

579 return;

580 GCPtrIndexMap[PtrSD] = LoweredGCPtrs.size() - 1;

581

582 assert(!LowerAsVReg.count(PtrSD) && "must not have been seen");

583 if (LowerAsVReg.size() == MaxVRegPtrs)

584 return;

586 "IR and SD types disagree");

587 if (!canPassGCPtrOnVReg(PtrSD)) {

589 return;

590 }

592 LowerAsVReg[PtrSD] = CurNumVRegs++;

593 };

594

595

596 for (const Value *V : SI.Ptrs)

597 processGCPtr(V);

598 for (const Value *V : SI.Bases)

599 processGCPtr(V);

600

601 LLVM_DEBUG(dbgs() << LowerAsVReg.size() << " pointers will go in vregs\n");

602

603 auto requireSpillSlot = [&](const Value *V) {

606 return true;

610 };

611

612

613

614

615

616

617 for (const Value *V : SI.DeoptState) {

618 if (requireSpillSlot(V))

620 }

621

622 for (const Value *V : SI.Ptrs) {

624 if (!LowerAsVReg.count(SDV))

626 }

627

628 for (const Value *V : SI.Bases) {

630 if (!LowerAsVReg.count(SDV))

632 }

633

634

635

636

637 const int NumVMSArgs = SI.DeoptState.size();

639

640

641

643 for (const Value *V : SI.DeoptState) {

645

646

647 if (const Argument *Arg = dyn_cast(V)) {

649 if (FI != INT_MAX)

651 }

655 << " requireSpillSlot = " << requireSpillSlot(V) << "\n");

657 Builder);

658 }

659

660

662 for (SDValue SDV : LoweredGCPtrs)

664 Builder);

665

666

668

669

670

671

672

673

675 for (Value *V : SI.GCLives) {

678

680 "Incoming value is a frame index!");

683

687 }

688 }

691

692

695 for (unsigned i = 0; i < SI.Ptrs.size(); ++i) {

697 assert(GCPtrIndexMap.count(Base) && "base not found in index map");

701 assert(GCPtrIndexMap.count(Derived) && "derived not found in index map");

704 }

705}

706

709

710

711

712

713 NumOfStatepoints++;

714

716 assert(SI.Bases.size() == SI.Ptrs.size() && "Pointer without base!");

717 assert((GFI || SI.Bases.empty()) &&

718 "No gc specified, so cannot relocate pointers!");

719

721 << "Lowering statepoint " << *SI.StatepointInstr << "\n");

722#ifndef NDEBUG

723 for (const auto *Reloc : SI.GCRelocates)

724 if (Reloc->getParent() == SI.StatepointInstr->getParent())

726#endif

727

728

729

730

732

735

738 SI, *this);

739

740

741

742 SI.CLI.setChain(getRoot());

743

744

748

749

750

751

752

754

756 bool CallHasIncomingGlue = CallNode->getGluedNode();

757 if (CallHasIncomingGlue) {

758

760 }

761

762

763

764

765

766

767

768

769 const bool IsGCTransition =

772 if (IsGCTransition) {

774

775

777

778

779 for (const Value *V : SI.GCTransitionArgs) {

781 if (V->getType()->isPointerTy())

783 }

784

785

786 if (CallHasIncomingGlue)

788

790

791 SDValue GCTransitionStart =

793

794 Chain = GCTransitionStart.getValue(0);

795 Glue = GCTransitionStart.getValue(1);

796 }

797

798

799

800

802

803

807

808

809

810 unsigned NumCallRegArgs =

811 CallNode->getNumOperands() - (CallHasIncomingGlue ? 4 : 3);

813

814

817

818

819

821 if (CallHasIncomingGlue)

822 RegMaskIt = CallNode->op_end() - 2;

823 else

824 RegMaskIt = CallNode->op_end() - 1;

826

827

829

830

831 uint64_t Flags = SI.StatepointFlags;

833 "Unknown flag used");

835

836

838

839

841

842

844

845

848

849

850

852 for (auto SD : LoweredGCArgs) {

853 if (!LowerAsVReg.count(SD))

854 continue;

855 NodeTys.push_back(SD.getValueType());

856 }

857 LLVM_DEBUG(dbgs() << "Statepoint has " << NodeTys.size() << " results\n");

858 assert(NodeTys.size() == LowerAsVReg.size() && "Inconsistent GC Ptr lowering");

861

862 unsigned NumResults = NodeTys.size();

866

867

868

869

871 for (const auto *Relocate : SI.GCRelocates) {

872 Value *Derived = Relocate->getDerivedPtr();

874 if (!LowerAsVReg.count(SD))

875 continue;

876

877 SDValue Relocated = SDValue(StatepointMCNode, LowerAsVReg[SD]);

878

879

880

881 if (SI.StatepointInstr->getParent() == Relocate->getParent()) {

883 if (Res)

884 assert(Res == Relocated);

885 else

887 continue;

888 }

889

890

891 if (VirtRegs.count(SD))

892 continue;

893

894 auto *RetTy = Relocate->getType();

900 PendingExports.push_back(Chain);

901

902 VirtRegs[SD] = Reg;

903 }

904

905

906

907 const Instruction *StatepointInstr = SI.StatepointInstr;

909 for (const GCRelocateInst *Relocate : SI.GCRelocates) {

913

914 bool IsLocal = (Relocate->getParent() == StatepointInstr->getParent());

915

917 if (IsLocal && LowerAsVReg.count(SDV)) {

918

920 } else if (LowerAsVReg.count(SDV)) {

923 Record.payload.Reg = VirtRegs[SDV];

924 } else if (Loc.getNode()) {

926 Record.payload.FI = cast(Loc)->getIndex();

927 } else {

929

930

931

932

935 }

936 RelocationMap[Relocate] = Record;

937 }

938

939

940

941 SDNode *SinkNode = StatepointMCNode;

942

943

944

945

946

947 if (IsGCTransition) {

949

950

952

953

954 for (const Value *V : SI.GCTransitionArgs) {

956 if (V->getType()->isPointerTy())

958 }

959

960

962

964

965 SDValue GCTransitionStart =

967

968 SinkNode = GCTransitionStart.getNode();

969 }

970

971

972

973

974 unsigned NumSinkValues = SinkNode->getNumValues();

975 SDValue StatepointValues[2] = {SDValue(SinkNode, NumSinkValues - 2),

976 SDValue(SinkNode, NumSinkValues - 1)};

978

980

981

982

984

985

986

987

988

989

990

991 return ReturnVal;

992}

993

994

995

996

997static std::pair<const GCResultInst*, const GCResultInst*>

999 std::pair<const GCResultInst *, const GCResultInst*> Res(nullptr, nullptr);

1000 for (const auto *U : S.users()) {

1001 auto *GRI = dyn_cast(U);

1002 if (!GRI)

1003 continue;

1004 if (GRI->getParent() == S.getParent())

1005 Res.first = GRI;

1006 else

1007 Res.second = GRI;

1008 }

1009 return Res;

1010}

1011

1012void

1014 const BasicBlock *EHPadBB ) {

1016 "anyregcc is not supported on statepoints!");

1017

1018#ifndef NDEBUG

1019

1021 "GCStrategy does not expect to encounter statepoints");

1022#endif

1023

1026

1027 if (I.getNumPatchBytes() > 0) {

1028

1029

1030

1031

1032

1033 ActualCallee = DAG.getUNDEF(Callee.getValueType());

1034 } else {

1035 ActualCallee = Callee;

1036 }

1037

1040 if (GCResultLocality.first)

1041 retAttrs = GCResultLocality.first->getAttributes().getRetAttrs();

1042

1045 I.getNumCallArgs(), ActualCallee,

1046 I.getActualReturnType(), retAttrs,

1047 false);

1048

1049

1050

1051

1052

1053

1054

1055

1056

1057

1058

1059

1060

1061

1063 for (const GCRelocateInst *Relocate : I.getGCRelocates()) {

1064 SI.GCRelocates.push_back(Relocate);

1065

1066 SDValue DerivedSD = getValue(Relocate->getDerivedPtr());

1067 if (Seen.insert(DerivedSD).second) {

1068 SI.Bases.push_back(Relocate->getBasePtr());

1069 SI.Ptrs.push_back(Relocate->getDerivedPtr());

1070 }

1071 }

1072

1073

1074

1075

1076

1077

1078

1079 for (Value *V : I.deopt_operands()) {

1081 continue;

1083 SI.Bases.push_back(V);

1084 SI.Ptrs.push_back(V);

1085 }

1086 }

1087

1089 SI.StatepointInstr = &I;

1090 SI.ID = I.getID();

1091

1094 I.gc_transition_args_end());

1095

1096 SI.StatepointFlags = I.getFlags();

1097 SI.NumPatchBytes = I.getNumPatchBytes();

1098 SI.EHPadBB = EHPadBB;

1099

1101

1102

1103 if (!GCResultLocality.first && !GCResultLocality.second) {

1104

1105

1107 return;

1108 }

1109

1110 if (GCResultLocality.first) {

1111

1112

1113

1115 }

1116

1117 if (!GCResultLocality.second)

1118 return;

1119

1120

1121

1122

1123

1124

1125

1126

1127 Type *RetTy = GCResultLocality.second->getType();

1131 I.getCallingConv());

1133

1135 PendingExports.push_back(Chain);

1137}

1138

1141 bool VarArgDisallowed, bool ForceVoidReturnTy) {

1143 unsigned ArgBeginIndex = Call->arg_begin() - Call->op_begin();

1145 SI.CLI, Call, ArgBeginIndex, Call->arg_size(), Callee,

1147 Call->getAttributes().getRetAttrs(), false);

1148 if (!VarArgDisallowed)

1149 SI.CLI.IsVarArg = Call->getFunctionType()->isVarArg();

1150

1152

1154

1156 SI.ID = SD.StatepointID.value_or(DefaultID);

1157 SI.NumPatchBytes = SD.NumPatchBytes.value_or(0);

1158

1159 SI.DeoptState =

1160 ArrayRef(DeoptBundle.Inputs.begin(), DeoptBundle.Inputs.end());

1162 SI.EHPadBB = EHPadBB;

1163

1164

1165

1166 LLVM_DEBUG(dbgs() << "Lowering call with deopt bundle " << *Call << "\n");

1170 }

1171}

1172

1176 false,

1177 false);

1178}

1179

1180void SelectionDAGBuilder::visitGCResult(const GCResultInst &CI) {

1181

1182

1184 assert((isa(SI) || isa(SI)) &&

1185 "GetStatepoint must return one of two types");

1186 if (isa(SI))

1187 return;

1188

1191 return;

1192 }

1193

1194

1195

1196

1197

1198

1201

1202 assert(CopyFromReg.getNode());

1204}

1205

1206void SelectionDAGBuilder::visitGCRelocate(const GCRelocateInst &Relocate) {

1208#ifndef NDEBUG

1209

1210

1211

1212

1213 assert((isa(Statepoint) || isa(Statepoint)) &&

1214 "GetStatepoint must return one of two types");

1215 if (isa(Statepoint))

1216 return;

1217

1218 if (cast(Statepoint)->getParent() == Relocate.getParent())

1220#endif

1221

1223 auto &RelocationMap =

1225 auto SlotIt = RelocationMap.find(&Relocate);

1226 assert(SlotIt != RelocationMap.end() && "Relocating not lowered gc value");

1228

1229

1231 assert(cast(Statepoint)->getParent() ==

1233 "Nonlocal gc.relocate mapped via SDValue");

1237 return;

1238 }

1243 std::nullopt);

1244

1245

1246

1249 Chain, nullptr, nullptr);

1250 setValue(&Relocate, Relocation);

1251 return;

1252 }

1253

1257

1258

1259

1260

1261

1262

1263

1264

1266

1271 MFI.getObjectSize(Index),

1272 MFI.getObjectAlign(Index));

1273

1276

1280

1282 setValue(&Relocate, SpillLoad);

1283 return;

1284 }

1285

1288

1290

1291

1293 return;

1294 }

1295

1296

1297

1299}

1300

1305

1306

1307

1308

1310 true,

1311 true);

1312}

1313

1315

1316

1317

1321}

static const Function * getParent(const Value *V)

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

This file implements a set that has insertion order iteration characteristics.

This file implements the SmallBitVector class.

This file defines the SmallSet class.

This file defines the SmallVector class.

static cl::opt< bool > UseRegistersForGCPointersInLandingPad("use-registers-for-gc-values-in-landing-pad", cl::Hidden, cl::init(false), cl::desc("Allow using registers for gc pointer in landing pad"))

static void lowerIncomingStatepointValue(SDValue Incoming, bool RequireSpillSlot, SmallVectorImpl< SDValue > &Ops, SmallVectorImpl< MachineMemOperand * > &MemRefs, SelectionDAGBuilder &Builder)

Lower a single value incoming to a statepoint node.

static std::optional< int > findPreviousSpillSlot(const Value *Val, SelectionDAGBuilder &Builder, int LookUpDepth)

Utility function for reservePreviousStackSlotForValue.

static void pushStackMapConstant(SmallVectorImpl< SDValue > &Ops, SelectionDAGBuilder &Builder, uint64_t Value)

static bool isGCValue(const Value *V, SelectionDAGBuilder &Builder)

Return true if value V represents the GC value.

static bool willLowerDirectly(SDValue Incoming)

Return true if-and-only-if the given SDValue can be lowered as either a constant argument or a stack ...

static void lowerStatepointMetaArgs(SmallVectorImpl< SDValue > &Ops, SmallVectorImpl< MachineMemOperand * > &MemRefs, SmallVectorImpl< SDValue > &GCPtrs, DenseMap< SDValue, int > &LowerAsVReg, SelectionDAGBuilder::StatepointLoweringInfo &SI, SelectionDAGBuilder &Builder)

Lower deopt state and gc pointer arguments of the statepoint.

static std::pair< const GCResultInst *, const GCResultInst * > getGCResultLocality(const GCStatepointInst &S)

Return two gc.results if present.

static cl::opt< bool > UseRegistersForDeoptValues("use-registers-for-deopt-values", cl::Hidden, cl::init(false), cl::desc("Allow using registers for non pointer deopt args"))

static cl::opt< unsigned > MaxRegistersForGCPointers("max-registers-for-gc-values", cl::Hidden, cl::init(0), cl::desc("Max number of VRegs allowed to pass GC pointer meta args in"))

static void reservePreviousStackSlotForValue(const Value *IncomingValue, SelectionDAGBuilder &Builder)

Try to find existing copies of the incoming values in stack slots used for statepoint spilling.

FunctionLoweringInfo::StatepointRelocationRecord RecordType

static MachineMemOperand * getMachineMemOperand(MachineFunction &MF, FrameIndexSDNode &FI)

static std::pair< SDValue, SDNode * > lowerCallFromStatepointLoweringInfo(SelectionDAGBuilder::StatepointLoweringInfo &SI, SelectionDAGBuilder &Builder)

Extract call from statepoint, lower it and return pointer to the call node.

static std::tuple< SDValue, SDValue, MachineMemOperand * > spillIncomingStatepointValue(SDValue Incoming, SDValue Chain, SelectionDAGBuilder &Builder)

Spill a value incoming to the statepoint.

This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...

#define STATISTIC(VARNAME, DESC)

This file describes how to lower LLVM code to machine code.

This class represents an incoming formal argument to a Function.

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

LLVM Basic Block Representation.

This class represents a no-op cast from one type to another.

Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...

This class represents a function call, abstracting a target machine's calling convention.

size_type count(const_arg_type_t< KeyT > Val) const

Return 1 if the specified key is in the map, 0 otherwise.

Register CreateRegs(const Value *V)

DenseMap< const Instruction *, StatepointSpillMapTy > StatepointRelocationMaps

int getArgumentFrameIndex(const Argument *A)

getArgumentFrameIndex - Get frame index for the byval argument.

DenseMap< const Value *, Register > ValueMap

ValueMap - Since we emit code for the function a basic block at a time, we must remember which virtua...

SmallVector< unsigned, 50 > StatepointStackSlots

StatepointStackSlots - A list of temporary stack slots (frame indices) used to spill values at a stat...

GCStrategy & getStrategy()

getStrategy - Return the GC strategy for the function.

const Value * getStatepoint() const

The statepoint with which this gc.relocate is associated.

Represents calls to the gc.relocate intrinsic.

Value * getDerivedPtr() const

Represents calls to the gc.result intrinsic.

Represents a gc.statepoint intrinsic call.

bool useStatepoints() const

Returns true if this strategy is expecting the use of gc.statepoints, and false otherwise.

The landingpad instruction holds all of the information necessary to generate correct exception handl...

The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.

void markAsStatepointSpillSlotObjectIndex(int ObjectIdx)

Align getObjectAlign(int ObjectIdx) const

Return the alignment of the specified stack object.

int64_t getObjectSize(int ObjectIdx) const

Return the size of the specified object.

MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)

getMachineMemOperand - Allocate a new MachineMemOperand.

MachineFrameInfo & getFrameInfo()

getFrameInfo - Return the frame info object for the current function.

A description of a memory reference used in the backend.

@ MOVolatile

The memory access is volatile.

@ MOLoad

The memory access reads data.

@ MOStore

The memory access writes data.

An SDNode that represents everything that will be needed to construct a MachineInstr.

Wrapper class representing virtual and physical registers.

Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...

Represents one node in the SelectionDAG.

unsigned getOpcode() const

Return the SelectionDAG opcode value for this node.

unsigned getNumValues() const

Return the number of values defined/returned by this operator.

unsigned getNumOperands() const

Return the number of values used by this operation.

const SDValue & getOperand(unsigned Num) const

SDNode * getGluedNode() const

If this node has a glue operand, return the node to which the glue operand points.

op_iterator op_end() const

op_iterator op_begin() const

Represents a use of a SDNode.

Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.

SDNode * getNode() const

get the SDNode which holds the desired result

SDValue getValue(unsigned R) const

EVT getValueType() const

Return the ValueType of the referenced return value.

SelectionDAGBuilder - This is the common target-independent lowering implementation that is parameter...

SDValue getValue(const Value *V)

getValue - Return an SDValue for the given Value.

MVT getFrameIndexTy()

Returns the type of FrameIndex and TargetFrameIndex nodes.

void LowerStatepoint(const GCStatepointInst &I, const BasicBlock *EHPadBB=nullptr)

SDValue lowerRangeToAssertZExt(SelectionDAG &DAG, const Instruction &I, SDValue Op)

void LowerDeoptimizeCall(const CallInst *CI)

void LowerCallSiteWithDeoptBundle(const CallBase *Call, SDValue Callee, const BasicBlock *EHPadBB)

void LowerCallSiteWithDeoptBundleImpl(const CallBase *Call, SDValue Callee, const BasicBlock *EHPadBB, bool VarArgDisallowed, bool ForceVoidReturnTy)

StatepointLoweringState StatepointLowering

State used while lowering a statepoint sequence (gc_statepoint, gc_relocate, and gc_result).

void populateCallLoweringInfo(TargetLowering::CallLoweringInfo &CLI, const CallBase *Call, unsigned ArgIdx, unsigned NumArgs, SDValue Callee, Type *ReturnTy, AttributeSet RetAttrs, bool IsPatchPoint)

Populate a CallLowerinInfo (into CLI) based on the properties of the call being lowered.

SmallVector< SDValue, 8 > PendingLoads

Loads are not emitted to the program immediately.

GCFunctionInfo * GFI

Garbage collection metadata for the function.

SDValue getRoot()

Similar to getMemoryRoot, but also flushes PendingConstrainedFP(Strict) items.

void ExportFromCurrentBlock(const Value *V)

ExportFromCurrentBlock - If this condition isn't known to be exported from the current basic block,...

std::pair< SDValue, SDValue > lowerInvokable(TargetLowering::CallLoweringInfo &CLI, const BasicBlock *EHPadBB=nullptr)

SDLoc getCurSDLoc() const

SDValue getCopyFromRegs(const Value *V, Type *Ty)

If there was virtual register allocated for the value V emit CopyFromReg of the specified type Ty.

void LowerDeoptimizingReturn()

FunctionLoweringInfo & FuncInfo

Information about the function as a whole.

void setValue(const Value *V, SDValue NewN)

SDValue getControlRoot()

Similar to getRoot, but instead of flushing all the PendingLoad items, flush all the PendingExports (...

SDValue LowerAsSTATEPOINT(StatepointLoweringInfo &SI)

Lower SLI into a STATEPOINT instruction.

const SDValue & getRoot() const

Return the root tag of the SelectionDAG.

SDVTList getVTList(EVT VT)

Return an SDVTList that represents the list of values specified.

MachineSDNode * getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT)

These are used for target selectors to create a new node with specified return type(s),...

SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr)

Loads are not normal binary operators: their result type is not determined by their operands,...

const TargetLowering & getTargetLoweringInfo() const

SDValue getUNDEF(EVT VT)

Return an UNDEF node. UNDEF does not have a useful SDLoc.

void DeleteNode(SDNode *N)

Remove the specified node from the system.

void setNodeMemRefs(MachineSDNode *N, ArrayRef< MachineMemOperand * > NewMemRefs)

Mutate the specified machine node's memory references to the provided list.

const DataLayout & getDataLayout() const

SDValue getTargetFrameIndex(int FI, EVT VT)

SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)

Create a ConstantSDNode wrapping a constant value.

void ReplaceAllUsesWith(SDValue From, SDValue To)

Modify anything using 'From' to use 'To' instead.

SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())

Helper function to build ISD::STORE nodes.

SDValue getSrcValue(const Value *v)

Construct a node to track a Value* through the backend.

SDValue getExternalSymbol(const char *Sym, EVT VT)

const TargetMachine & getTarget() const

SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)

SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)

Gets or creates the specified node.

SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)

MachineFunction & getMachineFunction() const

SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)

LLVMContext * getContext() const

const SDValue & setRoot(SDValue N)

Set the current root tag of the SelectionDAG.

SDValue CreateStackTemporary(TypeSize Bytes, Align Alignment)

Create a stack temporary based on the size in bytes and the alignment.

SDValue getEntryNode() const

Return the token chain corresponding to the entry of the function.

size_type size() const

Determine the number of elements in the SetVector.

Vector takeVector()

Clear the SetVector and return the underlying vector.

bool insert(const value_type &X)

Insert a new element into the SetVector.

bool test(unsigned Idx) const

void clear()

Clear all bits.

size_type size() const

Returns the number of bits in this bitvector.

void resize(unsigned N, bool t=false)

Grow or shrink the bitvector.

A SetVector that performs no allocations if smaller than a certain size.

SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...

size_type count(const T &V) const

count - Return 1 if the element is in the set, 0 otherwise.

std::pair< const_iterator, bool > insert(const T &V)

insert - Insert an element into the set if it isn't already there.

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

void append(ItTy in_start, ItTy in_end)

Add the specified range to the end of the SmallVector.

iterator insert(iterator I, T &&Elt)

void push_back(const T &Elt)

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

void clear()

Clear the memory usage of this object.

SDValue getLocation(SDValue Val)

Returns the spill location of a value incoming to the current statepoint.

SDValue allocateStackSlot(EVT ValueType, SelectionDAGBuilder &Builder)

Get a stack slot we can use to store an value of type ValueType.

void scheduleRelocCall(const GCRelocateInst &RelocCall)

Record the fact that we expect to encounter a given gc_relocate before the next statepoint.

bool isStackSlotAllocated(int Offset)

void setLocation(SDValue Val, SDValue Location)

void relocCallVisited(const GCRelocateInst &RelocCall)

Remove this gc_relocate from the list we're expecting to see before the next statepoint.

void startNewStatepoint(SelectionDAGBuilder &Builder)

Reset all state tracking for a newly encountered safepoint.

void reserveStackSlot(int Offset)

EVT getValueType(const DataLayout &DL, Type *Ty, bool AllowUnknown=false) const

Return the EVT corresponding to this LLVM type.

bool isTypeLegal(EVT VT) const

Return true if the target has native support for the specified value type.

unsigned TrapUnreachable

Emit target-specific trap instruction for 'unreachable' IR instructions.

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

static Type * getVoidTy(LLVMContext &C)

LLVM Value Representation.

Type * getType() const

All values are typed, get the type of this value.

iterator_range< user_iterator > users()

const ParentTy * getParent() const

#define llvm_unreachable(msg)

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

@ AnyReg

OBSOLETED - Used for stack based JavaScript calls.

@ C

The default llvm calling convention, compatible with C.

@ LOAD

LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...

@ EH_LABEL

EH_LABEL - Represents a label in mid basic block used to track locations needed for debug and excepti...

@ GC_TRANSITION_START

GC_TRANSITION_START/GC_TRANSITION_END - These operators mark the beginning and end of GC transition s...

@ CopyFromReg

CopyFromReg - This node indicates that the input value is a virtual or physical register that is defi...

@ TRAP

TRAP - Trapping instruction.

initializer< Ty > init(const Ty &Val)

This is an optimization pass for GlobalISel generic memory operations.

auto find(R &&Range, const T &Val)

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

bool isIntOrFPConstant(SDValue V)

Return true if V is either a integer or FP constant.

void append_range(Container &C, Range &&R)

Wrapper function to append range R to container C.

raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.

StatepointDirectives parseStatepointDirectivesFromAttrs(AttributeList AS)

Parse out statepoint directives from the function attributes present in AS.

@ MaskAll

A bitmask that includes all valid flags.

@ DeoptLiveIn

Mark the deopt arguments associated with the statepoint as only being "live-in".

@ GCTransition

Indicates that this statepoint is a transition from GC-aware code to code that is not GC-aware.

TypeSize getSizeInBits() const

Return the size of the specified value type in bits.

bool isVector() const

Return true if this is a vector value type.

Helper object to track which of three possible relocation mechanisms are used for a particular value ...

Incoming for lane maks phi as machine instruction, incoming register Reg and incoming block Block are...

static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)

Return a MachinePointerInfo record that refers to the specified FrameIndex.

This struct represents the registers (physical or virtual) that a particular set of values is assigne...

void getCopyToRegs(SDValue Val, SelectionDAG &DAG, const SDLoc &dl, SDValue &Chain, SDValue *Glue, const Value *V=nullptr, ISD::NodeType PreferredExtendType=ISD::ANY_EXTEND) const

Emit a series of CopyToReg nodes that copies the specified value into the registers specified by this...

This represents a list of ValueType's that has been intern'd by a SelectionDAG.

Describes a gc.statepoint or a gc.statepoint like thing for the purposes of lowering into a STATEPOIN...

static const uint64_t DeoptBundleStatepointID