llvm.org GIT mirror llvm / e6a9ed7
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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@258338 91177308-0d34-0410-b5e6-96231b3b80d8 Sanjoy Das 3 years ago
8 changed file(s) with 58 addition(s) and 10 deletion(s). Raw diff Collapse all Expand all
16001600
16011601 Similarly, if no funclet EH pads have been entered-but-not-yet-exited,
16021602 executing a ``call`` or ``invoke`` with a ``"funclet"`` bundle is undefined behavior.
1603
1604 GC Transition Operand Bundles
1605 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1606
1607 GC transition operand bundles are characterized by the
1608 ``"gc-transition"`` operand bundle tag. These operand bundles mark a
1609 call as a transition between a function with one GC strategy to a
1610 function with a different GC strategy. If coordinating the transition
1611 between GC strategies requires additional code generation at the call
1612 site, these bundles may contain any values that are needed by the
1613 generated code. For more details, see :ref:`GC Transitions
1614 `.
16031615
16041616 .. _moduleasm:
16051617
250250
251251 Note that in this example %p and %obj.relocate are the same address and we
252252 could replace one with the other, potentially removing the derived pointer
253 from the live set at the safepoint entirely.
253 from the live set at the safepoint entirely.
254
255 .. _gc_transition_args:
254256
255257 GC Transitions
256258 ^^^^^^^^^^^^^^^^^^
7070 /// Additionally, this scheme allows LLVM to efficiently check for specific
7171 /// operand bundle tags without comparing strings.
7272 enum {
73 OB_deopt = 0, // "deopt"
74 OB_funclet = 1, // "funclet"
73 OB_deopt = 0, // "deopt"
74 OB_funclet = 1, // "funclet"
75 OB_gc_transition = 2, // "gc-transition"
7576 };
7677
7778 /// getMDKindID - Return a unique non-zero ID for the specified metadata kind.
136136 assert(FuncletEntry->second == LLVMContext::OB_funclet &&
137137 "funclet operand bundle id drifted!");
138138 (void)FuncletEntry;
139
140 auto *GCTransitionEntry = pImpl->getOrInsertBundleTag("gc-transition");
141 assert(GCTransitionEntry->second == LLVMContext::OB_gc_transition &&
142 "gc-transition operand bundle id drifted!");
143 (void)GCTransitionEntry;
139144 }
140145 LLVMContext::~LLVMContext() { delete pImpl; }
141146
25122512 if (Intrinsic::ID ID = (Intrinsic::ID)F->getIntrinsicID())
25132513 visitIntrinsicCallSite(ID, CS);
25142514
2515 // Verify that a callsite has at most one "deopt" and one "funclet" operand
2516 // bundle.
2517 bool FoundDeoptBundle = false, FoundFuncletBundle = false;
2515 // Verify that a callsite has at most one "deopt", at most one "funclet" and
2516 // at most one "gc-transition" operand bundle.
2517 bool FoundDeoptBundle = false, FoundFuncletBundle = false,
2518 FoundGCTransitionBundle = false;
25182519 for (unsigned i = 0, e = CS.getNumOperandBundles(); i < e; ++i) {
25192520 OperandBundleUse BU = CS.getOperandBundleAt(i);
25202521 uint32_t Tag = BU.getTagID();
25212522 if (Tag == LLVMContext::OB_deopt) {
25222523 Assert(!FoundDeoptBundle, "Multiple deopt operand bundles", I);
25232524 FoundDeoptBundle = true;
2524 }
2525 if (Tag == LLVMContext::OB_funclet) {
2525 } else if (Tag == LLVMContext::OB_gc_transition) {
2526 Assert(!FoundGCTransitionBundle, "Multiple gc-transition operand bundles",
2527 I);
2528 FoundGCTransitionBundle = true;
2529 } else if (Tag == LLVMContext::OB_funclet) {
25262530 Assert(!FoundFuncletBundle, "Multiple funclet operand bundles", I);
25272531 FoundFuncletBundle = true;
25282532 Assert(BU.Inputs.size() == 1,
14031403 if (UseDeoptBundles) {
14041404 CallArgs = {CS.arg_begin(), CS.arg_end()};
14051405 DeoptArgs = GetDeoptBundleOperands(CS);
1406 // TODO: we don't fill in TransitionArgs or Flags in this branch, but we
1407 // could have an operand bundle for that too.
1406 if (auto TransitionBundle =
1407 CS.getOperandBundle(LLVMContext::OB_gc_transition)) {
1408 Flags |= uint32_t(StatepointFlags::GCTransition);
1409 TransitionArgs = TransitionBundle->Inputs;
1410 }
14081411 AttributeSet OriginalAttrs = CS.getAttributes();
14091412
14101413 Attribute AttrID = OriginalAttrs.getAttribute(AttributeSet::FunctionIndex,
6262 %lpad = landingpad token cleanup
6363 resume token undef
6464 }
65
66 define i32 addrspace(1)* @f4(i32 addrspace(1)* %arg) gc "statepoint-example" {
67 ; CHECK-LABEL: @f4(
68 entry:
69 ; CHECK: @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @g, i32 0, i32 1, i32 2, i32 400, i8 90,
70 call void @g() [ "gc-transition"(i32 400, i8 90) ]
71 ret i32 addrspace(1)* %arg
72 }
4646 %x = add i32 42, 1
4747 ret void
4848 }
49
50 define void @f_gc_transition(i32* %ptr) {
51 ; CHECK: Multiple gc-transition operand bundles
52 ; CHECK-NEXT: call void @g() [ "gc-transition"(i32 42, i64 100, i32 %x), "gc-transition"(float 0.000000e+00, i64 100, i32 %l) ]
53 ; CHECK-NOT: call void @g() [ "gc-transition"(i32 42, i64 120, i32 %x) ]
54
55 entry:
56 %l = load i32, i32* %ptr
57 call void @g() [ "gc-transition"(i32 42, i64 100, i32 %x), "gc-transition"(float 0.0, i64 100, i32 %l) ]
58 call void @g() [ "gc-transition"(i32 42, i64 120) ] ;; The verifier should not complain about this one
59 %x = add i32 42, 1
60 ret void
61 }