[docs] Modernize statepoint documentation
Update syntax (opaque pointers, elementype, gc-live), and remove a couple of misleading examples.
This commit is contained in:
committed by
Philip Reames
parent
7945435f46
commit
f05145cd31
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user