Skip to content

Commit a96fc46

Browse files
committed
Remove deopt and gc transition arguments from gc.statepoint intrinsic
(Forgot to land this a couple of weeks back.) In a recent series of changes, I've introduced support for using the respective operand bundle kinds on the statepoint. At the moment, code supports either/or, but there's no need to keep the old support around. For the moment, I am simply changing the specification and verifier to require zero length argument sets in the intrinsic. The intrinsic itself is experimental. Given that, there's no forward serialization needed. The in tree uses and generation have already been updated to use the new operand bundle based forms, the only folks broken by the change will be those with frontends generating statepoints directly and the updates should be easy. Why not go ahead and just remove the arguments entirely? Well, I plan to. But while working on this I've found that almost all of the arguments to the statepoint can be expressed via operand bundles or attributes. Given that, I'm planning a radical simplification of the arguments and figured I'd do one update not several small ones. Differential Revision: https://reviews.llvm.org/D80892
1 parent 72effd8 commit a96fc46

File tree

5 files changed

+35
-58
lines changed

5 files changed

+35
-58
lines changed

llvm/docs/LangRef.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2182,6 +2182,12 @@ site, these bundles may contain any values that are needed by the
21822182
generated code. For more details, see :ref:`GC Transitions
21832183
<gc_transition_args>`.
21842184

2185+
The bundle contain an arbitrary list of Values which need to be passed
2186+
to GC transition code. They will be lowered and passed as operands to
2187+
the appropriate GC_TRANSITION nodes in the selection DAG. It is assumed
2188+
that these arguments must be available before and after (but not
2189+
necessarily during) the execution of the callee.
2190+
21852191
.. _assume_opbundles:
21862192

21872193
Assume Operand Bundles

llvm/docs/Statepoints.rst

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -449,8 +449,7 @@ Syntax:
449449
func_type <target>,
450450
i64 <#call args>, i64 <flags>,
451451
... (call parameters),
452-
i64 <# transition args>, ... (transition parameters),
453-
i64 <# deopt args>, ... (deopt parameters),
452+
i64 0, i64 0,
454453
... (gc parameters))
455454

456455
Overview:
@@ -515,17 +514,11 @@ instruction. The number of arguments must exactly match what is
515514
specified in '# call args'. The types must match the signature of
516515
'target'.
517516

518-
The 'transition parameters' arguments contain an arbitrary list of
519-
Values which need to be passed to GC transition code. They will be
520-
lowered and passed as operands to the appropriate GC_TRANSITION nodes
521-
in the selection DAG. It is assumed that these arguments must be
522-
available before and after (but not necessarily during) the execution
523-
of the callee. The '# transition args' field indicates how many operands
524-
are to be interpreted as 'transition parameters'.
525-
526-
The 'deopt parameters' arguments contain an arbitrary list of Values
527-
which is meaningful to the runtime. The '# deopt args' field
528-
indicates how many operands are to be interpreted as 'deopt parameters'.
517+
The 'call parameter' attributes must be followed by two 'i64 0' constants.
518+
These were originally the length prefixes for 'gc transition parameter' and
519+
'deopt parameter' arguments, but the role of these parameter sets have been
520+
entirely replaced with the corresponding operand bundles. In a future
521+
revision, these now redundant arguments will be removed.
529522

530523
The 'gc parameters' arguments contain every pointer to a garbage
531524
collector object which potentially needs to be updated by the garbage
@@ -676,13 +669,12 @@ Each statepoint generates the following Locations:
676669
these identifiers.
677670
* Constant which describes the flags passed to the statepoint intrinsic
678671
* Constant which describes number of following deopt *Locations* (not
679-
operands)
680-
* Variable number of Locations, one for each deopt parameter listed in
681-
the IR statepoint (same number as described by previous Constant). At
682-
the moment, only deopt parameters with a bitwidth of 64 bits or less
683-
are supported. Values of a type larger than 64 bits can be specified
684-
and reported only if a) the value is constant at the call site, and b)
685-
the constant can be represented with less than 64 bits (assuming zero
672+
operands). Will be 0 if no "deopt" bundle is provided.
673+
* Variable number of Locations, one for each deopt parameter listed in the
674+
"deopt" operand bundle. At the moment, only deopt parameters with a bitwidth
675+
of 64 bits or less are supported. Values of a type larger than 64 bits can be
676+
specified and reported only if a) the value is constant at the call site, and
677+
b) the constant can be represented with less than 64 bits (assuming zero
686678
extension to the original bitwidth).
687679
* Variable number of relocation records, each of which consists of
688680
exactly two Locations. Relocation records are described in detail

llvm/lib/CodeGen/TargetInstrInfo.cpp

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -499,19 +499,14 @@ static MachineInstr *foldPatchpoint(MachineFunction &MF, MachineInstr &MI,
499499
// Return false if any operands requested for folding are not foldable (not
500500
// part of the stackmap's live values).
501501
for (unsigned Op : Ops) {
502+
// Caller is expected to avoid passing in tied operands
503+
assert(!MI.getOperand(Op).isTied());
502504
if (Op < NumDefs) {
503505
assert(DefToFoldIdx == MI.getNumOperands() && "Folding multiple defs");
504506
DefToFoldIdx = Op;
505507
} else if (Op < StartIdx) {
506508
return nullptr;
507509
}
508-
// When called from regalloc (InlineSpiller), operands must be untied,
509-
// and regalloc will take care of (re)loading operand from memory.
510-
// But when called from other places (e.g. peephole pass),
511-
// we cannot fold operand which are tied - callers are unaware they
512-
// need to reload destination register.
513-
if (MI.getOperand(Op).isTied())
514-
return nullptr;
515510
}
516511

517512
MachineInstr *NewMI =

llvm/lib/IR/Verifier.cpp

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2123,34 +2123,18 @@ void Verifier::verifyStatepoint(const CallBase &Call) {
21232123
Call);
21242124
const int NumTransitionArgs =
21252125
cast<ConstantInt>(NumTransitionArgsV)->getZExtValue();
2126-
Assert(NumTransitionArgs >= 0,
2127-
"gc.statepoint number of transition arguments must be positive", Call);
2126+
Assert(NumTransitionArgs == 0,
2127+
"gc.statepoint w/inline transition bundle is deprecated", Call);
21282128
const int EndTransitionArgsInx = EndCallArgsInx + 1 + NumTransitionArgs;
21292129

2130-
// We're migrating away from inline operands to operand bundles, enforce
2131-
// the either/or property during transition.
2132-
if (Call.getOperandBundle(LLVMContext::OB_gc_transition)) {
2133-
Assert(NumTransitionArgs == 0,
2134-
"can't use both deopt operands and deopt bundle on a statepoint");
2135-
}
2136-
21372130
const Value *NumDeoptArgsV = Call.getArgOperand(EndTransitionArgsInx + 1);
21382131
Assert(isa<ConstantInt>(NumDeoptArgsV),
21392132
"gc.statepoint number of deoptimization arguments "
21402133
"must be constant integer",
21412134
Call);
21422135
const int NumDeoptArgs = cast<ConstantInt>(NumDeoptArgsV)->getZExtValue();
2143-
Assert(NumDeoptArgs >= 0,
2144-
"gc.statepoint number of deoptimization arguments "
2145-
"must be positive",
2146-
Call);
2147-
2148-
// We're migrating away from inline operands to operand bundles, enforce
2149-
// the either/or property during transition.
2150-
if (Call.getOperandBundle(LLVMContext::OB_deopt)) {
2151-
Assert(NumDeoptArgs == 0,
2152-
"can't use both deopt operands and deopt bundle on a statepoint");
2153-
}
2136+
Assert(NumDeoptArgs == 0,
2137+
"gc.statepoint w/inline deopt operands is deprecated", Call);
21542138

21552139
const int ExpectedNumArgs =
21562140
7 + NumCallArgs + NumTransitionArgs + NumDeoptArgs;

llvm/test/Verifier/statepoint.ll

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@ declare i32 @"personality_function"()
1111
define i64 addrspace(1)* @test1(i8 addrspace(1)* %arg) gc "statepoint-example" {
1212
entry:
1313
%cast = bitcast i8 addrspace(1)* %arg to i64 addrspace(1)*
14-
%safepoint_token = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* undef, i32 0, i32 0, i32 0, i32 5, i32 0, i32 0, i32 0, i32 10, i32 0, i8 addrspace(1)* %arg, i64 addrspace(1)* %cast, i8 addrspace(1)* %arg, i8 addrspace(1)* %arg)
15-
%reloc = call i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(token %safepoint_token, i32 12, i32 13)
14+
%safepoint_token = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* undef, i32 0, i32 0, i32 0, i32 0, i8 addrspace(1)* %arg, i64 addrspace(1)* %cast, i8 addrspace(1)* %arg, i8 addrspace(1)* %arg) ["deopt" (i32 0, i32 0, i32 0, i32 10, i32 0)]
15+
%reloc = call i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(token %safepoint_token, i32 7, i32 8)
1616
;; It is perfectly legal to relocate the same value multiple times...
17-
%reloc2 = call i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(token %safepoint_token, i32 12, i32 13)
18-
%reloc3 = call i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %safepoint_token, i32 13, i32 12)
17+
%reloc2 = call i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(token %safepoint_token, i32 7, i32 8)
18+
%reloc3 = call i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %safepoint_token, i32 8, i32 7)
1919
ret i64 addrspace(1)* %reloc
2020
; CHECK-LABEL: test1
2121
; CHECK: statepoint
@@ -40,8 +40,8 @@ notequal:
4040
ret void
4141

4242
equal:
43-
%safepoint_token = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* undef, i32 0, i32 0, i32 0, i32 5, i32 0, i32 0, i32 0, i32 10, i32 0, i8 addrspace(1)* %arg, i64 addrspace(1)* %cast, i8 addrspace(1)* %arg, i8 addrspace(1)* %arg)
44-
%reloc = call i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(token %safepoint_token, i32 12, i32 13)
43+
%safepoint_token = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* undef, i32 0, i32 0, i32 0, i32 0, i8 addrspace(1)* %arg, i64 addrspace(1)* %cast, i8 addrspace(1)* %arg, i8 addrspace(1)* %arg) ["deopt" (i32 0, i32 0, i32 0, i32 10, i32 0)]
44+
%reloc = call i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(token %safepoint_token, i32 7, i32 7)
4545
call void undef(i64 addrspace(1)* %reloc)
4646
ret void
4747
; CHECK-LABEL: test2
@@ -58,16 +58,16 @@ define i8 addrspace(1)* @test3(i8 addrspace(1)* %obj, i8 addrspace(1)* %obj1) gc
5858
entry:
5959
; CHECK-LABEL: entry
6060
; CHECK: statepoint
61-
%0 = invoke token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* undef, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0, i8 addrspace(1)* %obj, i8 addrspace(1)* %obj1)
61+
%0 = invoke token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* undef, i32 0, i32 0, i32 0, i32 0, i8 addrspace(1)* %obj, i8 addrspace(1)* %obj1) ["deopt" (i32 0, i32 -1, i32 0, i32 0, i32 0)]
6262
to label %normal_dest unwind label %exceptional_return
6363

6464
normal_dest:
6565
; CHECK-LABEL: normal_dest:
6666
; CHECK: gc.relocate
6767
; CHECK: gc.relocate
6868
; CHECK: ret
69-
%obj.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %0, i32 12, i32 12)
70-
%obj1.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %0, i32 12, i32 12)
69+
%obj.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %0, i32 7, i32 7)
70+
%obj1.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %0, i32 8, i32 8)
7171
ret i8 addrspace(1)* %obj.relocated
7272

7373
exceptional_return:
@@ -76,8 +76,8 @@ exceptional_return:
7676
; CHECK: gc.relocate
7777
%landing_pad = landingpad token
7878
cleanup
79-
%obj.relocated1 = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %landing_pad, i32 12, i32 12)
80-
%obj1.relocated1 = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %landing_pad, i32 12, i32 12)
79+
%obj.relocated1 = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %landing_pad, i32 7, i32 7)
80+
%obj1.relocated1 = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %landing_pad, i32 8, i32 8)
8181
ret i8 addrspace(1)* %obj1.relocated1
8282
}
8383

0 commit comments

Comments
 (0)