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 11639d628a0SDimitry Andric /// Try to find existing copies of the incoming values in stack slots used for 11739d628a0SDimitry Andric /// statepoint spilling. If we can find a spill slot for the incoming value, 11839d628a0SDimitry Andric /// mark that slot as allocated, and reuse the same slot for this safepoint. 11939d628a0SDimitry Andric /// This helps to avoid series of loads and stores that only serve to resuffle 12039d628a0SDimitry Andric /// values on the stack between calls. 12139d628a0SDimitry Andric static void reservePreviousStackSlotForValue(SDValue Incoming, 12239d628a0SDimitry Andric SelectionDAGBuilder &Builder) { 12339d628a0SDimitry Andric 12439d628a0SDimitry Andric if (isa<ConstantSDNode>(Incoming) || isa<FrameIndexSDNode>(Incoming)) { 12539d628a0SDimitry Andric // We won't need to spill this, so no need to check for previously 12639d628a0SDimitry Andric // allocated stack slots 12739d628a0SDimitry Andric return; 12839d628a0SDimitry Andric } 12939d628a0SDimitry Andric 13039d628a0SDimitry Andric SDValue Loc = Builder.StatepointLowering.getLocation(Incoming); 13139d628a0SDimitry Andric if (Loc.getNode()) { 13239d628a0SDimitry Andric // duplicates in input 13339d628a0SDimitry Andric return; 13439d628a0SDimitry Andric } 13539d628a0SDimitry Andric 13639d628a0SDimitry Andric // Search back for the load from a stack slot pattern to find the original 13739d628a0SDimitry Andric // slot we allocated for this value. We could extend this to deal with 13839d628a0SDimitry Andric // simple modification patterns, but simple dealing with trivial load/store 13939d628a0SDimitry Andric // sequences helps a lot already. 14039d628a0SDimitry Andric if (LoadSDNode *Load = dyn_cast<LoadSDNode>(Incoming)) { 14139d628a0SDimitry Andric if (auto *FI = dyn_cast<FrameIndexSDNode>(Load->getBasePtr())) { 14239d628a0SDimitry Andric const int Index = FI->getIndex(); 14339d628a0SDimitry Andric auto Itr = std::find(Builder.FuncInfo.StatepointStackSlots.begin(), 14439d628a0SDimitry Andric Builder.FuncInfo.StatepointStackSlots.end(), Index); 14539d628a0SDimitry Andric if (Itr == Builder.FuncInfo.StatepointStackSlots.end()) { 14639d628a0SDimitry Andric // not one of the lowering stack slots, can't reuse! 14739d628a0SDimitry Andric // TODO: Actually, we probably could reuse the stack slot if the value 14839d628a0SDimitry Andric // hasn't changed at all, but we'd need to look for intervening writes 14939d628a0SDimitry Andric return; 15039d628a0SDimitry Andric } else { 15139d628a0SDimitry Andric // This is one of our dedicated lowering slots 15239d628a0SDimitry Andric const int Offset = 15339d628a0SDimitry Andric std::distance(Builder.FuncInfo.StatepointStackSlots.begin(), Itr); 15439d628a0SDimitry Andric if (Builder.StatepointLowering.isStackSlotAllocated(Offset)) { 15539d628a0SDimitry Andric // stack slot already assigned to someone else, can't use it! 15639d628a0SDimitry Andric // TODO: currently we reserve space for gc arguments after doing 15739d628a0SDimitry Andric // normal allocation for deopt arguments. We should reserve for 15839d628a0SDimitry Andric // _all_ deopt and gc arguments, then start allocating. This 15939d628a0SDimitry Andric // will prevent some moves being inserted when vm state changes, 16039d628a0SDimitry Andric // but gc state doesn't between two calls. 16139d628a0SDimitry Andric return; 16239d628a0SDimitry Andric } 16339d628a0SDimitry Andric // Reserve this stack slot 16439d628a0SDimitry Andric Builder.StatepointLowering.reserveStackSlot(Offset); 16539d628a0SDimitry Andric } 16639d628a0SDimitry Andric 16739d628a0SDimitry Andric // Cache this slot so we find it when going through the normal 16839d628a0SDimitry Andric // assignment loop. 16939d628a0SDimitry Andric SDValue Loc = 17039d628a0SDimitry Andric Builder.DAG.getTargetFrameIndex(Index, Incoming.getValueType()); 17139d628a0SDimitry Andric 17239d628a0SDimitry Andric Builder.StatepointLowering.setLocation(Incoming, Loc); 17339d628a0SDimitry Andric } 17439d628a0SDimitry Andric } 17539d628a0SDimitry Andric 17639d628a0SDimitry Andric // TODO: handle case where a reloaded value flows through a phi to 17739d628a0SDimitry Andric // another safepoint. e.g. 17839d628a0SDimitry Andric // bb1: 17939d628a0SDimitry Andric // a' = relocated... 18039d628a0SDimitry Andric // bb2: % pred: bb1, bb3, bb4, etc. 18139d628a0SDimitry Andric // a_phi = phi(a', ...) 18239d628a0SDimitry Andric // statepoint ... a_phi 18339d628a0SDimitry Andric // NOTE: This will require reasoning about cross basic block values. This is 18439d628a0SDimitry Andric // decidedly non trivial and this might not be the right place to do it. We 18539d628a0SDimitry Andric // don't really have the information we need here... 18639d628a0SDimitry Andric 18739d628a0SDimitry Andric // TODO: handle simple updates. If a value is modified and the original 18839d628a0SDimitry Andric // value is no longer live, it would be nice to put the modified value in the 18939d628a0SDimitry Andric // same slot. This allows folding of the memory accesses for some 19039d628a0SDimitry Andric // instructions types (like an increment). 19139d628a0SDimitry Andric // statepoint (i) 19239d628a0SDimitry Andric // i1 = i+1 19339d628a0SDimitry Andric // statepoint (i1) 19439d628a0SDimitry Andric } 19539d628a0SDimitry Andric 19639d628a0SDimitry Andric /// Remove any duplicate (as SDValues) from the derived pointer pairs. This 19739d628a0SDimitry Andric /// is not required for correctness. It's purpose is to reduce the size of 19839d628a0SDimitry Andric /// StackMap section. It has no effect on the number of spill slots required 19939d628a0SDimitry Andric /// or the actual lowering. 20039d628a0SDimitry Andric static void removeDuplicatesGCPtrs(SmallVectorImpl<const Value *> &Bases, 20139d628a0SDimitry Andric SmallVectorImpl<const Value *> &Ptrs, 20239d628a0SDimitry Andric SmallVectorImpl<const Value *> &Relocs, 20339d628a0SDimitry Andric SelectionDAGBuilder &Builder) { 20439d628a0SDimitry Andric 20539d628a0SDimitry Andric // This is horribly ineffecient, but I don't care right now 20639d628a0SDimitry Andric SmallSet<SDValue, 64> Seen; 20739d628a0SDimitry Andric 20839d628a0SDimitry Andric SmallVector<const Value *, 64> NewBases, NewPtrs, NewRelocs; 20939d628a0SDimitry Andric for (size_t i = 0; i < Ptrs.size(); i++) { 21039d628a0SDimitry Andric SDValue SD = Builder.getValue(Ptrs[i]); 21139d628a0SDimitry Andric // Only add non-duplicates 21239d628a0SDimitry Andric if (Seen.count(SD) == 0) { 21339d628a0SDimitry Andric NewBases.push_back(Bases[i]); 21439d628a0SDimitry Andric NewPtrs.push_back(Ptrs[i]); 21539d628a0SDimitry Andric NewRelocs.push_back(Relocs[i]); 21639d628a0SDimitry Andric } 21739d628a0SDimitry Andric Seen.insert(SD); 21839d628a0SDimitry Andric } 21939d628a0SDimitry Andric assert(Bases.size() >= NewBases.size()); 22039d628a0SDimitry Andric assert(Ptrs.size() >= NewPtrs.size()); 22139d628a0SDimitry Andric assert(Relocs.size() >= NewRelocs.size()); 22239d628a0SDimitry Andric Bases = NewBases; 22339d628a0SDimitry Andric Ptrs = NewPtrs; 22439d628a0SDimitry Andric Relocs = NewRelocs; 22539d628a0SDimitry Andric assert(Ptrs.size() == Bases.size()); 22639d628a0SDimitry Andric assert(Ptrs.size() == Relocs.size()); 22739d628a0SDimitry Andric } 22839d628a0SDimitry Andric 22939d628a0SDimitry Andric /// Extract call from statepoint, lower it and return pointer to the 23039d628a0SDimitry Andric /// call node. Also update NodeMap so that getValue(statepoint) will 23139d628a0SDimitry Andric /// reference lowered call result 232ff0cc061SDimitry Andric static SDNode * 233ff0cc061SDimitry Andric lowerCallFromStatepoint(ImmutableStatepoint ISP, MachineBasicBlock *LandingPad, 234ff0cc061SDimitry Andric SelectionDAGBuilder &Builder, 235ff0cc061SDimitry Andric SmallVectorImpl<SDValue> &PendingExports) { 23639d628a0SDimitry Andric 237ff0cc061SDimitry Andric ImmutableCallSite CS(ISP.getCallSite()); 23839d628a0SDimitry Andric 239ff0cc061SDimitry Andric SDValue ActualCallee = Builder.getValue(ISP.getActualCallee()); 24039d628a0SDimitry Andric 241ff0cc061SDimitry Andric // Handle immediate and symbolic callees. 242ff0cc061SDimitry Andric if (auto *ConstCallee = dyn_cast<ConstantSDNode>(ActualCallee.getNode())) 243ff0cc061SDimitry Andric ActualCallee = Builder.DAG.getIntPtrConstant(ConstCallee->getZExtValue(), 244ff0cc061SDimitry Andric Builder.getCurSDLoc(), 245ff0cc061SDimitry Andric /*isTarget=*/true); 246ff0cc061SDimitry Andric else if (auto *SymbolicCallee = 247ff0cc061SDimitry Andric dyn_cast<GlobalAddressSDNode>(ActualCallee.getNode())) 248ff0cc061SDimitry Andric ActualCallee = Builder.DAG.getTargetGlobalAddress( 249ff0cc061SDimitry Andric SymbolicCallee->getGlobal(), SDLoc(SymbolicCallee), 250ff0cc061SDimitry Andric SymbolicCallee->getValueType(0)); 25139d628a0SDimitry Andric 252ff0cc061SDimitry Andric assert(CS.getCallingConv() != CallingConv::AnyReg && 253ff0cc061SDimitry Andric "anyregcc is not supported on statepoints!"); 25439d628a0SDimitry Andric 255ff0cc061SDimitry Andric Type *DefTy = ISP.getActualReturnType(); 256ff0cc061SDimitry Andric bool HasDef = !DefTy->isVoidTy(); 257ff0cc061SDimitry Andric 258ff0cc061SDimitry Andric SDValue ReturnValue, CallEndVal; 259ff0cc061SDimitry Andric std::tie(ReturnValue, CallEndVal) = Builder.lowerCallOperands( 260ff0cc061SDimitry Andric ISP.getCallSite(), ImmutableStatepoint::CallArgsBeginPos, 261ff0cc061SDimitry Andric ISP.getNumCallArgs(), ActualCallee, DefTy, LandingPad, 262ff0cc061SDimitry Andric false /* IsPatchPoint */); 263ff0cc061SDimitry Andric 264ff0cc061SDimitry Andric SDNode *CallEnd = CallEndVal.getNode(); 265ff0cc061SDimitry Andric 266ff0cc061SDimitry Andric // Get a call instruction from the call sequence chain. Tail calls are not 267ff0cc061SDimitry Andric // allowed. The following code is essentially reverse engineering X86's 268ff0cc061SDimitry Andric // LowerCallTo. 269ff0cc061SDimitry Andric // 270ff0cc061SDimitry Andric // We are expecting DAG to have the following form: 271ff0cc061SDimitry Andric // 272ff0cc061SDimitry Andric // ch = eh_label (only in case of invoke statepoint) 273ff0cc061SDimitry Andric // ch, glue = callseq_start ch 274ff0cc061SDimitry Andric // ch, glue = X86::Call ch, glue 275ff0cc061SDimitry Andric // ch, glue = callseq_end ch, glue 276ff0cc061SDimitry Andric // get_return_value ch, glue 277ff0cc061SDimitry Andric // 278ff0cc061SDimitry Andric // get_return_value can either be a CopyFromReg to grab the return value from 279ff0cc061SDimitry Andric // %RAX, or it can be a LOAD to load a value returned by reference via a stack 280ff0cc061SDimitry Andric // slot. 281ff0cc061SDimitry Andric 282ff0cc061SDimitry Andric if (HasDef && (CallEnd->getOpcode() == ISD::CopyFromReg || 283ff0cc061SDimitry Andric CallEnd->getOpcode() == ISD::LOAD)) 284ff0cc061SDimitry Andric CallEnd = CallEnd->getOperand(0).getNode(); 285ff0cc061SDimitry Andric 286ff0cc061SDimitry Andric assert(CallEnd->getOpcode() == ISD::CALLSEQ_END && "expected!"); 287ff0cc061SDimitry Andric 28839d628a0SDimitry Andric if (HasDef) { 289ff0cc061SDimitry Andric if (CS.isInvoke()) { 290ff0cc061SDimitry Andric // Result value will be used in different basic block for invokes 291ff0cc061SDimitry Andric // so we need to export it now. But statepoint call has a different type 292ff0cc061SDimitry Andric // than the actuall call. It means that standart exporting mechanism will 293ff0cc061SDimitry Andric // create register of the wrong type. So instead we need to create 294ff0cc061SDimitry Andric // register with correct type and save value into it manually. 295ff0cc061SDimitry Andric // TODO: To eliminate this problem we can remove gc.result intrinsics 296ff0cc061SDimitry Andric // completelly and make statepoint call to return a tuple. 297ff0cc061SDimitry Andric unsigned Reg = Builder.FuncInfo.CreateRegs(ISP.getActualReturnType()); 298ff0cc061SDimitry Andric RegsForValue RFV(*Builder.DAG.getContext(), 299ff0cc061SDimitry Andric Builder.DAG.getTargetLoweringInfo(), Reg, 300ff0cc061SDimitry Andric ISP.getActualReturnType()); 301ff0cc061SDimitry Andric SDValue Chain = Builder.DAG.getEntryNode(); 302ff0cc061SDimitry Andric 303ff0cc061SDimitry Andric RFV.getCopyToRegs(ReturnValue, Builder.DAG, Builder.getCurSDLoc(), Chain, 304ff0cc061SDimitry Andric nullptr); 305ff0cc061SDimitry Andric PendingExports.push_back(Chain); 306ff0cc061SDimitry Andric Builder.FuncInfo.ValueMap[CS.getInstruction()] = Reg; 307ff0cc061SDimitry Andric } else { 30839d628a0SDimitry Andric // The value of the statepoint itself will be the value of call itself. 30939d628a0SDimitry Andric // We'll replace the actually call node shortly. gc_result will grab 31039d628a0SDimitry Andric // this value. 311ff0cc061SDimitry Andric Builder.setValue(CS.getInstruction(), ReturnValue); 312ff0cc061SDimitry Andric } 31339d628a0SDimitry Andric } else { 31439d628a0SDimitry Andric // The token value is never used from here on, just generate a poison value 315ff0cc061SDimitry Andric Builder.setValue(CS.getInstruction(), 316ff0cc061SDimitry Andric Builder.DAG.getIntPtrConstant(-1, Builder.getCurSDLoc())); 31739d628a0SDimitry Andric } 31839d628a0SDimitry Andric 319ff0cc061SDimitry Andric return CallEnd->getOperand(0).getNode(); 32039d628a0SDimitry Andric } 32139d628a0SDimitry Andric 32239d628a0SDimitry Andric /// Callect all gc pointers coming into statepoint intrinsic, clean them up, 32339d628a0SDimitry Andric /// and return two arrays: 32439d628a0SDimitry Andric /// Bases - base pointers incoming to this statepoint 32539d628a0SDimitry Andric /// Ptrs - derived pointers incoming to this statepoint 32639d628a0SDimitry Andric /// Relocs - the gc_relocate corresponding to each base/ptr pair 32739d628a0SDimitry Andric /// Elements of this arrays should be in one-to-one correspondence with each 32839d628a0SDimitry Andric /// other i.e Bases[i], Ptrs[i] are from the same gcrelocate call 329ff0cc061SDimitry Andric static void getIncomingStatepointGCValues( 330ff0cc061SDimitry Andric SmallVectorImpl<const Value *> &Bases, SmallVectorImpl<const Value *> &Ptrs, 331ff0cc061SDimitry Andric SmallVectorImpl<const Value *> &Relocs, ImmutableStatepoint StatepointSite, 33239d628a0SDimitry Andric SelectionDAGBuilder &Builder) { 333ff0cc061SDimitry Andric for (GCRelocateOperands relocateOpers : 334ff0cc061SDimitry Andric StatepointSite.getRelocates(StatepointSite)) { 335ff0cc061SDimitry Andric Relocs.push_back(relocateOpers.getUnderlyingCallSite().getInstruction()); 336ff0cc061SDimitry Andric Bases.push_back(relocateOpers.getBasePtr()); 337ff0cc061SDimitry Andric Ptrs.push_back(relocateOpers.getDerivedPtr()); 33839d628a0SDimitry Andric } 33939d628a0SDimitry Andric 34039d628a0SDimitry Andric // Remove any redundant llvm::Values which map to the same SDValue as another 34139d628a0SDimitry Andric // input. Also has the effect of removing duplicates in the original 34239d628a0SDimitry Andric // llvm::Value input list as well. This is a useful optimization for 34339d628a0SDimitry Andric // reducing the size of the StackMap section. It has no other impact. 34439d628a0SDimitry Andric removeDuplicatesGCPtrs(Bases, Ptrs, Relocs, Builder); 34539d628a0SDimitry Andric 34639d628a0SDimitry Andric assert(Bases.size() == Ptrs.size() && Ptrs.size() == Relocs.size()); 34739d628a0SDimitry Andric } 34839d628a0SDimitry Andric 34939d628a0SDimitry Andric /// Spill a value incoming to the statepoint. It might be either part of 35039d628a0SDimitry Andric /// vmstate 35139d628a0SDimitry Andric /// or gcstate. In both cases unconditionally spill it on the stack unless it 35239d628a0SDimitry Andric /// is a null constant. Return pair with first element being frame index 35339d628a0SDimitry Andric /// containing saved value and second element with outgoing chain from the 35439d628a0SDimitry Andric /// emitted store 35539d628a0SDimitry Andric static std::pair<SDValue, SDValue> 35639d628a0SDimitry Andric spillIncomingStatepointValue(SDValue Incoming, SDValue Chain, 35739d628a0SDimitry Andric SelectionDAGBuilder &Builder) { 35839d628a0SDimitry Andric SDValue Loc = Builder.StatepointLowering.getLocation(Incoming); 35939d628a0SDimitry Andric 36039d628a0SDimitry Andric // Emit new store if we didn't do it for this ptr before 36139d628a0SDimitry Andric if (!Loc.getNode()) { 36239d628a0SDimitry Andric Loc = Builder.StatepointLowering.allocateStackSlot(Incoming.getValueType(), 36339d628a0SDimitry Andric Builder); 36439d628a0SDimitry Andric assert(isa<FrameIndexSDNode>(Loc)); 36539d628a0SDimitry Andric int Index = cast<FrameIndexSDNode>(Loc)->getIndex(); 36639d628a0SDimitry Andric // We use TargetFrameIndex so that isel will not select it into LEA 36739d628a0SDimitry Andric Loc = Builder.DAG.getTargetFrameIndex(Index, Incoming.getValueType()); 36839d628a0SDimitry Andric 36939d628a0SDimitry Andric // TODO: We can create TokenFactor node instead of 37039d628a0SDimitry Andric // chaining stores one after another, this may allow 37139d628a0SDimitry Andric // a bit more optimal scheduling for them 37239d628a0SDimitry Andric Chain = Builder.DAG.getStore(Chain, Builder.getCurSDLoc(), Incoming, Loc, 37339d628a0SDimitry Andric MachinePointerInfo::getFixedStack(Index), 37439d628a0SDimitry Andric false, false, 0); 37539d628a0SDimitry Andric 37639d628a0SDimitry Andric Builder.StatepointLowering.setLocation(Incoming, Loc); 37739d628a0SDimitry Andric } 37839d628a0SDimitry Andric 37939d628a0SDimitry Andric assert(Loc.getNode()); 38039d628a0SDimitry Andric return std::make_pair(Loc, Chain); 38139d628a0SDimitry Andric } 38239d628a0SDimitry Andric 38339d628a0SDimitry Andric /// Lower a single value incoming to a statepoint node. This value can be 38439d628a0SDimitry Andric /// either a deopt value or a gc value, the handling is the same. We special 38539d628a0SDimitry Andric /// case constants and allocas, then fall back to spilling if required. 38639d628a0SDimitry Andric static void lowerIncomingStatepointValue(SDValue Incoming, 38739d628a0SDimitry Andric SmallVectorImpl<SDValue> &Ops, 38839d628a0SDimitry Andric SelectionDAGBuilder &Builder) { 38939d628a0SDimitry Andric SDValue Chain = Builder.getRoot(); 39039d628a0SDimitry Andric 39139d628a0SDimitry Andric if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Incoming)) { 39239d628a0SDimitry Andric // If the original value was a constant, make sure it gets recorded as 39339d628a0SDimitry Andric // such in the stackmap. This is required so that the consumer can 39439d628a0SDimitry Andric // parse any internal format to the deopt state. It also handles null 39539d628a0SDimitry Andric // pointers and other constant pointers in GC states 396ff0cc061SDimitry Andric pushStackMapConstant(Ops, Builder, C->getSExtValue()); 39739d628a0SDimitry Andric } else if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(Incoming)) { 398ff0cc061SDimitry Andric // This handles allocas as arguments to the statepoint (this is only 399ff0cc061SDimitry Andric // really meaningful for a deopt value. For GC, we'd be trying to 400ff0cc061SDimitry Andric // relocate the address of the alloca itself?) 401ff0cc061SDimitry Andric Ops.push_back(Builder.DAG.getTargetFrameIndex(FI->getIndex(), 402ff0cc061SDimitry Andric Incoming.getValueType())); 40339d628a0SDimitry Andric } else { 40439d628a0SDimitry Andric // Otherwise, locate a spill slot and explicitly spill it so it 40539d628a0SDimitry Andric // can be found by the runtime later. We currently do not support 40639d628a0SDimitry Andric // tracking values through callee saved registers to their eventual 40739d628a0SDimitry Andric // spill location. This would be a useful optimization, but would 40839d628a0SDimitry Andric // need to be optional since it requires a lot of complexity on the 40939d628a0SDimitry Andric // runtime side which not all would support. 41039d628a0SDimitry Andric std::pair<SDValue, SDValue> Res = 41139d628a0SDimitry Andric spillIncomingStatepointValue(Incoming, Chain, Builder); 41239d628a0SDimitry Andric Ops.push_back(Res.first); 41339d628a0SDimitry Andric Chain = Res.second; 41439d628a0SDimitry Andric } 41539d628a0SDimitry Andric 41639d628a0SDimitry Andric Builder.DAG.setRoot(Chain); 41739d628a0SDimitry Andric } 41839d628a0SDimitry Andric 41939d628a0SDimitry Andric /// Lower deopt state and gc pointer arguments of the statepoint. The actual 42039d628a0SDimitry Andric /// lowering is described in lowerIncomingStatepointValue. This function is 42139d628a0SDimitry Andric /// responsible for lowering everything in the right position and playing some 42239d628a0SDimitry Andric /// tricks to avoid redundant stack manipulation where possible. On 42339d628a0SDimitry Andric /// completion, 'Ops' will contain ready to use operands for machine code 42439d628a0SDimitry Andric /// statepoint. The chain nodes will have already been created and the DAG root 42539d628a0SDimitry Andric /// will be set to the last value spilled (if any were). 42639d628a0SDimitry Andric static void lowerStatepointMetaArgs(SmallVectorImpl<SDValue> &Ops, 427ff0cc061SDimitry Andric ImmutableStatepoint StatepointSite, 42839d628a0SDimitry Andric SelectionDAGBuilder &Builder) { 42939d628a0SDimitry Andric 43039d628a0SDimitry Andric // Lower the deopt and gc arguments for this statepoint. Layout will 43139d628a0SDimitry Andric // be: deopt argument length, deopt arguments.., gc arguments... 43239d628a0SDimitry Andric 43339d628a0SDimitry Andric SmallVector<const Value *, 64> Bases, Ptrs, Relocations; 434ff0cc061SDimitry Andric getIncomingStatepointGCValues(Bases, Ptrs, Relocations, StatepointSite, 435ff0cc061SDimitry Andric Builder); 43639d628a0SDimitry Andric 43739d628a0SDimitry Andric #ifndef NDEBUG 43839d628a0SDimitry Andric // Check that each of the gc pointer and bases we've gotten out of the 43939d628a0SDimitry Andric // safepoint is something the strategy thinks might be a pointer into the GC 44039d628a0SDimitry Andric // heap. This is basically just here to help catch errors during statepoint 44139d628a0SDimitry Andric // insertion. TODO: This should actually be in the Verifier, but we can't get 44239d628a0SDimitry Andric // to the GCStrategy from there (yet). 44339d628a0SDimitry Andric GCStrategy &S = Builder.GFI->getStrategy(); 44439d628a0SDimitry Andric for (const Value *V : Bases) { 44539d628a0SDimitry Andric auto Opt = S.isGCManagedPointer(V); 44639d628a0SDimitry Andric if (Opt.hasValue()) { 44739d628a0SDimitry Andric assert(Opt.getValue() && 44839d628a0SDimitry Andric "non gc managed base pointer found in statepoint"); 44939d628a0SDimitry Andric } 45039d628a0SDimitry Andric } 45139d628a0SDimitry Andric for (const Value *V : Ptrs) { 45239d628a0SDimitry Andric auto Opt = S.isGCManagedPointer(V); 45339d628a0SDimitry Andric if (Opt.hasValue()) { 45439d628a0SDimitry Andric assert(Opt.getValue() && 45539d628a0SDimitry Andric "non gc managed derived pointer found in statepoint"); 45639d628a0SDimitry Andric } 45739d628a0SDimitry Andric } 45839d628a0SDimitry Andric for (const Value *V : Relocations) { 45939d628a0SDimitry Andric auto Opt = S.isGCManagedPointer(V); 46039d628a0SDimitry Andric if (Opt.hasValue()) { 46139d628a0SDimitry Andric assert(Opt.getValue() && "non gc managed pointer relocated"); 46239d628a0SDimitry Andric } 46339d628a0SDimitry Andric } 46439d628a0SDimitry Andric #endif 46539d628a0SDimitry Andric 46639d628a0SDimitry Andric // Before we actually start lowering (and allocating spill slots for values), 46739d628a0SDimitry Andric // reserve any stack slots which we judge to be profitable to reuse for a 46839d628a0SDimitry Andric // particular value. This is purely an optimization over the code below and 46939d628a0SDimitry Andric // doesn't change semantics at all. It is important for performance that we 47039d628a0SDimitry Andric // reserve slots for both deopt and gc values before lowering either. 471ff0cc061SDimitry Andric for (const Value *V : StatepointSite.vm_state_args()) { 47239d628a0SDimitry Andric SDValue Incoming = Builder.getValue(V); 47339d628a0SDimitry Andric reservePreviousStackSlotForValue(Incoming, Builder); 47439d628a0SDimitry Andric } 475ff0cc061SDimitry Andric for (unsigned i = 0; i < Bases.size(); ++i) { 476ff0cc061SDimitry Andric const Value *Base = Bases[i]; 477ff0cc061SDimitry Andric reservePreviousStackSlotForValue(Builder.getValue(Base), Builder); 478ff0cc061SDimitry Andric 479ff0cc061SDimitry Andric const Value *Ptr = Ptrs[i]; 480ff0cc061SDimitry Andric reservePreviousStackSlotForValue(Builder.getValue(Ptr), Builder); 48139d628a0SDimitry Andric } 48239d628a0SDimitry Andric 48339d628a0SDimitry Andric // First, prefix the list with the number of unique values to be 48439d628a0SDimitry Andric // lowered. Note that this is the number of *Values* not the 48539d628a0SDimitry Andric // number of SDValues required to lower them. 486ff0cc061SDimitry Andric const int NumVMSArgs = StatepointSite.getNumTotalVMSArgs(); 487ff0cc061SDimitry Andric pushStackMapConstant(Ops, Builder, NumVMSArgs); 48839d628a0SDimitry Andric 489ff0cc061SDimitry Andric assert(NumVMSArgs == std::distance(StatepointSite.vm_state_begin(), 490ff0cc061SDimitry Andric StatepointSite.vm_state_end())); 49139d628a0SDimitry Andric 49239d628a0SDimitry Andric // The vm state arguments are lowered in an opaque manner. We do 49339d628a0SDimitry Andric // not know what type of values are contained within. We skip the 49439d628a0SDimitry Andric // first one since that happens to be the total number we lowered 49539d628a0SDimitry Andric // explicitly just above. We could have left it in the loop and 49639d628a0SDimitry Andric // not done it explicitly, but it's far easier to understand this 49739d628a0SDimitry Andric // way. 498ff0cc061SDimitry Andric for (const Value *V : StatepointSite.vm_state_args()) { 49939d628a0SDimitry Andric SDValue Incoming = Builder.getValue(V); 50039d628a0SDimitry Andric lowerIncomingStatepointValue(Incoming, Ops, Builder); 50139d628a0SDimitry Andric } 50239d628a0SDimitry Andric 50339d628a0SDimitry Andric // Finally, go ahead and lower all the gc arguments. There's no prefixed 50439d628a0SDimitry Andric // length for this one. After lowering, we'll have the base and pointer 50539d628a0SDimitry Andric // arrays interwoven with each (lowered) base pointer immediately followed by 50639d628a0SDimitry Andric // it's (lowered) derived pointer. i.e 50739d628a0SDimitry Andric // (base[0], ptr[0], base[1], ptr[1], ...) 508ff0cc061SDimitry Andric for (unsigned i = 0; i < Bases.size(); ++i) { 509ff0cc061SDimitry Andric const Value *Base = Bases[i]; 510ff0cc061SDimitry Andric lowerIncomingStatepointValue(Builder.getValue(Base), Ops, Builder); 511ff0cc061SDimitry Andric 512ff0cc061SDimitry Andric const Value *Ptr = Ptrs[i]; 513ff0cc061SDimitry Andric lowerIncomingStatepointValue(Builder.getValue(Ptr), Ops, Builder); 514ff0cc061SDimitry Andric } 515ff0cc061SDimitry Andric 516ff0cc061SDimitry Andric // If there are any explicit spill slots passed to the statepoint, record 517ff0cc061SDimitry Andric // them, but otherwise do not do anything special. These are user provided 518ff0cc061SDimitry Andric // allocas and give control over placement to the consumer. In this case, 519ff0cc061SDimitry Andric // it is the contents of the slot which may get updated, not the pointer to 520ff0cc061SDimitry Andric // the alloca 521ff0cc061SDimitry Andric for (Value *V : StatepointSite.gc_args()) { 52239d628a0SDimitry Andric SDValue Incoming = Builder.getValue(V); 523ff0cc061SDimitry Andric if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(Incoming)) { 524ff0cc061SDimitry Andric // This handles allocas as arguments to the statepoint 525ff0cc061SDimitry Andric Ops.push_back(Builder.DAG.getTargetFrameIndex(FI->getIndex(), 526ff0cc061SDimitry Andric Incoming.getValueType())); 52739d628a0SDimitry Andric } 52839d628a0SDimitry Andric } 529ff0cc061SDimitry Andric 530ff0cc061SDimitry Andric // Record computed locations for all lowered values. 531ff0cc061SDimitry Andric // This can not be embedded in lowering loops as we need to record *all* 532ff0cc061SDimitry Andric // values, while previous loops account only values with unique SDValues. 533ff0cc061SDimitry Andric const Instruction *StatepointInstr = 534ff0cc061SDimitry Andric StatepointSite.getCallSite().getInstruction(); 535ff0cc061SDimitry Andric FunctionLoweringInfo::StatepointSpilledValueMapTy &SpillMap = 536ff0cc061SDimitry Andric Builder.FuncInfo.StatepointRelocatedValues[StatepointInstr]; 537ff0cc061SDimitry Andric 538ff0cc061SDimitry Andric for (GCRelocateOperands RelocateOpers : 539ff0cc061SDimitry Andric StatepointSite.getRelocates(StatepointSite)) { 540ff0cc061SDimitry Andric const Value *V = RelocateOpers.getDerivedPtr(); 541ff0cc061SDimitry Andric SDValue SDV = Builder.getValue(V); 542ff0cc061SDimitry Andric SDValue Loc = Builder.StatepointLowering.getLocation(SDV); 543ff0cc061SDimitry Andric 544ff0cc061SDimitry Andric if (Loc.getNode()) { 545ff0cc061SDimitry Andric SpillMap[V] = cast<FrameIndexSDNode>(Loc)->getIndex(); 546ff0cc061SDimitry Andric } else { 547ff0cc061SDimitry Andric // Record value as visited, but not spilled. This is case for allocas 548ff0cc061SDimitry Andric // and constants. For this values we can avoid emiting spill load while 549ff0cc061SDimitry Andric // visiting corresponding gc_relocate. 550ff0cc061SDimitry Andric // Actually we do not need to record them in this map at all. 551ff0cc061SDimitry Andric // We do this only to check that we are not relocating any unvisited value. 552ff0cc061SDimitry Andric SpillMap[V] = None; 553ff0cc061SDimitry Andric 554ff0cc061SDimitry Andric // Default llvm mechanisms for exporting values which are used in 555ff0cc061SDimitry Andric // different basic blocks does not work for gc relocates. 556ff0cc061SDimitry Andric // Note that it would be incorrect to teach llvm that all relocates are 557ff0cc061SDimitry Andric // uses of the corresponging values so that it would automatically 558ff0cc061SDimitry Andric // export them. Relocates of the spilled values does not use original 559ff0cc061SDimitry Andric // value. 560ff0cc061SDimitry Andric if (StatepointSite.getCallSite().isInvoke()) 561ff0cc061SDimitry Andric Builder.ExportFromCurrentBlock(V); 562ff0cc061SDimitry Andric } 563ff0cc061SDimitry Andric } 564ff0cc061SDimitry Andric } 565ff0cc061SDimitry Andric 56639d628a0SDimitry Andric void SelectionDAGBuilder::visitStatepoint(const CallInst &CI) { 567ff0cc061SDimitry Andric // Check some preconditions for sanity 568ff0cc061SDimitry Andric assert(isStatepoint(&CI) && 569ff0cc061SDimitry Andric "function called must be the statepoint function"); 570ff0cc061SDimitry Andric 571ff0cc061SDimitry Andric LowerStatepoint(ImmutableStatepoint(&CI)); 572ff0cc061SDimitry Andric } 573ff0cc061SDimitry Andric 574ff0cc061SDimitry Andric void SelectionDAGBuilder::LowerStatepoint( 575ff0cc061SDimitry Andric ImmutableStatepoint ISP, MachineBasicBlock *LandingPad /*=nullptr*/) { 57639d628a0SDimitry Andric // The basic scheme here is that information about both the original call and 57739d628a0SDimitry Andric // the safepoint is encoded in the CallInst. We create a temporary call and 57839d628a0SDimitry Andric // lower it, then reverse engineer the calling sequence. 57939d628a0SDimitry Andric 58039d628a0SDimitry Andric NumOfStatepoints++; 58139d628a0SDimitry Andric // Clear state 58239d628a0SDimitry Andric StatepointLowering.startNewStatepoint(*this); 58339d628a0SDimitry Andric 584ff0cc061SDimitry Andric ImmutableCallSite CS(ISP.getCallSite()); 585ff0cc061SDimitry Andric 58639d628a0SDimitry Andric #ifndef NDEBUG 587ff0cc061SDimitry Andric // Consistency check. Don't do this for invokes. It would be too 588ff0cc061SDimitry Andric // expensive to preserve this information across different basic blocks 589ff0cc061SDimitry Andric if (!CS.isInvoke()) { 590ff0cc061SDimitry Andric for (const User *U : CS->users()) { 59139d628a0SDimitry Andric const CallInst *Call = cast<CallInst>(U); 59239d628a0SDimitry Andric if (isGCRelocate(Call)) 59339d628a0SDimitry Andric StatepointLowering.scheduleRelocCall(*Call); 59439d628a0SDimitry Andric } 595ff0cc061SDimitry Andric } 59639d628a0SDimitry Andric #endif 59739d628a0SDimitry Andric 59839d628a0SDimitry Andric #ifndef NDEBUG 59939d628a0SDimitry Andric // If this is a malformed statepoint, report it early to simplify debugging. 60039d628a0SDimitry Andric // This should catch any IR level mistake that's made when constructing or 60139d628a0SDimitry Andric // transforming statepoints. 60239d628a0SDimitry Andric ISP.verify(); 60339d628a0SDimitry Andric 60439d628a0SDimitry Andric // Check that the associated GCStrategy expects to encounter statepoints. 60539d628a0SDimitry Andric assert(GFI->getStrategy().useStatepoints() && 60639d628a0SDimitry Andric "GCStrategy does not expect to encounter statepoints"); 60739d628a0SDimitry Andric #endif 60839d628a0SDimitry Andric 60939d628a0SDimitry Andric // Lower statepoint vmstate and gcstate arguments 610ff0cc061SDimitry Andric SmallVector<SDValue, 10> LoweredMetaArgs; 611ff0cc061SDimitry Andric lowerStatepointMetaArgs(LoweredMetaArgs, ISP, *this); 61239d628a0SDimitry Andric 61339d628a0SDimitry Andric // Get call node, we will replace it later with statepoint 614ff0cc061SDimitry Andric SDNode *CallNode = 615ff0cc061SDimitry Andric lowerCallFromStatepoint(ISP, LandingPad, *this, PendingExports); 61639d628a0SDimitry Andric 617ff0cc061SDimitry Andric // Construct the actual GC_TRANSITION_START, STATEPOINT, and GC_TRANSITION_END 618ff0cc061SDimitry Andric // nodes with all the appropriate arguments and return values. 619ff0cc061SDimitry Andric 620ff0cc061SDimitry Andric // Call Node: Chain, Target, {Args}, RegMask, [Glue] 621ff0cc061SDimitry Andric SDValue Chain = CallNode->getOperand(0); 622ff0cc061SDimitry Andric 623ff0cc061SDimitry Andric SDValue Glue; 624ff0cc061SDimitry Andric bool CallHasIncomingGlue = CallNode->getGluedNode(); 625ff0cc061SDimitry Andric if (CallHasIncomingGlue) { 626ff0cc061SDimitry Andric // Glue is always last operand 627ff0cc061SDimitry Andric Glue = CallNode->getOperand(CallNode->getNumOperands() - 1); 628ff0cc061SDimitry Andric } 629ff0cc061SDimitry Andric 630ff0cc061SDimitry Andric // Build the GC_TRANSITION_START node if necessary. 631ff0cc061SDimitry Andric // 632ff0cc061SDimitry Andric // The operands to the GC_TRANSITION_{START,END} nodes are laid out in the 633ff0cc061SDimitry Andric // order in which they appear in the call to the statepoint intrinsic. If 634ff0cc061SDimitry Andric // any of the operands is a pointer-typed, that operand is immediately 635ff0cc061SDimitry Andric // followed by a SRCVALUE for the pointer that may be used during lowering 636ff0cc061SDimitry Andric // (e.g. to form MachinePointerInfo values for loads/stores). 637ff0cc061SDimitry Andric const bool IsGCTransition = 638ff0cc061SDimitry Andric (ISP.getFlags() & (uint64_t)StatepointFlags::GCTransition) == 639ff0cc061SDimitry Andric (uint64_t)StatepointFlags::GCTransition; 640ff0cc061SDimitry Andric if (IsGCTransition) { 641ff0cc061SDimitry Andric SmallVector<SDValue, 8> TSOps; 642ff0cc061SDimitry Andric 643ff0cc061SDimitry Andric // Add chain 644ff0cc061SDimitry Andric TSOps.push_back(Chain); 645ff0cc061SDimitry Andric 646ff0cc061SDimitry Andric // Add GC transition arguments 647ff0cc061SDimitry Andric for (const Value *V : ISP.gc_transition_args()) { 648ff0cc061SDimitry Andric TSOps.push_back(getValue(V)); 649ff0cc061SDimitry Andric if (V->getType()->isPointerTy()) 650ff0cc061SDimitry Andric TSOps.push_back(DAG.getSrcValue(V)); 651ff0cc061SDimitry Andric } 652ff0cc061SDimitry Andric 653ff0cc061SDimitry Andric // Add glue if necessary 654ff0cc061SDimitry Andric if (CallHasIncomingGlue) 655ff0cc061SDimitry Andric TSOps.push_back(Glue); 656ff0cc061SDimitry Andric 657ff0cc061SDimitry Andric SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); 658ff0cc061SDimitry Andric 659ff0cc061SDimitry Andric SDValue GCTransitionStart = 660ff0cc061SDimitry Andric DAG.getNode(ISD::GC_TRANSITION_START, getCurSDLoc(), NodeTys, TSOps); 661ff0cc061SDimitry Andric 662ff0cc061SDimitry Andric Chain = GCTransitionStart.getValue(0); 663ff0cc061SDimitry Andric Glue = GCTransitionStart.getValue(1); 664ff0cc061SDimitry Andric } 66539d628a0SDimitry Andric 66639d628a0SDimitry Andric // TODO: Currently, all of these operands are being marked as read/write in 66739d628a0SDimitry Andric // PrologEpilougeInserter.cpp, we should special case the VMState arguments 66839d628a0SDimitry Andric // and flags to be read-only. 66939d628a0SDimitry Andric SmallVector<SDValue, 40> Ops; 67039d628a0SDimitry Andric 671ff0cc061SDimitry Andric // Add the <id> and <numBytes> constants. 672ff0cc061SDimitry Andric Ops.push_back(DAG.getTargetConstant(ISP.getID(), getCurSDLoc(), MVT::i64)); 673ff0cc061SDimitry Andric Ops.push_back( 674ff0cc061SDimitry Andric DAG.getTargetConstant(ISP.getNumPatchBytes(), getCurSDLoc(), MVT::i32)); 675ff0cc061SDimitry Andric 67639d628a0SDimitry Andric // Calculate and push starting position of vmstate arguments 67739d628a0SDimitry Andric // Get number of arguments incoming directly into call node 67839d628a0SDimitry Andric unsigned NumCallRegArgs = 679ff0cc061SDimitry Andric CallNode->getNumOperands() - (CallHasIncomingGlue ? 4 : 3); 680ff0cc061SDimitry Andric Ops.push_back(DAG.getTargetConstant(NumCallRegArgs, getCurSDLoc(), MVT::i32)); 68139d628a0SDimitry Andric 68239d628a0SDimitry Andric // Add call target 68339d628a0SDimitry Andric SDValue CallTarget = SDValue(CallNode->getOperand(1).getNode(), 0); 68439d628a0SDimitry Andric Ops.push_back(CallTarget); 68539d628a0SDimitry Andric 68639d628a0SDimitry Andric // Add call arguments 68739d628a0SDimitry Andric // Get position of register mask in the call 68839d628a0SDimitry Andric SDNode::op_iterator RegMaskIt; 689ff0cc061SDimitry Andric if (CallHasIncomingGlue) 69039d628a0SDimitry Andric RegMaskIt = CallNode->op_end() - 2; 69139d628a0SDimitry Andric else 69239d628a0SDimitry Andric RegMaskIt = CallNode->op_end() - 1; 69339d628a0SDimitry Andric Ops.insert(Ops.end(), CallNode->op_begin() + 2, RegMaskIt); 69439d628a0SDimitry Andric 695ff0cc061SDimitry Andric // Add a constant argument for the calling convention 696ff0cc061SDimitry Andric pushStackMapConstant(Ops, *this, CS.getCallingConv()); 697ff0cc061SDimitry Andric 698ff0cc061SDimitry Andric // Add a constant argument for the flags 699ff0cc061SDimitry Andric uint64_t Flags = ISP.getFlags(); 700ff0cc061SDimitry Andric assert( 701ff0cc061SDimitry Andric ((Flags & ~(uint64_t)StatepointFlags::MaskAll) == 0) 702ff0cc061SDimitry Andric && "unknown flag used"); 703ff0cc061SDimitry Andric pushStackMapConstant(Ops, *this, Flags); 70439d628a0SDimitry Andric 70539d628a0SDimitry Andric // Insert all vmstate and gcstate arguments 706ff0cc061SDimitry Andric Ops.insert(Ops.end(), LoweredMetaArgs.begin(), LoweredMetaArgs.end()); 70739d628a0SDimitry Andric 70839d628a0SDimitry Andric // Add register mask from call node 70939d628a0SDimitry Andric Ops.push_back(*RegMaskIt); 71039d628a0SDimitry Andric 71139d628a0SDimitry Andric // Add chain 712ff0cc061SDimitry Andric Ops.push_back(Chain); 71339d628a0SDimitry Andric 71439d628a0SDimitry Andric // Same for the glue, but we add it only if original call had it 71539d628a0SDimitry Andric if (Glue.getNode()) 71639d628a0SDimitry Andric Ops.push_back(Glue); 71739d628a0SDimitry Andric 718ff0cc061SDimitry Andric // Compute return values. Provide a glue output since we consume one as 719ff0cc061SDimitry Andric // input. This allows someone else to chain off us as needed. 720ff0cc061SDimitry Andric SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); 72139d628a0SDimitry Andric 722ff0cc061SDimitry Andric SDNode *StatepointMCNode = 723ff0cc061SDimitry Andric DAG.getMachineNode(TargetOpcode::STATEPOINT, getCurSDLoc(), NodeTys, Ops); 724ff0cc061SDimitry Andric 725ff0cc061SDimitry Andric SDNode *SinkNode = StatepointMCNode; 726ff0cc061SDimitry Andric 727ff0cc061SDimitry Andric // Build the GC_TRANSITION_END node if necessary. 728ff0cc061SDimitry Andric // 729ff0cc061SDimitry Andric // See the comment above regarding GC_TRANSITION_START for the layout of 730ff0cc061SDimitry Andric // the operands to the GC_TRANSITION_END node. 731ff0cc061SDimitry Andric if (IsGCTransition) { 732ff0cc061SDimitry Andric SmallVector<SDValue, 8> TEOps; 733ff0cc061SDimitry Andric 734ff0cc061SDimitry Andric // Add chain 735ff0cc061SDimitry Andric TEOps.push_back(SDValue(StatepointMCNode, 0)); 736ff0cc061SDimitry Andric 737ff0cc061SDimitry Andric // Add GC transition arguments 738ff0cc061SDimitry Andric for (const Value *V : ISP.gc_transition_args()) { 739ff0cc061SDimitry Andric TEOps.push_back(getValue(V)); 740ff0cc061SDimitry Andric if (V->getType()->isPointerTy()) 741ff0cc061SDimitry Andric TEOps.push_back(DAG.getSrcValue(V)); 742ff0cc061SDimitry Andric } 743ff0cc061SDimitry Andric 744ff0cc061SDimitry Andric // Add glue 745ff0cc061SDimitry Andric TEOps.push_back(SDValue(StatepointMCNode, 1)); 746ff0cc061SDimitry Andric 747ff0cc061SDimitry Andric SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); 748ff0cc061SDimitry Andric 749ff0cc061SDimitry Andric SDValue GCTransitionStart = 750ff0cc061SDimitry Andric DAG.getNode(ISD::GC_TRANSITION_END, getCurSDLoc(), NodeTys, TEOps); 751ff0cc061SDimitry Andric 752ff0cc061SDimitry Andric SinkNode = GCTransitionStart.getNode(); 753ff0cc061SDimitry Andric } 75439d628a0SDimitry Andric 75539d628a0SDimitry Andric // Replace original call 756ff0cc061SDimitry Andric DAG.ReplaceAllUsesWith(CallNode, SinkNode); // This may update Root 75739d628a0SDimitry Andric // Remove originall call node 75839d628a0SDimitry Andric DAG.DeleteNode(CallNode); 75939d628a0SDimitry Andric 76039d628a0SDimitry Andric // DON'T set the root - under the assumption that it's already set past the 76139d628a0SDimitry Andric // inserted node we created. 76239d628a0SDimitry Andric 76339d628a0SDimitry Andric // TODO: A better future implementation would be to emit a single variable 76439d628a0SDimitry Andric // argument, variable return value STATEPOINT node here and then hookup the 76539d628a0SDimitry Andric // return value of each gc.relocate to the respective output of the 76639d628a0SDimitry Andric // previously emitted STATEPOINT value. Unfortunately, this doesn't appear 76739d628a0SDimitry Andric // to actually be possible today. 76839d628a0SDimitry Andric } 76939d628a0SDimitry Andric 77039d628a0SDimitry Andric void SelectionDAGBuilder::visitGCResult(const CallInst &CI) { 77139d628a0SDimitry Andric // The result value of the gc_result is simply the result of the actual 77239d628a0SDimitry Andric // call. We've already emitted this, so just grab the value. 77339d628a0SDimitry Andric Instruction *I = cast<Instruction>(CI.getArgOperand(0)); 774ff0cc061SDimitry Andric assert(isStatepoint(I) && "first argument must be a statepoint token"); 77539d628a0SDimitry Andric 776ff0cc061SDimitry Andric if (isa<InvokeInst>(I)) { 777ff0cc061SDimitry Andric // For invokes we should have stored call result in a virtual register. 778ff0cc061SDimitry Andric // We can not use default getValue() functionality to copy value from this 779ff0cc061SDimitry Andric // register because statepoint and actuall call return types can be 780ff0cc061SDimitry Andric // different, and getValue() will use CopyFromReg of the wrong type, 781ff0cc061SDimitry Andric // which is always i32 in our case. 782ff0cc061SDimitry Andric PointerType *CalleeType = 783ff0cc061SDimitry Andric cast<PointerType>(ImmutableStatepoint(I).getActualCallee()->getType()); 784ff0cc061SDimitry Andric Type *RetTy = 785ff0cc061SDimitry Andric cast<FunctionType>(CalleeType->getElementType())->getReturnType(); 786ff0cc061SDimitry Andric SDValue CopyFromReg = getCopyFromRegs(I, RetTy); 787ff0cc061SDimitry Andric 788ff0cc061SDimitry Andric assert(CopyFromReg.getNode()); 789ff0cc061SDimitry Andric setValue(&CI, CopyFromReg); 790ff0cc061SDimitry Andric } else { 79139d628a0SDimitry Andric setValue(&CI, getValue(I)); 79239d628a0SDimitry Andric } 793ff0cc061SDimitry Andric } 79439d628a0SDimitry Andric 79539d628a0SDimitry Andric void SelectionDAGBuilder::visitGCRelocate(const CallInst &CI) { 796ff0cc061SDimitry Andric GCRelocateOperands RelocateOpers(&CI); 797ff0cc061SDimitry Andric 79839d628a0SDimitry Andric #ifndef NDEBUG 79939d628a0SDimitry Andric // Consistency check 800ff0cc061SDimitry Andric // We skip this check for invoke statepoints. It would be too expensive to 801ff0cc061SDimitry Andric // preserve validation info through different basic blocks. 802ff0cc061SDimitry Andric if (!RelocateOpers.isTiedToInvoke()) { 80339d628a0SDimitry Andric StatepointLowering.relocCallVisited(CI); 804ff0cc061SDimitry Andric } 80539d628a0SDimitry Andric #endif 80639d628a0SDimitry Andric 807ff0cc061SDimitry Andric const Value *DerivedPtr = RelocateOpers.getDerivedPtr(); 808ff0cc061SDimitry Andric SDValue SD = getValue(DerivedPtr); 80939d628a0SDimitry Andric 810ff0cc061SDimitry Andric FunctionLoweringInfo::StatepointSpilledValueMapTy &SpillMap = 811ff0cc061SDimitry Andric FuncInfo.StatepointRelocatedValues[RelocateOpers.getStatepoint()]; 812ff0cc061SDimitry Andric 813ff0cc061SDimitry Andric // We should have recorded location for this pointer 814ff0cc061SDimitry Andric assert(SpillMap.count(DerivedPtr) && "Relocating not lowered gc value"); 815ff0cc061SDimitry Andric Optional<int> DerivedPtrLocation = SpillMap[DerivedPtr]; 816ff0cc061SDimitry Andric 81739d628a0SDimitry Andric // We didn't need to spill these special cases (constants and allocas). 81839d628a0SDimitry Andric // See the handling in spillIncomingValueForStatepoint for detail. 819ff0cc061SDimitry Andric if (!DerivedPtrLocation) { 82039d628a0SDimitry Andric setValue(&CI, SD); 82139d628a0SDimitry Andric return; 82239d628a0SDimitry Andric } 82339d628a0SDimitry Andric 824ff0cc061SDimitry Andric SDValue SpillSlot = DAG.getTargetFrameIndex(*DerivedPtrLocation, 825ff0cc061SDimitry Andric SD.getValueType()); 82639d628a0SDimitry Andric 82739d628a0SDimitry Andric // Be conservative: flush all pending loads 82839d628a0SDimitry Andric // TODO: Probably we can be less restrictive on this, 82939d628a0SDimitry Andric // it may allow more scheduling opprtunities 83039d628a0SDimitry Andric SDValue Chain = getRoot(); 83139d628a0SDimitry Andric 832ff0cc061SDimitry Andric SDValue SpillLoad = 833ff0cc061SDimitry Andric DAG.getLoad(SpillSlot.getValueType(), getCurSDLoc(), Chain, SpillSlot, 834ff0cc061SDimitry Andric MachinePointerInfo::getFixedStack(*DerivedPtrLocation), 835ff0cc061SDimitry Andric false, false, false, 0); 83639d628a0SDimitry Andric 83739d628a0SDimitry Andric // Again, be conservative, don't emit pending loads 838ff0cc061SDimitry Andric DAG.setRoot(SpillLoad.getValue(1)); 83939d628a0SDimitry Andric 840ff0cc061SDimitry Andric assert(SpillLoad.getNode()); 841ff0cc061SDimitry Andric setValue(&CI, SpillLoad); 84239d628a0SDimitry Andric } 843