57 #define DEBUG_TYPE "statepoint-lowering" 59 STATISTIC(NumSlotsAllocatedForStatepoints,
60 "Number of stack slots allocated for statepoints");
61 STATISTIC(NumOfStatepoints,
"Number of statepoint nodes encountered");
63 "Maximum number of stack slots required for a singe statepoint");
75 assert(PendingGCRelocateCalls.empty() &&
76 "Trying to visit statepoint before finished processing previous one");
78 NextSlotToAllocate = 0;
82 AllocatedStackSlots.
clear();
88 AllocatedStackSlots.
clear();
89 assert(PendingGCRelocateCalls.empty() &&
90 "cleared before statepoint sequence completed");
96 NumSlotsAllocatedForStatepoints++;
106 const size_t NumSlots = AllocatedStackSlots.
size();
107 assert(NextSlotToAllocate <= NumSlots &&
"Broken invariant");
113 for (; NextSlotToAllocate < NumSlots; NextSlotToAllocate++) {
114 if (!AllocatedStackSlots.
test(NextSlotToAllocate)) {
117 AllocatedStackSlots.
set(NextSlotToAllocate);
127 const unsigned FI = cast<FrameIndexSDNode>(SpillSlot)->getIndex();
131 AllocatedStackSlots.
resize(AllocatedStackSlots.
size()+1,
true);
136 StatepointMaxSlotsRequired.updateMax(
149 if (LookUpDepth <= 0)
153 if (
const auto *Relocate = dyn_cast<GCRelocateInst>(Val)) {
154 const auto &SpillMap =
157 auto It = SpillMap.find(Relocate->getDerivedPtr());
158 if (It == SpillMap.end())
165 if (
const BitCastInst *Cast = dyn_cast<BitCastInst>(Val))
171 if (
const PHINode *Phi = dyn_cast<PHINode>(Val)) {
174 for (
auto &IncomingValue : Phi->incoming_values()) {
180 if (MergedResult.
hasValue() && *MergedResult != *SpillSlot)
183 MergedResult = SpillSlot;
228 if (isa<ConstantSDNode>(Incoming) || isa<FrameIndexSDNode>(Incoming)) {
239 const int LookUpDepth = 6;
247 auto SlotIt =
find(StatepointSlots, *Index);
248 assert(SlotIt != StatepointSlots.end() &&
249 "Value spilled to the unknown stack slot");
252 const int Offset = std::distance(StatepointSlots.begin(), SlotIt);
286 for (
size_t i = 0, e = Ptrs.
size(); i < e; i++) {
288 auto SeenIt = Seen.
find(SD);
290 if (SeenIt == Seen.
end()) {
317 SDValue ReturnValue, CallEndVal;
318 std::tie(ReturnValue, CallEndVal) =
357 static std::pair<SDValue, SDValue>
366 int Index = cast<FrameIndexSDNode>(Loc)->getIndex();
382 "Bad spill: stack slot does not match!");
393 return std::make_pair(Loc, Chain);
417 "Incoming value is a frame index!");
420 }
else if (LiveInOnly) {
457 if (
auto *GFI = Builder.
GFI) {
466 if (Opt.hasValue()) {
468 "non gc managed base pointer found in statepoint");
473 if (Opt.hasValue()) {
475 "non gc managed derived pointer found in statepoint");
480 assert(SI.
Bases.empty() &&
"No gc specified, so cannot relocate pointers!");
481 assert(SI.
Ptrs.empty() &&
"No gc specified, so cannot relocate pointers!");
495 const bool LiveInDeopt =
498 auto isGCValue =[&](
const Value *V) {
508 if (!LiveInDeopt || isGCValue(V))
511 for (
unsigned i = 0; i < SI.
Bases.size(); ++i) {
535 const bool LiveInValue = LiveInDeopt && !isGCValue(V);
544 for (
unsigned i = 0; i < SI.
Bases.size(); ++i) {
564 "Incoming value is a frame index!");
582 SpillMap.SlotMap[V] = cast<FrameIndexSDNode>(Loc)->getIndex();
590 SpillMap.SlotMap[V] =
None;
612 StatepointLowering.startNewStatepoint(*
this);
619 StatepointLowering.scheduleRelocCall(*Reloc);
642 std::tie(ReturnVal, CallNode) =
653 if (CallHasIncomingGlue) {
665 const bool IsGCTransition =
668 if (IsGCTransition) {
682 if (CallHasIncomingGlue)
690 Chain = GCTransitionStart.
getValue(0);
691 Glue = GCTransitionStart.
getValue(1);
706 unsigned NumCallRegArgs =
717 if (CallHasIncomingGlue)
718 RegMaskIt = CallNode->
op_end() - 2;
720 RegMaskIt = CallNode->
op_end() - 1;
729 "Unknown flag used");
733 Ops.
insert(Ops.
end(), LoweredMetaArgs.begin(), LoweredMetaArgs.end());
749 SDNode *StatepointMCNode =
750 DAG.getMachineNode(TargetOpcode::STATEPOINT, getCurSDLoc(), NodeTys, Ops);
752 SDNode *SinkNode = StatepointMCNode;
758 if (IsGCTransition) {
779 SinkNode = GCTransitionStart.
getNode();
783 DAG.ReplaceAllUsesWith(CallNode, SinkNode);
785 DAG.DeleteNode(CallNode);
803 "anyregcc is not supported on statepoints!");
812 assert(GFI->getStrategy().useStatepoints() &&
813 "GCStrategy does not expect to encounter statepoints");
825 const auto &TLI = DAG.getTargetLoweringInfo();
826 const auto &DL = DAG.getDataLayout();
829 ActualCallee = DAG.getConstant(0, getCurSDLoc(), TLI.getPointerTy(DL, AS));
835 populateCallLoweringInfo(SI.CLI, ISP.
getCallSite(),
841 SI.GCRelocates.push_back(Relocate);
842 SI.Bases.push_back(Relocate->getBasePtr());
843 SI.Ptrs.push_back(Relocate->getDerivedPtr());
848 SI.GCTransitionArgs =
852 SI.StatepointFlags = ISP.
getFlags();
854 SI.EHPadBB = EHPadBB;
856 SDValue ReturnValue = LowerAsSTATEPOINT(SI);
861 if (!RetTy->
isVoidTy() && GCResult) {
871 unsigned Reg = FuncInfo.CreateRegs(RetTy);
872 RegsForValue RFV(*DAG.getContext(), DAG.getTargetLoweringInfo(),
873 DAG.getDataLayout(),
Reg, RetTy,
875 SDValue Chain = DAG.getEntryNode();
877 RFV.getCopyToRegs(ReturnValue, DAG, getCurSDLoc(), Chain,
nullptr);
878 PendingExports.push_back(Chain);
889 setValue(ISP.
getInstruction(), DAG.getIntPtrConstant(-1, getCurSDLoc()));
895 bool VarArgDisallowed,
bool ForceVoidReturnTy) {
898 populateCallLoweringInfo(
902 if (!VarArgDisallowed)
910 SI.
ID = SD.StatepointID.getValueOr(DefaultID);
920 if (
SDValue ReturnVal = LowerAsSTATEPOINT(SI)) {
922 ReturnVal = lowerRangeToAssertZExt(DAG, *Inst, ReturnVal);
923 setValue(Inst, ReturnVal);
929 LowerCallSiteWithDeoptBundleImpl(CS, Callee, EHPadBB,
934 void SelectionDAGBuilder::visitGCResult(
const GCResultInst &CI) {
949 cast<FunctionType>(CalleeType->
getElementType())->getReturnType();
953 setValue(&CI, CopyFromReg);
955 setValue(&CI, getValue(I));
959 void SelectionDAGBuilder::visitGCRelocate(
const GCRelocateInst &Relocate) {
966 StatepointLowering.relocCallVisited(Relocate);
969 if (
auto IsManaged = GFI->getStrategy().isGCManagedPointer(Ty))
970 assert(*IsManaged &&
"Non gc managed pointer relocated!");
974 SDValue SD = getValue(DerivedPtr);
976 auto &SpillMap = FuncInfo.StatepointSpillMaps[Relocate.
getStatepoint()];
977 auto SlotIt = SpillMap.find(DerivedPtr);
978 assert(SlotIt != SpillMap.end() &&
"Relocating not lowered gc value");
983 if (!DerivedPtrLocation) {
984 setValue(&Relocate, SD);
989 DAG.getTargetFrameIndex(*DerivedPtrLocation, getFrameIndexTy());
997 DAG.getLoad(DAG.getTargetLoweringInfo().getValueType(DAG.getDataLayout(),
999 getCurSDLoc(), Chain, SpillSlot,
1001 *DerivedPtrLocation));
1004 DAG.setRoot(SpillLoad.
getValue(1));
1007 setValue(&Relocate, SpillLoad);
1011 const auto &TLI = DAG.getTargetLoweringInfo();
1012 SDValue Callee = DAG.getExternalSymbol(TLI.getLibcallName(RTLIB::DEOPTIMIZE),
1013 TLI.getPointerTy(DAG.getDataLayout()));
1018 LowerCallSiteWithDeoptBundleImpl(CI, Callee,
nullptr,
1027 if (DAG.getTarget().Options.TrapUnreachable)
SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, unsigned Alignment=0, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
Helper function to build ISD::STORE nodes.
Represents calls to the gc.result intrinsic.
EVT getValueType() const
Return the ValueType of the referenced return value.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
This class represents an incoming formal argument to a Function.
CallingConv::ID getCallingConv() const
Get the calling convention of the call.
This class represents lattice values for constants.
void ExportFromCurrentBlock(const Value *V)
ExportFromCurrentBlock - If this condition isn't known to be exported from the current basic block...
ValueTy * getCalledValue() const
Return the value actually being called or invoked.
static void lowerStatepointMetaArgs(SmallVectorImpl< SDValue > &Ops, SelectionDAGBuilder::StatepointLoweringInfo &SI, SelectionDAGBuilder &Builder)
Lower deopt state and gc pointer arguments of the statepoint.
void LowerDeoptimizeCall(const CallInst *CI)
TargetLowering::CallLoweringInfo CLI
Information regarding the underlying call instruction.
StatepointDirectives parseStatepointDirectivesFromAttrs(AttributeList AS)
Parse out statepoint directives from the function attributes present in AS.
SmallVector< const GCRelocateInst *, 16 > GCRelocates
The set of gc.relocate calls associated with this gc.statepoint.
SelectionDAGBuilder - This is the common target-independent lowering implementation that is parameter...
A specialization of it's base class for read only access to a gc.statepoint.
void push_back(const T &Elt)
This class represents a function call, abstracting a target machine's calling convention.
void LowerDeoptimizingReturn()
uint64_t getID() const
Return the ID associated with this statepoint.
static std::pair< SDValue, SDNode * > lowerCallFromStatepointLoweringInfo(SelectionDAGBuilder::StatepointLoweringInfo &SI, SelectionDAGBuilder &Builder, SmallVectorImpl< SDValue > &PendingExports)
Extract call from statepoint, lower it and return pointer to the call node.
void resize(unsigned N, bool t=false)
Grow or shrink the bitvector.
STATISTIC(NumFunctions, "Total number of functions")
unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
CallSiteTy getCallSite() const
Return the underlying CallSite.
SDNode * getNode() const
get the SDNode which holds the desired result
const SDValue & setRoot(SDValue N)
Set the current root tag of the SelectionDAG.
unsigned getValueSizeInBits() const
Returns the size of the value in bits.
static void reservePreviousStackSlotForValue(const Value *IncomingValue, SelectionDAGBuilder &Builder)
Try to find existing copies of the incoming values in stack slots used for statepoint spilling...
Keep track of frame indices allocated for statepoints as they could be used across basic block bounda...
SDValue getValue(const Value *V)
getValue - Return an SDValue for the given Value.
bool test(unsigned Idx) const
unsigned ID
The ID that the resulting STATEPOINT instruction has to report.
SDValue getRoot()
Return the current virtual root of the Selection DAG, flushing any PendingLoad items.
CallSiteTy::arg_iterator gc_args_begin() const
uint64_t StatepointFlags
Flags associated with the meta arguments being lowered.
CallSiteTy::arg_iterator deopt_begin() const
Value * getDerivedPtr() const
ArrayRef< const Use > GCTransitionArgs
The list of gc transition arguments present in the gc.statepoint being lowered.
CallLoweringInfo & setChain(SDValue InChain)
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
op_iterator op_end() const
unsigned getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
InstrTy * getInstruction() const
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted...
static void removeDuplicateGCPtrs(SmallVectorImpl< const Value *> &Bases, SmallVectorImpl< const Value *> &Ptrs, SmallVectorImpl< const GCRelocateInst *> &Relocs, SelectionDAGBuilder &Builder, FunctionLoweringInfo::StatepointSpillMap &SSM)
Remove any duplicate (as SDValues) from the derived pointer pairs.
InstructionTy * getInstruction() const
SDValue LowerAsSTATEPOINT(StatepointLoweringInfo &SI)
Lower SLI into a STATEPOINT instruction.
void LowerCallSiteWithDeoptBundle(ImmutableCallSite CS, SDValue Callee, const BasicBlock *EHPadBB)
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
int getArgumentFrameIndex(const Argument *A)
getArgumentFrameIndex - Get frame index for the byval argument.
uint32_t getNumPatchBytes() const
Return the number of patchable bytes associated with this statepoint.
unsigned getSizeInBits() const
Return the size of the specified value type in bits.
Type * getType() const
All values are typed, get the type of this value.
MachineFunction & getMachineFunction() const
CallSiteTy::arg_iterator gc_args_end() const
SDValue getTargetFrameIndex(int FI, EVT VT)
virtual Optional< bool > isGCManagedPointer(const Type *Ty) const
If the type specified can be reliably distinguished, returns true for pointers to GC managed location...
This class represents a no-op cast from one type to another.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
op_iterator op_begin() const
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
amdgpu Simplify well known AMD library false Value * Callee
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
Class to represent pointers.
static const uint64_t DeoptBundleStatepointID
int getNumCallArgs() const
Number of arguments to be passed to the actual callee.
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
iterator find(const_arg_type_t< KeyT > Val)
Optional< OperandBundleUse > getOperandBundle(StringRef Name) const
bool isVoidTy() const
Return true if this is 'void'.
const Instruction * getStatepoint() const
The statepoint with which this gc.relocate is associated.
void reserveStackSlot(int Offset)
std::pair< SDValue, SDValue > lowerInvokable(TargetLowering::CallLoweringInfo &CLI, const BasicBlock *EHPadBB=nullptr)
const Instruction * StatepointInstr
The gc.statepoint instruction.
GC_TRANSITION_START/GC_TRANSITION_END - These operators mark the beginning and end of GC transition s...
ArrayRef< const Use > DeoptState
The deoptimization state associated with this gc.statepoint call, if any.
const GCResultInst * getGCResult() const
Get the experimental_gc_result call tied to this statepoint.
LLVM Basic Block Representation.
The instances of the Type class are immutable: once they are created, they are never changed...
static std::pair< SDValue, SDValue > spillIncomingStatepointValue(SDValue Incoming, SDValue Chain, SelectionDAGBuilder &Builder)
Spill a value incoming to the statepoint.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
static void pushStackMapConstant(SmallVectorImpl< SDValue > &Ops, SelectionDAGBuilder &Builder, uint64_t Value)
const SDValue & getOperand(unsigned Num) const
bool isStackSlotAllocated(int Offset)
bool isPointerTy() const
True if this is an instance of PointerType.
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.
static Type * getVoidTy(LLVMContext &C)
void clear()
Clear the memory usage of this object.
void verify()
Asserts if this statepoint is malformed.
TRAP - Trapping instruction.
SDNode * getGluedNode() const
If this node has a glue operand, return the node to which the glue operand points.
static Optional< int > findPreviousSpillSlot(const Value *Val, SelectionDAGBuilder &Builder, int LookUpDepth)
Utility function for reservePreviousStackSlotForValue.
DenseMap< const Instruction *, StatepointSpillMap > StatepointSpillMaps
Maps gc.statepoint instructions to their corresponding StatepointSpillMap instances.
unsigned getNumArgOperands() const
auto find(R &&Range, const T &Val) -> decltype(adl_begin(Range))
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly...
unsigned getNumOperands() const
Return the number of values used by this operation.
SDLoc getCurSDLoc() const
void setLocation(SDValue Val, SDValue Location)
SmallVector< unsigned, 50 > StatepointStackSlots
StatepointStackSlots - A list of temporary stack slots (frame indices) used to spill values at a stat...
SDValue CreateStackTemporary(EVT VT, unsigned minAlign=1)
Create a stack temporary, suitable for holding the specified value type.
void markAsStatepointSpillSlotObjectIndex(int ObjectIdx)
void clear()
Clear all bits.
static void lowerIncomingStatepointValue(SDValue Incoming, bool LiveInOnly, SmallVectorImpl< SDValue > &Ops, SelectionDAGBuilder &Builder)
Lower a single value incoming to a statepoint node.
RegsForValue - This struct represents the registers (physical or virtual) that a particular set of va...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
DenseMap< const Value *, const Value * > DuplicateMap
Maps llvm IR values to the values they were de-duplicated to.
CallSiteTy::arg_iterator deopt_end() const
Indicates that this statepoint is a transition from GC-aware code to code that is not GC-aware...
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
size_t size() const
Returns the number of bits in this bitvector.
Represents one node in the SelectionDAG.
BBTy * getParent() const
Get the basic block containing the call site.
GCFunctionInfo * GFI
GFI - Garbage collection metadata for the function.
iterator insert(iterator I, T &&Elt)
amdgpu Simplify well known AMD library false Value Value * Arg
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
Represents a use of a SDNode.
void LowerStatepoint(ImmutableStatepoint ISP, const BasicBlock *EHPadBB=nullptr)
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
GCStrategy describes a garbage collector algorithm's code generation requirements, and provides overridable hooks for those needs which cannot be abstractly described.
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
Establish a view to a call site for examination.
void startNewStatepoint(SelectionDAGBuilder &Builder)
Reset all state tracking for a newly encountered safepoint.
SmallVector< const Value *, 16 > Bases
Bases[i] is the base pointer for Ptrs[i].
SDValue getValue(unsigned R) const
StatepointLoweringState StatepointLowering
State used while lowering a statepoint sequence (gc_statepoint, gc_relocate, and gc_result).
CopyFromReg - This node indicates that the input value is a virtual or physical register that is defi...
std::vector< const GCRelocateInst * > getRelocates() const
Get list of all gc reloactes linked to this statepoint May contain several relocations for the same b...
Type * getType() const
Return the type of the instruction that generated this call site.
Type * getActualReturnType() const
Return the type of the value returned by the call underlying the statepoint.
unsigned NumPatchBytes
The number of patchable bytes the call needs to get lowered into.
void LowerCallSiteWithDeoptBundleImpl(ImmutableCallSite CS, SDValue Callee, const BasicBlock *EHPadBB, bool VarArgDisallowed, bool ForceVoidReturnTy)
FunctionLoweringInfo & FuncInfo
FuncInfo - Information about the function as a whole.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
const BasicBlock * EHPadBB
The exception handling unwind destination, in case this represents an invoke of gc.statepoint.
SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
Represents calls to the gc.relocate intrinsic.
Mark the deopt arguments associated with the statepoint as only being "live-in".
LLVM Value Representation.
FunctionType * getFunctionType() const
ArrayRef< const Use > GCArgs
The full list of gc arguments to the gc.statepoint being lowered.
MVT getFrameIndexTy()
Returns the type of FrameIndex and TargetFrameIndex nodes.
AttributeList getAttributes() const
Get the parameter attributes of the call.
uint64_t getFlags() const
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation...
A bitmask that includes all valid flags.
SmallVector< const Value *, 16 > Ptrs
Type * getElementType() const
Describes a gc.statepoint or a gc.statepoint like thing for the purposes of lowering into a STATEPOIN...
This file describes how to lower LLVM code to machine code.
const BasicBlock * getParent() const
A discriminated union of two pointer types, with the discriminator in the low bit of the pointer...
bool is_contained(R &&Range, const E &Element)
Wrapper function around std::find to detect if an element exists in a container.