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" 20ff0cc061SDimitry Andric #include "llvm/CodeGen/GCMetadata.h" 2139d628a0SDimitry Andric #include "llvm/CodeGen/GCStrategy.h" 2239d628a0SDimitry Andric #include "llvm/CodeGen/SelectionDAG.h" 2339d628a0SDimitry Andric #include "llvm/CodeGen/StackMaps.h" 2439d628a0SDimitry Andric #include "llvm/IR/CallingConv.h" 2539d628a0SDimitry Andric #include "llvm/IR/Instructions.h" 2639d628a0SDimitry Andric #include "llvm/IR/IntrinsicInst.h" 2739d628a0SDimitry Andric #include "llvm/IR/Intrinsics.h" 2839d628a0SDimitry Andric #include "llvm/IR/Statepoint.h" 2939d628a0SDimitry Andric #include "llvm/Target/TargetLowering.h" 3039d628a0SDimitry Andric #include <algorithm> 3139d628a0SDimitry Andric using namespace llvm; 3239d628a0SDimitry Andric 3339d628a0SDimitry Andric #define DEBUG_TYPE "statepoint-lowering" 3439d628a0SDimitry Andric 3539d628a0SDimitry Andric STATISTIC(NumSlotsAllocatedForStatepoints, 3639d628a0SDimitry Andric "Number of stack slots allocated for statepoints"); 3739d628a0SDimitry Andric STATISTIC(NumOfStatepoints, "Number of statepoint nodes encountered"); 3839d628a0SDimitry Andric STATISTIC(StatepointMaxSlotsRequired, 3939d628a0SDimitry Andric "Maximum number of stack slots required for a singe statepoint"); 4039d628a0SDimitry Andric 41ff0cc061SDimitry Andric static void pushStackMapConstant(SmallVectorImpl<SDValue>& Ops, 42ff0cc061SDimitry Andric SelectionDAGBuilder &Builder, uint64_t Value) { 43ff0cc061SDimitry Andric SDLoc L = Builder.getCurSDLoc(); 44ff0cc061SDimitry Andric Ops.push_back(Builder.DAG.getTargetConstant(StackMaps::ConstantOp, L, 45ff0cc061SDimitry Andric MVT::i64)); 46ff0cc061SDimitry Andric Ops.push_back(Builder.DAG.getTargetConstant(Value, L, MVT::i64)); 47ff0cc061SDimitry Andric } 48ff0cc061SDimitry Andric 49ff0cc061SDimitry Andric void StatepointLoweringState::startNewStatepoint(SelectionDAGBuilder &Builder) { 5039d628a0SDimitry Andric // Consistency check 5139d628a0SDimitry Andric assert(PendingGCRelocateCalls.empty() && 5239d628a0SDimitry Andric "Trying to visit statepoint before finished processing previous one"); 5339d628a0SDimitry Andric Locations.clear(); 5439d628a0SDimitry Andric NextSlotToAllocate = 0; 5539d628a0SDimitry Andric // Need to resize this on each safepoint - we need the two to stay in 5639d628a0SDimitry Andric // sync and the clear patterns of a SelectionDAGBuilder have no relation 5739d628a0SDimitry Andric // to FunctionLoweringInfo. 5839d628a0SDimitry Andric AllocatedStackSlots.resize(Builder.FuncInfo.StatepointStackSlots.size()); 5939d628a0SDimitry Andric for (size_t i = 0; i < AllocatedStackSlots.size(); i++) { 6039d628a0SDimitry Andric AllocatedStackSlots[i] = false; 6139d628a0SDimitry Andric } 6239d628a0SDimitry Andric } 63ff0cc061SDimitry Andric 6439d628a0SDimitry Andric void StatepointLoweringState::clear() { 6539d628a0SDimitry Andric Locations.clear(); 6639d628a0SDimitry Andric AllocatedStackSlots.clear(); 6739d628a0SDimitry Andric assert(PendingGCRelocateCalls.empty() && 6839d628a0SDimitry Andric "cleared before statepoint sequence completed"); 6939d628a0SDimitry Andric } 7039d628a0SDimitry Andric 7139d628a0SDimitry Andric SDValue 7239d628a0SDimitry Andric StatepointLoweringState::allocateStackSlot(EVT ValueType, 7339d628a0SDimitry Andric SelectionDAGBuilder &Builder) { 7439d628a0SDimitry Andric 7539d628a0SDimitry Andric NumSlotsAllocatedForStatepoints++; 7639d628a0SDimitry Andric 7739d628a0SDimitry Andric // The basic scheme here is to first look for a previously created stack slot 7839d628a0SDimitry Andric // which is not in use (accounting for the fact arbitrary slots may already 7939d628a0SDimitry Andric // be reserved), or to create a new stack slot and use it. 8039d628a0SDimitry Andric 8139d628a0SDimitry Andric // If this doesn't succeed in 40000 iterations, something is seriously wrong 8239d628a0SDimitry Andric for (int i = 0; i < 40000; i++) { 8339d628a0SDimitry Andric assert(Builder.FuncInfo.StatepointStackSlots.size() == 8439d628a0SDimitry Andric AllocatedStackSlots.size() && 8539d628a0SDimitry Andric "broken invariant"); 8639d628a0SDimitry Andric const size_t NumSlots = AllocatedStackSlots.size(); 8739d628a0SDimitry Andric assert(NextSlotToAllocate <= NumSlots && "broken invariant"); 8839d628a0SDimitry Andric 8939d628a0SDimitry Andric if (NextSlotToAllocate >= NumSlots) { 9039d628a0SDimitry Andric assert(NextSlotToAllocate == NumSlots); 9139d628a0SDimitry Andric // record stats 9239d628a0SDimitry Andric if (NumSlots + 1 > StatepointMaxSlotsRequired) { 9339d628a0SDimitry Andric StatepointMaxSlotsRequired = NumSlots + 1; 9439d628a0SDimitry Andric } 9539d628a0SDimitry Andric 9639d628a0SDimitry Andric SDValue SpillSlot = Builder.DAG.CreateStackTemporary(ValueType); 9739d628a0SDimitry Andric const unsigned FI = cast<FrameIndexSDNode>(SpillSlot)->getIndex(); 9839d628a0SDimitry Andric Builder.FuncInfo.StatepointStackSlots.push_back(FI); 9939d628a0SDimitry Andric AllocatedStackSlots.push_back(true); 10039d628a0SDimitry Andric return SpillSlot; 10139d628a0SDimitry Andric } 10239d628a0SDimitry Andric if (!AllocatedStackSlots[NextSlotToAllocate]) { 10339d628a0SDimitry Andric const int FI = Builder.FuncInfo.StatepointStackSlots[NextSlotToAllocate]; 10439d628a0SDimitry Andric AllocatedStackSlots[NextSlotToAllocate] = true; 10539d628a0SDimitry Andric return Builder.DAG.getFrameIndex(FI, ValueType); 10639d628a0SDimitry Andric } 10739d628a0SDimitry Andric // Note: We deliberately choose to advance this only on the failing path. 10839d628a0SDimitry Andric // Doing so on the suceeding path involes a bit of complexity that caused a 10939d628a0SDimitry Andric // minor bug previously. Unless performance shows this matters, please 11039d628a0SDimitry Andric // keep this code as simple as possible. 11139d628a0SDimitry Andric NextSlotToAllocate++; 11239d628a0SDimitry Andric } 11339d628a0SDimitry Andric llvm_unreachable("infinite loop?"); 11439d628a0SDimitry Andric } 11539d628a0SDimitry Andric 1168f0fd8f6SDimitry Andric /// Utility function for reservePreviousStackSlotForValue. Tries to find 1178f0fd8f6SDimitry Andric /// stack slot index to which we have spilled value for previous statepoints. 1188f0fd8f6SDimitry Andric /// LookUpDepth specifies maximum DFS depth this function is allowed to look. 1198f0fd8f6SDimitry Andric static Optional<int> findPreviousSpillSlot(const Value *Val, 1208f0fd8f6SDimitry Andric SelectionDAGBuilder &Builder, 1218f0fd8f6SDimitry Andric int LookUpDepth) { 1228f0fd8f6SDimitry Andric // Can not look any futher - give up now 1238f0fd8f6SDimitry Andric if (LookUpDepth <= 0) 1248f0fd8f6SDimitry Andric return Optional<int>(); 1258f0fd8f6SDimitry Andric 1268f0fd8f6SDimitry Andric // Spill location is known for gc relocates 1278f0fd8f6SDimitry Andric if (isGCRelocate(Val)) { 1288f0fd8f6SDimitry Andric GCRelocateOperands RelocOps(cast<Instruction>(Val)); 1298f0fd8f6SDimitry Andric 1308f0fd8f6SDimitry Andric FunctionLoweringInfo::StatepointSpilledValueMapTy &SpillMap = 1318f0fd8f6SDimitry Andric Builder.FuncInfo.StatepointRelocatedValues[RelocOps.getStatepoint()]; 1328f0fd8f6SDimitry Andric 1338f0fd8f6SDimitry Andric auto It = SpillMap.find(RelocOps.getDerivedPtr()); 1348f0fd8f6SDimitry Andric if (It == SpillMap.end()) 1358f0fd8f6SDimitry Andric return Optional<int>(); 1368f0fd8f6SDimitry Andric 1378f0fd8f6SDimitry Andric return It->second; 1388f0fd8f6SDimitry Andric } 1398f0fd8f6SDimitry Andric 1408f0fd8f6SDimitry Andric // Look through bitcast instructions. 1418f0fd8f6SDimitry Andric if (const BitCastInst *Cast = dyn_cast<BitCastInst>(Val)) { 1428f0fd8f6SDimitry Andric return findPreviousSpillSlot(Cast->getOperand(0), Builder, LookUpDepth - 1); 1438f0fd8f6SDimitry Andric } 1448f0fd8f6SDimitry Andric 1458f0fd8f6SDimitry Andric // Look through phi nodes 1468f0fd8f6SDimitry Andric // All incoming values should have same known stack slot, otherwise result 1478f0fd8f6SDimitry Andric // is unknown. 1488f0fd8f6SDimitry Andric if (const PHINode *Phi = dyn_cast<PHINode>(Val)) { 1498f0fd8f6SDimitry Andric Optional<int> MergedResult = None; 1508f0fd8f6SDimitry Andric 1518f0fd8f6SDimitry Andric for (auto &IncomingValue : Phi->incoming_values()) { 1528f0fd8f6SDimitry Andric Optional<int> SpillSlot = 1538f0fd8f6SDimitry Andric findPreviousSpillSlot(IncomingValue, Builder, LookUpDepth - 1); 1548f0fd8f6SDimitry Andric if (!SpillSlot.hasValue()) 1558f0fd8f6SDimitry Andric return Optional<int>(); 1568f0fd8f6SDimitry Andric 1578f0fd8f6SDimitry Andric if (MergedResult.hasValue() && *MergedResult != *SpillSlot) 1588f0fd8f6SDimitry Andric return Optional<int>(); 1598f0fd8f6SDimitry Andric 1608f0fd8f6SDimitry Andric MergedResult = SpillSlot; 1618f0fd8f6SDimitry Andric } 1628f0fd8f6SDimitry Andric return MergedResult; 1638f0fd8f6SDimitry Andric } 1648f0fd8f6SDimitry Andric 1658f0fd8f6SDimitry Andric // TODO: We can do better for PHI nodes. In cases like this: 1668f0fd8f6SDimitry Andric // ptr = phi(relocated_pointer, not_relocated_pointer) 1678f0fd8f6SDimitry Andric // statepoint(ptr) 1688f0fd8f6SDimitry Andric // We will return that stack slot for ptr is unknown. And later we might 1698f0fd8f6SDimitry Andric // assign different stack slots for ptr and relocated_pointer. This limits 1708f0fd8f6SDimitry Andric // llvm's ability to remove redundant stores. 1718f0fd8f6SDimitry Andric // Unfortunately it's hard to accomplish in current infrastructure. 1728f0fd8f6SDimitry Andric // We use this function to eliminate spill store completely, while 1738f0fd8f6SDimitry Andric // in example we still need to emit store, but instead of any location 1748f0fd8f6SDimitry Andric // we need to use special "preferred" location. 1758f0fd8f6SDimitry Andric 1768f0fd8f6SDimitry Andric // TODO: handle simple updates. If a value is modified and the original 1778f0fd8f6SDimitry Andric // value is no longer live, it would be nice to put the modified value in the 1788f0fd8f6SDimitry Andric // same slot. This allows folding of the memory accesses for some 1798f0fd8f6SDimitry Andric // instructions types (like an increment). 1808f0fd8f6SDimitry Andric // statepoint (i) 1818f0fd8f6SDimitry Andric // i1 = i+1 1828f0fd8f6SDimitry Andric // statepoint (i1) 1838f0fd8f6SDimitry Andric // However we need to be careful for cases like this: 1848f0fd8f6SDimitry Andric // statepoint(i) 1858f0fd8f6SDimitry Andric // i1 = i+1 1868f0fd8f6SDimitry Andric // statepoint(i, i1) 1878f0fd8f6SDimitry Andric // Here we want to reserve spill slot for 'i', but not for 'i+1'. If we just 1888f0fd8f6SDimitry Andric // put handling of simple modifications in this function like it's done 1898f0fd8f6SDimitry Andric // for bitcasts we might end up reserving i's slot for 'i+1' because order in 1908f0fd8f6SDimitry Andric // which we visit values is unspecified. 1918f0fd8f6SDimitry Andric 1928f0fd8f6SDimitry Andric // Don't know any information about this instruction 1938f0fd8f6SDimitry Andric return Optional<int>(); 1948f0fd8f6SDimitry Andric } 1958f0fd8f6SDimitry Andric 19639d628a0SDimitry Andric /// Try to find existing copies of the incoming values in stack slots used for 19739d628a0SDimitry Andric /// statepoint spilling. If we can find a spill slot for the incoming value, 19839d628a0SDimitry Andric /// mark that slot as allocated, and reuse the same slot for this safepoint. 19939d628a0SDimitry Andric /// This helps to avoid series of loads and stores that only serve to resuffle 20039d628a0SDimitry Andric /// values on the stack between calls. 2018f0fd8f6SDimitry Andric static void reservePreviousStackSlotForValue(const Value *IncomingValue, 20239d628a0SDimitry Andric SelectionDAGBuilder &Builder) { 20339d628a0SDimitry Andric 2048f0fd8f6SDimitry Andric SDValue Incoming = Builder.getValue(IncomingValue); 2058f0fd8f6SDimitry Andric 20639d628a0SDimitry Andric if (isa<ConstantSDNode>(Incoming) || isa<FrameIndexSDNode>(Incoming)) { 20739d628a0SDimitry Andric // We won't need to spill this, so no need to check for previously 20839d628a0SDimitry Andric // allocated stack slots 20939d628a0SDimitry Andric return; 21039d628a0SDimitry Andric } 21139d628a0SDimitry Andric 2128f0fd8f6SDimitry Andric SDValue OldLocation = Builder.StatepointLowering.getLocation(Incoming); 2138f0fd8f6SDimitry Andric if (OldLocation.getNode()) 21439d628a0SDimitry Andric // duplicates in input 21539d628a0SDimitry Andric return; 21639d628a0SDimitry Andric 2178f0fd8f6SDimitry Andric const int LookUpDepth = 6; 2188f0fd8f6SDimitry Andric Optional<int> Index = 2198f0fd8f6SDimitry Andric findPreviousSpillSlot(IncomingValue, Builder, LookUpDepth); 2208f0fd8f6SDimitry Andric if (!Index.hasValue()) 22139d628a0SDimitry Andric return; 2228f0fd8f6SDimitry Andric 2238f0fd8f6SDimitry Andric auto Itr = std::find(Builder.FuncInfo.StatepointStackSlots.begin(), 2248f0fd8f6SDimitry Andric Builder.FuncInfo.StatepointStackSlots.end(), *Index); 2258f0fd8f6SDimitry Andric assert(Itr != Builder.FuncInfo.StatepointStackSlots.end() && 2268f0fd8f6SDimitry Andric "value spilled to the unknown stack slot"); 2278f0fd8f6SDimitry Andric 22839d628a0SDimitry Andric // This is one of our dedicated lowering slots 22939d628a0SDimitry Andric const int Offset = 23039d628a0SDimitry Andric std::distance(Builder.FuncInfo.StatepointStackSlots.begin(), Itr); 23139d628a0SDimitry Andric if (Builder.StatepointLowering.isStackSlotAllocated(Offset)) { 23239d628a0SDimitry Andric // stack slot already assigned to someone else, can't use it! 23339d628a0SDimitry Andric // TODO: currently we reserve space for gc arguments after doing 23439d628a0SDimitry Andric // normal allocation for deopt arguments. We should reserve for 23539d628a0SDimitry Andric // _all_ deopt and gc arguments, then start allocating. This 23639d628a0SDimitry Andric // will prevent some moves being inserted when vm state changes, 23739d628a0SDimitry Andric // but gc state doesn't between two calls. 23839d628a0SDimitry Andric return; 23939d628a0SDimitry Andric } 24039d628a0SDimitry Andric // Reserve this stack slot 24139d628a0SDimitry Andric Builder.StatepointLowering.reserveStackSlot(Offset); 24239d628a0SDimitry Andric 24339d628a0SDimitry Andric // Cache this slot so we find it when going through the normal 24439d628a0SDimitry Andric // assignment loop. 2458f0fd8f6SDimitry Andric SDValue Loc = Builder.DAG.getTargetFrameIndex(*Index, Incoming.getValueType()); 24639d628a0SDimitry Andric Builder.StatepointLowering.setLocation(Incoming, Loc); 24739d628a0SDimitry Andric } 24839d628a0SDimitry Andric 24939d628a0SDimitry Andric /// Remove any duplicate (as SDValues) from the derived pointer pairs. This 25039d628a0SDimitry Andric /// is not required for correctness. It's purpose is to reduce the size of 25139d628a0SDimitry Andric /// StackMap section. It has no effect on the number of spill slots required 25239d628a0SDimitry Andric /// or the actual lowering. 25339d628a0SDimitry Andric static void removeDuplicatesGCPtrs(SmallVectorImpl<const Value *> &Bases, 25439d628a0SDimitry Andric SmallVectorImpl<const Value *> &Ptrs, 25539d628a0SDimitry Andric SmallVectorImpl<const Value *> &Relocs, 25639d628a0SDimitry Andric SelectionDAGBuilder &Builder) { 25739d628a0SDimitry Andric 25839d628a0SDimitry Andric // This is horribly ineffecient, but I don't care right now 25939d628a0SDimitry Andric SmallSet<SDValue, 64> Seen; 26039d628a0SDimitry Andric 26139d628a0SDimitry Andric SmallVector<const Value *, 64> NewBases, NewPtrs, NewRelocs; 26239d628a0SDimitry Andric for (size_t i = 0; i < Ptrs.size(); i++) { 26339d628a0SDimitry Andric SDValue SD = Builder.getValue(Ptrs[i]); 26439d628a0SDimitry Andric // Only add non-duplicates 26539d628a0SDimitry Andric if (Seen.count(SD) == 0) { 26639d628a0SDimitry Andric NewBases.push_back(Bases[i]); 26739d628a0SDimitry Andric NewPtrs.push_back(Ptrs[i]); 26839d628a0SDimitry Andric NewRelocs.push_back(Relocs[i]); 26939d628a0SDimitry Andric } 27039d628a0SDimitry Andric Seen.insert(SD); 27139d628a0SDimitry Andric } 27239d628a0SDimitry Andric assert(Bases.size() >= NewBases.size()); 27339d628a0SDimitry Andric assert(Ptrs.size() >= NewPtrs.size()); 27439d628a0SDimitry Andric assert(Relocs.size() >= NewRelocs.size()); 27539d628a0SDimitry Andric Bases = NewBases; 27639d628a0SDimitry Andric Ptrs = NewPtrs; 27739d628a0SDimitry Andric Relocs = NewRelocs; 27839d628a0SDimitry Andric assert(Ptrs.size() == Bases.size()); 27939d628a0SDimitry Andric assert(Ptrs.size() == Relocs.size()); 28039d628a0SDimitry Andric } 28139d628a0SDimitry Andric 28239d628a0SDimitry Andric /// Extract call from statepoint, lower it and return pointer to the 28339d628a0SDimitry Andric /// call node. Also update NodeMap so that getValue(statepoint) will 28439d628a0SDimitry Andric /// reference lowered call result 285ff0cc061SDimitry Andric static SDNode * 286ff0cc061SDimitry Andric lowerCallFromStatepoint(ImmutableStatepoint ISP, MachineBasicBlock *LandingPad, 287ff0cc061SDimitry Andric SelectionDAGBuilder &Builder, 288ff0cc061SDimitry Andric SmallVectorImpl<SDValue> &PendingExports) { 28939d628a0SDimitry Andric 290ff0cc061SDimitry Andric ImmutableCallSite CS(ISP.getCallSite()); 29139d628a0SDimitry Andric 292ff0cc061SDimitry Andric SDValue ActualCallee = Builder.getValue(ISP.getActualCallee()); 29339d628a0SDimitry Andric 294ff0cc061SDimitry Andric assert(CS.getCallingConv() != CallingConv::AnyReg && 295ff0cc061SDimitry Andric "anyregcc is not supported on statepoints!"); 29639d628a0SDimitry Andric 297ff0cc061SDimitry Andric Type *DefTy = ISP.getActualReturnType(); 298ff0cc061SDimitry Andric bool HasDef = !DefTy->isVoidTy(); 299ff0cc061SDimitry Andric 300ff0cc061SDimitry Andric SDValue ReturnValue, CallEndVal; 301ff0cc061SDimitry Andric std::tie(ReturnValue, CallEndVal) = Builder.lowerCallOperands( 302ff0cc061SDimitry Andric ISP.getCallSite(), ImmutableStatepoint::CallArgsBeginPos, 303ff0cc061SDimitry Andric ISP.getNumCallArgs(), ActualCallee, DefTy, LandingPad, 304ff0cc061SDimitry Andric false /* IsPatchPoint */); 305ff0cc061SDimitry Andric 306ff0cc061SDimitry Andric SDNode *CallEnd = CallEndVal.getNode(); 307ff0cc061SDimitry Andric 308ff0cc061SDimitry Andric // Get a call instruction from the call sequence chain. Tail calls are not 309ff0cc061SDimitry Andric // allowed. The following code is essentially reverse engineering X86's 310ff0cc061SDimitry Andric // LowerCallTo. 311ff0cc061SDimitry Andric // 312ff0cc061SDimitry Andric // We are expecting DAG to have the following form: 313ff0cc061SDimitry Andric // 314ff0cc061SDimitry Andric // ch = eh_label (only in case of invoke statepoint) 315ff0cc061SDimitry Andric // ch, glue = callseq_start ch 316ff0cc061SDimitry Andric // ch, glue = X86::Call ch, glue 317ff0cc061SDimitry Andric // ch, glue = callseq_end ch, glue 318ff0cc061SDimitry Andric // get_return_value ch, glue 319ff0cc061SDimitry Andric // 320ff0cc061SDimitry Andric // get_return_value can either be a CopyFromReg to grab the return value from 321ff0cc061SDimitry Andric // %RAX, or it can be a LOAD to load a value returned by reference via a stack 322ff0cc061SDimitry Andric // slot. 323ff0cc061SDimitry Andric 324ff0cc061SDimitry Andric if (HasDef && (CallEnd->getOpcode() == ISD::CopyFromReg || 325ff0cc061SDimitry Andric CallEnd->getOpcode() == ISD::LOAD)) 326ff0cc061SDimitry Andric CallEnd = CallEnd->getOperand(0).getNode(); 327ff0cc061SDimitry Andric 328ff0cc061SDimitry Andric assert(CallEnd->getOpcode() == ISD::CALLSEQ_END && "expected!"); 329ff0cc061SDimitry Andric 33039d628a0SDimitry Andric if (HasDef) { 331ff0cc061SDimitry Andric if (CS.isInvoke()) { 332ff0cc061SDimitry Andric // Result value will be used in different basic block for invokes 333ff0cc061SDimitry Andric // so we need to export it now. But statepoint call has a different type 334ff0cc061SDimitry Andric // than the actuall call. It means that standart exporting mechanism will 335ff0cc061SDimitry Andric // create register of the wrong type. So instead we need to create 336ff0cc061SDimitry Andric // register with correct type and save value into it manually. 337ff0cc061SDimitry Andric // TODO: To eliminate this problem we can remove gc.result intrinsics 338ff0cc061SDimitry Andric // completelly and make statepoint call to return a tuple. 339ff0cc061SDimitry Andric unsigned Reg = Builder.FuncInfo.CreateRegs(ISP.getActualReturnType()); 340ff0cc061SDimitry Andric RegsForValue RFV(*Builder.DAG.getContext(), 341ff0cc061SDimitry Andric Builder.DAG.getTargetLoweringInfo(), Reg, 342ff0cc061SDimitry Andric ISP.getActualReturnType()); 343ff0cc061SDimitry Andric SDValue Chain = Builder.DAG.getEntryNode(); 344ff0cc061SDimitry Andric 345ff0cc061SDimitry Andric RFV.getCopyToRegs(ReturnValue, Builder.DAG, Builder.getCurSDLoc(), Chain, 346ff0cc061SDimitry Andric nullptr); 347ff0cc061SDimitry Andric PendingExports.push_back(Chain); 348ff0cc061SDimitry Andric Builder.FuncInfo.ValueMap[CS.getInstruction()] = Reg; 349ff0cc061SDimitry Andric } else { 35039d628a0SDimitry Andric // The value of the statepoint itself will be the value of call itself. 35139d628a0SDimitry Andric // We'll replace the actually call node shortly. gc_result will grab 35239d628a0SDimitry Andric // this value. 353ff0cc061SDimitry Andric Builder.setValue(CS.getInstruction(), ReturnValue); 354ff0cc061SDimitry Andric } 35539d628a0SDimitry Andric } else { 35639d628a0SDimitry Andric // The token value is never used from here on, just generate a poison value 357ff0cc061SDimitry Andric Builder.setValue(CS.getInstruction(), 358ff0cc061SDimitry Andric Builder.DAG.getIntPtrConstant(-1, Builder.getCurSDLoc())); 35939d628a0SDimitry Andric } 36039d628a0SDimitry Andric 361ff0cc061SDimitry Andric return CallEnd->getOperand(0).getNode(); 36239d628a0SDimitry Andric } 36339d628a0SDimitry Andric 36439d628a0SDimitry Andric /// Callect all gc pointers coming into statepoint intrinsic, clean them up, 36539d628a0SDimitry Andric /// and return two arrays: 36639d628a0SDimitry Andric /// Bases - base pointers incoming to this statepoint 36739d628a0SDimitry Andric /// Ptrs - derived pointers incoming to this statepoint 36839d628a0SDimitry Andric /// Relocs - the gc_relocate corresponding to each base/ptr pair 36939d628a0SDimitry Andric /// Elements of this arrays should be in one-to-one correspondence with each 37039d628a0SDimitry Andric /// other i.e Bases[i], Ptrs[i] are from the same gcrelocate call 371ff0cc061SDimitry Andric static void getIncomingStatepointGCValues( 372ff0cc061SDimitry Andric SmallVectorImpl<const Value *> &Bases, SmallVectorImpl<const Value *> &Ptrs, 373ff0cc061SDimitry Andric SmallVectorImpl<const Value *> &Relocs, ImmutableStatepoint StatepointSite, 37439d628a0SDimitry Andric SelectionDAGBuilder &Builder) { 3758f0fd8f6SDimitry Andric for (GCRelocateOperands relocateOpers : StatepointSite.getRelocates()) { 376ff0cc061SDimitry Andric Relocs.push_back(relocateOpers.getUnderlyingCallSite().getInstruction()); 377ff0cc061SDimitry Andric Bases.push_back(relocateOpers.getBasePtr()); 378ff0cc061SDimitry Andric Ptrs.push_back(relocateOpers.getDerivedPtr()); 37939d628a0SDimitry Andric } 38039d628a0SDimitry Andric 38139d628a0SDimitry Andric // Remove any redundant llvm::Values which map to the same SDValue as another 38239d628a0SDimitry Andric // input. Also has the effect of removing duplicates in the original 38339d628a0SDimitry Andric // llvm::Value input list as well. This is a useful optimization for 38439d628a0SDimitry Andric // reducing the size of the StackMap section. It has no other impact. 38539d628a0SDimitry Andric removeDuplicatesGCPtrs(Bases, Ptrs, Relocs, Builder); 38639d628a0SDimitry Andric 38739d628a0SDimitry Andric assert(Bases.size() == Ptrs.size() && Ptrs.size() == Relocs.size()); 38839d628a0SDimitry Andric } 38939d628a0SDimitry Andric 39039d628a0SDimitry Andric /// Spill a value incoming to the statepoint. It might be either part of 39139d628a0SDimitry Andric /// vmstate 39239d628a0SDimitry Andric /// or gcstate. In both cases unconditionally spill it on the stack unless it 39339d628a0SDimitry Andric /// is a null constant. Return pair with first element being frame index 39439d628a0SDimitry Andric /// containing saved value and second element with outgoing chain from the 39539d628a0SDimitry Andric /// emitted store 39639d628a0SDimitry Andric static std::pair<SDValue, SDValue> 39739d628a0SDimitry Andric spillIncomingStatepointValue(SDValue Incoming, SDValue Chain, 39839d628a0SDimitry Andric SelectionDAGBuilder &Builder) { 39939d628a0SDimitry Andric SDValue Loc = Builder.StatepointLowering.getLocation(Incoming); 40039d628a0SDimitry Andric 40139d628a0SDimitry Andric // Emit new store if we didn't do it for this ptr before 40239d628a0SDimitry Andric if (!Loc.getNode()) { 40339d628a0SDimitry Andric Loc = Builder.StatepointLowering.allocateStackSlot(Incoming.getValueType(), 40439d628a0SDimitry Andric Builder); 40539d628a0SDimitry Andric assert(isa<FrameIndexSDNode>(Loc)); 40639d628a0SDimitry Andric int Index = cast<FrameIndexSDNode>(Loc)->getIndex(); 40739d628a0SDimitry Andric // We use TargetFrameIndex so that isel will not select it into LEA 40839d628a0SDimitry Andric Loc = Builder.DAG.getTargetFrameIndex(Index, Incoming.getValueType()); 40939d628a0SDimitry Andric 41039d628a0SDimitry Andric // TODO: We can create TokenFactor node instead of 41139d628a0SDimitry Andric // chaining stores one after another, this may allow 41239d628a0SDimitry Andric // a bit more optimal scheduling for them 41339d628a0SDimitry Andric Chain = Builder.DAG.getStore(Chain, Builder.getCurSDLoc(), Incoming, Loc, 41439d628a0SDimitry Andric MachinePointerInfo::getFixedStack(Index), 41539d628a0SDimitry Andric false, false, 0); 41639d628a0SDimitry Andric 41739d628a0SDimitry Andric Builder.StatepointLowering.setLocation(Incoming, Loc); 41839d628a0SDimitry Andric } 41939d628a0SDimitry Andric 42039d628a0SDimitry Andric assert(Loc.getNode()); 42139d628a0SDimitry Andric return std::make_pair(Loc, Chain); 42239d628a0SDimitry Andric } 42339d628a0SDimitry Andric 42439d628a0SDimitry Andric /// Lower a single value incoming to a statepoint node. This value can be 42539d628a0SDimitry Andric /// either a deopt value or a gc value, the handling is the same. We special 42639d628a0SDimitry Andric /// case constants and allocas, then fall back to spilling if required. 42739d628a0SDimitry Andric static void lowerIncomingStatepointValue(SDValue Incoming, 42839d628a0SDimitry Andric SmallVectorImpl<SDValue> &Ops, 42939d628a0SDimitry Andric SelectionDAGBuilder &Builder) { 43039d628a0SDimitry Andric SDValue Chain = Builder.getRoot(); 43139d628a0SDimitry Andric 43239d628a0SDimitry Andric if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Incoming)) { 43339d628a0SDimitry Andric // If the original value was a constant, make sure it gets recorded as 43439d628a0SDimitry Andric // such in the stackmap. This is required so that the consumer can 43539d628a0SDimitry Andric // parse any internal format to the deopt state. It also handles null 43639d628a0SDimitry Andric // pointers and other constant pointers in GC states 437ff0cc061SDimitry Andric pushStackMapConstant(Ops, Builder, C->getSExtValue()); 43839d628a0SDimitry Andric } else if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(Incoming)) { 439ff0cc061SDimitry Andric // This handles allocas as arguments to the statepoint (this is only 440ff0cc061SDimitry Andric // really meaningful for a deopt value. For GC, we'd be trying to 441ff0cc061SDimitry Andric // relocate the address of the alloca itself?) 442ff0cc061SDimitry Andric Ops.push_back(Builder.DAG.getTargetFrameIndex(FI->getIndex(), 443ff0cc061SDimitry Andric Incoming.getValueType())); 44439d628a0SDimitry Andric } else { 44539d628a0SDimitry Andric // Otherwise, locate a spill slot and explicitly spill it so it 44639d628a0SDimitry Andric // can be found by the runtime later. We currently do not support 44739d628a0SDimitry Andric // tracking values through callee saved registers to their eventual 44839d628a0SDimitry Andric // spill location. This would be a useful optimization, but would 44939d628a0SDimitry Andric // need to be optional since it requires a lot of complexity on the 45039d628a0SDimitry Andric // runtime side which not all would support. 45139d628a0SDimitry Andric std::pair<SDValue, SDValue> Res = 45239d628a0SDimitry Andric spillIncomingStatepointValue(Incoming, Chain, Builder); 45339d628a0SDimitry Andric Ops.push_back(Res.first); 45439d628a0SDimitry Andric Chain = Res.second; 45539d628a0SDimitry Andric } 45639d628a0SDimitry Andric 45739d628a0SDimitry Andric Builder.DAG.setRoot(Chain); 45839d628a0SDimitry Andric } 45939d628a0SDimitry Andric 46039d628a0SDimitry Andric /// Lower deopt state and gc pointer arguments of the statepoint. The actual 46139d628a0SDimitry Andric /// lowering is described in lowerIncomingStatepointValue. This function is 46239d628a0SDimitry Andric /// responsible for lowering everything in the right position and playing some 46339d628a0SDimitry Andric /// tricks to avoid redundant stack manipulation where possible. On 46439d628a0SDimitry Andric /// completion, 'Ops' will contain ready to use operands for machine code 46539d628a0SDimitry Andric /// statepoint. The chain nodes will have already been created and the DAG root 46639d628a0SDimitry Andric /// will be set to the last value spilled (if any were). 46739d628a0SDimitry Andric static void lowerStatepointMetaArgs(SmallVectorImpl<SDValue> &Ops, 468ff0cc061SDimitry Andric ImmutableStatepoint StatepointSite, 46939d628a0SDimitry Andric SelectionDAGBuilder &Builder) { 47039d628a0SDimitry Andric 47139d628a0SDimitry Andric // Lower the deopt and gc arguments for this statepoint. Layout will 47239d628a0SDimitry Andric // be: deopt argument length, deopt arguments.., gc arguments... 47339d628a0SDimitry Andric 47439d628a0SDimitry Andric SmallVector<const Value *, 64> Bases, Ptrs, Relocations; 475ff0cc061SDimitry Andric getIncomingStatepointGCValues(Bases, Ptrs, Relocations, StatepointSite, 476ff0cc061SDimitry Andric Builder); 47739d628a0SDimitry Andric 47839d628a0SDimitry Andric #ifndef NDEBUG 47939d628a0SDimitry Andric // Check that each of the gc pointer and bases we've gotten out of the 48039d628a0SDimitry Andric // safepoint is something the strategy thinks might be a pointer into the GC 48139d628a0SDimitry Andric // heap. This is basically just here to help catch errors during statepoint 48239d628a0SDimitry Andric // insertion. TODO: This should actually be in the Verifier, but we can't get 48339d628a0SDimitry Andric // to the GCStrategy from there (yet). 48439d628a0SDimitry Andric GCStrategy &S = Builder.GFI->getStrategy(); 48539d628a0SDimitry Andric for (const Value *V : Bases) { 48639d628a0SDimitry Andric auto Opt = S.isGCManagedPointer(V); 48739d628a0SDimitry Andric if (Opt.hasValue()) { 48839d628a0SDimitry Andric assert(Opt.getValue() && 48939d628a0SDimitry Andric "non gc managed base pointer found in statepoint"); 49039d628a0SDimitry Andric } 49139d628a0SDimitry Andric } 49239d628a0SDimitry Andric for (const Value *V : Ptrs) { 49339d628a0SDimitry Andric auto Opt = S.isGCManagedPointer(V); 49439d628a0SDimitry Andric if (Opt.hasValue()) { 49539d628a0SDimitry Andric assert(Opt.getValue() && 49639d628a0SDimitry Andric "non gc managed derived pointer found in statepoint"); 49739d628a0SDimitry Andric } 49839d628a0SDimitry Andric } 49939d628a0SDimitry Andric for (const Value *V : Relocations) { 50039d628a0SDimitry Andric auto Opt = S.isGCManagedPointer(V); 50139d628a0SDimitry Andric if (Opt.hasValue()) { 50239d628a0SDimitry Andric assert(Opt.getValue() && "non gc managed pointer relocated"); 50339d628a0SDimitry Andric } 50439d628a0SDimitry Andric } 50539d628a0SDimitry Andric #endif 50639d628a0SDimitry Andric 50739d628a0SDimitry Andric // Before we actually start lowering (and allocating spill slots for values), 50839d628a0SDimitry Andric // reserve any stack slots which we judge to be profitable to reuse for a 50939d628a0SDimitry Andric // particular value. This is purely an optimization over the code below and 51039d628a0SDimitry Andric // doesn't change semantics at all. It is important for performance that we 51139d628a0SDimitry Andric // reserve slots for both deopt and gc values before lowering either. 512ff0cc061SDimitry Andric for (const Value *V : StatepointSite.vm_state_args()) { 5138f0fd8f6SDimitry Andric reservePreviousStackSlotForValue(V, Builder); 51439d628a0SDimitry Andric } 515ff0cc061SDimitry Andric for (unsigned i = 0; i < Bases.size(); ++i) { 5168f0fd8f6SDimitry Andric reservePreviousStackSlotForValue(Bases[i], Builder); 5178f0fd8f6SDimitry Andric reservePreviousStackSlotForValue(Ptrs[i], Builder); 51839d628a0SDimitry Andric } 51939d628a0SDimitry Andric 52039d628a0SDimitry Andric // First, prefix the list with the number of unique values to be 52139d628a0SDimitry Andric // lowered. Note that this is the number of *Values* not the 52239d628a0SDimitry Andric // number of SDValues required to lower them. 523ff0cc061SDimitry Andric const int NumVMSArgs = StatepointSite.getNumTotalVMSArgs(); 524ff0cc061SDimitry Andric pushStackMapConstant(Ops, Builder, NumVMSArgs); 52539d628a0SDimitry Andric 526ff0cc061SDimitry Andric assert(NumVMSArgs == std::distance(StatepointSite.vm_state_begin(), 527ff0cc061SDimitry Andric StatepointSite.vm_state_end())); 52839d628a0SDimitry Andric 52939d628a0SDimitry Andric // The vm state arguments are lowered in an opaque manner. We do 53039d628a0SDimitry Andric // not know what type of values are contained within. We skip the 53139d628a0SDimitry Andric // first one since that happens to be the total number we lowered 53239d628a0SDimitry Andric // explicitly just above. We could have left it in the loop and 53339d628a0SDimitry Andric // not done it explicitly, but it's far easier to understand this 53439d628a0SDimitry Andric // way. 535ff0cc061SDimitry Andric for (const Value *V : StatepointSite.vm_state_args()) { 53639d628a0SDimitry Andric SDValue Incoming = Builder.getValue(V); 53739d628a0SDimitry Andric lowerIncomingStatepointValue(Incoming, Ops, Builder); 53839d628a0SDimitry Andric } 53939d628a0SDimitry Andric 54039d628a0SDimitry Andric // Finally, go ahead and lower all the gc arguments. There's no prefixed 54139d628a0SDimitry Andric // length for this one. After lowering, we'll have the base and pointer 54239d628a0SDimitry Andric // arrays interwoven with each (lowered) base pointer immediately followed by 54339d628a0SDimitry Andric // it's (lowered) derived pointer. i.e 54439d628a0SDimitry Andric // (base[0], ptr[0], base[1], ptr[1], ...) 545ff0cc061SDimitry Andric for (unsigned i = 0; i < Bases.size(); ++i) { 546ff0cc061SDimitry Andric const Value *Base = Bases[i]; 547ff0cc061SDimitry Andric lowerIncomingStatepointValue(Builder.getValue(Base), Ops, Builder); 548ff0cc061SDimitry Andric 549ff0cc061SDimitry Andric const Value *Ptr = Ptrs[i]; 550ff0cc061SDimitry Andric lowerIncomingStatepointValue(Builder.getValue(Ptr), Ops, Builder); 551ff0cc061SDimitry Andric } 552ff0cc061SDimitry Andric 553ff0cc061SDimitry Andric // If there are any explicit spill slots passed to the statepoint, record 554ff0cc061SDimitry Andric // them, but otherwise do not do anything special. These are user provided 555ff0cc061SDimitry Andric // allocas and give control over placement to the consumer. In this case, 556ff0cc061SDimitry Andric // it is the contents of the slot which may get updated, not the pointer to 557ff0cc061SDimitry Andric // the alloca 558ff0cc061SDimitry Andric for (Value *V : StatepointSite.gc_args()) { 55939d628a0SDimitry Andric SDValue Incoming = Builder.getValue(V); 560ff0cc061SDimitry Andric if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(Incoming)) { 561ff0cc061SDimitry Andric // This handles allocas as arguments to the statepoint 562ff0cc061SDimitry Andric Ops.push_back(Builder.DAG.getTargetFrameIndex(FI->getIndex(), 563ff0cc061SDimitry Andric Incoming.getValueType())); 56439d628a0SDimitry Andric } 56539d628a0SDimitry Andric } 566ff0cc061SDimitry Andric 567ff0cc061SDimitry Andric // Record computed locations for all lowered values. 568ff0cc061SDimitry Andric // This can not be embedded in lowering loops as we need to record *all* 569ff0cc061SDimitry Andric // values, while previous loops account only values with unique SDValues. 570ff0cc061SDimitry Andric const Instruction *StatepointInstr = 571ff0cc061SDimitry Andric StatepointSite.getCallSite().getInstruction(); 572ff0cc061SDimitry Andric FunctionLoweringInfo::StatepointSpilledValueMapTy &SpillMap = 573ff0cc061SDimitry Andric Builder.FuncInfo.StatepointRelocatedValues[StatepointInstr]; 574ff0cc061SDimitry Andric 5758f0fd8f6SDimitry Andric for (GCRelocateOperands RelocateOpers : StatepointSite.getRelocates()) { 576ff0cc061SDimitry Andric const Value *V = RelocateOpers.getDerivedPtr(); 577ff0cc061SDimitry Andric SDValue SDV = Builder.getValue(V); 578ff0cc061SDimitry Andric SDValue Loc = Builder.StatepointLowering.getLocation(SDV); 579ff0cc061SDimitry Andric 580ff0cc061SDimitry Andric if (Loc.getNode()) { 581ff0cc061SDimitry Andric SpillMap[V] = cast<FrameIndexSDNode>(Loc)->getIndex(); 582ff0cc061SDimitry Andric } else { 583ff0cc061SDimitry Andric // Record value as visited, but not spilled. This is case for allocas 584ff0cc061SDimitry Andric // and constants. For this values we can avoid emiting spill load while 585ff0cc061SDimitry Andric // visiting corresponding gc_relocate. 586ff0cc061SDimitry Andric // Actually we do not need to record them in this map at all. 587ff0cc061SDimitry Andric // We do this only to check that we are not relocating any unvisited value. 588ff0cc061SDimitry Andric SpillMap[V] = None; 589ff0cc061SDimitry Andric 590ff0cc061SDimitry Andric // Default llvm mechanisms for exporting values which are used in 591ff0cc061SDimitry Andric // different basic blocks does not work for gc relocates. 592ff0cc061SDimitry Andric // Note that it would be incorrect to teach llvm that all relocates are 593ff0cc061SDimitry Andric // uses of the corresponging values so that it would automatically 594ff0cc061SDimitry Andric // export them. Relocates of the spilled values does not use original 595ff0cc061SDimitry Andric // value. 596ff0cc061SDimitry Andric if (StatepointSite.getCallSite().isInvoke()) 597ff0cc061SDimitry Andric Builder.ExportFromCurrentBlock(V); 598ff0cc061SDimitry Andric } 599ff0cc061SDimitry Andric } 600ff0cc061SDimitry Andric } 601ff0cc061SDimitry Andric 60239d628a0SDimitry Andric void SelectionDAGBuilder::visitStatepoint(const CallInst &CI) { 603ff0cc061SDimitry Andric // Check some preconditions for sanity 604ff0cc061SDimitry Andric assert(isStatepoint(&CI) && 605ff0cc061SDimitry Andric "function called must be the statepoint function"); 606ff0cc061SDimitry Andric 607ff0cc061SDimitry Andric LowerStatepoint(ImmutableStatepoint(&CI)); 608ff0cc061SDimitry Andric } 609ff0cc061SDimitry Andric 610ff0cc061SDimitry Andric void SelectionDAGBuilder::LowerStatepoint( 611ff0cc061SDimitry Andric ImmutableStatepoint ISP, MachineBasicBlock *LandingPad /*=nullptr*/) { 61239d628a0SDimitry Andric // The basic scheme here is that information about both the original call and 61339d628a0SDimitry Andric // the safepoint is encoded in the CallInst. We create a temporary call and 61439d628a0SDimitry Andric // lower it, then reverse engineer the calling sequence. 61539d628a0SDimitry Andric 61639d628a0SDimitry Andric NumOfStatepoints++; 61739d628a0SDimitry Andric // Clear state 61839d628a0SDimitry Andric StatepointLowering.startNewStatepoint(*this); 61939d628a0SDimitry Andric 620ff0cc061SDimitry Andric ImmutableCallSite CS(ISP.getCallSite()); 621ff0cc061SDimitry Andric 62239d628a0SDimitry Andric #ifndef NDEBUG 623ff0cc061SDimitry Andric // Consistency check. Don't do this for invokes. It would be too 624ff0cc061SDimitry Andric // expensive to preserve this information across different basic blocks 625ff0cc061SDimitry Andric if (!CS.isInvoke()) { 626ff0cc061SDimitry Andric for (const User *U : CS->users()) { 62739d628a0SDimitry Andric const CallInst *Call = cast<CallInst>(U); 62839d628a0SDimitry Andric if (isGCRelocate(Call)) 62939d628a0SDimitry Andric StatepointLowering.scheduleRelocCall(*Call); 63039d628a0SDimitry Andric } 631ff0cc061SDimitry Andric } 63239d628a0SDimitry Andric #endif 63339d628a0SDimitry Andric 63439d628a0SDimitry Andric #ifndef NDEBUG 63539d628a0SDimitry Andric // If this is a malformed statepoint, report it early to simplify debugging. 63639d628a0SDimitry Andric // This should catch any IR level mistake that's made when constructing or 63739d628a0SDimitry Andric // transforming statepoints. 63839d628a0SDimitry Andric ISP.verify(); 63939d628a0SDimitry Andric 64039d628a0SDimitry Andric // Check that the associated GCStrategy expects to encounter statepoints. 64139d628a0SDimitry Andric assert(GFI->getStrategy().useStatepoints() && 64239d628a0SDimitry Andric "GCStrategy does not expect to encounter statepoints"); 64339d628a0SDimitry Andric #endif 64439d628a0SDimitry Andric 64539d628a0SDimitry Andric // Lower statepoint vmstate and gcstate arguments 646ff0cc061SDimitry Andric SmallVector<SDValue, 10> LoweredMetaArgs; 647ff0cc061SDimitry Andric lowerStatepointMetaArgs(LoweredMetaArgs, ISP, *this); 64839d628a0SDimitry Andric 64939d628a0SDimitry Andric // Get call node, we will replace it later with statepoint 650ff0cc061SDimitry Andric SDNode *CallNode = 651ff0cc061SDimitry Andric lowerCallFromStatepoint(ISP, LandingPad, *this, PendingExports); 65239d628a0SDimitry Andric 653ff0cc061SDimitry Andric // Construct the actual GC_TRANSITION_START, STATEPOINT, and GC_TRANSITION_END 654ff0cc061SDimitry Andric // nodes with all the appropriate arguments and return values. 655ff0cc061SDimitry Andric 656ff0cc061SDimitry Andric // Call Node: Chain, Target, {Args}, RegMask, [Glue] 657ff0cc061SDimitry Andric SDValue Chain = CallNode->getOperand(0); 658ff0cc061SDimitry Andric 659ff0cc061SDimitry Andric SDValue Glue; 660ff0cc061SDimitry Andric bool CallHasIncomingGlue = CallNode->getGluedNode(); 661ff0cc061SDimitry Andric if (CallHasIncomingGlue) { 662ff0cc061SDimitry Andric // Glue is always last operand 663ff0cc061SDimitry Andric Glue = CallNode->getOperand(CallNode->getNumOperands() - 1); 664ff0cc061SDimitry Andric } 665ff0cc061SDimitry Andric 666ff0cc061SDimitry Andric // Build the GC_TRANSITION_START node if necessary. 667ff0cc061SDimitry Andric // 668ff0cc061SDimitry Andric // The operands to the GC_TRANSITION_{START,END} nodes are laid out in the 669ff0cc061SDimitry Andric // order in which they appear in the call to the statepoint intrinsic. If 670ff0cc061SDimitry Andric // any of the operands is a pointer-typed, that operand is immediately 671ff0cc061SDimitry Andric // followed by a SRCVALUE for the pointer that may be used during lowering 672ff0cc061SDimitry Andric // (e.g. to form MachinePointerInfo values for loads/stores). 673ff0cc061SDimitry Andric const bool IsGCTransition = 674ff0cc061SDimitry Andric (ISP.getFlags() & (uint64_t)StatepointFlags::GCTransition) == 675ff0cc061SDimitry Andric (uint64_t)StatepointFlags::GCTransition; 676ff0cc061SDimitry Andric if (IsGCTransition) { 677ff0cc061SDimitry Andric SmallVector<SDValue, 8> TSOps; 678ff0cc061SDimitry Andric 679ff0cc061SDimitry Andric // Add chain 680ff0cc061SDimitry Andric TSOps.push_back(Chain); 681ff0cc061SDimitry Andric 682ff0cc061SDimitry Andric // Add GC transition arguments 683ff0cc061SDimitry Andric for (const Value *V : ISP.gc_transition_args()) { 684ff0cc061SDimitry Andric TSOps.push_back(getValue(V)); 685ff0cc061SDimitry Andric if (V->getType()->isPointerTy()) 686ff0cc061SDimitry Andric TSOps.push_back(DAG.getSrcValue(V)); 687ff0cc061SDimitry Andric } 688ff0cc061SDimitry Andric 689ff0cc061SDimitry Andric // Add glue if necessary 690ff0cc061SDimitry Andric if (CallHasIncomingGlue) 691ff0cc061SDimitry Andric TSOps.push_back(Glue); 692ff0cc061SDimitry Andric 693ff0cc061SDimitry Andric SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); 694ff0cc061SDimitry Andric 695ff0cc061SDimitry Andric SDValue GCTransitionStart = 696ff0cc061SDimitry Andric DAG.getNode(ISD::GC_TRANSITION_START, getCurSDLoc(), NodeTys, TSOps); 697ff0cc061SDimitry Andric 698ff0cc061SDimitry Andric Chain = GCTransitionStart.getValue(0); 699ff0cc061SDimitry Andric Glue = GCTransitionStart.getValue(1); 700ff0cc061SDimitry Andric } 70139d628a0SDimitry Andric 70239d628a0SDimitry Andric // TODO: Currently, all of these operands are being marked as read/write in 70339d628a0SDimitry Andric // PrologEpilougeInserter.cpp, we should special case the VMState arguments 70439d628a0SDimitry Andric // and flags to be read-only. 70539d628a0SDimitry Andric SmallVector<SDValue, 40> Ops; 70639d628a0SDimitry Andric 707ff0cc061SDimitry Andric // Add the <id> and <numBytes> constants. 708ff0cc061SDimitry Andric Ops.push_back(DAG.getTargetConstant(ISP.getID(), getCurSDLoc(), MVT::i64)); 709ff0cc061SDimitry Andric Ops.push_back( 710ff0cc061SDimitry Andric DAG.getTargetConstant(ISP.getNumPatchBytes(), getCurSDLoc(), MVT::i32)); 711ff0cc061SDimitry Andric 71239d628a0SDimitry Andric // Calculate and push starting position of vmstate arguments 71339d628a0SDimitry Andric // Get number of arguments incoming directly into call node 71439d628a0SDimitry Andric unsigned NumCallRegArgs = 715ff0cc061SDimitry Andric CallNode->getNumOperands() - (CallHasIncomingGlue ? 4 : 3); 716ff0cc061SDimitry Andric Ops.push_back(DAG.getTargetConstant(NumCallRegArgs, getCurSDLoc(), MVT::i32)); 71739d628a0SDimitry Andric 71839d628a0SDimitry Andric // Add call target 71939d628a0SDimitry Andric SDValue CallTarget = SDValue(CallNode->getOperand(1).getNode(), 0); 72039d628a0SDimitry Andric Ops.push_back(CallTarget); 72139d628a0SDimitry Andric 72239d628a0SDimitry Andric // Add call arguments 72339d628a0SDimitry Andric // Get position of register mask in the call 72439d628a0SDimitry Andric SDNode::op_iterator RegMaskIt; 725ff0cc061SDimitry Andric if (CallHasIncomingGlue) 72639d628a0SDimitry Andric RegMaskIt = CallNode->op_end() - 2; 72739d628a0SDimitry Andric else 72839d628a0SDimitry Andric RegMaskIt = CallNode->op_end() - 1; 72939d628a0SDimitry Andric Ops.insert(Ops.end(), CallNode->op_begin() + 2, RegMaskIt); 73039d628a0SDimitry Andric 731ff0cc061SDimitry Andric // Add a constant argument for the calling convention 732ff0cc061SDimitry Andric pushStackMapConstant(Ops, *this, CS.getCallingConv()); 733ff0cc061SDimitry Andric 734ff0cc061SDimitry Andric // Add a constant argument for the flags 735ff0cc061SDimitry Andric uint64_t Flags = ISP.getFlags(); 736ff0cc061SDimitry Andric assert( 737ff0cc061SDimitry Andric ((Flags & ~(uint64_t)StatepointFlags::MaskAll) == 0) 738ff0cc061SDimitry Andric && "unknown flag used"); 739ff0cc061SDimitry Andric pushStackMapConstant(Ops, *this, Flags); 74039d628a0SDimitry Andric 74139d628a0SDimitry Andric // Insert all vmstate and gcstate arguments 742ff0cc061SDimitry Andric Ops.insert(Ops.end(), LoweredMetaArgs.begin(), LoweredMetaArgs.end()); 74339d628a0SDimitry Andric 74439d628a0SDimitry Andric // Add register mask from call node 74539d628a0SDimitry Andric Ops.push_back(*RegMaskIt); 74639d628a0SDimitry Andric 74739d628a0SDimitry Andric // Add chain 748ff0cc061SDimitry Andric Ops.push_back(Chain); 74939d628a0SDimitry Andric 75039d628a0SDimitry Andric // Same for the glue, but we add it only if original call had it 75139d628a0SDimitry Andric if (Glue.getNode()) 75239d628a0SDimitry Andric Ops.push_back(Glue); 75339d628a0SDimitry Andric 754ff0cc061SDimitry Andric // Compute return values. Provide a glue output since we consume one as 755ff0cc061SDimitry Andric // input. This allows someone else to chain off us as needed. 756ff0cc061SDimitry Andric SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); 75739d628a0SDimitry Andric 758ff0cc061SDimitry Andric SDNode *StatepointMCNode = 759ff0cc061SDimitry Andric DAG.getMachineNode(TargetOpcode::STATEPOINT, getCurSDLoc(), NodeTys, Ops); 760ff0cc061SDimitry Andric 761ff0cc061SDimitry Andric SDNode *SinkNode = StatepointMCNode; 762ff0cc061SDimitry Andric 763ff0cc061SDimitry Andric // Build the GC_TRANSITION_END node if necessary. 764ff0cc061SDimitry Andric // 765ff0cc061SDimitry Andric // See the comment above regarding GC_TRANSITION_START for the layout of 766ff0cc061SDimitry Andric // the operands to the GC_TRANSITION_END node. 767ff0cc061SDimitry Andric if (IsGCTransition) { 768ff0cc061SDimitry Andric SmallVector<SDValue, 8> TEOps; 769ff0cc061SDimitry Andric 770ff0cc061SDimitry Andric // Add chain 771ff0cc061SDimitry Andric TEOps.push_back(SDValue(StatepointMCNode, 0)); 772ff0cc061SDimitry Andric 773ff0cc061SDimitry Andric // Add GC transition arguments 774ff0cc061SDimitry Andric for (const Value *V : ISP.gc_transition_args()) { 775ff0cc061SDimitry Andric TEOps.push_back(getValue(V)); 776ff0cc061SDimitry Andric if (V->getType()->isPointerTy()) 777ff0cc061SDimitry Andric TEOps.push_back(DAG.getSrcValue(V)); 778ff0cc061SDimitry Andric } 779ff0cc061SDimitry Andric 780ff0cc061SDimitry Andric // Add glue 781ff0cc061SDimitry Andric TEOps.push_back(SDValue(StatepointMCNode, 1)); 782ff0cc061SDimitry Andric 783ff0cc061SDimitry Andric SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); 784ff0cc061SDimitry Andric 785ff0cc061SDimitry Andric SDValue GCTransitionStart = 786ff0cc061SDimitry Andric DAG.getNode(ISD::GC_TRANSITION_END, getCurSDLoc(), NodeTys, TEOps); 787ff0cc061SDimitry Andric 788ff0cc061SDimitry Andric SinkNode = GCTransitionStart.getNode(); 789ff0cc061SDimitry Andric } 79039d628a0SDimitry Andric 79139d628a0SDimitry Andric // Replace original call 792ff0cc061SDimitry Andric DAG.ReplaceAllUsesWith(CallNode, SinkNode); // This may update Root 79339d628a0SDimitry Andric // Remove originall call node 79439d628a0SDimitry Andric DAG.DeleteNode(CallNode); 79539d628a0SDimitry Andric 79639d628a0SDimitry Andric // DON'T set the root - under the assumption that it's already set past the 79739d628a0SDimitry Andric // inserted node we created. 79839d628a0SDimitry Andric 79939d628a0SDimitry Andric // TODO: A better future implementation would be to emit a single variable 80039d628a0SDimitry Andric // argument, variable return value STATEPOINT node here and then hookup the 80139d628a0SDimitry Andric // return value of each gc.relocate to the respective output of the 80239d628a0SDimitry Andric // previously emitted STATEPOINT value. Unfortunately, this doesn't appear 80339d628a0SDimitry Andric // to actually be possible today. 80439d628a0SDimitry Andric } 80539d628a0SDimitry Andric 80639d628a0SDimitry Andric void SelectionDAGBuilder::visitGCResult(const CallInst &CI) { 80739d628a0SDimitry Andric // The result value of the gc_result is simply the result of the actual 80839d628a0SDimitry Andric // call. We've already emitted this, so just grab the value. 80939d628a0SDimitry Andric Instruction *I = cast<Instruction>(CI.getArgOperand(0)); 810ff0cc061SDimitry Andric assert(isStatepoint(I) && "first argument must be a statepoint token"); 81139d628a0SDimitry Andric 812ff0cc061SDimitry Andric if (isa<InvokeInst>(I)) { 813ff0cc061SDimitry Andric // For invokes we should have stored call result in a virtual register. 814ff0cc061SDimitry Andric // We can not use default getValue() functionality to copy value from this 815ff0cc061SDimitry Andric // register because statepoint and actuall call return types can be 816ff0cc061SDimitry Andric // different, and getValue() will use CopyFromReg of the wrong type, 817ff0cc061SDimitry Andric // which is always i32 in our case. 818ff0cc061SDimitry Andric PointerType *CalleeType = 819ff0cc061SDimitry Andric cast<PointerType>(ImmutableStatepoint(I).getActualCallee()->getType()); 820ff0cc061SDimitry Andric Type *RetTy = 821ff0cc061SDimitry Andric cast<FunctionType>(CalleeType->getElementType())->getReturnType(); 822ff0cc061SDimitry Andric SDValue CopyFromReg = getCopyFromRegs(I, RetTy); 823ff0cc061SDimitry Andric 824ff0cc061SDimitry Andric assert(CopyFromReg.getNode()); 825ff0cc061SDimitry Andric setValue(&CI, CopyFromReg); 826ff0cc061SDimitry Andric } else { 82739d628a0SDimitry Andric setValue(&CI, getValue(I)); 82839d628a0SDimitry Andric } 829ff0cc061SDimitry Andric } 83039d628a0SDimitry Andric 83139d628a0SDimitry Andric void SelectionDAGBuilder::visitGCRelocate(const CallInst &CI) { 832ff0cc061SDimitry Andric GCRelocateOperands RelocateOpers(&CI); 833ff0cc061SDimitry Andric 83439d628a0SDimitry Andric #ifndef NDEBUG 83539d628a0SDimitry Andric // Consistency check 836ff0cc061SDimitry Andric // We skip this check for invoke statepoints. It would be too expensive to 837ff0cc061SDimitry Andric // preserve validation info through different basic blocks. 838ff0cc061SDimitry Andric if (!RelocateOpers.isTiedToInvoke()) { 83939d628a0SDimitry Andric StatepointLowering.relocCallVisited(CI); 840ff0cc061SDimitry Andric } 84139d628a0SDimitry Andric #endif 84239d628a0SDimitry Andric 843ff0cc061SDimitry Andric const Value *DerivedPtr = RelocateOpers.getDerivedPtr(); 844ff0cc061SDimitry Andric SDValue SD = getValue(DerivedPtr); 84539d628a0SDimitry Andric 846ff0cc061SDimitry Andric FunctionLoweringInfo::StatepointSpilledValueMapTy &SpillMap = 847ff0cc061SDimitry Andric FuncInfo.StatepointRelocatedValues[RelocateOpers.getStatepoint()]; 848ff0cc061SDimitry Andric 849ff0cc061SDimitry Andric // We should have recorded location for this pointer 850ff0cc061SDimitry Andric assert(SpillMap.count(DerivedPtr) && "Relocating not lowered gc value"); 851ff0cc061SDimitry Andric Optional<int> DerivedPtrLocation = SpillMap[DerivedPtr]; 852ff0cc061SDimitry Andric 85339d628a0SDimitry Andric // We didn't need to spill these special cases (constants and allocas). 85439d628a0SDimitry Andric // See the handling in spillIncomingValueForStatepoint for detail. 855ff0cc061SDimitry Andric if (!DerivedPtrLocation) { 85639d628a0SDimitry Andric setValue(&CI, SD); 85739d628a0SDimitry Andric return; 85839d628a0SDimitry Andric } 85939d628a0SDimitry Andric 860ff0cc061SDimitry Andric SDValue SpillSlot = DAG.getTargetFrameIndex(*DerivedPtrLocation, 861ff0cc061SDimitry Andric SD.getValueType()); 86239d628a0SDimitry Andric 86339d628a0SDimitry Andric // Be conservative: flush all pending loads 86439d628a0SDimitry Andric // TODO: Probably we can be less restrictive on this, 86539d628a0SDimitry Andric // it may allow more scheduling opprtunities 86639d628a0SDimitry Andric SDValue Chain = getRoot(); 86739d628a0SDimitry Andric 868ff0cc061SDimitry Andric SDValue SpillLoad = 869ff0cc061SDimitry Andric DAG.getLoad(SpillSlot.getValueType(), getCurSDLoc(), Chain, SpillSlot, 870ff0cc061SDimitry Andric MachinePointerInfo::getFixedStack(*DerivedPtrLocation), 871ff0cc061SDimitry Andric false, false, false, 0); 87239d628a0SDimitry Andric 87339d628a0SDimitry Andric // Again, be conservative, don't emit pending loads 874ff0cc061SDimitry Andric DAG.setRoot(SpillLoad.getValue(1)); 87539d628a0SDimitry Andric 876ff0cc061SDimitry Andric assert(SpillLoad.getNode()); 877ff0cc061SDimitry Andric setValue(&CI, SpillLoad); 87839d628a0SDimitry Andric } 879