mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 20:23:11 +01:00
[GC] Document the recently added PlaceSafepoints and RewriteGCForStatepoints passes
llvm-svn: 230420
This commit is contained in:
parent
3eb494d1b9
commit
b509c48283
@ -111,8 +111,8 @@ garbage collected objects.
|
||||
collected values, transforming the IR to expose a pointer giving the
|
||||
base object for every such live pointer, and inserting all the
|
||||
intrinsics correctly is explicitly out of scope for this document.
|
||||
The recommended approach is described in the section of Late
|
||||
Safepoint Placement below.
|
||||
The recommended approach is to use the :ref:`utility passes
|
||||
<statepoint-utilities>` described below.
|
||||
|
||||
This abstract function call is concretely represented by a sequence of
|
||||
intrinsic calls known as a 'statepoint sequence'.
|
||||
@ -151,7 +151,7 @@ When lowered, this example would generate the following x86 assembly::
|
||||
|
||||
Each of the potentially relocated values has been spilled to the
|
||||
stack, and a record of that location has been recorded to the
|
||||
:ref:`Stack Map section <stackmap-section>`. If the garbage collector
|
||||
:ref: `Stack Map section <stackmap-section>`. If the garbage collector
|
||||
needs to update any of these pointers during the call, it knows
|
||||
exactly what to change.
|
||||
|
||||
@ -393,6 +393,93 @@ key relocation invariant, but this is ongoing work on developing such
|
||||
a verifier. Please ask on llvmdev if you're interested in
|
||||
experimenting with the current version.
|
||||
|
||||
.. _statepoint-utilities:
|
||||
|
||||
Utility Passes for Safepoint Insertion
|
||||
======================================
|
||||
|
||||
.. _RewriteStatepointsForGC:
|
||||
|
||||
RewriteStatepointsForGC
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The pass RewriteStatepointsForGC transforms a functions IR by replacing a
|
||||
``gc.statepoint`` (with an optional ``gc.result``) with a full relocation
|
||||
sequence, including all required ``gc.relocates``. To function, the pass
|
||||
requires that the GC strategy specified for the function be able to reliably
|
||||
distinguish between GC references and non-GC references in IR it is given.
|
||||
|
||||
As an example, given this code:
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
define i8 addrspace(1)* @test1(i8 addrspace(1)* %obj)
|
||||
gc "statepoint-example" {
|
||||
call i32 (void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
|
||||
ret i8 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 i32 (void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, 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(i32 %0, i32 9, i32 9)
|
||||
ret i8 addrspace(1)* %obj.relocated
|
||||
}
|
||||
|
||||
In the above examples, the addrspace(1) marker on the pointers is the mechanism
|
||||
that the ``statepoint-example`` GC strategy uses to distinguish references from
|
||||
non references. Address space 1 is not globally reserved for this purpose.
|
||||
|
||||
This pass can be used an utility function by a language frontend that doesn't
|
||||
want to manually reason about liveness, base pointers, or relocation when
|
||||
constructing IR. As currently implemented, RewriteStatepointsForGC must be
|
||||
run after SSA construction (i.e. mem2ref).
|
||||
|
||||
|
||||
In practice, RewriteStatepointsForGC can be run much later in the pass
|
||||
pipeline, after most optimization is already done. This helps to improve
|
||||
the quality of the generated code when compiled with garbage collection support.
|
||||
In the long run, this is the intended usage model. At this time, a few details
|
||||
have yet to be worked out about the semantic model required to guarantee this
|
||||
is always correct. As such, please use with caution and report bugs.
|
||||
|
||||
.. _PlaceSafepoints:
|
||||
|
||||
PlaceSafepoints
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
The pass PlaceSafepoints transforms a function's IR by replacing any call or
|
||||
invoke instructions with appropriate ``gc.statepoint`` and ``gc.result`` pairs,
|
||||
and inserting safepoint polls sufficient to ensure running code checks for a
|
||||
safepoint request on a timely manner. This pass is expected to be run before
|
||||
RewriteStatepointsForGC and thus does not produce full relocation sequences.
|
||||
|
||||
At the moment, PlaceSafepoints can insert safepoint polls at method entry and
|
||||
loop backedges locations. Extending this to work with return polls would be
|
||||
straight forward if desired.
|
||||
|
||||
PlaceSafepoints includes a number of optimizations to avoid placing safepoint
|
||||
polls at particular sites unless needed to ensure timely execution of a poll
|
||||
under normal conditions. PlaceSafepoints does not attempt to ensure timely
|
||||
execution of a poll under worst case conditions such as heavy system paging.
|
||||
|
||||
The implementation of a safepoint poll action is specified by looking up a
|
||||
function of the name ``gc.safepoint_poll`` in the containing Module. The body
|
||||
of this function is inserted at each poll site desired. While calls or invokes
|
||||
inside this method are transformed to a ``gc.statepoints``, recursive poll
|
||||
insertion is not performed.
|
||||
|
||||
If you are scheduling the RewriteStatepointsForGC pass late in the pass order,
|
||||
you should probably schedule this pass immediately before it. The exception
|
||||
would be if you need to preserve abstract frame information (e.g. for
|
||||
deoptimization or introspection) at safepoints. In that case, ask on the
|
||||
llvmdev mailing list for suggestions.
|
||||
|
||||
|
||||
Bugs and Enhancements
|
||||
=====================
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user