139d628a0SDimitry Andric //===-- StatepointLowering.cpp - SDAGBuilder's statepoint code -----------===// 239d628a0SDimitry Andric // 339d628a0SDimitry Andric // The LLVM Compiler Infrastructure 439d628a0SDimitry Andric // 539d628a0SDimitry Andric // This file is distributed under the University of Illinois Open Source 639d628a0SDimitry Andric // License. See LICENSE.TXT for details. 739d628a0SDimitry Andric // 839d628a0SDimitry Andric //===----------------------------------------------------------------------===// 939d628a0SDimitry Andric // 1039d628a0SDimitry Andric // This file includes support code use by SelectionDAGBuilder when lowering a 1139d628a0SDimitry Andric // statepoint sequence in SelectionDAG IR. 1239d628a0SDimitry Andric // 1339d628a0SDimitry Andric //===----------------------------------------------------------------------===// 1439d628a0SDimitry Andric 1539d628a0SDimitry Andric #include "StatepointLowering.h" 1639d628a0SDimitry Andric #include "SelectionDAGBuilder.h" 1739d628a0SDimitry Andric #include "llvm/ADT/SmallSet.h" 1839d628a0SDimitry Andric #include "llvm/ADT/Statistic.h" 1939d628a0SDimitry Andric #include "llvm/CodeGen/FunctionLoweringInfo.h" 207d523365SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h" 21ff0cc061SDimitry Andric #include "llvm/CodeGen/GCMetadata.h" 2239d628a0SDimitry Andric #include "llvm/CodeGen/GCStrategy.h" 2339d628a0SDimitry Andric #include "llvm/CodeGen/SelectionDAG.h" 2439d628a0SDimitry Andric #include "llvm/CodeGen/StackMaps.h" 2539d628a0SDimitry Andric #include "llvm/IR/CallingConv.h" 2639d628a0SDimitry Andric #include "llvm/IR/Instructions.h" 2739d628a0SDimitry Andric #include "llvm/IR/IntrinsicInst.h" 2839d628a0SDimitry Andric #include "llvm/IR/Intrinsics.h" 2939d628a0SDimitry Andric #include "llvm/IR/Statepoint.h" 3039d628a0SDimitry Andric #include "llvm/Target/TargetLowering.h" 3139d628a0SDimitry Andric #include <algorithm> 3239d628a0SDimitry Andric using namespace llvm; 3339d628a0SDimitry Andric 3439d628a0SDimitry Andric #define DEBUG_TYPE "statepoint-lowering" 3539d628a0SDimitry Andric 3639d628a0SDimitry Andric STATISTIC(NumSlotsAllocatedForStatepoints, 3739d628a0SDimitry Andric "Number of stack slots allocated for statepoints"); 3839d628a0SDimitry Andric STATISTIC(NumOfStatepoints, "Number of statepoint nodes encountered"); 3939d628a0SDimitry Andric STATISTIC(StatepointMaxSlotsRequired, 4039d628a0SDimitry Andric "Maximum number of stack slots required for a singe statepoint"); 4139d628a0SDimitry Andric 42ff0cc061SDimitry Andric static void pushStackMapConstant(SmallVectorImpl<SDValue>& Ops, 43ff0cc061SDimitry Andric SelectionDAGBuilder &Builder, uint64_t Value) { 44ff0cc061SDimitry Andric SDLoc L = Builder.getCurSDLoc(); 45ff0cc061SDimitry Andric Ops.push_back(Builder.DAG.getTargetConstant(StackMaps::ConstantOp, L, 46ff0cc061SDimitry Andric MVT::i64)); 47ff0cc061SDimitry Andric Ops.push_back(Builder.DAG.getTargetConstant(Value, L, MVT::i64)); 48ff0cc061SDimitry Andric } 49ff0cc061SDimitry Andric 50ff0cc061SDimitry Andric void StatepointLoweringState::startNewStatepoint(SelectionDAGBuilder &Builder) { 5139d628a0SDimitry Andric // Consistency check 5239d628a0SDimitry Andric assert(PendingGCRelocateCalls.empty() && 5339d628a0SDimitry Andric "Trying to visit statepoint before finished processing previous one"); 5439d628a0SDimitry Andric Locations.clear(); 5539d628a0SDimitry Andric NextSlotToAllocate = 0; 5639d628a0SDimitry Andric // Need to resize this on each safepoint - we need the two to stay in 5739d628a0SDimitry Andric // sync and the clear patterns of a SelectionDAGBuilder have no relation 5839d628a0SDimitry Andric // to FunctionLoweringInfo. 5939d628a0SDimitry Andric AllocatedStackSlots.resize(Builder.FuncInfo.StatepointStackSlots.size()); 6039d628a0SDimitry Andric for (size_t i = 0; i < AllocatedStackSlots.size(); i++) { 6139d628a0SDimitry Andric AllocatedStackSlots[i] = false; 6239d628a0SDimitry Andric } 6339d628a0SDimitry Andric } 64ff0cc061SDimitry Andric 6539d628a0SDimitry Andric void StatepointLoweringState::clear() { 6639d628a0SDimitry Andric Locations.clear(); 6739d628a0SDimitry Andric AllocatedStackSlots.clear(); 6839d628a0SDimitry Andric assert(PendingGCRelocateCalls.empty() && 6939d628a0SDimitry Andric "cleared before statepoint sequence completed"); 7039d628a0SDimitry Andric } 7139d628a0SDimitry Andric 7239d628a0SDimitry Andric SDValue 7339d628a0SDimitry Andric StatepointLoweringState::allocateStackSlot(EVT ValueType, 7439d628a0SDimitry Andric SelectionDAGBuilder &Builder) { 7539d628a0SDimitry Andric 7639d628a0SDimitry Andric NumSlotsAllocatedForStatepoints++; 7739d628a0SDimitry Andric 7839d628a0SDimitry Andric // The basic scheme here is to first look for a previously created stack slot 7939d628a0SDimitry Andric // which is not in use (accounting for the fact arbitrary slots may already 8039d628a0SDimitry Andric // be reserved), or to create a new stack slot and use it. 8139d628a0SDimitry Andric 8239d628a0SDimitry Andric // If this doesn't succeed in 40000 iterations, something is seriously wrong 8339d628a0SDimitry Andric for (int i = 0; i < 40000; i++) { 8439d628a0SDimitry Andric assert(Builder.FuncInfo.StatepointStackSlots.size() == 8539d628a0SDimitry Andric AllocatedStackSlots.size() && 8639d628a0SDimitry Andric "broken invariant"); 8739d628a0SDimitry Andric const size_t NumSlots = AllocatedStackSlots.size(); 8839d628a0SDimitry Andric assert(NextSlotToAllocate <= NumSlots && "broken invariant"); 8939d628a0SDimitry Andric 9039d628a0SDimitry Andric if (NextSlotToAllocate >= NumSlots) { 9139d628a0SDimitry Andric assert(NextSlotToAllocate == NumSlots); 9239d628a0SDimitry Andric // record stats 9339d628a0SDimitry Andric if (NumSlots + 1 > StatepointMaxSlotsRequired) { 9439d628a0SDimitry Andric StatepointMaxSlotsRequired = NumSlots + 1; 9539d628a0SDimitry Andric } 9639d628a0SDimitry Andric 9739d628a0SDimitry Andric SDValue SpillSlot = Builder.DAG.CreateStackTemporary(ValueType); 9839d628a0SDimitry Andric const unsigned FI = cast<FrameIndexSDNode>(SpillSlot)->getIndex(); 997d523365SDimitry Andric auto *MFI = Builder.DAG.getMachineFunction().getFrameInfo(); 1007d523365SDimitry Andric MFI->markAsStatepointSpillSlotObjectIndex(FI); 1017d523365SDimitry Andric 10239d628a0SDimitry Andric Builder.FuncInfo.StatepointStackSlots.push_back(FI); 10339d628a0SDimitry Andric AllocatedStackSlots.push_back(true); 10439d628a0SDimitry Andric return SpillSlot; 10539d628a0SDimitry Andric } 10639d628a0SDimitry Andric if (!AllocatedStackSlots[NextSlotToAllocate]) { 10739d628a0SDimitry Andric const int FI = Builder.FuncInfo.StatepointStackSlots[NextSlotToAllocate]; 10839d628a0SDimitry Andric AllocatedStackSlots[NextSlotToAllocate] = true; 10939d628a0SDimitry Andric return Builder.DAG.getFrameIndex(FI, ValueType); 11039d628a0SDimitry Andric } 11139d628a0SDimitry Andric // Note: We deliberately choose to advance this only on the failing path. 1127d523365SDimitry Andric // Doing so on the succeeding path involves a bit of complexity that caused 1137d523365SDimitry Andric // a minor bug previously. Unless performance shows this matters, please 11439d628a0SDimitry Andric // keep this code as simple as possible. 11539d628a0SDimitry Andric NextSlotToAllocate++; 11639d628a0SDimitry Andric } 11739d628a0SDimitry Andric llvm_unreachable("infinite loop?"); 11839d628a0SDimitry Andric } 11939d628a0SDimitry Andric 1208f0fd8f6SDimitry Andric /// Utility function for reservePreviousStackSlotForValue. Tries to find 1218f0fd8f6SDimitry Andric /// stack slot index to which we have spilled value for previous statepoints. 1228f0fd8f6SDimitry Andric /// LookUpDepth specifies maximum DFS depth this function is allowed to look. 1238f0fd8f6SDimitry Andric static Optional<int> findPreviousSpillSlot(const Value *Val, 1248f0fd8f6SDimitry Andric SelectionDAGBuilder &Builder, 1258f0fd8f6SDimitry Andric int LookUpDepth) { 1267d523365SDimitry Andric // Can not look any further - give up now 1278f0fd8f6SDimitry Andric if (LookUpDepth <= 0) 1288f0fd8f6SDimitry Andric return Optional<int>(); 1298f0fd8f6SDimitry Andric 1308f0fd8f6SDimitry Andric // Spill location is known for gc relocates 1314d0b32cdSDimitry Andric if (const auto *Relocate = dyn_cast<GCRelocateInst>(Val)) { 1328f0fd8f6SDimitry Andric FunctionLoweringInfo::StatepointSpilledValueMapTy &SpillMap = 1334d0b32cdSDimitry Andric Builder.FuncInfo.StatepointRelocatedValues[Relocate->getStatepoint()]; 1348f0fd8f6SDimitry Andric 1354d0b32cdSDimitry Andric auto It = SpillMap.find(Relocate->getDerivedPtr()); 1368f0fd8f6SDimitry Andric if (It == SpillMap.end()) 1378f0fd8f6SDimitry Andric return Optional<int>(); 1388f0fd8f6SDimitry Andric 1398f0fd8f6SDimitry Andric return It->second; 1408f0fd8f6SDimitry Andric } 1418f0fd8f6SDimitry Andric 1428f0fd8f6SDimitry Andric // Look through bitcast instructions. 1438f0fd8f6SDimitry Andric if (const BitCastInst *Cast = dyn_cast<BitCastInst>(Val)) { 1448f0fd8f6SDimitry Andric return findPreviousSpillSlot(Cast->getOperand(0), Builder, LookUpDepth - 1); 1458f0fd8f6SDimitry Andric } 1468f0fd8f6SDimitry Andric 1478f0fd8f6SDimitry Andric // Look through phi nodes 1488f0fd8f6SDimitry Andric // All incoming values should have same known stack slot, otherwise result 1498f0fd8f6SDimitry Andric // is unknown. 1508f0fd8f6SDimitry Andric if (const PHINode *Phi = dyn_cast<PHINode>(Val)) { 1518f0fd8f6SDimitry Andric Optional<int> MergedResult = None; 1528f0fd8f6SDimitry Andric 1538f0fd8f6SDimitry Andric for (auto &IncomingValue : Phi->incoming_values()) { 1548f0fd8f6SDimitry Andric Optional<int> SpillSlot = 1558f0fd8f6SDimitry Andric findPreviousSpillSlot(IncomingValue, Builder, LookUpDepth - 1); 1568f0fd8f6SDimitry Andric if (!SpillSlot.hasValue()) 1578f0fd8f6SDimitry Andric return Optional<int>(); 1588f0fd8f6SDimitry Andric 1598f0fd8f6SDimitry Andric if (MergedResult.hasValue() && *MergedResult != *SpillSlot) 1608f0fd8f6SDimitry Andric return Optional<int>(); 1618f0fd8f6SDimitry Andric 1628f0fd8f6SDimitry Andric MergedResult = SpillSlot; 1638f0fd8f6SDimitry Andric } 1648f0fd8f6SDimitry Andric return MergedResult; 1658f0fd8f6SDimitry Andric } 1668f0fd8f6SDimitry Andric 1678f0fd8f6SDimitry Andric // TODO: We can do better for PHI nodes. In cases like this: 1688f0fd8f6SDimitry Andric // ptr = phi(relocated_pointer, not_relocated_pointer) 1698f0fd8f6SDimitry Andric // statepoint(ptr) 1708f0fd8f6SDimitry Andric // We will return that stack slot for ptr is unknown. And later we might 1718f0fd8f6SDimitry Andric // assign different stack slots for ptr and relocated_pointer. This limits 1728f0fd8f6SDimitry Andric // llvm's ability to remove redundant stores. 1738f0fd8f6SDimitry Andric // Unfortunately it's hard to accomplish in current infrastructure. 1748f0fd8f6SDimitry Andric // We use this function to eliminate spill store completely, while 1758f0fd8f6SDimitry Andric // in example we still need to emit store, but instead of any location 1768f0fd8f6SDimitry Andric // we need to use special "preferred" location. 1778f0fd8f6SDimitry Andric 1788f0fd8f6SDimitry Andric // TODO: handle simple updates. If a value is modified and the original 1798f0fd8f6SDimitry Andric // value is no longer live, it would be nice to put the modified value in the 1808f0fd8f6SDimitry Andric // same slot. This allows folding of the memory accesses for some 1818f0fd8f6SDimitry Andric // instructions types (like an increment). 1828f0fd8f6SDimitry Andric // statepoint (i) 1838f0fd8f6SDimitry Andric // i1 = i+1 1848f0fd8f6SDimitry Andric // statepoint (i1) 1858f0fd8f6SDimitry Andric // However we need to be careful for cases like this: 1868f0fd8f6SDimitry Andric // statepoint(i) 1878f0fd8f6SDimitry Andric // i1 = i+1 1888f0fd8f6SDimitry Andric // statepoint(i, i1) 1898f0fd8f6SDimitry Andric // Here we want to reserve spill slot for 'i', but not for 'i+1'. If we just 1908f0fd8f6SDimitry Andric // put handling of simple modifications in this function like it's done 1918f0fd8f6SDimitry Andric // for bitcasts we might end up reserving i's slot for 'i+1' because order in 1928f0fd8f6SDimitry Andric // which we visit values is unspecified. 1938f0fd8f6SDimitry Andric 1948f0fd8f6SDimitry Andric // Don't know any information about this instruction 1958f0fd8f6SDimitry Andric return Optional<int>(); 1968f0fd8f6SDimitry Andric } 1978f0fd8f6SDimitry Andric 19839d628a0SDimitry Andric /// Try to find existing copies of the incoming values in stack slots used for 19939d628a0SDimitry Andric /// statepoint spilling. If we can find a spill slot for the incoming value, 20039d628a0SDimitry Andric /// mark that slot as allocated, and reuse the same slot for this safepoint. 2017d523365SDimitry Andric /// This helps to avoid series of loads and stores that only serve to reshuffle 20239d628a0SDimitry Andric /// values on the stack between calls. 2038f0fd8f6SDimitry Andric static void reservePreviousStackSlotForValue(const Value *IncomingValue, 20439d628a0SDimitry Andric SelectionDAGBuilder &Builder) { 20539d628a0SDimitry Andric 2068f0fd8f6SDimitry Andric SDValue Incoming = Builder.getValue(IncomingValue); 2078f0fd8f6SDimitry Andric 20839d628a0SDimitry Andric if (isa<ConstantSDNode>(Incoming) || isa<FrameIndexSDNode>(Incoming)) { 20939d628a0SDimitry Andric // We won't need to spill this, so no need to check for previously 21039d628a0SDimitry Andric // allocated stack slots 21139d628a0SDimitry Andric return; 21239d628a0SDimitry Andric } 21339d628a0SDimitry Andric 2148f0fd8f6SDimitry Andric SDValue OldLocation = Builder.StatepointLowering.getLocation(Incoming); 2158f0fd8f6SDimitry Andric if (OldLocation.getNode()) 21639d628a0SDimitry Andric // duplicates in input 21739d628a0SDimitry Andric return; 21839d628a0SDimitry Andric 2198f0fd8f6SDimitry Andric const int LookUpDepth = 6; 2208f0fd8f6SDimitry Andric Optional<int> Index = 2218f0fd8f6SDimitry Andric findPreviousSpillSlot(IncomingValue, Builder, LookUpDepth); 2228f0fd8f6SDimitry Andric if (!Index.hasValue()) 22339d628a0SDimitry Andric return; 2248f0fd8f6SDimitry Andric 2258f0fd8f6SDimitry Andric auto Itr = std::find(Builder.FuncInfo.StatepointStackSlots.begin(), 2268f0fd8f6SDimitry Andric Builder.FuncInfo.StatepointStackSlots.end(), *Index); 2278f0fd8f6SDimitry Andric assert(Itr != Builder.FuncInfo.StatepointStackSlots.end() && 2288f0fd8f6SDimitry Andric "value spilled to the unknown stack slot"); 2298f0fd8f6SDimitry Andric 23039d628a0SDimitry Andric // This is one of our dedicated lowering slots 23139d628a0SDimitry Andric const int Offset = 23239d628a0SDimitry Andric std::distance(Builder.FuncInfo.StatepointStackSlots.begin(), Itr); 23339d628a0SDimitry Andric if (Builder.StatepointLowering.isStackSlotAllocated(Offset)) { 23439d628a0SDimitry Andric // stack slot already assigned to someone else, can't use it! 23539d628a0SDimitry Andric // TODO: currently we reserve space for gc arguments after doing 23639d628a0SDimitry Andric // normal allocation for deopt arguments. We should reserve for 23739d628a0SDimitry Andric // _all_ deopt and gc arguments, then start allocating. This 23839d628a0SDimitry Andric // will prevent some moves being inserted when vm state changes, 23939d628a0SDimitry Andric // but gc state doesn't between two calls. 24039d628a0SDimitry Andric return; 24139d628a0SDimitry Andric } 24239d628a0SDimitry Andric // Reserve this stack slot 24339d628a0SDimitry Andric Builder.StatepointLowering.reserveStackSlot(Offset); 24439d628a0SDimitry Andric 24539d628a0SDimitry Andric // Cache this slot so we find it when going through the normal 24639d628a0SDimitry Andric // assignment loop. 2478f0fd8f6SDimitry Andric SDValue Loc = Builder.DAG.getTargetFrameIndex(*Index, Incoming.getValueType()); 24839d628a0SDimitry Andric Builder.StatepointLowering.setLocation(Incoming, Loc); 24939d628a0SDimitry Andric } 25039d628a0SDimitry Andric 25139d628a0SDimitry Andric /// Remove any duplicate (as SDValues) from the derived pointer pairs. This 25239d628a0SDimitry Andric /// is not required for correctness. It's purpose is to reduce the size of 25339d628a0SDimitry Andric /// StackMap section. It has no effect on the number of spill slots required 25439d628a0SDimitry Andric /// or the actual lowering. 25539d628a0SDimitry Andric static void removeDuplicatesGCPtrs(SmallVectorImpl<const Value *> &Bases, 25639d628a0SDimitry Andric SmallVectorImpl<const Value *> &Ptrs, 25739d628a0SDimitry Andric SmallVectorImpl<const Value *> &Relocs, 25839d628a0SDimitry Andric SelectionDAGBuilder &Builder) { 25939d628a0SDimitry Andric 2607d523365SDimitry Andric // This is horribly inefficient, but I don't care right now 26139d628a0SDimitry Andric SmallSet<SDValue, 64> Seen; 26239d628a0SDimitry Andric 26339d628a0SDimitry Andric SmallVector<const Value *, 64> NewBases, NewPtrs, NewRelocs; 26439d628a0SDimitry Andric for (size_t i = 0; i < Ptrs.size(); i++) { 26539d628a0SDimitry Andric SDValue SD = Builder.getValue(Ptrs[i]); 26639d628a0SDimitry Andric // Only add non-duplicates 26739d628a0SDimitry Andric if (Seen.count(SD) == 0) { 26839d628a0SDimitry Andric NewBases.push_back(Bases[i]); 26939d628a0SDimitry Andric NewPtrs.push_back(Ptrs[i]); 27039d628a0SDimitry Andric NewRelocs.push_back(Relocs[i]); 27139d628a0SDimitry Andric } 27239d628a0SDimitry Andric Seen.insert(SD); 27339d628a0SDimitry Andric } 27439d628a0SDimitry Andric assert(Bases.size() >= NewBases.size()); 27539d628a0SDimitry Andric assert(Ptrs.size() >= NewPtrs.size()); 27639d628a0SDimitry Andric assert(Relocs.size() >= NewRelocs.size()); 27739d628a0SDimitry Andric Bases = NewBases; 27839d628a0SDimitry Andric Ptrs = NewPtrs; 27939d628a0SDimitry Andric Relocs = NewRelocs; 28039d628a0SDimitry Andric assert(Ptrs.size() == Bases.size()); 28139d628a0SDimitry Andric assert(Ptrs.size() == Relocs.size()); 28239d628a0SDimitry Andric } 28339d628a0SDimitry Andric 28439d628a0SDimitry Andric /// Extract call from statepoint, lower it and return pointer to the 28539d628a0SDimitry Andric /// call node. Also update NodeMap so that getValue(statepoint) will 28639d628a0SDimitry Andric /// reference lowered call result 287ff0cc061SDimitry Andric static SDNode * 2887d523365SDimitry Andric lowerCallFromStatepoint(ImmutableStatepoint ISP, const BasicBlock *EHPadBB, 289ff0cc061SDimitry Andric SelectionDAGBuilder &Builder, 290ff0cc061SDimitry Andric SmallVectorImpl<SDValue> &PendingExports) { 29139d628a0SDimitry Andric 292ff0cc061SDimitry Andric ImmutableCallSite CS(ISP.getCallSite()); 29339d628a0SDimitry Andric 2947d523365SDimitry Andric SDValue ActualCallee; 2957d523365SDimitry Andric 2967d523365SDimitry Andric if (ISP.getNumPatchBytes() > 0) { 2977d523365SDimitry Andric // If we've been asked to emit a nop sequence instead of a call instruction 2987d523365SDimitry Andric // for this statepoint then don't lower the call target, but use a constant 2997d523365SDimitry Andric // `null` instead. Not lowering the call target lets statepoint clients get 3007d523365SDimitry Andric // away without providing a physical address for the symbolic call target at 3017d523365SDimitry Andric // link time. 3027d523365SDimitry Andric 3037d523365SDimitry Andric const auto &TLI = Builder.DAG.getTargetLoweringInfo(); 3047d523365SDimitry Andric const auto &DL = Builder.DAG.getDataLayout(); 3057d523365SDimitry Andric 3067d523365SDimitry Andric unsigned AS = ISP.getCalledValue()->getType()->getPointerAddressSpace(); 3077d523365SDimitry Andric ActualCallee = Builder.DAG.getConstant(0, Builder.getCurSDLoc(), 3087d523365SDimitry Andric TLI.getPointerTy(DL, AS)); 3097d523365SDimitry Andric } else 3107d523365SDimitry Andric ActualCallee = Builder.getValue(ISP.getCalledValue()); 31139d628a0SDimitry Andric 312ff0cc061SDimitry Andric assert(CS.getCallingConv() != CallingConv::AnyReg && 313ff0cc061SDimitry Andric "anyregcc is not supported on statepoints!"); 31439d628a0SDimitry Andric 315ff0cc061SDimitry Andric Type *DefTy = ISP.getActualReturnType(); 316ff0cc061SDimitry Andric bool HasDef = !DefTy->isVoidTy(); 317ff0cc061SDimitry Andric 318ff0cc061SDimitry Andric SDValue ReturnValue, CallEndVal; 319ff0cc061SDimitry Andric std::tie(ReturnValue, CallEndVal) = Builder.lowerCallOperands( 320ff0cc061SDimitry Andric ISP.getCallSite(), ImmutableStatepoint::CallArgsBeginPos, 3217d523365SDimitry Andric ISP.getNumCallArgs(), ActualCallee, DefTy, EHPadBB, 322ff0cc061SDimitry Andric false /* IsPatchPoint */); 323ff0cc061SDimitry Andric 324ff0cc061SDimitry Andric SDNode *CallEnd = CallEndVal.getNode(); 325ff0cc061SDimitry Andric 326ff0cc061SDimitry Andric // Get a call instruction from the call sequence chain. Tail calls are not 327ff0cc061SDimitry Andric // allowed. The following code is essentially reverse engineering X86's 328ff0cc061SDimitry Andric // LowerCallTo. 329ff0cc061SDimitry Andric // 330ff0cc061SDimitry Andric // We are expecting DAG to have the following form: 331ff0cc061SDimitry Andric // 332ff0cc061SDimitry Andric // ch = eh_label (only in case of invoke statepoint) 333ff0cc061SDimitry Andric // ch, glue = callseq_start ch 334ff0cc061SDimitry Andric // ch, glue = X86::Call ch, glue 335ff0cc061SDimitry Andric // ch, glue = callseq_end ch, glue 336ff0cc061SDimitry Andric // get_return_value ch, glue 337ff0cc061SDimitry Andric // 3387d523365SDimitry Andric // get_return_value can either be a sequence of CopyFromReg instructions 3397d523365SDimitry Andric // to grab the return value from the return register(s), or it can be a LOAD 3407d523365SDimitry Andric // to load a value returned by reference via a stack slot. 341ff0cc061SDimitry Andric 3427d523365SDimitry Andric if (HasDef) { 3437d523365SDimitry Andric if (CallEnd->getOpcode() == ISD::LOAD) 344ff0cc061SDimitry Andric CallEnd = CallEnd->getOperand(0).getNode(); 3457d523365SDimitry Andric else 3467d523365SDimitry Andric while (CallEnd->getOpcode() == ISD::CopyFromReg) 3477d523365SDimitry Andric CallEnd = CallEnd->getOperand(0).getNode(); 3487d523365SDimitry Andric } 349ff0cc061SDimitry Andric 350ff0cc061SDimitry Andric assert(CallEnd->getOpcode() == ISD::CALLSEQ_END && "expected!"); 351ff0cc061SDimitry Andric 3527d523365SDimitry Andric // Export the result value if needed 3537d523365SDimitry Andric const Instruction *GCResult = ISP.getGCResult(); 3547d523365SDimitry Andric if (HasDef && GCResult) { 3557d523365SDimitry Andric if (GCResult->getParent() != CS.getParent()) { 3567d523365SDimitry Andric // Result value will be used in a different basic block so we need to 3577d523365SDimitry Andric // export it now. 3587d523365SDimitry Andric // Default exporting mechanism will not work here because statepoint call 3597d523365SDimitry Andric // has a different type than the actual call. It means that by default 3607d523365SDimitry Andric // llvm will create export register of the wrong type (always i32 in our 3617d523365SDimitry Andric // case). So instead we need to create export register with correct type 3627d523365SDimitry Andric // manually. 363ff0cc061SDimitry Andric // TODO: To eliminate this problem we can remove gc.result intrinsics 3647d523365SDimitry Andric // completely and make statepoint call to return a tuple. 365ff0cc061SDimitry Andric unsigned Reg = Builder.FuncInfo.CreateRegs(ISP.getActualReturnType()); 366875ed548SDimitry Andric RegsForValue RFV( 367875ed548SDimitry Andric *Builder.DAG.getContext(), Builder.DAG.getTargetLoweringInfo(), 368875ed548SDimitry Andric Builder.DAG.getDataLayout(), Reg, ISP.getActualReturnType()); 369ff0cc061SDimitry Andric SDValue Chain = Builder.DAG.getEntryNode(); 370ff0cc061SDimitry Andric 371ff0cc061SDimitry Andric RFV.getCopyToRegs(ReturnValue, Builder.DAG, Builder.getCurSDLoc(), Chain, 372ff0cc061SDimitry Andric nullptr); 373ff0cc061SDimitry Andric PendingExports.push_back(Chain); 374ff0cc061SDimitry Andric Builder.FuncInfo.ValueMap[CS.getInstruction()] = Reg; 375ff0cc061SDimitry Andric } else { 3767d523365SDimitry Andric // Result value will be used in a same basic block. Don't export it or 3777d523365SDimitry Andric // perform any explicit register copies. 3787d523365SDimitry Andric // We'll replace the actuall call node shortly. gc_result will grab 37939d628a0SDimitry Andric // this value. 380ff0cc061SDimitry Andric Builder.setValue(CS.getInstruction(), ReturnValue); 381ff0cc061SDimitry Andric } 38239d628a0SDimitry Andric } else { 38339d628a0SDimitry Andric // The token value is never used from here on, just generate a poison value 384ff0cc061SDimitry Andric Builder.setValue(CS.getInstruction(), 385ff0cc061SDimitry Andric Builder.DAG.getIntPtrConstant(-1, Builder.getCurSDLoc())); 38639d628a0SDimitry Andric } 38739d628a0SDimitry Andric 388ff0cc061SDimitry Andric return CallEnd->getOperand(0).getNode(); 38939d628a0SDimitry Andric } 39039d628a0SDimitry Andric 39139d628a0SDimitry Andric /// Callect all gc pointers coming into statepoint intrinsic, clean them up, 39239d628a0SDimitry Andric /// and return two arrays: 39339d628a0SDimitry Andric /// Bases - base pointers incoming to this statepoint 39439d628a0SDimitry Andric /// Ptrs - derived pointers incoming to this statepoint 39539d628a0SDimitry Andric /// Relocs - the gc_relocate corresponding to each base/ptr pair 39639d628a0SDimitry Andric /// Elements of this arrays should be in one-to-one correspondence with each 39739d628a0SDimitry Andric /// other i.e Bases[i], Ptrs[i] are from the same gcrelocate call 398ff0cc061SDimitry Andric static void getIncomingStatepointGCValues( 399ff0cc061SDimitry Andric SmallVectorImpl<const Value *> &Bases, SmallVectorImpl<const Value *> &Ptrs, 400ff0cc061SDimitry Andric SmallVectorImpl<const Value *> &Relocs, ImmutableStatepoint StatepointSite, 40139d628a0SDimitry Andric SelectionDAGBuilder &Builder) { 4024d0b32cdSDimitry Andric for (const GCRelocateInst *Relocate : StatepointSite.getRelocates()) { 4034d0b32cdSDimitry Andric Relocs.push_back(Relocate); 4044d0b32cdSDimitry Andric Bases.push_back(Relocate->getBasePtr()); 4054d0b32cdSDimitry Andric Ptrs.push_back(Relocate->getDerivedPtr()); 40639d628a0SDimitry Andric } 40739d628a0SDimitry Andric 40839d628a0SDimitry Andric // Remove any redundant llvm::Values which map to the same SDValue as another 40939d628a0SDimitry Andric // input. Also has the effect of removing duplicates in the original 41039d628a0SDimitry Andric // llvm::Value input list as well. This is a useful optimization for 41139d628a0SDimitry Andric // reducing the size of the StackMap section. It has no other impact. 41239d628a0SDimitry Andric removeDuplicatesGCPtrs(Bases, Ptrs, Relocs, Builder); 41339d628a0SDimitry Andric 41439d628a0SDimitry Andric assert(Bases.size() == Ptrs.size() && Ptrs.size() == Relocs.size()); 41539d628a0SDimitry Andric } 41639d628a0SDimitry Andric 41739d628a0SDimitry Andric /// Spill a value incoming to the statepoint. It might be either part of 41839d628a0SDimitry Andric /// vmstate 41939d628a0SDimitry Andric /// or gcstate. In both cases unconditionally spill it on the stack unless it 42039d628a0SDimitry Andric /// is a null constant. Return pair with first element being frame index 42139d628a0SDimitry Andric /// containing saved value and second element with outgoing chain from the 42239d628a0SDimitry Andric /// emitted store 42339d628a0SDimitry Andric static std::pair<SDValue, SDValue> 42439d628a0SDimitry Andric spillIncomingStatepointValue(SDValue Incoming, SDValue Chain, 42539d628a0SDimitry Andric SelectionDAGBuilder &Builder) { 42639d628a0SDimitry Andric SDValue Loc = Builder.StatepointLowering.getLocation(Incoming); 42739d628a0SDimitry Andric 42839d628a0SDimitry Andric // Emit new store if we didn't do it for this ptr before 42939d628a0SDimitry Andric if (!Loc.getNode()) { 43039d628a0SDimitry Andric Loc = Builder.StatepointLowering.allocateStackSlot(Incoming.getValueType(), 43139d628a0SDimitry Andric Builder); 43239d628a0SDimitry Andric assert(isa<FrameIndexSDNode>(Loc)); 43339d628a0SDimitry Andric int Index = cast<FrameIndexSDNode>(Loc)->getIndex(); 43439d628a0SDimitry Andric // We use TargetFrameIndex so that isel will not select it into LEA 43539d628a0SDimitry Andric Loc = Builder.DAG.getTargetFrameIndex(Index, Incoming.getValueType()); 43639d628a0SDimitry Andric 43739d628a0SDimitry Andric // TODO: We can create TokenFactor node instead of 43839d628a0SDimitry Andric // chaining stores one after another, this may allow 43939d628a0SDimitry Andric // a bit more optimal scheduling for them 44039d628a0SDimitry Andric Chain = Builder.DAG.getStore(Chain, Builder.getCurSDLoc(), Incoming, Loc, 4417d523365SDimitry Andric MachinePointerInfo::getFixedStack( 4427d523365SDimitry Andric Builder.DAG.getMachineFunction(), Index), 44339d628a0SDimitry Andric false, false, 0); 44439d628a0SDimitry Andric 44539d628a0SDimitry Andric Builder.StatepointLowering.setLocation(Incoming, Loc); 44639d628a0SDimitry Andric } 44739d628a0SDimitry Andric 44839d628a0SDimitry Andric assert(Loc.getNode()); 44939d628a0SDimitry Andric return std::make_pair(Loc, Chain); 45039d628a0SDimitry Andric } 45139d628a0SDimitry Andric 45239d628a0SDimitry Andric /// Lower a single value incoming to a statepoint node. This value can be 45339d628a0SDimitry Andric /// either a deopt value or a gc value, the handling is the same. We special 45439d628a0SDimitry Andric /// case constants and allocas, then fall back to spilling if required. 45539d628a0SDimitry Andric static void lowerIncomingStatepointValue(SDValue Incoming, 45639d628a0SDimitry Andric SmallVectorImpl<SDValue> &Ops, 45739d628a0SDimitry Andric SelectionDAGBuilder &Builder) { 45839d628a0SDimitry Andric SDValue Chain = Builder.getRoot(); 45939d628a0SDimitry Andric 46039d628a0SDimitry Andric if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Incoming)) { 46139d628a0SDimitry Andric // If the original value was a constant, make sure it gets recorded as 46239d628a0SDimitry Andric // such in the stackmap. This is required so that the consumer can 46339d628a0SDimitry Andric // parse any internal format to the deopt state. It also handles null 46439d628a0SDimitry Andric // pointers and other constant pointers in GC states 465ff0cc061SDimitry Andric pushStackMapConstant(Ops, Builder, C->getSExtValue()); 46639d628a0SDimitry Andric } else if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(Incoming)) { 467ff0cc061SDimitry Andric // This handles allocas as arguments to the statepoint (this is only 468ff0cc061SDimitry Andric // really meaningful for a deopt value. For GC, we'd be trying to 469ff0cc061SDimitry Andric // relocate the address of the alloca itself?) 470ff0cc061SDimitry Andric Ops.push_back(Builder.DAG.getTargetFrameIndex(FI->getIndex(), 471ff0cc061SDimitry Andric Incoming.getValueType())); 47239d628a0SDimitry Andric } else { 47339d628a0SDimitry Andric // Otherwise, locate a spill slot and explicitly spill it so it 47439d628a0SDimitry Andric // can be found by the runtime later. We currently do not support 47539d628a0SDimitry Andric // tracking values through callee saved registers to their eventual 47639d628a0SDimitry Andric // spill location. This would be a useful optimization, but would 47739d628a0SDimitry Andric // need to be optional since it requires a lot of complexity on the 47839d628a0SDimitry Andric // runtime side which not all would support. 47939d628a0SDimitry Andric std::pair<SDValue, SDValue> Res = 48039d628a0SDimitry Andric spillIncomingStatepointValue(Incoming, Chain, Builder); 48139d628a0SDimitry Andric Ops.push_back(Res.first); 48239d628a0SDimitry Andric Chain = Res.second; 48339d628a0SDimitry Andric } 48439d628a0SDimitry Andric 48539d628a0SDimitry Andric Builder.DAG.setRoot(Chain); 48639d628a0SDimitry Andric } 48739d628a0SDimitry Andric 48839d628a0SDimitry Andric /// Lower deopt state and gc pointer arguments of the statepoint. The actual 48939d628a0SDimitry Andric /// lowering is described in lowerIncomingStatepointValue. This function is 49039d628a0SDimitry Andric /// responsible for lowering everything in the right position and playing some 49139d628a0SDimitry Andric /// tricks to avoid redundant stack manipulation where possible. On 49239d628a0SDimitry Andric /// completion, 'Ops' will contain ready to use operands for machine code 49339d628a0SDimitry Andric /// statepoint. The chain nodes will have already been created and the DAG root 49439d628a0SDimitry Andric /// will be set to the last value spilled (if any were). 49539d628a0SDimitry Andric static void lowerStatepointMetaArgs(SmallVectorImpl<SDValue> &Ops, 496ff0cc061SDimitry Andric ImmutableStatepoint StatepointSite, 49739d628a0SDimitry Andric SelectionDAGBuilder &Builder) { 49839d628a0SDimitry Andric 49939d628a0SDimitry Andric // Lower the deopt and gc arguments for this statepoint. Layout will 50039d628a0SDimitry Andric // be: deopt argument length, deopt arguments.., gc arguments... 50139d628a0SDimitry Andric 50239d628a0SDimitry Andric SmallVector<const Value *, 64> Bases, Ptrs, Relocations; 503ff0cc061SDimitry Andric getIncomingStatepointGCValues(Bases, Ptrs, Relocations, StatepointSite, 504ff0cc061SDimitry Andric Builder); 50539d628a0SDimitry Andric 50639d628a0SDimitry Andric #ifndef NDEBUG 50739d628a0SDimitry Andric // Check that each of the gc pointer and bases we've gotten out of the 50839d628a0SDimitry Andric // safepoint is something the strategy thinks might be a pointer into the GC 50939d628a0SDimitry Andric // heap. This is basically just here to help catch errors during statepoint 51039d628a0SDimitry Andric // insertion. TODO: This should actually be in the Verifier, but we can't get 51139d628a0SDimitry Andric // to the GCStrategy from there (yet). 51239d628a0SDimitry Andric GCStrategy &S = Builder.GFI->getStrategy(); 51339d628a0SDimitry Andric for (const Value *V : Bases) { 5147d523365SDimitry Andric auto Opt = S.isGCManagedPointer(V->getType()); 51539d628a0SDimitry Andric if (Opt.hasValue()) { 51639d628a0SDimitry Andric assert(Opt.getValue() && 51739d628a0SDimitry Andric "non gc managed base pointer found in statepoint"); 51839d628a0SDimitry Andric } 51939d628a0SDimitry Andric } 52039d628a0SDimitry Andric for (const Value *V : Ptrs) { 5217d523365SDimitry Andric auto Opt = S.isGCManagedPointer(V->getType()); 52239d628a0SDimitry Andric if (Opt.hasValue()) { 52339d628a0SDimitry Andric assert(Opt.getValue() && 52439d628a0SDimitry Andric "non gc managed derived pointer found in statepoint"); 52539d628a0SDimitry Andric } 52639d628a0SDimitry Andric } 52739d628a0SDimitry Andric for (const Value *V : Relocations) { 5287d523365SDimitry Andric auto Opt = S.isGCManagedPointer(V->getType()); 52939d628a0SDimitry Andric if (Opt.hasValue()) { 53039d628a0SDimitry Andric assert(Opt.getValue() && "non gc managed pointer relocated"); 53139d628a0SDimitry Andric } 53239d628a0SDimitry Andric } 53339d628a0SDimitry Andric #endif 53439d628a0SDimitry Andric 53539d628a0SDimitry Andric // Before we actually start lowering (and allocating spill slots for values), 53639d628a0SDimitry Andric // reserve any stack slots which we judge to be profitable to reuse for a 53739d628a0SDimitry Andric // particular value. This is purely an optimization over the code below and 53839d628a0SDimitry Andric // doesn't change semantics at all. It is important for performance that we 53939d628a0SDimitry Andric // reserve slots for both deopt and gc values before lowering either. 540ff0cc061SDimitry Andric for (const Value *V : StatepointSite.vm_state_args()) { 5418f0fd8f6SDimitry Andric reservePreviousStackSlotForValue(V, Builder); 54239d628a0SDimitry Andric } 543ff0cc061SDimitry Andric for (unsigned i = 0; i < Bases.size(); ++i) { 5448f0fd8f6SDimitry Andric reservePreviousStackSlotForValue(Bases[i], Builder); 5458f0fd8f6SDimitry Andric reservePreviousStackSlotForValue(Ptrs[i], Builder); 54639d628a0SDimitry Andric } 54739d628a0SDimitry Andric 54839d628a0SDimitry Andric // First, prefix the list with the number of unique values to be 54939d628a0SDimitry Andric // lowered. Note that this is the number of *Values* not the 55039d628a0SDimitry Andric // number of SDValues required to lower them. 551ff0cc061SDimitry Andric const int NumVMSArgs = StatepointSite.getNumTotalVMSArgs(); 552ff0cc061SDimitry Andric pushStackMapConstant(Ops, Builder, NumVMSArgs); 55339d628a0SDimitry Andric 554ff0cc061SDimitry Andric assert(NumVMSArgs == std::distance(StatepointSite.vm_state_begin(), 555ff0cc061SDimitry Andric StatepointSite.vm_state_end())); 55639d628a0SDimitry Andric 55739d628a0SDimitry Andric // The vm state arguments are lowered in an opaque manner. We do 55839d628a0SDimitry Andric // not know what type of values are contained within. We skip the 55939d628a0SDimitry Andric // first one since that happens to be the total number we lowered 56039d628a0SDimitry Andric // explicitly just above. We could have left it in the loop and 56139d628a0SDimitry Andric // not done it explicitly, but it's far easier to understand this 56239d628a0SDimitry Andric // way. 563ff0cc061SDimitry Andric for (const Value *V : StatepointSite.vm_state_args()) { 56439d628a0SDimitry Andric SDValue Incoming = Builder.getValue(V); 56539d628a0SDimitry Andric lowerIncomingStatepointValue(Incoming, Ops, Builder); 56639d628a0SDimitry Andric } 56739d628a0SDimitry Andric 56839d628a0SDimitry Andric // Finally, go ahead and lower all the gc arguments. There's no prefixed 56939d628a0SDimitry Andric // length for this one. After lowering, we'll have the base and pointer 57039d628a0SDimitry Andric // arrays interwoven with each (lowered) base pointer immediately followed by 57139d628a0SDimitry Andric // it's (lowered) derived pointer. i.e 57239d628a0SDimitry Andric // (base[0], ptr[0], base[1], ptr[1], ...) 573ff0cc061SDimitry Andric for (unsigned i = 0; i < Bases.size(); ++i) { 574ff0cc061SDimitry Andric const Value *Base = Bases[i]; 575ff0cc061SDimitry Andric lowerIncomingStatepointValue(Builder.getValue(Base), Ops, Builder); 576ff0cc061SDimitry Andric 577ff0cc061SDimitry Andric const Value *Ptr = Ptrs[i]; 578ff0cc061SDimitry Andric lowerIncomingStatepointValue(Builder.getValue(Ptr), Ops, Builder); 579ff0cc061SDimitry Andric } 580ff0cc061SDimitry Andric 581ff0cc061SDimitry Andric // If there are any explicit spill slots passed to the statepoint, record 582ff0cc061SDimitry Andric // them, but otherwise do not do anything special. These are user provided 583ff0cc061SDimitry Andric // allocas and give control over placement to the consumer. In this case, 584ff0cc061SDimitry Andric // it is the contents of the slot which may get updated, not the pointer to 585ff0cc061SDimitry Andric // the alloca 586ff0cc061SDimitry Andric for (Value *V : StatepointSite.gc_args()) { 58739d628a0SDimitry Andric SDValue Incoming = Builder.getValue(V); 588ff0cc061SDimitry Andric if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(Incoming)) { 589ff0cc061SDimitry Andric // This handles allocas as arguments to the statepoint 590ff0cc061SDimitry Andric Ops.push_back(Builder.DAG.getTargetFrameIndex(FI->getIndex(), 591ff0cc061SDimitry Andric Incoming.getValueType())); 59239d628a0SDimitry Andric } 59339d628a0SDimitry Andric } 594ff0cc061SDimitry Andric 595ff0cc061SDimitry Andric // Record computed locations for all lowered values. 596ff0cc061SDimitry Andric // This can not be embedded in lowering loops as we need to record *all* 597ff0cc061SDimitry Andric // values, while previous loops account only values with unique SDValues. 598ff0cc061SDimitry Andric const Instruction *StatepointInstr = 599ff0cc061SDimitry Andric StatepointSite.getCallSite().getInstruction(); 600ff0cc061SDimitry Andric FunctionLoweringInfo::StatepointSpilledValueMapTy &SpillMap = 601ff0cc061SDimitry Andric Builder.FuncInfo.StatepointRelocatedValues[StatepointInstr]; 602ff0cc061SDimitry Andric 6034d0b32cdSDimitry Andric for (const GCRelocateInst *Relocate : StatepointSite.getRelocates()) { 6044d0b32cdSDimitry Andric const Value *V = Relocate->getDerivedPtr(); 605ff0cc061SDimitry Andric SDValue SDV = Builder.getValue(V); 606ff0cc061SDimitry Andric SDValue Loc = Builder.StatepointLowering.getLocation(SDV); 607ff0cc061SDimitry Andric 608ff0cc061SDimitry Andric if (Loc.getNode()) { 609ff0cc061SDimitry Andric SpillMap[V] = cast<FrameIndexSDNode>(Loc)->getIndex(); 610ff0cc061SDimitry Andric } else { 611ff0cc061SDimitry Andric // Record value as visited, but not spilled. This is case for allocas 6127d523365SDimitry Andric // and constants. For this values we can avoid emitting spill load while 613ff0cc061SDimitry Andric // visiting corresponding gc_relocate. 614ff0cc061SDimitry Andric // Actually we do not need to record them in this map at all. 6157d523365SDimitry Andric // We do this only to check that we are not relocating any unvisited 6167d523365SDimitry Andric // value. 617ff0cc061SDimitry Andric SpillMap[V] = None; 618ff0cc061SDimitry Andric 619ff0cc061SDimitry Andric // Default llvm mechanisms for exporting values which are used in 620ff0cc061SDimitry Andric // different basic blocks does not work for gc relocates. 621ff0cc061SDimitry Andric // Note that it would be incorrect to teach llvm that all relocates are 6227d523365SDimitry Andric // uses of the corresponding values so that it would automatically 623ff0cc061SDimitry Andric // export them. Relocates of the spilled values does not use original 624ff0cc061SDimitry Andric // value. 6254d0b32cdSDimitry Andric if (Relocate->getParent() != StatepointInstr->getParent()) 626ff0cc061SDimitry Andric Builder.ExportFromCurrentBlock(V); 627ff0cc061SDimitry Andric } 628ff0cc061SDimitry Andric } 629ff0cc061SDimitry Andric } 630ff0cc061SDimitry Andric 63139d628a0SDimitry Andric void SelectionDAGBuilder::visitStatepoint(const CallInst &CI) { 632ff0cc061SDimitry Andric // Check some preconditions for sanity 633ff0cc061SDimitry Andric assert(isStatepoint(&CI) && 634ff0cc061SDimitry Andric "function called must be the statepoint function"); 635ff0cc061SDimitry Andric 636ff0cc061SDimitry Andric LowerStatepoint(ImmutableStatepoint(&CI)); 637ff0cc061SDimitry Andric } 638ff0cc061SDimitry Andric 639ff0cc061SDimitry Andric void SelectionDAGBuilder::LowerStatepoint( 6407d523365SDimitry Andric ImmutableStatepoint ISP, const BasicBlock *EHPadBB /*= nullptr*/) { 64139d628a0SDimitry Andric // The basic scheme here is that information about both the original call and 64239d628a0SDimitry Andric // the safepoint is encoded in the CallInst. We create a temporary call and 64339d628a0SDimitry Andric // lower it, then reverse engineer the calling sequence. 64439d628a0SDimitry Andric 64539d628a0SDimitry Andric NumOfStatepoints++; 64639d628a0SDimitry Andric // Clear state 64739d628a0SDimitry Andric StatepointLowering.startNewStatepoint(*this); 64839d628a0SDimitry Andric 649ff0cc061SDimitry Andric ImmutableCallSite CS(ISP.getCallSite()); 650ff0cc061SDimitry Andric 65139d628a0SDimitry Andric #ifndef NDEBUG 6527d523365SDimitry Andric // Consistency check. Check only relocates in the same basic block as thier 6537d523365SDimitry Andric // statepoint. 654ff0cc061SDimitry Andric for (const User *U : CS->users()) { 65539d628a0SDimitry Andric const CallInst *Call = cast<CallInst>(U); 6564d0b32cdSDimitry Andric if (isa<GCRelocateInst>(Call) && Call->getParent() == CS.getParent()) 65739d628a0SDimitry Andric StatepointLowering.scheduleRelocCall(*Call); 65839d628a0SDimitry Andric } 65939d628a0SDimitry Andric #endif 66039d628a0SDimitry Andric 66139d628a0SDimitry Andric #ifndef NDEBUG 66239d628a0SDimitry Andric // If this is a malformed statepoint, report it early to simplify debugging. 66339d628a0SDimitry Andric // This should catch any IR level mistake that's made when constructing or 66439d628a0SDimitry Andric // transforming statepoints. 66539d628a0SDimitry Andric ISP.verify(); 66639d628a0SDimitry Andric 66739d628a0SDimitry Andric // Check that the associated GCStrategy expects to encounter statepoints. 66839d628a0SDimitry Andric assert(GFI->getStrategy().useStatepoints() && 66939d628a0SDimitry Andric "GCStrategy does not expect to encounter statepoints"); 67039d628a0SDimitry Andric #endif 67139d628a0SDimitry Andric 67239d628a0SDimitry Andric // Lower statepoint vmstate and gcstate arguments 673ff0cc061SDimitry Andric SmallVector<SDValue, 10> LoweredMetaArgs; 674ff0cc061SDimitry Andric lowerStatepointMetaArgs(LoweredMetaArgs, ISP, *this); 67539d628a0SDimitry Andric 67639d628a0SDimitry Andric // Get call node, we will replace it later with statepoint 677ff0cc061SDimitry Andric SDNode *CallNode = 6787d523365SDimitry Andric lowerCallFromStatepoint(ISP, EHPadBB, *this, PendingExports); 67939d628a0SDimitry Andric 680ff0cc061SDimitry Andric // Construct the actual GC_TRANSITION_START, STATEPOINT, and GC_TRANSITION_END 681ff0cc061SDimitry Andric // nodes with all the appropriate arguments and return values. 682ff0cc061SDimitry Andric 683ff0cc061SDimitry Andric // Call Node: Chain, Target, {Args}, RegMask, [Glue] 684ff0cc061SDimitry Andric SDValue Chain = CallNode->getOperand(0); 685ff0cc061SDimitry Andric 686ff0cc061SDimitry Andric SDValue Glue; 687ff0cc061SDimitry Andric bool CallHasIncomingGlue = CallNode->getGluedNode(); 688ff0cc061SDimitry Andric if (CallHasIncomingGlue) { 689ff0cc061SDimitry Andric // Glue is always last operand 690ff0cc061SDimitry Andric Glue = CallNode->getOperand(CallNode->getNumOperands() - 1); 691ff0cc061SDimitry Andric } 692ff0cc061SDimitry Andric 693ff0cc061SDimitry Andric // Build the GC_TRANSITION_START node if necessary. 694ff0cc061SDimitry Andric // 695ff0cc061SDimitry Andric // The operands to the GC_TRANSITION_{START,END} nodes are laid out in the 696ff0cc061SDimitry Andric // order in which they appear in the call to the statepoint intrinsic. If 697ff0cc061SDimitry Andric // any of the operands is a pointer-typed, that operand is immediately 698ff0cc061SDimitry Andric // followed by a SRCVALUE for the pointer that may be used during lowering 699ff0cc061SDimitry Andric // (e.g. to form MachinePointerInfo values for loads/stores). 700ff0cc061SDimitry Andric const bool IsGCTransition = 701ff0cc061SDimitry Andric (ISP.getFlags() & (uint64_t)StatepointFlags::GCTransition) == 702ff0cc061SDimitry Andric (uint64_t)StatepointFlags::GCTransition; 703ff0cc061SDimitry Andric if (IsGCTransition) { 704ff0cc061SDimitry Andric SmallVector<SDValue, 8> TSOps; 705ff0cc061SDimitry Andric 706ff0cc061SDimitry Andric // Add chain 707ff0cc061SDimitry Andric TSOps.push_back(Chain); 708ff0cc061SDimitry Andric 709ff0cc061SDimitry Andric // Add GC transition arguments 710ff0cc061SDimitry Andric for (const Value *V : ISP.gc_transition_args()) { 711ff0cc061SDimitry Andric TSOps.push_back(getValue(V)); 712ff0cc061SDimitry Andric if (V->getType()->isPointerTy()) 713ff0cc061SDimitry Andric TSOps.push_back(DAG.getSrcValue(V)); 714ff0cc061SDimitry Andric } 715ff0cc061SDimitry Andric 716ff0cc061SDimitry Andric // Add glue if necessary 717ff0cc061SDimitry Andric if (CallHasIncomingGlue) 718ff0cc061SDimitry Andric TSOps.push_back(Glue); 719ff0cc061SDimitry Andric 720ff0cc061SDimitry Andric SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); 721ff0cc061SDimitry Andric 722ff0cc061SDimitry Andric SDValue GCTransitionStart = 723ff0cc061SDimitry Andric DAG.getNode(ISD::GC_TRANSITION_START, getCurSDLoc(), NodeTys, TSOps); 724ff0cc061SDimitry Andric 725ff0cc061SDimitry Andric Chain = GCTransitionStart.getValue(0); 726ff0cc061SDimitry Andric Glue = GCTransitionStart.getValue(1); 727ff0cc061SDimitry Andric } 72839d628a0SDimitry Andric 72939d628a0SDimitry Andric // TODO: Currently, all of these operands are being marked as read/write in 73039d628a0SDimitry Andric // PrologEpilougeInserter.cpp, we should special case the VMState arguments 73139d628a0SDimitry Andric // and flags to be read-only. 73239d628a0SDimitry Andric SmallVector<SDValue, 40> Ops; 73339d628a0SDimitry Andric 734ff0cc061SDimitry Andric // Add the <id> and <numBytes> constants. 735ff0cc061SDimitry Andric Ops.push_back(DAG.getTargetConstant(ISP.getID(), getCurSDLoc(), MVT::i64)); 736ff0cc061SDimitry Andric Ops.push_back( 737ff0cc061SDimitry Andric DAG.getTargetConstant(ISP.getNumPatchBytes(), getCurSDLoc(), MVT::i32)); 738ff0cc061SDimitry Andric 73939d628a0SDimitry Andric // Calculate and push starting position of vmstate arguments 74039d628a0SDimitry Andric // Get number of arguments incoming directly into call node 74139d628a0SDimitry Andric unsigned NumCallRegArgs = 742ff0cc061SDimitry Andric CallNode->getNumOperands() - (CallHasIncomingGlue ? 4 : 3); 743ff0cc061SDimitry Andric Ops.push_back(DAG.getTargetConstant(NumCallRegArgs, getCurSDLoc(), MVT::i32)); 74439d628a0SDimitry Andric 74539d628a0SDimitry Andric // Add call target 74639d628a0SDimitry Andric SDValue CallTarget = SDValue(CallNode->getOperand(1).getNode(), 0); 74739d628a0SDimitry Andric Ops.push_back(CallTarget); 74839d628a0SDimitry Andric 74939d628a0SDimitry Andric // Add call arguments 75039d628a0SDimitry Andric // Get position of register mask in the call 75139d628a0SDimitry Andric SDNode::op_iterator RegMaskIt; 752ff0cc061SDimitry Andric if (CallHasIncomingGlue) 75339d628a0SDimitry Andric RegMaskIt = CallNode->op_end() - 2; 75439d628a0SDimitry Andric else 75539d628a0SDimitry Andric RegMaskIt = CallNode->op_end() - 1; 75639d628a0SDimitry Andric Ops.insert(Ops.end(), CallNode->op_begin() + 2, RegMaskIt); 75739d628a0SDimitry Andric 758ff0cc061SDimitry Andric // Add a constant argument for the calling convention 759ff0cc061SDimitry Andric pushStackMapConstant(Ops, *this, CS.getCallingConv()); 760ff0cc061SDimitry Andric 761ff0cc061SDimitry Andric // Add a constant argument for the flags 762ff0cc061SDimitry Andric uint64_t Flags = ISP.getFlags(); 763ff0cc061SDimitry Andric assert( 764ff0cc061SDimitry Andric ((Flags & ~(uint64_t)StatepointFlags::MaskAll) == 0) 765ff0cc061SDimitry Andric && "unknown flag used"); 766ff0cc061SDimitry Andric pushStackMapConstant(Ops, *this, Flags); 76739d628a0SDimitry Andric 76839d628a0SDimitry Andric // Insert all vmstate and gcstate arguments 769ff0cc061SDimitry Andric Ops.insert(Ops.end(), LoweredMetaArgs.begin(), LoweredMetaArgs.end()); 77039d628a0SDimitry Andric 77139d628a0SDimitry Andric // Add register mask from call node 77239d628a0SDimitry Andric Ops.push_back(*RegMaskIt); 77339d628a0SDimitry Andric 77439d628a0SDimitry Andric // Add chain 775ff0cc061SDimitry Andric Ops.push_back(Chain); 77639d628a0SDimitry Andric 77739d628a0SDimitry Andric // Same for the glue, but we add it only if original call had it 77839d628a0SDimitry Andric if (Glue.getNode()) 77939d628a0SDimitry Andric Ops.push_back(Glue); 78039d628a0SDimitry Andric 781ff0cc061SDimitry Andric // Compute return values. Provide a glue output since we consume one as 782ff0cc061SDimitry Andric // input. This allows someone else to chain off us as needed. 783ff0cc061SDimitry Andric SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); 78439d628a0SDimitry Andric 785ff0cc061SDimitry Andric SDNode *StatepointMCNode = 786ff0cc061SDimitry Andric DAG.getMachineNode(TargetOpcode::STATEPOINT, getCurSDLoc(), NodeTys, Ops); 787ff0cc061SDimitry Andric 788ff0cc061SDimitry Andric SDNode *SinkNode = StatepointMCNode; 789ff0cc061SDimitry Andric 790ff0cc061SDimitry Andric // Build the GC_TRANSITION_END node if necessary. 791ff0cc061SDimitry Andric // 792ff0cc061SDimitry Andric // See the comment above regarding GC_TRANSITION_START for the layout of 793ff0cc061SDimitry Andric // the operands to the GC_TRANSITION_END node. 794ff0cc061SDimitry Andric if (IsGCTransition) { 795ff0cc061SDimitry Andric SmallVector<SDValue, 8> TEOps; 796ff0cc061SDimitry Andric 797ff0cc061SDimitry Andric // Add chain 798ff0cc061SDimitry Andric TEOps.push_back(SDValue(StatepointMCNode, 0)); 799ff0cc061SDimitry Andric 800ff0cc061SDimitry Andric // Add GC transition arguments 801ff0cc061SDimitry Andric for (const Value *V : ISP.gc_transition_args()) { 802ff0cc061SDimitry Andric TEOps.push_back(getValue(V)); 803ff0cc061SDimitry Andric if (V->getType()->isPointerTy()) 804ff0cc061SDimitry Andric TEOps.push_back(DAG.getSrcValue(V)); 805ff0cc061SDimitry Andric } 806ff0cc061SDimitry Andric 807ff0cc061SDimitry Andric // Add glue 808ff0cc061SDimitry Andric TEOps.push_back(SDValue(StatepointMCNode, 1)); 809ff0cc061SDimitry Andric 810ff0cc061SDimitry Andric SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); 811ff0cc061SDimitry Andric 812ff0cc061SDimitry Andric SDValue GCTransitionStart = 813ff0cc061SDimitry Andric DAG.getNode(ISD::GC_TRANSITION_END, getCurSDLoc(), NodeTys, TEOps); 814ff0cc061SDimitry Andric 815ff0cc061SDimitry Andric SinkNode = GCTransitionStart.getNode(); 816ff0cc061SDimitry Andric } 81739d628a0SDimitry Andric 81839d628a0SDimitry Andric // Replace original call 819ff0cc061SDimitry Andric DAG.ReplaceAllUsesWith(CallNode, SinkNode); // This may update Root 8207d523365SDimitry Andric // Remove original call node 82139d628a0SDimitry Andric DAG.DeleteNode(CallNode); 82239d628a0SDimitry Andric 82339d628a0SDimitry Andric // DON'T set the root - under the assumption that it's already set past the 82439d628a0SDimitry Andric // inserted node we created. 82539d628a0SDimitry Andric 82639d628a0SDimitry Andric // TODO: A better future implementation would be to emit a single variable 82739d628a0SDimitry Andric // argument, variable return value STATEPOINT node here and then hookup the 82839d628a0SDimitry Andric // return value of each gc.relocate to the respective output of the 82939d628a0SDimitry Andric // previously emitted STATEPOINT value. Unfortunately, this doesn't appear 83039d628a0SDimitry Andric // to actually be possible today. 83139d628a0SDimitry Andric } 83239d628a0SDimitry Andric 83339d628a0SDimitry Andric void SelectionDAGBuilder::visitGCResult(const CallInst &CI) { 83439d628a0SDimitry Andric // The result value of the gc_result is simply the result of the actual 83539d628a0SDimitry Andric // call. We've already emitted this, so just grab the value. 83639d628a0SDimitry Andric Instruction *I = cast<Instruction>(CI.getArgOperand(0)); 837ff0cc061SDimitry Andric assert(isStatepoint(I) && "first argument must be a statepoint token"); 83839d628a0SDimitry Andric 8397d523365SDimitry Andric if (I->getParent() != CI.getParent()) { 8407d523365SDimitry Andric // Statepoint is in different basic block so we should have stored call 8417d523365SDimitry Andric // result in a virtual register. 842ff0cc061SDimitry Andric // We can not use default getValue() functionality to copy value from this 843ff0cc061SDimitry Andric // register because statepoint and actuall call return types can be 844ff0cc061SDimitry Andric // different, and getValue() will use CopyFromReg of the wrong type, 845ff0cc061SDimitry Andric // which is always i32 in our case. 8463dac3a9bSDimitry Andric PointerType *CalleeType = cast<PointerType>( 8473dac3a9bSDimitry Andric ImmutableStatepoint(I).getCalledValue()->getType()); 848ff0cc061SDimitry Andric Type *RetTy = 849ff0cc061SDimitry Andric cast<FunctionType>(CalleeType->getElementType())->getReturnType(); 850ff0cc061SDimitry Andric SDValue CopyFromReg = getCopyFromRegs(I, RetTy); 851ff0cc061SDimitry Andric 852ff0cc061SDimitry Andric assert(CopyFromReg.getNode()); 853ff0cc061SDimitry Andric setValue(&CI, CopyFromReg); 854ff0cc061SDimitry Andric } else { 85539d628a0SDimitry Andric setValue(&CI, getValue(I)); 85639d628a0SDimitry Andric } 857ff0cc061SDimitry Andric } 85839d628a0SDimitry Andric 8594d0b32cdSDimitry Andric void SelectionDAGBuilder::visitGCRelocate(const GCRelocateInst &Relocate) { 86039d628a0SDimitry Andric #ifndef NDEBUG 86139d628a0SDimitry Andric // Consistency check 8627d523365SDimitry Andric // We skip this check for relocates not in the same basic block as thier 8637d523365SDimitry Andric // statepoint. It would be too expensive to preserve validation info through 8647d523365SDimitry Andric // different basic blocks. 8654d0b32cdSDimitry Andric if (Relocate.getStatepoint()->getParent() == Relocate.getParent()) { 8664d0b32cdSDimitry Andric StatepointLowering.relocCallVisited(Relocate); 867ff0cc061SDimitry Andric } 86839d628a0SDimitry Andric #endif 86939d628a0SDimitry Andric 8704d0b32cdSDimitry Andric const Value *DerivedPtr = Relocate.getDerivedPtr(); 871ff0cc061SDimitry Andric SDValue SD = getValue(DerivedPtr); 87239d628a0SDimitry Andric 873ff0cc061SDimitry Andric FunctionLoweringInfo::StatepointSpilledValueMapTy &SpillMap = 8744d0b32cdSDimitry Andric FuncInfo.StatepointRelocatedValues[Relocate.getStatepoint()]; 875ff0cc061SDimitry Andric 876ff0cc061SDimitry Andric // We should have recorded location for this pointer 877ff0cc061SDimitry Andric assert(SpillMap.count(DerivedPtr) && "Relocating not lowered gc value"); 878ff0cc061SDimitry Andric Optional<int> DerivedPtrLocation = SpillMap[DerivedPtr]; 879ff0cc061SDimitry Andric 88039d628a0SDimitry Andric // We didn't need to spill these special cases (constants and allocas). 88139d628a0SDimitry Andric // See the handling in spillIncomingValueForStatepoint for detail. 882ff0cc061SDimitry Andric if (!DerivedPtrLocation) { 8834d0b32cdSDimitry Andric setValue(&Relocate, SD); 88439d628a0SDimitry Andric return; 88539d628a0SDimitry Andric } 88639d628a0SDimitry Andric 887ff0cc061SDimitry Andric SDValue SpillSlot = DAG.getTargetFrameIndex(*DerivedPtrLocation, 888ff0cc061SDimitry Andric SD.getValueType()); 88939d628a0SDimitry Andric 89039d628a0SDimitry Andric // Be conservative: flush all pending loads 89139d628a0SDimitry Andric // TODO: Probably we can be less restrictive on this, 8927d523365SDimitry Andric // it may allow more scheduling opportunities. 89339d628a0SDimitry Andric SDValue Chain = getRoot(); 89439d628a0SDimitry Andric 895ff0cc061SDimitry Andric SDValue SpillLoad = 896ff0cc061SDimitry Andric DAG.getLoad(SpillSlot.getValueType(), getCurSDLoc(), Chain, SpillSlot, 8977d523365SDimitry Andric MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), 8987d523365SDimitry Andric *DerivedPtrLocation), 899ff0cc061SDimitry Andric false, false, false, 0); 90039d628a0SDimitry Andric 90139d628a0SDimitry Andric // Again, be conservative, don't emit pending loads 902ff0cc061SDimitry Andric DAG.setRoot(SpillLoad.getValue(1)); 90339d628a0SDimitry Andric 904ff0cc061SDimitry Andric assert(SpillLoad.getNode()); 9054d0b32cdSDimitry Andric setValue(&Relocate, SpillLoad); 90639d628a0SDimitry Andric } 907