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