[docs] Modernize statepoint documentation

Update syntax (opaque pointers, elementype, gc-live), and remove a couple
of misleading examples.
This commit is contained in:
Philip Reames
2024-08-26 13:15:28 -07:00
committed by Philip Reames
parent 7945435f46
commit f05145cd31

View File

@@ -167,10 +167,11 @@ Let's consider a simple call in LLVM IR:
.. code-block:: llvm
define i8 addrspace(1)* @test1(i8 addrspace(1)* %obj)
declare void @foo()
define ptr addrspace(1) @test1(ptr addrspace(1) %obj)
gc "statepoint-example" {
call void ()* @foo()
ret i8 addrspace(1)* %obj
call void @foo()
ret ptr addrspace(1) %obj
}
Depending on our language we may need to allow a safepoint during the execution
@@ -186,11 +187,11 @@ resulting relocation sequence is:
.. code-block:: llvm
define i8 addrspace(1)* @test1(i8 addrspace(1)* %obj)
define ptr addrspace(1) @test(ptr addrspace(1) %obj)
gc "statepoint-example" {
%0 = call token (i64, i32, void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0, i8 addrspace(1)* %obj)
%obj.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %0, i32 7, i32 7)
ret i8 addrspace(1)* %obj.relocated
%safepoint = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, ptr elementtype(void ()) @foo, i32 0, i32 0, i32 0, i32 0) ["gc-live" (ptr addrspace(1) %obj)]
%obj.relocated = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint, i32 0, i32 0)
ret ptr addrspace(1) %obj.relocated
}
Ideally, this sequence would have been represented as a M argument, N
@@ -269,10 +270,13 @@ collector:
.. code-block:: llvm
define i8 addrspace(1)* @test1(i8 addrspace(1)* %obj)
gc "statepoint-example" {
call token (i64, i32, void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0, i8 addrspace(1)* %obj)
ret i8 addrspace(1)* %obj
define void @manual_frame(ptr %a, ptr %b) gc "statepoint-example" {
%alloca = alloca ptr
%allocb = alloca ptr
store ptr %a, ptr %alloca
store ptr %b, ptr %allocb
call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void ()) @func, i32 0, i32 0, i32 0, i32 0) ["gc-live" (ptr %alloca, ptr %allocb)]
ret void
}
Recording On Stack Regions
@@ -332,25 +336,6 @@ lowering both the base and derived pointer operands are required to be live
over the associated call safepoint even if the base is otherwise unused
afterwards.
If we extend our previous example to include a pointless derived pointer,
we get:
.. code-block:: llvm
define i8 addrspace(1)* @test1(i8 addrspace(1)* %obj)
gc "statepoint-example" {
%gep = getelementptr i8, i8 addrspace(1)* %obj, i64 20000
%token = call token (i64, i32, void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0, i8 addrspace(1)* %obj, i8 addrspace(1)* %gep)
%obj.relocated = call i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %token, i32 7, i32 7)
%gep.relocated = call i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %token, i32 7, i32 8)
%p = getelementptr i8, i8 addrspace(1)* %gep, i64 -20000
ret i8 addrspace(1)* %p
}
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.
.. _gc_transition_args:
GC Transitions
@@ -564,21 +549,20 @@ As an example, given this code:
.. code-block:: llvm
define i8 addrspace(1)* @test1(i8 addrspace(1)* %obj)
define ptr addrspace(1) @test1(ptr addrspace(1) %obj)
gc "statepoint-example" {
call void @foo()
ret i8 addrspace(1)* %obj
ret ptr addrspace(1) %obj
}
The pass would produce this IR:
.. code-block:: llvm
define i8 addrspace(1)* @test1(i8 addrspace(1)* %obj)
gc "statepoint-example" {
%0 = call token (i64, i32, void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0, i8 addrspace(1)* %obj)
%obj.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %0, i32 12, i32 12)
ret i8 addrspace(1)* %obj.relocated
define ptr addrspace(1) @test_rs4gc(ptr addrspace(1) %obj) gc "statepoint-example" {
%statepoint_token = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void ()) @foo, i32 0, i32 0, i32 0, i32 0) [ "gc-live"(ptr addrspace(1) %obj) ]
%obj.relocated = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %statepoint_token, i32 0, i32 0) ; (%obj, %obj)
ret ptr addrspace(1) %obj.relocated
}
In the above examples, the addrspace(1) marker on the pointers is the mechanism