[llvm] r258338 - Add a "gc-transition" operand bundle

Sanjoy Das via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 20 11:50:25 PST 2016


Author: sanjoy
Date: Wed Jan 20 13:50:25 2016
New Revision: 258338

URL: http://llvm.org/viewvc/llvm-project?rev=258338&view=rev
Log:
Add a "gc-transition" operand bundle

Summary:
This adds a new kind of operand bundle to LLVM denoted by the
`"gc-transition"` tag.  Inputs to `"gc-transition"` operand bundle are
lowered into the "transition args" section of `gc.statepoint` by
`RewriteStatepointsForGC`.

This removes the last bit of functionality that was unsupported in the
deopt bundle based code path in `RewriteStatepointsForGC`.

Reviewers: pgavlin, JosephTremoulet, reames

Subscribers: sanjoy, mcrosier, llvm-commits

Differential Revision: http://reviews.llvm.org/D16342

Modified:
    llvm/trunk/docs/LangRef.rst
    llvm/trunk/docs/Statepoints.rst
    llvm/trunk/include/llvm/IR/LLVMContext.h
    llvm/trunk/lib/IR/LLVMContext.cpp
    llvm/trunk/lib/IR/Verifier.cpp
    llvm/trunk/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp
    llvm/trunk/test/Transforms/RewriteStatepointsForGC/deopt-bundles/basic.ll
    llvm/trunk/test/Verifier/operand-bundles.ll

Modified: llvm/trunk/docs/LangRef.rst
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.rst?rev=258338&r1=258337&r2=258338&view=diff
==============================================================================
--- llvm/trunk/docs/LangRef.rst (original)
+++ llvm/trunk/docs/LangRef.rst Wed Jan 20 13:50:25 2016
@@ -1602,6 +1602,18 @@ it is undefined behavior to execute a ``
 Similarly, if no funclet EH pads have been entered-but-not-yet-exited,
 executing a ``call`` or ``invoke`` with a ``"funclet"`` bundle is undefined behavior.
 
+GC Transition Operand Bundles
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+GC transition operand bundles are characterized by the
+``"gc-transition"`` operand bundle tag. These operand bundles mark a
+call as a transition between a function with one GC strategy to a
+function with a different GC strategy. If coordinating the transition
+between GC strategies requires additional code generation at the call
+site, these bundles may contain any values that are needed by the
+generated code.  For more details, see :ref:`GC Transitions
+<gc_transition_args>`.
+
 .. _moduleasm:
 
 Module-Level Inline Assembly

Modified: llvm/trunk/docs/Statepoints.rst
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/Statepoints.rst?rev=258338&r1=258337&r2=258338&view=diff
==============================================================================
--- llvm/trunk/docs/Statepoints.rst (original)
+++ llvm/trunk/docs/Statepoints.rst Wed Jan 20 13:50:25 2016
@@ -251,7 +251,9 @@ we get:
 
 Note that in this example %p and %obj.relocate are the same address and we
 could replace one with the other, potentially removing the derived pointer
-from the live set at the safepoint entirely.  
+from the live set at the safepoint entirely.
+
+.. _gc_transition_args:
 
 GC Transitions
 ^^^^^^^^^^^^^^^^^^

Modified: llvm/trunk/include/llvm/IR/LLVMContext.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/LLVMContext.h?rev=258338&r1=258337&r2=258338&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/LLVMContext.h (original)
+++ llvm/trunk/include/llvm/IR/LLVMContext.h Wed Jan 20 13:50:25 2016
@@ -71,8 +71,9 @@ public:
   /// Additionally, this scheme allows LLVM to efficiently check for specific
   /// operand bundle tags without comparing strings.
   enum {
-    OB_deopt = 0,   // "deopt"
-    OB_funclet = 1, // "funclet"
+    OB_deopt = 0,         // "deopt"
+    OB_funclet = 1,       // "funclet"
+    OB_gc_transition = 2, // "gc-transition"
   };
 
   /// getMDKindID - Return a unique non-zero ID for the specified metadata kind.

Modified: llvm/trunk/lib/IR/LLVMContext.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/LLVMContext.cpp?rev=258338&r1=258337&r2=258338&view=diff
==============================================================================
--- llvm/trunk/lib/IR/LLVMContext.cpp (original)
+++ llvm/trunk/lib/IR/LLVMContext.cpp Wed Jan 20 13:50:25 2016
@@ -137,6 +137,11 @@ LLVMContext::LLVMContext() : pImpl(new L
   assert(FuncletEntry->second == LLVMContext::OB_funclet &&
          "funclet operand bundle id drifted!");
   (void)FuncletEntry;
+
+  auto *GCTransitionEntry = pImpl->getOrInsertBundleTag("gc-transition");
+  assert(GCTransitionEntry->second == LLVMContext::OB_gc_transition &&
+         "gc-transition operand bundle id drifted!");
+  (void)GCTransitionEntry;
 }
 LLVMContext::~LLVMContext() { delete pImpl; }
 

Modified: llvm/trunk/lib/IR/Verifier.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Verifier.cpp?rev=258338&r1=258337&r2=258338&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Verifier.cpp (original)
+++ llvm/trunk/lib/IR/Verifier.cpp Wed Jan 20 13:50:25 2016
@@ -2513,17 +2513,21 @@ void Verifier::VerifyCallSite(CallSite C
     if (Intrinsic::ID ID = (Intrinsic::ID)F->getIntrinsicID())
       visitIntrinsicCallSite(ID, CS);
 
-  // Verify that a callsite has at most one "deopt" and one "funclet" operand
-  // bundle.
-  bool FoundDeoptBundle = false, FoundFuncletBundle = false;
+  // Verify that a callsite has at most one "deopt", at most one "funclet" and
+  // at most one "gc-transition" operand bundle.
+  bool FoundDeoptBundle = false, FoundFuncletBundle = false,
+       FoundGCTransitionBundle = false;
   for (unsigned i = 0, e = CS.getNumOperandBundles(); i < e; ++i) {
     OperandBundleUse BU = CS.getOperandBundleAt(i);
     uint32_t Tag = BU.getTagID();
     if (Tag == LLVMContext::OB_deopt) {
       Assert(!FoundDeoptBundle, "Multiple deopt operand bundles", I);
       FoundDeoptBundle = true;
-    }
-    if (Tag == LLVMContext::OB_funclet) {
+    } else if (Tag == LLVMContext::OB_gc_transition) {
+      Assert(!FoundGCTransitionBundle, "Multiple gc-transition operand bundles",
+             I);
+      FoundGCTransitionBundle = true;
+    } else if (Tag == LLVMContext::OB_funclet) {
       Assert(!FoundFuncletBundle, "Multiple funclet operand bundles", I);
       FoundFuncletBundle = true;
       Assert(BU.Inputs.size() == 1,

Modified: llvm/trunk/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp?rev=258338&r1=258337&r2=258338&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp Wed Jan 20 13:50:25 2016
@@ -1404,8 +1404,11 @@ makeStatepointExplicitImpl(const CallSit
   if (UseDeoptBundles) {
     CallArgs = {CS.arg_begin(), CS.arg_end()};
     DeoptArgs = GetDeoptBundleOperands(CS);
-    // TODO: we don't fill in TransitionArgs or Flags in this branch, but we
-    // could have an operand bundle for that too.
+    if (auto TransitionBundle =
+            CS.getOperandBundle(LLVMContext::OB_gc_transition)) {
+      Flags |= uint32_t(StatepointFlags::GCTransition);
+      TransitionArgs = TransitionBundle->Inputs;
+    }
     AttributeSet OriginalAttrs = CS.getAttributes();
 
     Attribute AttrID = OriginalAttrs.getAttribute(AttributeSet::FunctionIndex,

Modified: llvm/trunk/test/Transforms/RewriteStatepointsForGC/deopt-bundles/basic.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/RewriteStatepointsForGC/deopt-bundles/basic.ll?rev=258338&r1=258337&r2=258338&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/RewriteStatepointsForGC/deopt-bundles/basic.ll (original)
+++ llvm/trunk/test/Transforms/RewriteStatepointsForGC/deopt-bundles/basic.ll Wed Jan 20 13:50:25 2016
@@ -63,3 +63,11 @@ define i32 addrspace(1)* @f3(i32 addrspa
   %lpad = landingpad token cleanup
   resume token undef
 }
+
+define i32 addrspace(1)* @f4(i32 addrspace(1)* %arg) gc "statepoint-example" {
+; CHECK-LABEL: @f4(
+ entry:
+; CHECK: @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @g, i32 0, i32 1, i32 2, i32 400, i8 90,
+  call void @g() [ "gc-transition"(i32 400, i8 90) ]
+  ret i32 addrspace(1)* %arg
+}

Modified: llvm/trunk/test/Verifier/operand-bundles.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Verifier/operand-bundles.ll?rev=258338&r1=258337&r2=258338&view=diff
==============================================================================
--- llvm/trunk/test/Verifier/operand-bundles.ll (original)
+++ llvm/trunk/test/Verifier/operand-bundles.ll Wed Jan 20 13:50:25 2016
@@ -47,3 +47,16 @@ define void @f_deopt(i32* %ptr) {
   %x = add i32 42, 1
   ret void
 }
+
+define void @f_gc_transition(i32* %ptr) {
+; CHECK: Multiple gc-transition operand bundles
+; CHECK-NEXT: call void @g() [ "gc-transition"(i32 42, i64 100, i32 %x), "gc-transition"(float 0.000000e+00, i64 100, i32 %l) ]
+; CHECK-NOT: call void @g() [ "gc-transition"(i32 42, i64 120, i32 %x) ]
+
+ entry:
+  %l = load i32, i32* %ptr
+  call void @g() [ "gc-transition"(i32 42, i64 100, i32 %x), "gc-transition"(float 0.0, i64 100, i32 %l) ]
+  call void @g() [ "gc-transition"(i32 42, i64 120) ]  ;; The verifier should not complain about this one
+  %x = add i32 42, 1
+  ret void
+}




More information about the llvm-commits mailing list