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 1318f0fd8f6SDimitry Andric if (isGCRelocate(Val)) { 1328f0fd8f6SDimitry Andric GCRelocateOperands RelocOps(cast<Instruction>(Val)); 1338f0fd8f6SDimitry Andric 1348f0fd8f6SDimitry Andric FunctionLoweringInfo::StatepointSpilledValueMapTy &SpillMap = 1358f0fd8f6SDimitry Andric Builder.FuncInfo.StatepointRelocatedValues[RelocOps.getStatepoint()]; 1368f0fd8f6SDimitry Andric 1378f0fd8f6SDimitry Andric auto It = SpillMap.find(RelocOps.getDerivedPtr()); 1388f0fd8f6SDimitry Andric if (It == SpillMap.end()) 1398f0fd8f6SDimitry Andric return Optional<int>(); 1408f0fd8f6SDimitry Andric 1418f0fd8f6SDimitry Andric return It->second; 1428f0fd8f6SDimitry Andric } 1438f0fd8f6SDimitry Andric 1448f0fd8f6SDimitry Andric // Look through bitcast instructions. 1458f0fd8f6SDimitry Andric if (const BitCastInst *Cast = dyn_cast<BitCastInst>(Val)) { 1468f0fd8f6SDimitry Andric return findPreviousSpillSlot(Cast->getOperand(0), Builder, LookUpDepth - 1); 1478f0fd8f6SDimitry Andric } 1488f0fd8f6SDimitry Andric 1498f0fd8f6SDimitry Andric // Look through phi nodes 1508f0fd8f6SDimitry Andric // All incoming values should have same known stack slot, otherwise result 1518f0fd8f6SDimitry Andric // is unknown. 1528f0fd8f6SDimitry Andric if (const PHINode *Phi = dyn_cast<PHINode>(Val)) { 1538f0fd8f6SDimitry Andric Optional<int> MergedResult = None; 1548f0fd8f6SDimitry Andric 1558f0fd8f6SDimitry Andric for (auto &IncomingValue : Phi->incoming_values()) { 1568f0fd8f6SDimitry Andric Optional<int> SpillSlot = 1578f0fd8f6SDimitry Andric findPreviousSpillSlot(IncomingValue, Builder, LookUpDepth - 1); 1588f0fd8f6SDimitry Andric if (!SpillSlot.hasValue()) 1598f0fd8f6SDimitry Andric return Optional<int>(); 1608f0fd8f6SDimitry Andric 1618f0fd8f6SDimitry Andric if (MergedResult.hasValue() && *MergedResult != *SpillSlot) 1628f0fd8f6SDimitry Andric return Optional<int>(); 1638f0fd8f6SDimitry Andric 1648f0fd8f6SDimitry Andric MergedResult = SpillSlot; 1658f0fd8f6SDimitry Andric } 1668f0fd8f6SDimitry Andric return MergedResult; 1678f0fd8f6SDimitry Andric } 1688f0fd8f6SDimitry Andric 1698f0fd8f6SDimitry Andric // TODO: We can do better for PHI nodes. In cases like this: 1708f0fd8f6SDimitry Andric // ptr = phi(relocated_pointer, not_relocated_pointer) 1718f0fd8f6SDimitry Andric // statepoint(ptr) 1728f0fd8f6SDimitry Andric // We will return that stack slot for ptr is unknown. And later we might 1738f0fd8f6SDimitry Andric // assign different stack slots for ptr and relocated_pointer. This limits 1748f0fd8f6SDimitry Andric // llvm's ability to remove redundant stores. 1758f0fd8f6SDimitry Andric // Unfortunately it's hard to accomplish in current infrastructure. 1768f0fd8f6SDimitry Andric // We use this function to eliminate spill store completely, while 1778f0fd8f6SDimitry Andric // in example we still need to emit store, but instead of any location 1788f0fd8f6SDimitry Andric // we need to use special "preferred" location. 1798f0fd8f6SDimitry Andric 1808f0fd8f6SDimitry Andric // TODO: handle simple updates. If a value is modified and the original 1818f0fd8f6SDimitry Andric // value is no longer live, it would be nice to put the modified value in the 1828f0fd8f6SDimitry Andric // same slot. This allows folding of the memory accesses for some 1838f0fd8f6SDimitry Andric // instructions types (like an increment). 1848f0fd8f6SDimitry Andric // statepoint (i) 1858f0fd8f6SDimitry Andric // i1 = i+1 1868f0fd8f6SDimitry Andric // statepoint (i1) 1878f0fd8f6SDimitry Andric // However we need to be careful for cases like this: 1888f0fd8f6SDimitry Andric // statepoint(i) 1898f0fd8f6SDimitry Andric // i1 = i+1 1908f0fd8f6SDimitry Andric // statepoint(i, i1) 1918f0fd8f6SDimitry Andric // Here we want to reserve spill slot for 'i', but not for 'i+1'. If we just 1928f0fd8f6SDimitry Andric // put handling of simple modifications in this function like it's done 1938f0fd8f6SDimitry Andric // for bitcasts we might end up reserving i's slot for 'i+1' because order in 1948f0fd8f6SDimitry Andric // which we visit values is unspecified. 1958f0fd8f6SDimitry Andric 1968f0fd8f6SDimitry Andric // Don't know any information about this instruction 1978f0fd8f6SDimitry Andric return Optional<int>(); 1988f0fd8f6SDimitry Andric } 1998f0fd8f6SDimitry Andric 20039d628a0SDimitry Andric /// Try to find existing copies of the incoming values in stack slots used for 20139d628a0SDimitry Andric /// statepoint spilling. If we can find a spill slot for the incoming value, 20239d628a0SDimitry Andric /// mark that slot as allocated, and reuse the same slot for this safepoint. 2037d523365SDimitry Andric /// This helps to avoid series of loads and stores that only serve to reshuffle 20439d628a0SDimitry Andric /// values on the stack between calls. 2058f0fd8f6SDimitry Andric static void reservePreviousStackSlotForValue(const Value *IncomingValue, 20639d628a0SDimitry Andric SelectionDAGBuilder &Builder) { 20739d628a0SDimitry Andric 2088f0fd8f6SDimitry Andric SDValue Incoming = Builder.getValue(IncomingValue); 2098f0fd8f6SDimitry Andric 21039d628a0SDimitry Andric if (isa<ConstantSDNode>(Incoming) || isa<FrameIndexSDNode>(Incoming)) { 21139d628a0SDimitry Andric // We won't need to spill this, so no need to check for previously 21239d628a0SDimitry Andric // allocated stack slots 21339d628a0SDimitry Andric return; 21439d628a0SDimitry Andric } 21539d628a0SDimitry Andric 2168f0fd8f6SDimitry Andric SDValue OldLocation = Builder.StatepointLowering.getLocation(Incoming); 2178f0fd8f6SDimitry Andric if (OldLocation.getNode()) 21839d628a0SDimitry Andric // duplicates in input 21939d628a0SDimitry Andric return; 22039d628a0SDimitry Andric 2218f0fd8f6SDimitry Andric const int LookUpDepth = 6; 2228f0fd8f6SDimitry Andric Optional<int> Index = 2238f0fd8f6SDimitry Andric findPreviousSpillSlot(IncomingValue, Builder, LookUpDepth); 2248f0fd8f6SDimitry Andric if (!Index.hasValue()) 22539d628a0SDimitry Andric return; 2268f0fd8f6SDimitry Andric 2278f0fd8f6SDimitry Andric auto Itr = std::find(Builder.FuncInfo.StatepointStackSlots.begin(), 2288f0fd8f6SDimitry Andric Builder.FuncInfo.StatepointStackSlots.end(), *Index); 2298f0fd8f6SDimitry Andric assert(Itr != Builder.FuncInfo.StatepointStackSlots.end() && 2308f0fd8f6SDimitry Andric "value spilled to the unknown stack slot"); 2318f0fd8f6SDimitry Andric 23239d628a0SDimitry Andric // This is one of our dedicated lowering slots 23339d628a0SDimitry Andric const int Offset = 23439d628a0SDimitry Andric std::distance(Builder.FuncInfo.StatepointStackSlots.begin(), Itr); 23539d628a0SDimitry Andric if (Builder.StatepointLowering.isStackSlotAllocated(Offset)) { 23639d628a0SDimitry Andric // stack slot already assigned to someone else, can't use it! 23739d628a0SDimitry Andric // TODO: currently we reserve space for gc arguments after doing 23839d628a0SDimitry Andric // normal allocation for deopt arguments. We should reserve for 23939d628a0SDimitry Andric // _all_ deopt and gc arguments, then start allocating. This 24039d628a0SDimitry Andric // will prevent some moves being inserted when vm state changes, 24139d628a0SDimitry Andric // but gc state doesn't between two calls. 24239d628a0SDimitry Andric return; 24339d628a0SDimitry Andric } 24439d628a0SDimitry Andric // Reserve this stack slot 24539d628a0SDimitry Andric Builder.StatepointLowering.reserveStackSlot(Offset); 24639d628a0SDimitry Andric 24739d628a0SDimitry Andric // Cache this slot so we find it when going through the normal 24839d628a0SDimitry Andric // assignment loop. 2498f0fd8f6SDimitry Andric SDValue Loc = Builder.DAG.getTargetFrameIndex(*Index, Incoming.getValueType()); 25039d628a0SDimitry Andric Builder.StatepointLowering.setLocation(Incoming, Loc); 25139d628a0SDimitry Andric } 25239d628a0SDimitry Andric 25339d628a0SDimitry Andric /// Remove any duplicate (as SDValues) from the derived pointer pairs. This 25439d628a0SDimitry Andric /// is not required for correctness. It's purpose is to reduce the size of 25539d628a0SDimitry Andric /// StackMap section. It has no effect on the number of spill slots required 25639d628a0SDimitry Andric /// or the actual lowering. 25739d628a0SDimitry Andric static void removeDuplicatesGCPtrs(SmallVectorImpl<const Value *> &Bases, 25839d628a0SDimitry Andric SmallVectorImpl<const Value *> &Ptrs, 25939d628a0SDimitry Andric SmallVectorImpl<const Value *> &Relocs, 26039d628a0SDimitry Andric SelectionDAGBuilder &Builder) { 26139d628a0SDimitry Andric 2627d523365SDimitry Andric // This is horribly inefficient, but I don't care right now 26339d628a0SDimitry Andric SmallSet<SDValue, 64> Seen; 26439d628a0SDimitry Andric 26539d628a0SDimitry Andric SmallVector<const Value *, 64> NewBases, NewPtrs, NewRelocs; 26639d628a0SDimitry Andric for (size_t i = 0; i < Ptrs.size(); i++) { 26739d628a0SDimitry Andric SDValue SD = Builder.getValue(Ptrs[i]); 26839d628a0SDimitry Andric // Only add non-duplicates 26939d628a0SDimitry Andric if (Seen.count(SD) == 0) { 27039d628a0SDimitry Andric NewBases.push_back(Bases[i]); 27139d628a0SDimitry Andric NewPtrs.push_back(Ptrs[i]); 27239d628a0SDimitry Andric NewRelocs.push_back(Relocs[i]); 27339d628a0SDimitry Andric } 27439d628a0SDimitry Andric Seen.insert(SD); 27539d628a0SDimitry Andric } 27639d628a0SDimitry Andric assert(Bases.size() >= NewBases.size()); 27739d628a0SDimitry Andric assert(Ptrs.size() >= NewPtrs.size()); 27839d628a0SDimitry Andric assert(Relocs.size() >= NewRelocs.size()); 27939d628a0SDimitry Andric Bases = NewBases; 28039d628a0SDimitry Andric Ptrs = NewPtrs; 28139d628a0SDimitry Andric Relocs = NewRelocs; 28239d628a0SDimitry Andric assert(Ptrs.size() == Bases.size()); 28339d628a0SDimitry Andric assert(Ptrs.size() == Relocs.size()); 28439d628a0SDimitry Andric } 28539d628a0SDimitry Andric 28639d628a0SDimitry Andric /// Extract call from statepoint, lower it and return pointer to the 28739d628a0SDimitry Andric /// call node. Also update NodeMap so that getValue(statepoint) will 28839d628a0SDimitry Andric /// reference lowered call result 289ff0cc061SDimitry Andric static SDNode * 2907d523365SDimitry Andric lowerCallFromStatepoint(ImmutableStatepoint ISP, const BasicBlock *EHPadBB, 291ff0cc061SDimitry Andric SelectionDAGBuilder &Builder, 292ff0cc061SDimitry Andric SmallVectorImpl<SDValue> &PendingExports) { 29339d628a0SDimitry Andric 294ff0cc061SDimitry Andric ImmutableCallSite CS(ISP.getCallSite()); 29539d628a0SDimitry Andric 2967d523365SDimitry Andric SDValue ActualCallee; 2977d523365SDimitry Andric 2987d523365SDimitry Andric if (ISP.getNumPatchBytes() > 0) { 2997d523365SDimitry Andric // If we've been asked to emit a nop sequence instead of a call instruction 3007d523365SDimitry Andric // for this statepoint then don't lower the call target, but use a constant 3017d523365SDimitry Andric // `null` instead. Not lowering the call target lets statepoint clients get 3027d523365SDimitry Andric // away without providing a physical address for the symbolic call target at 3037d523365SDimitry Andric // link time. 3047d523365SDimitry Andric 3057d523365SDimitry Andric const auto &TLI = Builder.DAG.getTargetLoweringInfo(); 3067d523365SDimitry Andric const auto &DL = Builder.DAG.getDataLayout(); 3077d523365SDimitry Andric 3087d523365SDimitry Andric unsigned AS = ISP.getCalledValue()->getType()->getPointerAddressSpace(); 3097d523365SDimitry Andric ActualCallee = Builder.DAG.getConstant(0, Builder.getCurSDLoc(), 3107d523365SDimitry Andric TLI.getPointerTy(DL, AS)); 3117d523365SDimitry Andric } else 3127d523365SDimitry Andric ActualCallee = Builder.getValue(ISP.getCalledValue()); 31339d628a0SDimitry Andric 314ff0cc061SDimitry Andric assert(CS.getCallingConv() != CallingConv::AnyReg && 315ff0cc061SDimitry Andric "anyregcc is not supported on statepoints!"); 31639d628a0SDimitry Andric 317ff0cc061SDimitry Andric Type *DefTy = ISP.getActualReturnType(); 318ff0cc061SDimitry Andric bool HasDef = !DefTy->isVoidTy(); 319ff0cc061SDimitry Andric 320ff0cc061SDimitry Andric SDValue ReturnValue, CallEndVal; 321ff0cc061SDimitry Andric std::tie(ReturnValue, CallEndVal) = Builder.lowerCallOperands( 322ff0cc061SDimitry Andric ISP.getCallSite(), ImmutableStatepoint::CallArgsBeginPos, 3237d523365SDimitry Andric ISP.getNumCallArgs(), ActualCallee, DefTy, EHPadBB, 324ff0cc061SDimitry Andric false /* IsPatchPoint */); 325ff0cc061SDimitry Andric 326ff0cc061SDimitry Andric SDNode *CallEnd = CallEndVal.getNode(); 327ff0cc061SDimitry Andric 328ff0cc061SDimitry Andric // Get a call instruction from the call sequence chain. Tail calls are not 329ff0cc061SDimitry Andric // allowed. The following code is essentially reverse engineering X86's 330ff0cc061SDimitry Andric // LowerCallTo. 331ff0cc061SDimitry Andric // 332ff0cc061SDimitry Andric // We are expecting DAG to have the following form: 333ff0cc061SDimitry Andric // 334ff0cc061SDimitry Andric // ch = eh_label (only in case of invoke statepoint) 335ff0cc061SDimitry Andric // ch, glue = callseq_start ch 336ff0cc061SDimitry Andric // ch, glue = X86::Call ch, glue 337ff0cc061SDimitry Andric // ch, glue = callseq_end ch, glue 338ff0cc061SDimitry Andric // get_return_value ch, glue 339ff0cc061SDimitry Andric // 3407d523365SDimitry Andric // get_return_value can either be a sequence of CopyFromReg instructions 3417d523365SDimitry Andric // to grab the return value from the return register(s), or it can be a LOAD 3427d523365SDimitry Andric // to load a value returned by reference via a stack slot. 343ff0cc061SDimitry Andric 3447d523365SDimitry Andric if (HasDef) { 3457d523365SDimitry Andric if (CallEnd->getOpcode() == ISD::LOAD) 346ff0cc061SDimitry Andric CallEnd = CallEnd->getOperand(0).getNode(); 3477d523365SDimitry Andric else 3487d523365SDimitry Andric while (CallEnd->getOpcode() == ISD::CopyFromReg) 3497d523365SDimitry Andric CallEnd = CallEnd->getOperand(0).getNode(); 3507d523365SDimitry Andric } 351ff0cc061SDimitry Andric 352ff0cc061SDimitry Andric assert(CallEnd->getOpcode() == ISD::CALLSEQ_END && "expected!"); 353ff0cc061SDimitry Andric 3547d523365SDimitry Andric // Export the result value if needed 3557d523365SDimitry Andric const Instruction *GCResult = ISP.getGCResult(); 3567d523365SDimitry Andric if (HasDef && GCResult) { 3577d523365SDimitry Andric if (GCResult->getParent() != CS.getParent()) { 3587d523365SDimitry Andric // Result value will be used in a different basic block so we need to 3597d523365SDimitry Andric // export it now. 3607d523365SDimitry Andric // Default exporting mechanism will not work here because statepoint call 3617d523365SDimitry Andric // has a different type than the actual call. It means that by default 3627d523365SDimitry Andric // llvm will create export register of the wrong type (always i32 in our 3637d523365SDimitry Andric // case). So instead we need to create export register with correct type 3647d523365SDimitry Andric // manually. 365ff0cc061SDimitry Andric // TODO: To eliminate this problem we can remove gc.result intrinsics 3667d523365SDimitry Andric // completely and make statepoint call to return a tuple. 367ff0cc061SDimitry Andric unsigned Reg = Builder.FuncInfo.CreateRegs(ISP.getActualReturnType()); 368875ed548SDimitry Andric RegsForValue RFV( 369875ed548SDimitry Andric *Builder.DAG.getContext(), Builder.DAG.getTargetLoweringInfo(), 370875ed548SDimitry Andric Builder.DAG.getDataLayout(), Reg, ISP.getActualReturnType()); 371ff0cc061SDimitry Andric SDValue Chain = Builder.DAG.getEntryNode(); 372ff0cc061SDimitry Andric 373ff0cc061SDimitry Andric RFV.getCopyToRegs(ReturnValue, Builder.DAG, Builder.getCurSDLoc(), Chain, 374ff0cc061SDimitry Andric nullptr); 375ff0cc061SDimitry Andric PendingExports.push_back(Chain); 376ff0cc061SDimitry Andric Builder.FuncInfo.ValueMap[CS.getInstruction()] = Reg; 377ff0cc061SDimitry Andric } else { 3787d523365SDimitry Andric // Result value will be used in a same basic block. Don't export it or 3797d523365SDimitry Andric // perform any explicit register copies. 3807d523365SDimitry Andric // We'll replace the actuall call node shortly. gc_result will grab 38139d628a0SDimitry Andric // this value. 382ff0cc061SDimitry Andric Builder.setValue(CS.getInstruction(), ReturnValue); 383ff0cc061SDimitry Andric } 38439d628a0SDimitry Andric } else { 38539d628a0SDimitry Andric // The token value is never used from here on, just generate a poison value 386ff0cc061SDimitry Andric Builder.setValue(CS.getInstruction(), 387ff0cc061SDimitry Andric Builder.DAG.getIntPtrConstant(-1, Builder.getCurSDLoc())); 38839d628a0SDimitry Andric } 38939d628a0SDimitry Andric 390ff0cc061SDimitry Andric return CallEnd->getOperand(0).getNode(); 39139d628a0SDimitry Andric } 39239d628a0SDimitry Andric 39339d628a0SDimitry Andric /// Callect all gc pointers coming into statepoint intrinsic, clean them up, 39439d628a0SDimitry Andric /// and return two arrays: 39539d628a0SDimitry Andric /// Bases - base pointers incoming to this statepoint 39639d628a0SDimitry Andric /// Ptrs - derived pointers incoming to this statepoint 39739d628a0SDimitry Andric /// Relocs - the gc_relocate corresponding to each base/ptr pair 39839d628a0SDimitry Andric /// Elements of this arrays should be in one-to-one correspondence with each 39939d628a0SDimitry Andric /// other i.e Bases[i], Ptrs[i] are from the same gcrelocate call 400ff0cc061SDimitry Andric static void getIncomingStatepointGCValues( 401ff0cc061SDimitry Andric SmallVectorImpl<const Value *> &Bases, SmallVectorImpl<const Value *> &Ptrs, 402ff0cc061SDimitry Andric SmallVectorImpl<const Value *> &Relocs, ImmutableStatepoint StatepointSite, 40339d628a0SDimitry Andric SelectionDAGBuilder &Builder) { 4048f0fd8f6SDimitry Andric for (GCRelocateOperands relocateOpers : StatepointSite.getRelocates()) { 405ff0cc061SDimitry Andric Relocs.push_back(relocateOpers.getUnderlyingCallSite().getInstruction()); 406ff0cc061SDimitry Andric Bases.push_back(relocateOpers.getBasePtr()); 407ff0cc061SDimitry Andric Ptrs.push_back(relocateOpers.getDerivedPtr()); 40839d628a0SDimitry Andric } 40939d628a0SDimitry Andric 41039d628a0SDimitry Andric // Remove any redundant llvm::Values which map to the same SDValue as another 41139d628a0SDimitry Andric // input. Also has the effect of removing duplicates in the original 41239d628a0SDimitry Andric // llvm::Value input list as well. This is a useful optimization for 41339d628a0SDimitry Andric // reducing the size of the StackMap section. It has no other impact. 41439d628a0SDimitry Andric removeDuplicatesGCPtrs(Bases, Ptrs, Relocs, Builder); 41539d628a0SDimitry Andric 41639d628a0SDimitry Andric assert(Bases.size() == Ptrs.size() && Ptrs.size() == Relocs.size()); 41739d628a0SDimitry Andric } 41839d628a0SDimitry Andric 41939d628a0SDimitry Andric /// Spill a value incoming to the statepoint. It might be either part of 42039d628a0SDimitry Andric /// vmstate 42139d628a0SDimitry Andric /// or gcstate. In both cases unconditionally spill it on the stack unless it 42239d628a0SDimitry Andric /// is a null constant. Return pair with first element being frame index 42339d628a0SDimitry Andric /// containing saved value and second element with outgoing chain from the 42439d628a0SDimitry Andric /// emitted store 42539d628a0SDimitry Andric static std::pair<SDValue, SDValue> 42639d628a0SDimitry Andric spillIncomingStatepointValue(SDValue Incoming, SDValue Chain, 42739d628a0SDimitry Andric SelectionDAGBuilder &Builder) { 42839d628a0SDimitry Andric SDValue Loc = Builder.StatepointLowering.getLocation(Incoming); 42939d628a0SDimitry Andric 43039d628a0SDimitry Andric // Emit new store if we didn't do it for this ptr before 43139d628a0SDimitry Andric if (!Loc.getNode()) { 43239d628a0SDimitry Andric Loc = Builder.StatepointLowering.allocateStackSlot(Incoming.getValueType(), 43339d628a0SDimitry Andric Builder); 43439d628a0SDimitry Andric assert(isa<FrameIndexSDNode>(Loc)); 43539d628a0SDimitry Andric int Index = cast<FrameIndexSDNode>(Loc)->getIndex(); 43639d628a0SDimitry Andric // We use TargetFrameIndex so that isel will not select it into LEA 43739d628a0SDimitry Andric Loc = Builder.DAG.getTargetFrameIndex(Index, Incoming.getValueType()); 43839d628a0SDimitry Andric 43939d628a0SDimitry Andric // TODO: We can create TokenFactor node instead of 44039d628a0SDimitry Andric // chaining stores one after another, this may allow 44139d628a0SDimitry Andric // a bit more optimal scheduling for them 44239d628a0SDimitry Andric Chain = Builder.DAG.getStore(Chain, Builder.getCurSDLoc(), Incoming, Loc, 4437d523365SDimitry Andric MachinePointerInfo::getFixedStack( 4447d523365SDimitry Andric Builder.DAG.getMachineFunction(), Index), 44539d628a0SDimitry Andric false, false, 0); 44639d628a0SDimitry Andric 44739d628a0SDimitry Andric Builder.StatepointLowering.setLocation(Incoming, Loc); 44839d628a0SDimitry Andric } 44939d628a0SDimitry Andric 45039d628a0SDimitry Andric assert(Loc.getNode()); 45139d628a0SDimitry Andric return std::make_pair(Loc, Chain); 45239d628a0SDimitry Andric } 45339d628a0SDimitry Andric 45439d628a0SDimitry Andric /// Lower a single value incoming to a statepoint node. This value can be 45539d628a0SDimitry Andric /// either a deopt value or a gc value, the handling is the same. We special 45639d628a0SDimitry Andric /// case constants and allocas, then fall back to spilling if required. 45739d628a0SDimitry Andric static void lowerIncomingStatepointValue(SDValue Incoming, 45839d628a0SDimitry Andric SmallVectorImpl<SDValue> &Ops, 45939d628a0SDimitry Andric SelectionDAGBuilder &Builder) { 46039d628a0SDimitry Andric SDValue Chain = Builder.getRoot(); 46139d628a0SDimitry Andric 46239d628a0SDimitry Andric if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Incoming)) { 46339d628a0SDimitry Andric // If the original value was a constant, make sure it gets recorded as 46439d628a0SDimitry Andric // such in the stackmap. This is required so that the consumer can 46539d628a0SDimitry Andric // parse any internal format to the deopt state. It also handles null 46639d628a0SDimitry Andric // pointers and other constant pointers in GC states 467ff0cc061SDimitry Andric pushStackMapConstant(Ops, Builder, C->getSExtValue()); 46839d628a0SDimitry Andric } else if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(Incoming)) { 469ff0cc061SDimitry Andric // This handles allocas as arguments to the statepoint (this is only 470ff0cc061SDimitry Andric // really meaningful for a deopt value. For GC, we'd be trying to 471ff0cc061SDimitry Andric // relocate the address of the alloca itself?) 472ff0cc061SDimitry Andric Ops.push_back(Builder.DAG.getTargetFrameIndex(FI->getIndex(), 473ff0cc061SDimitry Andric Incoming.getValueType())); 47439d628a0SDimitry Andric } else { 47539d628a0SDimitry Andric // Otherwise, locate a spill slot and explicitly spill it so it 47639d628a0SDimitry Andric // can be found by the runtime later. We currently do not support 47739d628a0SDimitry Andric // tracking values through callee saved registers to their eventual 47839d628a0SDimitry Andric // spill location. This would be a useful optimization, but would 47939d628a0SDimitry Andric // need to be optional since it requires a lot of complexity on the 48039d628a0SDimitry Andric // runtime side which not all would support. 48139d628a0SDimitry Andric std::pair<SDValue, SDValue> Res = 48239d628a0SDimitry Andric spillIncomingStatepointValue(Incoming, Chain, Builder); 48339d628a0SDimitry Andric Ops.push_back(Res.first); 48439d628a0SDimitry Andric Chain = Res.second; 48539d628a0SDimitry Andric } 48639d628a0SDimitry Andric 48739d628a0SDimitry Andric Builder.DAG.setRoot(Chain); 48839d628a0SDimitry Andric } 48939d628a0SDimitry Andric 49039d628a0SDimitry Andric /// Lower deopt state and gc pointer arguments of the statepoint. The actual 49139d628a0SDimitry Andric /// lowering is described in lowerIncomingStatepointValue. This function is 49239d628a0SDimitry Andric /// responsible for lowering everything in the right position and playing some 49339d628a0SDimitry Andric /// tricks to avoid redundant stack manipulation where possible. On 49439d628a0SDimitry Andric /// completion, 'Ops' will contain ready to use operands for machine code 49539d628a0SDimitry Andric /// statepoint. The chain nodes will have already been created and the DAG root 49639d628a0SDimitry Andric /// will be set to the last value spilled (if any were). 49739d628a0SDimitry Andric static void lowerStatepointMetaArgs(SmallVectorImpl<SDValue> &Ops, 498ff0cc061SDimitry Andric ImmutableStatepoint StatepointSite, 49939d628a0SDimitry Andric SelectionDAGBuilder &Builder) { 50039d628a0SDimitry Andric 50139d628a0SDimitry Andric // Lower the deopt and gc arguments for this statepoint. Layout will 50239d628a0SDimitry Andric // be: deopt argument length, deopt arguments.., gc arguments... 50339d628a0SDimitry Andric 50439d628a0SDimitry Andric SmallVector<const Value *, 64> Bases, Ptrs, Relocations; 505ff0cc061SDimitry Andric getIncomingStatepointGCValues(Bases, Ptrs, Relocations, StatepointSite, 506ff0cc061SDimitry Andric Builder); 50739d628a0SDimitry Andric 50839d628a0SDimitry Andric #ifndef NDEBUG 50939d628a0SDimitry Andric // Check that each of the gc pointer and bases we've gotten out of the 51039d628a0SDimitry Andric // safepoint is something the strategy thinks might be a pointer into the GC 51139d628a0SDimitry Andric // heap. This is basically just here to help catch errors during statepoint 51239d628a0SDimitry Andric // insertion. TODO: This should actually be in the Verifier, but we can't get 51339d628a0SDimitry Andric // to the GCStrategy from there (yet). 51439d628a0SDimitry Andric GCStrategy &S = Builder.GFI->getStrategy(); 51539d628a0SDimitry Andric for (const Value *V : Bases) { 5167d523365SDimitry Andric auto Opt = S.isGCManagedPointer(V->getType()); 51739d628a0SDimitry Andric if (Opt.hasValue()) { 51839d628a0SDimitry Andric assert(Opt.getValue() && 51939d628a0SDimitry Andric "non gc managed base pointer found in statepoint"); 52039d628a0SDimitry Andric } 52139d628a0SDimitry Andric } 52239d628a0SDimitry Andric for (const Value *V : Ptrs) { 5237d523365SDimitry Andric auto Opt = S.isGCManagedPointer(V->getType()); 52439d628a0SDimitry Andric if (Opt.hasValue()) { 52539d628a0SDimitry Andric assert(Opt.getValue() && 52639d628a0SDimitry Andric "non gc managed derived pointer found in statepoint"); 52739d628a0SDimitry Andric } 52839d628a0SDimitry Andric } 52939d628a0SDimitry Andric for (const Value *V : Relocations) { 5307d523365SDimitry Andric auto Opt = S.isGCManagedPointer(V->getType()); 53139d628a0SDimitry Andric if (Opt.hasValue()) { 53239d628a0SDimitry Andric assert(Opt.getValue() && "non gc managed pointer relocated"); 53339d628a0SDimitry Andric } 53439d628a0SDimitry Andric } 53539d628a0SDimitry Andric #endif 53639d628a0SDimitry Andric 53739d628a0SDimitry Andric // Before we actually start lowering (and allocating spill slots for values), 53839d628a0SDimitry Andric // reserve any stack slots which we judge to be profitable to reuse for a 53939d628a0SDimitry Andric // particular value. This is purely an optimization over the code below and 54039d628a0SDimitry Andric // doesn't change semantics at all. It is important for performance that we 54139d628a0SDimitry Andric // reserve slots for both deopt and gc values before lowering either. 542ff0cc061SDimitry Andric for (const Value *V : StatepointSite.vm_state_args()) { 5438f0fd8f6SDimitry Andric reservePreviousStackSlotForValue(V, Builder); 54439d628a0SDimitry Andric } 545ff0cc061SDimitry Andric for (unsigned i = 0; i < Bases.size(); ++i) { 5468f0fd8f6SDimitry Andric reservePreviousStackSlotForValue(Bases[i], Builder); 5478f0fd8f6SDimitry Andric reservePreviousStackSlotForValue(Ptrs[i], Builder); 54839d628a0SDimitry Andric } 54939d628a0SDimitry Andric 55039d628a0SDimitry Andric // First, prefix the list with the number of unique values to be 55139d628a0SDimitry Andric // lowered. Note that this is the number of *Values* not the 55239d628a0SDimitry Andric // number of SDValues required to lower them. 553ff0cc061SDimitry Andric const int NumVMSArgs = StatepointSite.getNumTotalVMSArgs(); 554ff0cc061SDimitry Andric pushStackMapConstant(Ops, Builder, NumVMSArgs); 55539d628a0SDimitry Andric 556ff0cc061SDimitry Andric assert(NumVMSArgs == std::distance(StatepointSite.vm_state_begin(), 557ff0cc061SDimitry Andric StatepointSite.vm_state_end())); 55839d628a0SDimitry Andric 55939d628a0SDimitry Andric // The vm state arguments are lowered in an opaque manner. We do 56039d628a0SDimitry Andric // not know what type of values are contained within. We skip the 56139d628a0SDimitry Andric // first one since that happens to be the total number we lowered 56239d628a0SDimitry Andric // explicitly just above. We could have left it in the loop and 56339d628a0SDimitry Andric // not done it explicitly, but it's far easier to understand this 56439d628a0SDimitry Andric // way. 565ff0cc061SDimitry Andric for (const Value *V : StatepointSite.vm_state_args()) { 56639d628a0SDimitry Andric SDValue Incoming = Builder.getValue(V); 56739d628a0SDimitry Andric lowerIncomingStatepointValue(Incoming, Ops, Builder); 56839d628a0SDimitry Andric } 56939d628a0SDimitry Andric 57039d628a0SDimitry Andric // Finally, go ahead and lower all the gc arguments. There's no prefixed 57139d628a0SDimitry Andric // length for this one. After lowering, we'll have the base and pointer 57239d628a0SDimitry Andric // arrays interwoven with each (lowered) base pointer immediately followed by 57339d628a0SDimitry Andric // it's (lowered) derived pointer. i.e 57439d628a0SDimitry Andric // (base[0], ptr[0], base[1], ptr[1], ...) 575ff0cc061SDimitry Andric for (unsigned i = 0; i < Bases.size(); ++i) { 576ff0cc061SDimitry Andric const Value *Base = Bases[i]; 577ff0cc061SDimitry Andric lowerIncomingStatepointValue(Builder.getValue(Base), Ops, Builder); 578ff0cc061SDimitry Andric 579ff0cc061SDimitry Andric const Value *Ptr = Ptrs[i]; 580ff0cc061SDimitry Andric lowerIncomingStatepointValue(Builder.getValue(Ptr), Ops, Builder); 581ff0cc061SDimitry Andric } 582ff0cc061SDimitry Andric 583ff0cc061SDimitry Andric // If there are any explicit spill slots passed to the statepoint, record 584ff0cc061SDimitry Andric // them, but otherwise do not do anything special. These are user provided 585ff0cc061SDimitry Andric // allocas and give control over placement to the consumer. In this case, 586ff0cc061SDimitry Andric // it is the contents of the slot which may get updated, not the pointer to 587ff0cc061SDimitry Andric // the alloca 588ff0cc061SDimitry Andric for (Value *V : StatepointSite.gc_args()) { 58939d628a0SDimitry Andric SDValue Incoming = Builder.getValue(V); 590ff0cc061SDimitry Andric if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(Incoming)) { 591ff0cc061SDimitry Andric // This handles allocas as arguments to the statepoint 592ff0cc061SDimitry Andric Ops.push_back(Builder.DAG.getTargetFrameIndex(FI->getIndex(), 593ff0cc061SDimitry Andric Incoming.getValueType())); 59439d628a0SDimitry Andric } 59539d628a0SDimitry Andric } 596ff0cc061SDimitry Andric 597ff0cc061SDimitry Andric // Record computed locations for all lowered values. 598ff0cc061SDimitry Andric // This can not be embedded in lowering loops as we need to record *all* 599ff0cc061SDimitry Andric // values, while previous loops account only values with unique SDValues. 600ff0cc061SDimitry Andric const Instruction *StatepointInstr = 601ff0cc061SDimitry Andric StatepointSite.getCallSite().getInstruction(); 602ff0cc061SDimitry Andric FunctionLoweringInfo::StatepointSpilledValueMapTy &SpillMap = 603ff0cc061SDimitry Andric Builder.FuncInfo.StatepointRelocatedValues[StatepointInstr]; 604ff0cc061SDimitry Andric 6058f0fd8f6SDimitry Andric for (GCRelocateOperands RelocateOpers : StatepointSite.getRelocates()) { 606ff0cc061SDimitry Andric const Value *V = RelocateOpers.getDerivedPtr(); 607ff0cc061SDimitry Andric SDValue SDV = Builder.getValue(V); 608ff0cc061SDimitry Andric SDValue Loc = Builder.StatepointLowering.getLocation(SDV); 609ff0cc061SDimitry Andric 610ff0cc061SDimitry Andric if (Loc.getNode()) { 611ff0cc061SDimitry Andric SpillMap[V] = cast<FrameIndexSDNode>(Loc)->getIndex(); 612ff0cc061SDimitry Andric } else { 613ff0cc061SDimitry Andric // Record value as visited, but not spilled. This is case for allocas 6147d523365SDimitry Andric // and constants. For this values we can avoid emitting spill load while 615ff0cc061SDimitry Andric // visiting corresponding gc_relocate. 616ff0cc061SDimitry Andric // Actually we do not need to record them in this map at all. 6177d523365SDimitry Andric // We do this only to check that we are not relocating any unvisited 6187d523365SDimitry Andric // value. 619ff0cc061SDimitry Andric SpillMap[V] = None; 620ff0cc061SDimitry Andric 621ff0cc061SDimitry Andric // Default llvm mechanisms for exporting values which are used in 622ff0cc061SDimitry Andric // different basic blocks does not work for gc relocates. 623ff0cc061SDimitry Andric // Note that it would be incorrect to teach llvm that all relocates are 6247d523365SDimitry Andric // uses of the corresponding values so that it would automatically 625ff0cc061SDimitry Andric // export them. Relocates of the spilled values does not use original 626ff0cc061SDimitry Andric // value. 6277d523365SDimitry Andric if (RelocateOpers.getUnderlyingCallSite().getParent() != 6287d523365SDimitry Andric StatepointInstr->getParent()) 629ff0cc061SDimitry Andric Builder.ExportFromCurrentBlock(V); 630ff0cc061SDimitry Andric } 631ff0cc061SDimitry Andric } 632ff0cc061SDimitry Andric } 633ff0cc061SDimitry Andric 63439d628a0SDimitry Andric void SelectionDAGBuilder::visitStatepoint(const CallInst &CI) { 635ff0cc061SDimitry Andric // Check some preconditions for sanity 636ff0cc061SDimitry Andric assert(isStatepoint(&CI) && 637ff0cc061SDimitry Andric "function called must be the statepoint function"); 638ff0cc061SDimitry Andric 639ff0cc061SDimitry Andric LowerStatepoint(ImmutableStatepoint(&CI)); 640ff0cc061SDimitry Andric } 641ff0cc061SDimitry Andric 642ff0cc061SDimitry Andric void SelectionDAGBuilder::LowerStatepoint( 6437d523365SDimitry Andric ImmutableStatepoint ISP, const BasicBlock *EHPadBB /*= nullptr*/) { 64439d628a0SDimitry Andric // The basic scheme here is that information about both the original call and 64539d628a0SDimitry Andric // the safepoint is encoded in the CallInst. We create a temporary call and 64639d628a0SDimitry Andric // lower it, then reverse engineer the calling sequence. 64739d628a0SDimitry Andric 64839d628a0SDimitry Andric NumOfStatepoints++; 64939d628a0SDimitry Andric // Clear state 65039d628a0SDimitry Andric StatepointLowering.startNewStatepoint(*this); 65139d628a0SDimitry Andric 652ff0cc061SDimitry Andric ImmutableCallSite CS(ISP.getCallSite()); 653ff0cc061SDimitry Andric 65439d628a0SDimitry Andric #ifndef NDEBUG 6557d523365SDimitry Andric // Consistency check. Check only relocates in the same basic block as thier 6567d523365SDimitry Andric // statepoint. 657ff0cc061SDimitry Andric for (const User *U : CS->users()) { 65839d628a0SDimitry Andric const CallInst *Call = cast<CallInst>(U); 6597d523365SDimitry Andric if (isGCRelocate(Call) && Call->getParent() == CS.getParent()) 66039d628a0SDimitry Andric StatepointLowering.scheduleRelocCall(*Call); 66139d628a0SDimitry Andric } 66239d628a0SDimitry Andric #endif 66339d628a0SDimitry Andric 66439d628a0SDimitry Andric #ifndef NDEBUG 66539d628a0SDimitry Andric // If this is a malformed statepoint, report it early to simplify debugging. 66639d628a0SDimitry Andric // This should catch any IR level mistake that's made when constructing or 66739d628a0SDimitry Andric // transforming statepoints. 66839d628a0SDimitry Andric ISP.verify(); 66939d628a0SDimitry Andric 67039d628a0SDimitry Andric // Check that the associated GCStrategy expects to encounter statepoints. 67139d628a0SDimitry Andric assert(GFI->getStrategy().useStatepoints() && 67239d628a0SDimitry Andric "GCStrategy does not expect to encounter statepoints"); 67339d628a0SDimitry Andric #endif 67439d628a0SDimitry Andric 67539d628a0SDimitry Andric // Lower statepoint vmstate and gcstate arguments 676ff0cc061SDimitry Andric SmallVector<SDValue, 10> LoweredMetaArgs; 677ff0cc061SDimitry Andric lowerStatepointMetaArgs(LoweredMetaArgs, ISP, *this); 67839d628a0SDimitry Andric 67939d628a0SDimitry Andric // Get call node, we will replace it later with statepoint 680ff0cc061SDimitry Andric SDNode *CallNode = 6817d523365SDimitry Andric lowerCallFromStatepoint(ISP, EHPadBB, *this, PendingExports); 68239d628a0SDimitry Andric 683ff0cc061SDimitry Andric // Construct the actual GC_TRANSITION_START, STATEPOINT, and GC_TRANSITION_END 684ff0cc061SDimitry Andric // nodes with all the appropriate arguments and return values. 685ff0cc061SDimitry Andric 686ff0cc061SDimitry Andric // Call Node: Chain, Target, {Args}, RegMask, [Glue] 687ff0cc061SDimitry Andric SDValue Chain = CallNode->getOperand(0); 688ff0cc061SDimitry Andric 689ff0cc061SDimitry Andric SDValue Glue; 690ff0cc061SDimitry Andric bool CallHasIncomingGlue = CallNode->getGluedNode(); 691ff0cc061SDimitry Andric if (CallHasIncomingGlue) { 692ff0cc061SDimitry Andric // Glue is always last operand 693ff0cc061SDimitry Andric Glue = CallNode->getOperand(CallNode->getNumOperands() - 1); 694ff0cc061SDimitry Andric } 695ff0cc061SDimitry Andric 696ff0cc061SDimitry Andric // Build the GC_TRANSITION_START node if necessary. 697ff0cc061SDimitry Andric // 698ff0cc061SDimitry Andric // The operands to the GC_TRANSITION_{START,END} nodes are laid out in the 699ff0cc061SDimitry Andric // order in which they appear in the call to the statepoint intrinsic. If 700ff0cc061SDimitry Andric // any of the operands is a pointer-typed, that operand is immediately 701ff0cc061SDimitry Andric // followed by a SRCVALUE for the pointer that may be used during lowering 702ff0cc061SDimitry Andric // (e.g. to form MachinePointerInfo values for loads/stores). 703ff0cc061SDimitry Andric const bool IsGCTransition = 704ff0cc061SDimitry Andric (ISP.getFlags() & (uint64_t)StatepointFlags::GCTransition) == 705ff0cc061SDimitry Andric (uint64_t)StatepointFlags::GCTransition; 706ff0cc061SDimitry Andric if (IsGCTransition) { 707ff0cc061SDimitry Andric SmallVector<SDValue, 8> TSOps; 708ff0cc061SDimitry Andric 709ff0cc061SDimitry Andric // Add chain 710ff0cc061SDimitry Andric TSOps.push_back(Chain); 711ff0cc061SDimitry Andric 712ff0cc061SDimitry Andric // Add GC transition arguments 713ff0cc061SDimitry Andric for (const Value *V : ISP.gc_transition_args()) { 714ff0cc061SDimitry Andric TSOps.push_back(getValue(V)); 715ff0cc061SDimitry Andric if (V->getType()->isPointerTy()) 716ff0cc061SDimitry Andric TSOps.push_back(DAG.getSrcValue(V)); 717ff0cc061SDimitry Andric } 718ff0cc061SDimitry Andric 719ff0cc061SDimitry Andric // Add glue if necessary 720ff0cc061SDimitry Andric if (CallHasIncomingGlue) 721ff0cc061SDimitry Andric TSOps.push_back(Glue); 722ff0cc061SDimitry Andric 723ff0cc061SDimitry Andric SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); 724ff0cc061SDimitry Andric 725ff0cc061SDimitry Andric SDValue GCTransitionStart = 726ff0cc061SDimitry Andric DAG.getNode(ISD::GC_TRANSITION_START, getCurSDLoc(), NodeTys, TSOps); 727ff0cc061SDimitry Andric 728ff0cc061SDimitry Andric Chain = GCTransitionStart.getValue(0); 729ff0cc061SDimitry Andric Glue = GCTransitionStart.getValue(1); 730ff0cc061SDimitry Andric } 73139d628a0SDimitry Andric 73239d628a0SDimitry Andric // TODO: Currently, all of these operands are being marked as read/write in 73339d628a0SDimitry Andric // PrologEpilougeInserter.cpp, we should special case the VMState arguments 73439d628a0SDimitry Andric // and flags to be read-only. 73539d628a0SDimitry Andric SmallVector<SDValue, 40> Ops; 73639d628a0SDimitry Andric 737ff0cc061SDimitry Andric // Add the <id> and <numBytes> constants. 738ff0cc061SDimitry Andric Ops.push_back(DAG.getTargetConstant(ISP.getID(), getCurSDLoc(), MVT::i64)); 739ff0cc061SDimitry Andric Ops.push_back( 740ff0cc061SDimitry Andric DAG.getTargetConstant(ISP.getNumPatchBytes(), getCurSDLoc(), MVT::i32)); 741ff0cc061SDimitry Andric 74239d628a0SDimitry Andric // Calculate and push starting position of vmstate arguments 74339d628a0SDimitry Andric // Get number of arguments incoming directly into call node 74439d628a0SDimitry Andric unsigned NumCallRegArgs = 745ff0cc061SDimitry Andric CallNode->getNumOperands() - (CallHasIncomingGlue ? 4 : 3); 746ff0cc061SDimitry Andric Ops.push_back(DAG.getTargetConstant(NumCallRegArgs, getCurSDLoc(), MVT::i32)); 74739d628a0SDimitry Andric 74839d628a0SDimitry Andric // Add call target 74939d628a0SDimitry Andric SDValue CallTarget = SDValue(CallNode->getOperand(1).getNode(), 0); 75039d628a0SDimitry Andric Ops.push_back(CallTarget); 75139d628a0SDimitry Andric 75239d628a0SDimitry Andric // Add call arguments 75339d628a0SDimitry Andric // Get position of register mask in the call 75439d628a0SDimitry Andric SDNode::op_iterator RegMaskIt; 755ff0cc061SDimitry Andric if (CallHasIncomingGlue) 75639d628a0SDimitry Andric RegMaskIt = CallNode->op_end() - 2; 75739d628a0SDimitry Andric else 75839d628a0SDimitry Andric RegMaskIt = CallNode->op_end() - 1; 75939d628a0SDimitry Andric Ops.insert(Ops.end(), CallNode->op_begin() + 2, RegMaskIt); 76039d628a0SDimitry Andric 761ff0cc061SDimitry Andric // Add a constant argument for the calling convention 762ff0cc061SDimitry Andric pushStackMapConstant(Ops, *this, CS.getCallingConv()); 763ff0cc061SDimitry Andric 764ff0cc061SDimitry Andric // Add a constant argument for the flags 765ff0cc061SDimitry Andric uint64_t Flags = ISP.getFlags(); 766ff0cc061SDimitry Andric assert( 767ff0cc061SDimitry Andric ((Flags & ~(uint64_t)StatepointFlags::MaskAll) == 0) 768ff0cc061SDimitry Andric && "unknown flag used"); 769ff0cc061SDimitry Andric pushStackMapConstant(Ops, *this, Flags); 77039d628a0SDimitry Andric 77139d628a0SDimitry Andric // Insert all vmstate and gcstate arguments 772ff0cc061SDimitry Andric Ops.insert(Ops.end(), LoweredMetaArgs.begin(), LoweredMetaArgs.end()); 77339d628a0SDimitry Andric 77439d628a0SDimitry Andric // Add register mask from call node 77539d628a0SDimitry Andric Ops.push_back(*RegMaskIt); 77639d628a0SDimitry Andric 77739d628a0SDimitry Andric // Add chain 778ff0cc061SDimitry Andric Ops.push_back(Chain); 77939d628a0SDimitry Andric 78039d628a0SDimitry Andric // Same for the glue, but we add it only if original call had it 78139d628a0SDimitry Andric if (Glue.getNode()) 78239d628a0SDimitry Andric Ops.push_back(Glue); 78339d628a0SDimitry Andric 784ff0cc061SDimitry Andric // Compute return values. Provide a glue output since we consume one as 785ff0cc061SDimitry Andric // input. This allows someone else to chain off us as needed. 786ff0cc061SDimitry Andric SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); 78739d628a0SDimitry Andric 788ff0cc061SDimitry Andric SDNode *StatepointMCNode = 789ff0cc061SDimitry Andric DAG.getMachineNode(TargetOpcode::STATEPOINT, getCurSDLoc(), NodeTys, Ops); 790ff0cc061SDimitry Andric 791ff0cc061SDimitry Andric SDNode *SinkNode = StatepointMCNode; 792ff0cc061SDimitry Andric 793ff0cc061SDimitry Andric // Build the GC_TRANSITION_END node if necessary. 794ff0cc061SDimitry Andric // 795ff0cc061SDimitry Andric // See the comment above regarding GC_TRANSITION_START for the layout of 796ff0cc061SDimitry Andric // the operands to the GC_TRANSITION_END node. 797ff0cc061SDimitry Andric if (IsGCTransition) { 798ff0cc061SDimitry Andric SmallVector<SDValue, 8> TEOps; 799ff0cc061SDimitry Andric 800ff0cc061SDimitry Andric // Add chain 801ff0cc061SDimitry Andric TEOps.push_back(SDValue(StatepointMCNode, 0)); 802ff0cc061SDimitry Andric 803ff0cc061SDimitry Andric // Add GC transition arguments 804ff0cc061SDimitry Andric for (const Value *V : ISP.gc_transition_args()) { 805ff0cc061SDimitry Andric TEOps.push_back(getValue(V)); 806ff0cc061SDimitry Andric if (V->getType()->isPointerTy()) 807ff0cc061SDimitry Andric TEOps.push_back(DAG.getSrcValue(V)); 808ff0cc061SDimitry Andric } 809ff0cc061SDimitry Andric 810ff0cc061SDimitry Andric // Add glue 811ff0cc061SDimitry Andric TEOps.push_back(SDValue(StatepointMCNode, 1)); 812ff0cc061SDimitry Andric 813ff0cc061SDimitry Andric SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); 814ff0cc061SDimitry Andric 815ff0cc061SDimitry Andric SDValue GCTransitionStart = 816ff0cc061SDimitry Andric DAG.getNode(ISD::GC_TRANSITION_END, getCurSDLoc(), NodeTys, TEOps); 817ff0cc061SDimitry Andric 818ff0cc061SDimitry Andric SinkNode = GCTransitionStart.getNode(); 819ff0cc061SDimitry Andric } 82039d628a0SDimitry Andric 82139d628a0SDimitry Andric // Replace original call 822ff0cc061SDimitry Andric DAG.ReplaceAllUsesWith(CallNode, SinkNode); // This may update Root 8237d523365SDimitry Andric // Remove original call node 82439d628a0SDimitry Andric DAG.DeleteNode(CallNode); 82539d628a0SDimitry Andric 82639d628a0SDimitry Andric // DON'T set the root - under the assumption that it's already set past the 82739d628a0SDimitry Andric // inserted node we created. 82839d628a0SDimitry Andric 82939d628a0SDimitry Andric // TODO: A better future implementation would be to emit a single variable 83039d628a0SDimitry Andric // argument, variable return value STATEPOINT node here and then hookup the 83139d628a0SDimitry Andric // return value of each gc.relocate to the respective output of the 83239d628a0SDimitry Andric // previously emitted STATEPOINT value. Unfortunately, this doesn't appear 83339d628a0SDimitry Andric // to actually be possible today. 83439d628a0SDimitry Andric } 83539d628a0SDimitry Andric 83639d628a0SDimitry Andric void SelectionDAGBuilder::visitGCResult(const CallInst &CI) { 83739d628a0SDimitry Andric // The result value of the gc_result is simply the result of the actual 83839d628a0SDimitry Andric // call. We've already emitted this, so just grab the value. 83939d628a0SDimitry Andric Instruction *I = cast<Instruction>(CI.getArgOperand(0)); 840ff0cc061SDimitry Andric assert(isStatepoint(I) && "first argument must be a statepoint token"); 84139d628a0SDimitry Andric 8427d523365SDimitry Andric if (I->getParent() != CI.getParent()) { 8437d523365SDimitry Andric // Statepoint is in different basic block so we should have stored call 8447d523365SDimitry Andric // result in a virtual register. 845ff0cc061SDimitry Andric // We can not use default getValue() functionality to copy value from this 846ff0cc061SDimitry Andric // register because statepoint and actuall call return types can be 847ff0cc061SDimitry Andric // different, and getValue() will use CopyFromReg of the wrong type, 848ff0cc061SDimitry Andric // which is always i32 in our case. 8493dac3a9bSDimitry Andric PointerType *CalleeType = cast<PointerType>( 8503dac3a9bSDimitry Andric ImmutableStatepoint(I).getCalledValue()->getType()); 851ff0cc061SDimitry Andric Type *RetTy = 852ff0cc061SDimitry Andric cast<FunctionType>(CalleeType->getElementType())->getReturnType(); 853ff0cc061SDimitry Andric SDValue CopyFromReg = getCopyFromRegs(I, RetTy); 854ff0cc061SDimitry Andric 855ff0cc061SDimitry Andric assert(CopyFromReg.getNode()); 856ff0cc061SDimitry Andric setValue(&CI, CopyFromReg); 857ff0cc061SDimitry Andric } else { 85839d628a0SDimitry Andric setValue(&CI, getValue(I)); 85939d628a0SDimitry Andric } 860ff0cc061SDimitry Andric } 86139d628a0SDimitry Andric 86239d628a0SDimitry Andric void SelectionDAGBuilder::visitGCRelocate(const CallInst &CI) { 863ff0cc061SDimitry Andric GCRelocateOperands RelocateOpers(&CI); 864ff0cc061SDimitry Andric 86539d628a0SDimitry Andric #ifndef NDEBUG 86639d628a0SDimitry Andric // Consistency check 8677d523365SDimitry Andric // We skip this check for relocates not in the same basic block as thier 8687d523365SDimitry Andric // statepoint. It would be too expensive to preserve validation info through 8697d523365SDimitry Andric // different basic blocks. 8707d523365SDimitry Andric if (RelocateOpers.getStatepoint()->getParent() == CI.getParent()) { 87139d628a0SDimitry Andric StatepointLowering.relocCallVisited(CI); 872ff0cc061SDimitry Andric } 87339d628a0SDimitry Andric #endif 87439d628a0SDimitry Andric 875ff0cc061SDimitry Andric const Value *DerivedPtr = RelocateOpers.getDerivedPtr(); 876ff0cc061SDimitry Andric SDValue SD = getValue(DerivedPtr); 87739d628a0SDimitry Andric 878ff0cc061SDimitry Andric FunctionLoweringInfo::StatepointSpilledValueMapTy &SpillMap = 879ff0cc061SDimitry Andric FuncInfo.StatepointRelocatedValues[RelocateOpers.getStatepoint()]; 880ff0cc061SDimitry Andric 881ff0cc061SDimitry Andric // We should have recorded location for this pointer 882ff0cc061SDimitry Andric assert(SpillMap.count(DerivedPtr) && "Relocating not lowered gc value"); 883ff0cc061SDimitry Andric Optional<int> DerivedPtrLocation = SpillMap[DerivedPtr]; 884ff0cc061SDimitry Andric 88539d628a0SDimitry Andric // We didn't need to spill these special cases (constants and allocas). 88639d628a0SDimitry Andric // See the handling in spillIncomingValueForStatepoint for detail. 887ff0cc061SDimitry Andric if (!DerivedPtrLocation) { 88839d628a0SDimitry Andric setValue(&CI, SD); 88939d628a0SDimitry Andric return; 89039d628a0SDimitry Andric } 89139d628a0SDimitry Andric 892ff0cc061SDimitry Andric SDValue SpillSlot = DAG.getTargetFrameIndex(*DerivedPtrLocation, 893ff0cc061SDimitry Andric SD.getValueType()); 89439d628a0SDimitry Andric 89539d628a0SDimitry Andric // Be conservative: flush all pending loads 89639d628a0SDimitry Andric // TODO: Probably we can be less restrictive on this, 8977d523365SDimitry Andric // it may allow more scheduling opportunities. 89839d628a0SDimitry Andric SDValue Chain = getRoot(); 89939d628a0SDimitry Andric 900ff0cc061SDimitry Andric SDValue SpillLoad = 901ff0cc061SDimitry Andric DAG.getLoad(SpillSlot.getValueType(), getCurSDLoc(), Chain, SpillSlot, 9027d523365SDimitry Andric MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), 9037d523365SDimitry Andric *DerivedPtrLocation), 904ff0cc061SDimitry Andric false, false, false, 0); 90539d628a0SDimitry Andric 90639d628a0SDimitry Andric // Again, be conservative, don't emit pending loads 907ff0cc061SDimitry Andric DAG.setRoot(SpillLoad.getValue(1)); 90839d628a0SDimitry Andric 909ff0cc061SDimitry Andric assert(SpillLoad.getNode()); 910ff0cc061SDimitry Andric setValue(&CI, SpillLoad); 91139d628a0SDimitry Andric } 912