Index: llvm/trunk/docs/Statepoints.rst =================================================================== --- llvm/trunk/docs/Statepoints.rst +++ llvm/trunk/docs/Statepoints.rst @@ -483,6 +483,12 @@ Each statepoint generates the following Locations: +* Constant which describes the calling convention of the call target. This + constant is a valid :ref:`calling convention identifier ` for + the version of LLVM used to generate the stackmap. No additional compatibility + guarantees are made for this constant over what LLVM provides elsewhere w.r.t. + these identifiers. +* Constant which describes the flags passed to the statepoint intrinsic * Constant which describes number of following deopt *Locations* (not operands) * Variable number of Locations, one for each deopt parameter listed in Index: llvm/trunk/include/llvm/CodeGen/StackMaps.h =================================================================== --- llvm/trunk/include/llvm/CodeGen/StackMaps.h +++ llvm/trunk/include/llvm/CodeGen/StackMaps.h @@ -86,22 +86,33 @@ /// /// Statepoint operands take the form: /// , , [call arguments], -/// , , +/// , , +/// , , /// , , [other args], /// [gc values] class StatepointOpers { private: + // These values are aboolute offsets into the operands of the statepoint + // instruction. enum { NCallArgsPos = 0, CallTargetPos = 1 }; + // These values are relative offests from the start of the statepoint meta + // arguments (i.e. the end of the call arguments). + enum { + CCOffset = 1, + FlagsOffset = 3, + NumVMSArgsOffset = 5 + }; + public: explicit StatepointOpers(const MachineInstr *MI): MI(MI) { } /// Get starting index of non call related arguments - /// (statepoint flags, vm state and gc state). + /// (calling convention, statepoint flags, vm state and gc state). unsigned getVarIdx() const { return MI->getOperand(NCallArgsPos).getImm() + 2; } @@ -109,7 +120,7 @@ /// Returns the index of the operand containing the number of non-gc non-call /// arguments. unsigned getNumVMSArgsIdx() const { - return getVarIdx() + 3; + return getVarIdx() + NumVMSArgsOffset; } /// Returns the number of non-gc non-call arguments attached to the Index: llvm/trunk/lib/CodeGen/SelectionDAG/StatepointLowering.cpp =================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/StatepointLowering.cpp +++ llvm/trunk/lib/CodeGen/SelectionDAG/StatepointLowering.cpp @@ -38,6 +38,14 @@ STATISTIC(StatepointMaxSlotsRequired, "Maximum number of stack slots required for a singe statepoint"); +static void pushStackMapConstant(SmallVectorImpl& Ops, + SelectionDAGBuilder &Builder, uint64_t Value) { + SDLoc L = Builder.getCurSDLoc(); + Ops.push_back(Builder.DAG.getTargetConstant(StackMaps::ConstantOp, L, + MVT::i64)); + Ops.push_back(Builder.DAG.getTargetConstant(Value, L, MVT::i64)); +} + void StatepointLoweringState::startNewStatepoint(SelectionDAGBuilder &Builder) { // Consistency check assert(PendingGCRelocateCalls.empty() && @@ -386,12 +394,7 @@ // such in the stackmap. This is required so that the consumer can // parse any internal format to the deopt state. It also handles null // pointers and other constant pointers in GC states - Ops.push_back(Builder.DAG.getTargetConstant(StackMaps::ConstantOp, - Builder.getCurSDLoc(), - MVT::i64)); - Ops.push_back(Builder.DAG.getTargetConstant(C->getSExtValue(), - Builder.getCurSDLoc(), - MVT::i64)); + pushStackMapConstant(Ops, Builder, C->getSExtValue()); } else if (FrameIndexSDNode *FI = dyn_cast(Incoming)) { // This handles allocas as arguments to the statepoint (this is only // really meaningful for a deopt value. For GC, we'd be trying to @@ -485,11 +488,7 @@ // lowered. Note that this is the number of *Values* not the // number of SDValues required to lower them. const int NumVMSArgs = StatepointSite.getNumTotalVMSArgs(); - Ops.push_back( Builder.DAG.getTargetConstant(StackMaps::ConstantOp, - Builder.getCurSDLoc(), - MVT::i64)); - Ops.push_back(Builder.DAG.getTargetConstant(NumVMSArgs, Builder.getCurSDLoc(), - MVT::i64)); + pushStackMapConstant(Ops, Builder, NumVMSArgs); assert(NumVMSArgs + 1 == std::distance(StatepointSite.vm_state_begin(), StatepointSite.vm_state_end())); @@ -662,21 +661,15 @@ RegMaskIt = CallNode->op_end() - 1; Ops.insert(Ops.end(), CallNode->op_begin() + 2, RegMaskIt); - // Add a leading constant argument with the Flags and the calling convention - // masked together - CallingConv::ID CallConv = CS.getCallingConv(); + // Add a constant argument for the calling convention + pushStackMapConstant(Ops, *this, CS.getCallingConv()); + + // Add a constant argument for the flags uint64_t Flags = cast(CS.getArgument(2))->getZExtValue(); assert( ((Flags & ~(uint64_t)StatepointFlags::MaskAll) == 0) && "unknown flag used"); - const int Shift = 1; - static_assert( - ((~(uint64_t)0 << Shift) & (uint64_t)StatepointFlags::MaskAll) == 0, - "shift width too small"); - Ops.push_back(DAG.getTargetConstant(StackMaps::ConstantOp, getCurSDLoc(), - MVT::i64)); - Ops.push_back(DAG.getTargetConstant(Flags | ((unsigned)CallConv << Shift), - getCurSDLoc(), MVT::i64)); + pushStackMapConstant(Ops, *this, Flags); // Insert all vmstate and gcstate arguments Ops.insert(Ops.end(), LoweredMetaArgs.begin(), LoweredMetaArgs.end()); Index: llvm/trunk/test/CodeGen/X86/statepoint-allocas.ll =================================================================== --- llvm/trunk/test/CodeGen/X86/statepoint-allocas.ll +++ llvm/trunk/test/CodeGen/X86/statepoint-allocas.ll @@ -72,7 +72,12 @@ ; The GC one ; CHECK: .long .Ltmp1-test ; CHECK: .short 0 -; CHECK: .short 3 +; CHECK: .short 4 +; SmallConstant (0) +; CHECK: .byte 4 +; CHECK: .byte 8 +; CHECK: .short 0 +; CHECK: .long 0 ; SmallConstant (0) ; CHECK: .byte 4 ; CHECK: .byte 8 @@ -96,7 +101,12 @@ ; The Deopt one ; CHECK: .long .Ltmp3-test2 ; CHECK: .short 0 -; CHECK: .short 3 +; CHECK: .short 4 +; SmallConstant (0) +; CHECK: .byte 4 +; CHECK: .byte 8 +; CHECK: .short 0 +; CHECK: .long 0 ; SmallConstant (0) ; CHECK: .byte 4 ; CHECK: .byte 8 Index: llvm/trunk/test/CodeGen/X86/statepoint-stackmap-format.ll =================================================================== --- llvm/trunk/test/CodeGen/X86/statepoint-stackmap-format.ll +++ llvm/trunk/test/CodeGen/X86/statepoint-stackmap-format.ll @@ -97,7 +97,12 @@ ; Constant arguments ; CHECK: .long .Ltmp1-test ; CHECK: .short 0 -; CHECK: .short 10 +; CHECK: .short 11 +; SmallConstant (0) +; CHECK: .byte 4 +; CHECK: .byte 8 +; CHECK: .short 0 +; CHECK: .long 0 ; SmallConstant (0) ; CHECK: .byte 4 ; CHECK: .byte 8 @@ -166,7 +171,7 @@ ; Constant arguments ; CHECK: .long .Ltmp3-test_derived_arg ; CHECK: .short 0 -; CHECK: .short 10 +; CHECK: .short 11 ; SmallConstant (0) ; CHECK: .byte 4 ; CHECK: .byte 8