[GC] Document the recently added PlaceSafepoints and RewriteGCForStatepoints passes

llvm-svn: 230420
This commit is contained in:
Philip Reames 2015-02-25 01:23:59 +00:00
parent 74dc7ea2e9
commit c88d732822
1 changed files with 90 additions and 3 deletions

View File

@ -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
=====================