[Statepoints] Split the calling convention and statepoint flags operand to STATEPOINT...
authorPat Gavlin <pagavlin@microsoft.com>
Tue, 12 May 2015 19:50:19 +0000 (19:50 +0000)
committerPat Gavlin <pagavlin@microsoft.com>
Tue, 12 May 2015 19:50:19 +0000 (19:50 +0000)
Differential Revision: http://reviews.llvm.org/D9623

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@237166 91177308-0d34-0410-b5e6-96231b3b80d8

docs/Statepoints.rst
include/llvm/CodeGen/StackMaps.h
lib/CodeGen/SelectionDAG/StatepointLowering.cpp
test/CodeGen/X86/statepoint-allocas.ll
test/CodeGen/X86/statepoint-stackmap-format.ll

index c381c3e75f94ad06ac7dcd7ea6ab7633e60c666f..d6576293dbdac114114f0568827d54d247edf24b 100644 (file)
@@ -483,6 +483,12 @@ the runtime or collector are provided via the :ref:`Stack Map format
 
 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 <callingconv>` 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 caec994bc37b9eee122875c5e39812898be4502e..c6d097b916f462339a42e78afc0314e054275d53 100644 (file)
@@ -86,22 +86,33 @@ public:
 ///
 /// Statepoint operands take the form:
 ///   <num call arguments>, <call target>, [call arguments],
-///   <StackMaps::ConstantOp>, <flags>,
+///   <StackMaps::ConstantOp>, <calling convention>,
+///   <StackMaps::ConstantOp>, <statepoint flags>,
 ///   <StackMaps::ConstantOp>, <num other args>, [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 @@ public:
   /// 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 4a21ce247c9beb03d0450b7802f7da8d492f42a0..86fbc6354589aef63d635904dd8ebfd46caaf49f 100644 (file)
@@ -38,6 +38,14 @@ STATISTIC(NumOfStatepoints, "Number of statepoint nodes encountered");
 STATISTIC(StatepointMaxSlotsRequired,
           "Maximum number of stack slots required for a singe statepoint");
 
+static void pushStackMapConstant(SmallVectorImpl<SDValue>& 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 @@ static void lowerIncomingStatepointValue(SDValue Incoming,
     // 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<FrameIndexSDNode>(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 @@ static void lowerStatepointMetaArgs(SmallVectorImpl<SDValue> &Ops,
   // 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 @@ void SelectionDAGBuilder::LowerStatepoint(
     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<ConstantInt>(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 fe11990a718aba87c60b04662cb80dc5aab4150c..7cdcb0cfe813c49053fe5927ad2dfc29c5887af3 100644 (file)
@@ -72,7 +72,12 @@ declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()*, i32, i32, ...)
 ; 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 @@ declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()*, i32, i32, ...)
 ; 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 14f48bce9fa0c5ab644927c6d8ba961b2f92bd76..b79714d002263fe4834504025abfe1a331f9c5ee 100644 (file)
@@ -97,7 +97,12 @@ declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32, i32, i32) #3
 ; 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 @@ declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32, i32, i32) #3
 ; 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