33 #define DEBUG_TYPE "statepoint-lowering"
35 STATISTIC(NumSlotsAllocatedForStatepoints,
36 "Number of stack slots allocated for statepoints");
37 STATISTIC(NumOfStatepoints,
"Number of statepoint nodes encountered");
39 "Maximum number of stack slots required for a singe statepoint");
51 assert(PendingGCRelocateCalls.empty() &&
52 "Trying to visit statepoint before finished processing previous one");
54 NextSlotToAllocate = 0;
59 for (
size_t i = 0; i < AllocatedStackSlots.
size(); i++) {
60 AllocatedStackSlots[i] =
false;
66 AllocatedStackSlots.
clear();
67 assert(PendingGCRelocateCalls.empty() &&
68 "cleared before statepoint sequence completed");
75 NumSlotsAllocatedForStatepoints++;
82 for (
int i = 0; i < 40000; i++) {
84 AllocatedStackSlots.
size() &&
86 const size_t NumSlots = AllocatedStackSlots.
size();
87 assert(NextSlotToAllocate <= NumSlots &&
"broken invariant");
89 if (NextSlotToAllocate >= NumSlots) {
90 assert(NextSlotToAllocate == NumSlots);
92 if (NumSlots + 1 > StatepointMaxSlotsRequired) {
93 StatepointMaxSlotsRequired = NumSlots + 1;
97 const unsigned FI = cast<FrameIndexSDNode>(SpillSlot)->getIndex();
102 if (!AllocatedStackSlots[NextSlotToAllocate]) {
104 AllocatedStackSlots[NextSlotToAllocate] =
true;
111 NextSlotToAllocate++;
123 if (LookUpDepth <= 0)
134 if (It == SpillMap.
end())
141 if (
const BitCastInst *Cast = dyn_cast<BitCastInst>(Val)) {
148 if (
const PHINode *Phi = dyn_cast<PHINode>(Val)) {
151 for (
auto &IncomingValue : Phi->incoming_values()) {
157 if (MergedResult.
hasValue() && *MergedResult != *SpillSlot)
160 MergedResult = SpillSlot;
206 if (isa<ConstantSDNode>(Incoming) || isa<FrameIndexSDNode>(Incoming)) {
217 const int LookUpDepth = 6;
226 "value spilled to the unknown stack slot");
262 for (
size_t i = 0; i < Ptrs.
size(); i++) {
265 if (Seen.
count(SD) == 0) {
272 assert(Bases.
size() >= NewBases.
size());
273 assert(Ptrs.
size() >= NewPtrs.
size());
274 assert(Relocs.
size() >= NewRelocs.
size());
278 assert(Ptrs.
size() == Bases.size());
279 assert(Ptrs.
size() == Relocs.
size());
295 "anyregcc is not supported on statepoints!");
300 SDValue ReturnValue, CallEndVal;
345 RFV.getCopyToRegs(ReturnValue, Builder.
DAG, Builder.
getCurSDLoc(), Chain,
353 Builder.
setValue(
CS.getInstruction(), ReturnValue);
376 Relocs.
push_back(relocateOpers.getUnderlyingCallSite().getInstruction());
377 Bases.
push_back(relocateOpers.getBasePtr());
378 Ptrs.
push_back(relocateOpers.getDerivedPtr());
396 static std::pair<SDValue, SDValue>
405 assert(isa<FrameIndexSDNode>(Loc));
406 int Index = cast<FrameIndexSDNode>(Loc)->getIndex();
421 return std::make_pair(Loc, Chain);
451 std::pair<SDValue, SDValue> Res =
485 for (
const Value *V : Bases) {
487 if (Opt.hasValue()) {
488 assert(Opt.getValue() &&
489 "non gc managed base pointer found in statepoint");
492 for (
const Value *V : Ptrs) {
494 if (Opt.hasValue()) {
495 assert(Opt.getValue() &&
496 "non gc managed derived pointer found in statepoint");
499 for (
const Value *V : Relocations) {
501 if (Opt.hasValue()) {
502 assert(Opt.getValue() &&
"non gc managed pointer relocated");
515 for (
unsigned i = 0; i < Bases.size(); ++i) {
526 assert(NumVMSArgs == std::distance(StatepointSite.
vm_state_begin(),
545 for (
unsigned i = 0; i < Bases.size(); ++i) {
546 const Value *Base = Bases[i];
549 const Value *Ptr = Ptrs[i];
576 const Value *V = RelocateOpers.getDerivedPtr();
581 SpillMap[V] = cast<FrameIndexSDNode>(Loc)->getIndex();
602 void SelectionDAGBuilder::visitStatepoint(
const CallInst &CI) {
605 "function called must be the statepoint function");
625 if (!
CS.isInvoke()) {
626 for (
const User *U :
CS->users()) {
642 "GCStrategy does not expect to encounter statepoints");
661 if (CallHasIncomingGlue) {
673 const bool IsGCTransition =
676 if (IsGCTransition) {
685 if (V->getType()->isPointerTy())
690 if (CallHasIncomingGlue)
698 Chain = GCTransitionStart.
getValue(0);
699 Glue = GCTransitionStart.
getValue(1);
714 unsigned NumCallRegArgs =
725 if (CallHasIncomingGlue)
726 RegMaskIt = CallNode->
op_end() - 2;
728 RegMaskIt = CallNode->
op_end() - 1;
738 &&
"unknown flag used");
742 Ops.
insert(Ops.
end(), LoweredMetaArgs.begin(), LoweredMetaArgs.end());
758 SDNode *StatepointMCNode =
761 SDNode *SinkNode = StatepointMCNode;
767 if (IsGCTransition) {
776 if (V->getType()->isPointerTy())
788 SinkNode = GCTransitionStart.
getNode();
806 void SelectionDAGBuilder::visitGCResult(
const CallInst &CI) {
810 assert(
isStatepoint(I) &&
"first argument must be a statepoint token");
812 if (isa<InvokeInst>(I)) {
821 cast<FunctionType>(CalleeType->
getElementType())->getReturnType();
831 void SelectionDAGBuilder::visitGCRelocate(
const CallInst &CI) {
838 if (!RelocateOpers.isTiedToInvoke()) {
843 const Value *DerivedPtr = RelocateOpers.getDerivedPtr();
850 assert(SpillMap.
count(DerivedPtr) &&
"Relocating not lowered gc value");
855 if (!DerivedPtrLocation) {
871 false,
false,
false, 0);
void push_back(const T &Elt)
SDValue getValue(unsigned R) const
ValueTy * getCalledValue() const
Return the value actually being called or invoked.
LLVMContext * getContext() const
STATISTIC(NumFunctions,"Total number of functions")
void ExportFromCurrentBlock(const Value *V)
ExportFromCurrentBlock - If this condition isn't known to be exported from the current basic block...
void LowerStatepoint(ImmutableStatepoint Statepoint, MachineBasicBlock *LandingPad=nullptr)
InstrTy * getInstruction() const
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.
DenseMap< const Instruction *, StatepointSpilledValueMapTy > StatepointRelocatedValues
SDNode * getGluedNode() const
If this node has a glue operand, return the node to which the glue operand points.
CallInst - This class represents a function call, abstracting a target machine's calling convention...
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
void setValue(const Value *V, SDValue NewN)
CallSiteTy::arg_iterator vm_state_begin() const
SDValue getLoad(EVT VT, SDLoc dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, bool isVolatile, bool isNonTemporal, bool isInvariant, unsigned Alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr)
Loads are not normal binary operators: their result type is not determined by their operands...
unsigned getNumOperands() const
Return the number of values used by this operation.
const SDValue & getOperand(unsigned Num) const
const SDValue & setRoot(SDValue N)
Set the current root tag of the SelectionDAG.
void DeleteNode(SDNode *N)
Remove the specified node from the system.
static void reservePreviousStackSlotForValue(const Value *IncomingValue, SelectionDAGBuilder &Builder)
Try to find existing copies of the incoming values in stack slots used for statepoint spilling...
static MachinePointerInfo getFixedStack(int FI, int64_t offset=0)
getFixedStack - Return a MachinePointerInfo record that refers to the the specified FrameIndex...
SDValue getValue(const Value *V)
getValue - Return an SDValue for the given Value.
SDValue getRoot()
getRoot - Return the current virtual root of the Selection DAG, flushing any PendingLoad items...
iterator_range< arg_iterator > gc_transition_args() const
range adapter for GC transition arguments
SDValue getStore(SDValue Chain, SDLoc dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, bool isVolatile, bool isNonTemporal, unsigned Alignment, const AAMDNodes &AAInfo=AAMDNodes())
Helper function to build ISD::STORE nodes.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static SDNode * lowerCallFromStatepoint(ImmutableStatepoint ISP, MachineBasicBlock *LandingPad, SelectionDAGBuilder &Builder, SmallVectorImpl< SDValue > &PendingExports)
Extract call from statepoint, lower it and return pointer to the call node.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Reg
All possible values of the reg field in the ModR/M byte.
SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
CallSiteTy getCallSite() const
Return the underlying CallSite.
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
bool isStatepoint(const ImmutableCallSite &CS)
bool useStatepoints() const
Returns true if this strategy is expecting the use of gc.statepoints, and false otherwise.
SDValue getTargetFrameIndex(int FI, EVT VT)
This class represents a no-op cast from one type to another.
Type * getElementType() const
const DataLayout & getDataLayout() const
PointerType - Class to represent pointers.
SDNode * getNode() const
get the SDNode which holds the desired result
static void lowerIncomingStatepointValue(SDValue Incoming, SmallVectorImpl< SDValue > &Ops, SelectionDAGBuilder &Builder)
Lower a single value incoming to a statepoint node.
void reserveStackSlot(int Offset)
iterator_range< arg_iterator > vm_state_args() const
range adapter for vm state arguments
GC_TRANSITION_START/GC_TRANSITION_END - These operators mark the beginning and end of GC transition s...
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.
static void pushStackMapConstant(SmallVectorImpl< SDValue > &Ops, SelectionDAGBuilder &Builder, uint64_t Value)
bool isStackSlotAllocated(int Offset)
bool isGCRelocate(const Value *V)
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
iterator_range< arg_iterator > gc_args() const
range adapter for gc arguments
GCStrategy & getStrategy()
getStrategy - Return the GC strategy for the function.
SDValue allocateStackSlot(EVT ValueType, SelectionDAGBuilder &Builder)
Get a stack slot we can use to store an value of type ValueType.
void clear()
Clear the memory usage of this object.
SDValue getTargetConstant(uint64_t Val, SDLoc DL, EVT VT, bool isOpaque=false)
void verify()
Asserts if this statepoint is malformed.
std::pair< NoneType, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
SDLoc getCurSDLoc() const
static Optional< int > findPreviousSpillSlot(const Value *Val, SelectionDAGBuilder &Builder, int LookUpDepth)
Utility function for reservePreviousStackSlotForValue.
Wraps a call to a gc.relocate and provides access to it's operands.
virtual Optional< bool > isGCManagedPointer(const Value *V) const
If the value specified can be reliably distinguished, returns true for pointers to GC managed locatio...
EVT - Extended Value Type.
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.
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
CallSiteTy::arg_iterator vm_state_end() const
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...
Type * getType() const
All values are typed, get the type of this value.
uint64_t getID() const
Return the ID associated with this statepoint.
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...
Represents one node in the SelectionDAG.
Type * getActualReturnType() const
Return the type of the value returned by the call underlying the statepoint.
int getNumCallArgs() const
Number of arguments to be passed to the actual callee.
unsigned CreateRegs(Type *Ty)
CreateRegs - Allocate the appropriate number of virtual registers of the correctly promoted or expand...
size_type count(const KeyT &Val) const
Return 1 if the specified key is in the map, 0 otherwise.
void setLocation(SDValue val, SDValue Location)
GCFunctionInfo * GFI
GFI - Garbage collection metadata for the function.
Value * getArgOperand(unsigned i) const
getArgOperand/setArgOperand - Return/set the i-th call argument.
op_iterator op_begin() const
SDValue getNode(unsigned Opcode, SDLoc DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
const Instruction * getStatepoint()
The statepoint with which this gc.relocate is associated.
iterator insert(iterator I, T &&Elt)
Represents a use of a SDNode.
GCStrategy describes a garbage collector algorithm's code generation requirements, and provides overridable hooks for those needs which cannot be abstractly described.
static void getIncomingStatepointGCValues(SmallVectorImpl< const Value * > &Bases, SmallVectorImpl< const Value * > &Ptrs, SmallVectorImpl< const Value * > &Relocs, ImmutableStatepoint StatepointSite, SelectionDAGBuilder &Builder)
Callect all gc pointers coming into statepoint intrinsic, clean them up, and return two arrays: Bases...
static void removeDuplicatesGCPtrs(SmallVectorImpl< const Value * > &Bases, SmallVectorImpl< const Value * > &Ptrs, SmallVectorImpl< const Value * > &Relocs, SelectionDAGBuilder &Builder)
Remove any duplicate (as SDValues) from the derived pointer pairs.
std::vector< GCRelocateOperands > getRelocates() const
Get list of all gc reloactes linked to this statepoint May contain several relocations for the same b...
Call instruction with associated vm state for deoptimization and list of live pointers for relocation...
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
ImmutableCallSite - establish a view to a call site for examination.
void ReplaceAllUsesWith(SDValue From, SDValue Op)
Modify anything using 'From' to use 'To' instead.
void startNewStatepoint(SelectionDAGBuilder &Builder)
Reset all state tracking for a newly encountered safepoint.
int getNumTotalVMSArgs() const
Number of additional arguments excluding those intended for garbage collection.
std::pair< SDValue, SDValue > lowerCallOperands(ImmutableCallSite CS, unsigned ArgIdx, unsigned NumArgs, SDValue Callee, Type *ReturnTy, MachineBasicBlock *LandingPad=nullptr, bool IsPatchPoint=false)
Lower an argument list according to the target calling convention.
iterator find(const KeyT &Val)
op_iterator op_end() const
MachineSDNode * getMachineNode(unsigned Opcode, SDLoc dl, EVT VT)
These are used for target selectors to create a new node with specified return type(s), MachineInstr opcode, and operands.
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...
SDValue getCopyFromRegs(const Value *V, Type *Ty)
getCopyFromRegs - If there was virtual register allocated for the value V emit CopyFromReg of the spe...
EVT getValueType() const
Return the ValueType of the referenced return value.
FunctionLoweringInfo & FuncInfo
FuncInfo - Information about the function as a whole.
SDValue getLocation(SDValue val)
Returns the spill location of a value incoming to the current statepoint.
SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
LLVM Value Representation.
void scheduleRelocCall(const CallInst &RelocCall)
Record the fact that we expect to encounter a given gc_relocate before the next statepoint.
const TargetLowering & getTargetLoweringInfo() const
uint32_t getNumPatchBytes() const
Return the number of patchable bytes associated with this statepoint.
void relocCallVisited(const CallInst &RelocCall)
Remove this gc_relocate from the list we're expecting to see before the next statepoint.
SDValue getSrcValue(const Value *v)
Construct a node to track a Value* through the backend.
static void lowerStatepointMetaArgs(SmallVectorImpl< SDValue > &Ops, ImmutableStatepoint StatepointSite, SelectionDAGBuilder &Builder)
Lower deopt state and gc pointer arguments of the statepoint.
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
uint64_t getFlags() const
bool isInvoke() const
isInvoke - true if a InvokeInst is enclosed.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation...
A bitmask that includes all valid flags.
DenseMap< const Value *, unsigned > ValueMap
ValueMap - Since we emit code for the function a basic block at a time, we must remember which virtua...
SDValue getIntPtrConstant(uint64_t Val, SDLoc DL, bool isTarget=false)
This file describes how to lower LLVM code to machine code.
bool isVoidTy() const
isVoidTy - Return true if this is 'void'.