[LangRef] Make lifetime intrinsic's semantics consistent with StackColoring's comment

This patch is an update to LangRef by describing lifetime intrinsics' behavior
by following the description of MIR's LIFETIME_START/LIFETIME_END markers
at StackColoring.cpp (eb44682d67/llvm/lib/CodeGen/StackColoring.cpp (L163)) and the discussion in llvm-dev.

In order to explicitly define the meaning of an object lifetime, I added 'Object Lifetime' subsection.

Reviewed By: nlopes

Differential Revision: https://reviews.llvm.org/D94002
This commit is contained in:
Juneyoung Lee 2021-03-04 09:57:50 +09:00
parent 83ef862fad
commit c821ef4513
1 changed files with 58 additions and 14 deletions

View File

@ -2544,6 +2544,33 @@ This information is passed along to the backend so that it generates
code for the proper architecture. It's possible to override this on the code for the proper architecture. It's possible to override this on the
command line with the ``-mtriple`` command line option. command line with the ``-mtriple`` command line option.
.. _objectlifetime:
Object Lifetime
----------------------
A memory object, or simply object, is a region of a memory space that is
reserved by a memory allocation such as :ref:`alloca <i_alloca>`, heap
allocation calls, and global variable definitions.
Once it is allocated, the bytes stored in the region can only be read or written
through a pointer that is :ref:`based on <_pointeraliasing>` the allocation
value.
If a pointer that is not based on the object tries to read or write to the
object, it is undefined behavior.
A lifetime of a memory object is a property that decides its accessibility.
Unless stated otherwise, a memory object is alive since its allocation, and
dead after its deallocation.
It is undefined behavior to access a memory object that isn't alive, but
operations that don't dereference it such as
:ref:`getelementptr <i_getelementptr>`, :ref:`ptrtoint <i_ptrtoint>` and
:ref:`icmp <i_icmp>` return a valid result.
This explains code motion of these instructions across operations that
impact the object's lifetime.
A stack object's lifetime can be explicitly specified using
:ref:`llvm.lifetime.start <_int_lifestart>` and
:ref:`llvm.lifetime.end <_int_lifeend>` intrinsic function calls.
.. _pointeraliasing: .. _pointeraliasing:
Pointer Aliasing Rules Pointer Aliasing Rules
@ -17808,8 +17835,9 @@ Other targets may support this intrinsic differently, for example, by lowering i
Memory Use Markers Memory Use Markers
------------------ ------------------
This class of intrinsics provides information about the lifetime of This class of intrinsics provides information about the
memory objects and ranges where variables are immutable. :ref:`lifetime of memory objects <_objectlifetime>` and ranges where variables
are immutable.
.. _int_lifestart: .. _int_lifestart:
@ -17826,8 +17854,8 @@ Syntax:
Overview: Overview:
""""""""" """""""""
The '``llvm.lifetime.start``' intrinsic specifies the start of a memory The '``llvm.lifetime.start``' intrinsic specifies the start of
object's lifetime. :ref:`a memory object's lifetime <_objectlifetime>`.
Arguments: Arguments:
"""""""""" """"""""""
@ -17839,10 +17867,23 @@ to the object.
Semantics: Semantics:
"""""""""" """"""""""
This intrinsic indicates that before this point in the code, the value If ``ptr`` is a stack-allocated object and its offset is zero, the object is
of the memory pointed to by ``ptr`` is dead. This means that it is known initially marked as dead.
to never be used and has an undefined value. A load from the pointer After '``llvm.lifetime.start``', the stack object that ``ptr`` points is marked
that precedes this intrinsic can be replaced with ``'undef'``. as alive and has an uninitialized value.
The stack object is marked as dead when either
:ref:`llvm.lifetime.end <int_lifeend>` to the alloca is executed or the
function returns.
After :ref:`llvm.lifetime.end <int_lifeend>` is called,
'``llvm.lifetime.start``' on the stack object can be called again.
The second '``llvm.lifetime.start``' call marks the object as alive, but it
does not change the address of the object.
If ``ptr`` is a non-stack-allocated object, its offset is non-zero or it is
a stack object that is already alive, it simply fills all bytes of the object
with ``poison``.
.. _int_lifeend: .. _int_lifeend:
@ -17859,8 +17900,8 @@ Syntax:
Overview: Overview:
""""""""" """""""""
The '``llvm.lifetime.end``' intrinsic specifies the end of a memory The '``llvm.lifetime.end``' intrinsic specifies the end of
object's lifetime. :ref:`a memory object's lifetime <_objectlifetime>`.
Arguments: Arguments:
"""""""""" """"""""""
@ -17872,10 +17913,13 @@ to the object.
Semantics: Semantics:
"""""""""" """"""""""
This intrinsic indicates that after this point in the code, the value of If ``ptr`` is a stack-allocated object and its offset is zero, the object is
the memory pointed to by ``ptr`` is dead. This means that it is known to dead.
never be used and has an undefined value. Any stores into the memory Calling ``llvm.lifetime.end`` on an already dead alloca is no-op.
object following this intrinsic may be removed as dead.
If ``ptr`` is a non-stack-allocated object or its offset is non-zero,
it is equivalent to simply filling all bytes of the object with ``poison``.
'``llvm.invariant.start``' Intrinsic '``llvm.invariant.start``' Intrinsic
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^