56#define DEBUG_TYPE "statepoint-lowering"
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");
66 cl::desc(
"Allow using registers for non pointer deopt args"));
70 cl::desc(
"Allow using registers for gc pointer in landing pad"));
74 cl::desc(
"Max number of VRegs allowed to pass GC pointer meta args in"));
84 SDLoc L = Builder.getCurSDLoc();
85 Ops.push_back(Builder.DAG.getTargetConstant(StackMaps::ConstantOp, L,
87 Ops.push_back(Builder.DAG.getTargetConstant(
Value, L, MVT::i64));
92 assert(PendingGCRelocateCalls.empty() &&
93 "Trying to visit statepoint before finished processing previous one");
95 NextSlotToAllocate = 0;
99 AllocatedStackSlots.clear();
100 AllocatedStackSlots.resize(Builder.FuncInfo.StatepointStackSlots.size());
105 AllocatedStackSlots.clear();
106 assert(PendingGCRelocateCalls.empty() &&
107 "cleared before statepoint sequence completed");
113 NumSlotsAllocatedForStatepoints++;
116 unsigned SpillSize =
ValueType.getStoreSize();
118 (-8u & (7 +
ValueType.getSizeInBits())) &&
119 "Size not in bytes?");
125 const size_t NumSlots = AllocatedStackSlots.size();
126 assert(NextSlotToAllocate <= NumSlots &&
"Broken invariant");
128 assert(AllocatedStackSlots.size() ==
129 Builder.FuncInfo.StatepointStackSlots.size() &&
132 for (; NextSlotToAllocate < NumSlots; NextSlotToAllocate++) {
133 if (!AllocatedStackSlots.test(NextSlotToAllocate)) {
134 const int FI = Builder.FuncInfo.StatepointStackSlots[NextSlotToAllocate];
136 AllocatedStackSlots.set(NextSlotToAllocate);
138 return Builder.DAG.getFrameIndex(FI,
ValueType);
149 Builder.FuncInfo.StatepointStackSlots.push_back(FI);
150 AllocatedStackSlots.resize(AllocatedStackSlots.size()+1,
true);
151 assert(AllocatedStackSlots.size() ==
152 Builder.FuncInfo.StatepointStackSlots.size() &&
155 StatepointMaxSlotsRequired.updateMax(
156 Builder.FuncInfo.StatepointStackSlots.size());
168 if (LookUpDepth <= 0)
173 const Value *Statepoint = Relocate->getStatepoint();
175 "GetStatepoint must return one of two types");
179 const auto &RelocationMap = Builder.FuncInfo.StatepointRelocationMaps
182 auto It = RelocationMap.find(Relocate);
183 if (It == RelocationMap.end())
186 auto &
Record = It->second;
201 std::optional<int> MergedResult;
203 for (
const auto &IncomingValue : Phi->incoming_values()) {
204 std::optional<int> SpillSlot =
209 if (MergedResult && *MergedResult != *SpillSlot)
212 MergedResult = SpillSlot;
307 SDValue OldLocation = Builder.StatepointLowering.getLocation(Incoming);
312 const int LookUpDepth = 6;
313 std::optional<int> Index =
318 const auto &StatepointSlots = Builder.FuncInfo.StatepointStackSlots;
320 auto SlotIt =
find(StatepointSlots, *Index);
321 assert(SlotIt != StatepointSlots.end() &&
322 "Value spilled to the unknown stack slot");
325 const int Offset = std::distance(StatepointSlots.begin(), SlotIt);
326 if (Builder.StatepointLowering.isStackSlotAllocated(
Offset)) {
336 Builder.StatepointLowering.reserveStackSlot(
Offset);
341 Builder.DAG.getTargetFrameIndex(*Index, Builder.getFrameIndexTy());
342 Builder.StatepointLowering.setLocation(Incoming,
Loc);
351 SDValue ReturnValue, CallEndVal;
352 std::tie(ReturnValue, CallEndVal) =
353 Builder.lowerInvokable(
SI.CLI,
SI.EHPadBB);
375 bool HasDef = !
SI.CLI.RetTy->isVoidTy();
405static std::tuple<SDValue, SDValue, MachineMemOperand*>
408 SDValue Loc = Builder.StatepointLowering.getLocation(Incoming);
412 if (!
Loc.getNode()) {
413 Loc = Builder.StatepointLowering.allocateStackSlot(Incoming.
getValueType(),
417 Loc = Builder.DAG.getTargetFrameIndex(Index, Builder.getFrameIndexTy());
428 "Bad spill: stack slot does not match!");
433 auto &
MF = Builder.DAG.getMachineFunction();
438 Chain = Builder.DAG.getStore(Chain, Builder.getCurSDLoc(), Incoming,
Loc,
443 Builder.StatepointLowering.setLocation(Incoming,
Loc);
447 return std::make_tuple(
Loc, Chain, MMO);
465 "Incoming value is a frame index!");
466 Ops.push_back(Builder.DAG.getTargetFrameIndex(FI->getIndex(),
467 Builder.getFrameIndexTy()));
469 auto &
MF = Builder.DAG.getMachineFunction();
495 C->getValueAPF().bitcastToAPInt().getZExtValue());
504 if (!RequireSpillSlot) {
512 Ops.push_back(Incoming);
519 SDValue Chain = Builder.getRoot();
521 Ops.push_back(std::get<0>(Res));
522 if (
auto *MMO = std::get<2>(Res))
524 Chain = std::get<1>(Res);
525 Builder.DAG.setRoot(Chain);
533 auto *Ty = V->getType();
534 if (!Ty->isPtrOrPtrVectorTy())
536 if (
auto *GFI = Builder.GFI)
537 if (
auto IsManaged = GFI->getStrategy().isGCManagedPointer(Ty))
569 const bool LiveInDeopt =
579 if (
const auto *StInvoke =
582 for (
const auto *Relocate :
SI.GCRelocates)
583 if (Relocate->getOperand(0) == LPI) {
584 LPadPointers.
insert(Builder.getValue(Relocate->getBasePtr()));
585 LPadPointers.
insert(Builder.getValue(Relocate->getDerivedPtr()));
596 unsigned CurNumVRegs = 0;
598 auto canPassGCPtrOnVReg = [&](
SDValue SD) {
599 if (SD.getValueType().isVector())
601 if (LPadPointers.
count(SD))
606 auto processGCPtr = [&](
const Value *V) {
608 if (!LoweredGCPtrs.
insert(PtrSD))
610 GCPtrIndexMap[PtrSD] = LoweredGCPtrs.
size() - 1;
612 assert(!LowerAsVReg.
count(PtrSD) &&
"must not have been seen");
613 if (LowerAsVReg.
size() == MaxVRegPtrs)
616 "IR and SD types disagree");
617 if (!canPassGCPtrOnVReg(PtrSD)) {
622 LowerAsVReg[PtrSD] = CurNumVRegs++;
628 for (
const Value *V :
SI.Bases)
633 auto requireSpillSlot = [&](
const Value *V) {
634 if (!Builder.DAG.getTargetLoweringInfo().isTypeLegal(
635 Builder.getValue(V).getValueType()))
638 return !LowerAsVReg.
count(Builder.getValue(V));
647 for (
const Value *V :
SI.DeoptState) {
648 if (requireSpillSlot(V))
652 for (
const Value *V :
SI.Ptrs) {
654 if (!LowerAsVReg.
count(SDV))
658 for (
const Value *V :
SI.Bases) {
660 if (!LowerAsVReg.
count(SDV))
667 const int NumVMSArgs =
SI.DeoptState.size();
673 for (
const Value *V :
SI.DeoptState) {
678 int FI = Builder.FuncInfo.getArgumentFrameIndex(Arg);
680 Incoming = Builder.DAG.getFrameIndex(FI, Builder.getFrameIndexTy());
685 <<
" requireSpillSlot = " << requireSpillSlot(V) <<
"\n");
692 for (
SDValue SDV : LoweredGCPtrs)
710 "Incoming value is a frame index!");
711 Allocas.
push_back(Builder.DAG.getTargetFrameIndex(
712 FI->getIndex(), Builder.getFrameIndexTy()));
714 auto &
MF = Builder.DAG.getMachineFunction();
724 SDLoc L = Builder.getCurSDLoc();
725 for (
unsigned i = 0; i <
SI.Ptrs.size(); ++i) {
729 Builder.DAG.getTargetConstant(GCPtrIndexMap[
Base], L, MVT::i64));
731 assert(GCPtrIndexMap.
count(Derived) &&
"derived not found in index map");
733 Builder.DAG.getTargetConstant(GCPtrIndexMap[Derived], L, MVT::i64));
746 assert(
SI.Bases.size() ==
SI.Ptrs.size() &&
"Pointer without base!");
748 "No gc specified, so cannot relocate pointers!");
751 <<
"Lowering statepoint " << *
SI.StatepointInstr <<
"\n");
753 for (
const auto *
Reloc :
SI.GCRelocates)
754 if (
Reloc->getParent() ==
SI.StatepointInstr->getParent())
787 if (CallHasIncomingGlue) {
799 const bool IsGCTransition =
802 if (IsGCTransition) {
809 for (
const Value *V :
SI.GCTransitionArgs) {
811 if (V->getType()->isPointerTy())
816 if (CallHasIncomingGlue)
819 SDVTList NodeTys =
DAG.getVTList(MVT::Other, MVT::Glue);
824 Chain = GCTransitionStart.
getValue(0);
825 Glue = GCTransitionStart.
getValue(1);
840 unsigned NumCallRegArgs =
846 Ops.push_back(CallTarget);
851 if (CallHasIncomingGlue)
852 RegMaskIt = CallNode->
op_end() - 2;
854 RegMaskIt = CallNode->
op_end() - 1;
861 uint64_t Flags =
SI.StatepointFlags;
863 "Unknown flag used");
870 Ops.push_back(*RegMaskIt);
873 Ops.push_back(Chain);
882 for (
auto SD : LoweredGCArgs) {
883 if (!LowerAsVReg.
count(SD))
888 assert(NodeTys.
size() == LowerAsVReg.
size() &&
"Inconsistent GC Ptr lowering");
892 unsigned NumResults = NodeTys.
size();
895 DAG.setNodeMemRefs(StatepointMCNode, MemRefs);
901 for (
const auto *Relocate :
SI.GCRelocates) {
902 Value *Derived = Relocate->getDerivedPtr();
904 auto It = LowerAsVReg.
find(SD);
905 if (It == LowerAsVReg.
end())
912 if (
SI.StatepointInstr->getParent() == Relocate->getParent()) {
922 auto [VRegIt, Inserted] = VirtRegs.
try_emplace(SD);
926 auto *RetTy = Relocate->getType();
929 DAG.getDataLayout(), Reg, RetTy, std::nullopt);
932 PendingExports.push_back(Chain);
934 VRegIt->second = Reg;
940 auto &RelocationMap =
FuncInfo.StatepointRelocationMaps[StatepointInstr];
949 if (LowerAsVReg.
count(SDV)) {
955 auto It = VirtRegs.
find(SDV);
957 Record.payload.Reg = It->second;
959 }
else if (
Loc.getNode()) {
971 Record.RematLeaf.emplace(SDV);
973 RelocationMap[Relocate] =
Record;
976 SDNode *SinkNode = StatepointMCNode;
982 if (IsGCTransition) {
989 for (
const Value *V :
SI.GCTransitionArgs) {
991 if (V->getType()->isPointerTy())
998 SDVTList NodeTys =
DAG.getVTList(MVT::Other, MVT::Glue);
1003 SinkNode = GCTransitionStart.
getNode();
1010 SDValue StatepointValues[2] = {
SDValue(SinkNode, NumSinkValues - 2),
1011 SDValue(SinkNode, NumSinkValues - 1)};
1012 DAG.ReplaceAllUsesWith(CallNode, StatepointValues);
1014 DAG.DeleteNode(CallNode);
1032static std::pair<const GCResultInst*, const GCResultInst*>
1034 std::pair<const GCResultInst *, const GCResultInst*> Res(
nullptr,
nullptr);
1035 for (
const auto *U : S.
users()) {
1051 "anyregcc is not supported on statepoints!");
1055 assert(
GFI->getStrategy().useStatepoints() &&
1056 "GCStrategy does not expect to encounter statepoints");
1062 if (
I.getNumPatchBytes() > 0) {
1068 ActualCallee =
DAG.getUNDEF(Callee.getValueType());
1070 ActualCallee = Callee;
1075 if (GCResultLocality.first)
1076 retAttrs = GCResultLocality.first->getAttributes().getRetAttrs();
1080 I.getNumCallArgs(), ActualCallee,
1081 I.getActualReturnType(), retAttrs,
1099 SI.GCRelocates.push_back(Relocate);
1102 if (Seen.
insert(DerivedSD).second) {
1103 SI.Bases.push_back(Relocate->getBasePtr());
1104 SI.Ptrs.push_back(Relocate->getDerivedPtr());
1114 for (Value *V :
I.deopt_operands()) {
1118 SI.Bases.push_back(V);
1119 SI.Ptrs.push_back(V);
1124 SI.StatepointInstr = &
I;
1129 I.gc_transition_args_end());
1131 SI.StatepointFlags =
I.getFlags();
1132 SI.NumPatchBytes =
I.getNumPatchBytes();
1133 SI.EHPadBB = EHPadBB;
1138 if (!GCResultLocality.first && !GCResultLocality.second) {
1145 if (GCResultLocality.first) {
1152 if (!GCResultLocality.second)
1162 Type *RetTy = GCResultLocality.second->getType();
1165 DAG.getDataLayout(), Reg, RetTy,
1166 I.getCallingConv());
1170 PendingExports.push_back(Chain);
1176 bool VarArgDisallowed,
bool ForceVoidReturnTy) {
1180 unsigned ArgBeginIndex =
Call->arg_begin() -
Call->op_begin();
1182 SI.CLI,
Call, ArgBeginIndex,
Call->arg_size(), Callee,
1184 Call->getAttributes().getRetAttrs(),
false);
1185 if (!VarArgDisallowed)
1186 SI.CLI.IsVarArg =
Call->getFunctionType()->isVarArg();
1193 SI.ID = SD.StatepointID.value_or(DefaultID);
1194 SI.NumPatchBytes = SD.NumPatchBytes.value_or(0);
1199 SI.EHPadBB = EHPadBB;
1217void SelectionDAGBuilder::visitGCResult(
const GCResultInst &CI) {
1222 "GetStatepoint must return one of two types");
1237 SDValue CopyFromReg = getCopyFromRegs(
SI, RetTy);
1239 assert(CopyFromReg.getNode());
1240 setValue(&CI, CopyFromReg);
1243void SelectionDAGBuilder::visitGCRelocate(
const GCRelocateInst &Relocate) {
1251 "GetStatepoint must return one of two types");
1256 StatepointLowering.relocCallVisited(Relocate);
1260 auto &RelocationMap =
1262 auto SlotIt = RelocationMap.find(&Relocate);
1263 assert(SlotIt != RelocationMap.end() &&
"Relocating not lowered gc value");
1270 "Nonlocal gc.relocate mapped via SDValue");
1271 SDValue SDV = StatepointLowering.getLocation(
getValue(DerivedPtr));
1273 setValue(&Relocate, SDV);
1278 RegsForValue RFV(*DAG.getContext(), DAG.getTargetLoweringInfo(),
1279 DAG.getDataLayout(), InReg, Relocate.
getType(),
1284 SDValue Chain = DAG.getRoot();
1285 SDValue Relocation = RFV.getCopyFromRegs(DAG, FuncInfo, getCurSDLoc(),
1286 Chain,
nullptr,
nullptr);
1287 setValue(&Relocate, Relocation);
1293 SDValue SpillSlot = DAG.getFrameIndex(Index, getFrameIndexTy());
1302 const SDValue Chain = DAG.getRoot();
1304 auto &
MF = DAG.getMachineFunction();
1305 auto &MFI =
MF.getFrameInfo();
1308 MFI.getObjectSize(Index),
1309 MFI.getObjectAlign(Index));
1311 auto LoadVT = DAG.getTargetLoweringInfo().getValueType(DAG.getDataLayout(),
1315 DAG.getLoad(LoadVT, getCurSDLoc(), Chain, SpillSlot, LoadMMO);
1316 PendingLoads.push_back(SpillLoad.
getValue(1));
1319 setValue(&Relocate, SpillLoad);
1328 EVT VT = DAG.getTargetLoweringInfo().getValueType(DAG.getDataLayout(),
1331 Record.RematLeaf->rematerialize(DAG, getCurSDLoc(), VT));
1345 setValue(&Relocate, SD);
1349 const auto &
TLI =
DAG.getTargetLoweringInfo();
1351 RTLIB::LibcallImpl DeoptImpl =
1352 DAG.getLibcalls().getLibcallImpl(RTLIB::DEOPTIMIZE);
1353 if (DeoptImpl == RTLIB::Unsupported) {
1354 DAG.getContext()->emitError(
"no deoptimize libcall available");
1374 if (
DAG.getTarget().Options.TrapUnreachable)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static const Function * getParent(const Value *V)
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static DeltaTreeNode * getRoot(void *Root)
static constexpr Value * getValue(Ty &ValueOrUse)
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
Promote Memory to Register
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 constexpr uint32_t UndefStackMapValue
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.
This class holds the attributes for a particular argument, parameter, function, or return value.
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.
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
const TargetLowering * TLI
LLVM_ABI const Value * getStatepoint() const
The statepoint with which this gc.relocate is associated.
Represents calls to the gc.relocate intrinsic.
LLVM_ABI Value * getDerivedPtr() const
Represents calls to the gc.result intrinsic.
Represents a gc.statepoint intrinsic call.
iterator_range< user_iterator > users()
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.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags F, LLT MemTy, Align BaseAlignment, const MMOMetadata &Metadata=MMOMetadata(), SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
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
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.
TypeSize getValueSizeInBits() const
Returns the size of the value in bits.
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.
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.
GCFunctionInfo * GFI
Garbage collection metadata for the function.
SDLoc getCurSDLoc() const
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.
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
LLVM_ABI SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
LLVM_ABI SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
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.
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 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 allocateStackSlot(EVT ValueType, SelectionDAGBuilder &Builder)
Get a stack slot we can use to store an value of type ValueType.
void startNewStatepoint(SelectionDAGBuilder &Builder)
Reset all state tracking for a newly encountered safepoint.
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
The instances of the Type class are immutable: once they are created, they are never changed.
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
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.
@ 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.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
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.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
auto dyn_cast_or_null(const Y &Val)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI StatepointDirectives parseStatepointDirectivesFromAttrs(AttributeList AS)
Parse out statepoint directives from the function attributes present in AS.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
ArrayRef(const T &OneElt) -> ArrayRef< T >
@ 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.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
PointerUnion< const Value *, const PseudoSourceValue * > ValueType
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.
LLVM_ABI SDValue rematerialize(SelectionDAG &DAG, const SDLoc &DL, EVT VT) const
Rebuild the captured leaf as a fresh SDValue of type VT.
LLVM_ABI StatepointDirectLeaf(SDValue V)
Capture the leaf V, which must be a directly-lowered value.
Helper object to track which of three possible relocation mechanisms are used for a particular value ...
static LLVM_ABI 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