diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -2534,6 +2534,44 @@ code for the proper architecture. It's possible to override this on the 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 `, 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 ` or :ref:`ptrtoint ` return +a valid result. +This explains code motion of these instructions across instructions that +deallocate the object or impact it's lifetime. +A memory object's lifetime can be explicitly specified using +:ref:`llvm.lifetime.start <_int_lifestart>` and +:ref:`llvm.lifetime.end <_int_lifeend>` intrinsic function calls. + +Two memory objects that are both alive at some program execution point have +addresses that don't overlap. +If their addresses can be represented in integers, two integer ranges +``[a1, a1+sz1)`` and ``[a2, a2+sz2)`` where a1/sz1 is the begin address/size of +the first object and a2/sz2 is the size of the second object respectively +are disjoint. +It is allowed for the two objects to be adjacent and share the same integral +address at the beginning of one object and at the end of another object. +A dead memory object can overlap any other memory object, unless stated +otherwise. + .. _pointeraliasing: Pointer Aliasing Rules @@ -17742,8 +17780,9 @@ Memory Use Markers ------------------ -This class of intrinsics provides information about the lifetime of -memory objects and ranges where variables are immutable. +This class of intrinsics provides information about the +:ref:`lifetime of memory objects <_objectlifetime>` and ranges where variables +are immutable. .. _int_lifestart: @@ -17760,8 +17799,8 @@ Overview: """"""""" -The '``llvm.lifetime.start``' intrinsic specifies the start of a memory -object's lifetime. +The '``llvm.lifetime.start``' intrinsic specifies the start of +:ref:`a memory object's lifetime <_objectlifetime>`. Arguments: """""""""" @@ -17773,10 +17812,31 @@ Semantics: """""""""" -This intrinsic indicates that before this point in the code, the value -of the memory pointed to by ``ptr`` is dead. This means that it is known -to never be used and has an undefined value. A load from the pointer -that precedes this intrinsic can be replaced with ``'undef'``. +If ``ptr`` is syntactically pointing to a stack-allocated object, the object is +initially marked as dead. The syntactic use is determined by following use-def +chains of operations. If ``ptr`` syntactically points to more than one +stack-allocated object via e.g., ``phi``, all of those are dead. This explains +merging multiple ``lifetime.start`` calls into one. + +After '``llvm.lifetime.start``', the stack object that ``ptr`` points to in +runtime is marked as alive and it is initialized with '``undef``'. +The stack object is dead again when either +:ref:`llvm.lifetime.end ` to the alloca is executed or the +function returns. + +After :ref:`llvm.lifetime.end ` is called, +'``llvm.lifetime.start``' on the stack object can be called again. +In this case, the stack object has multiple lifetimes. +The second '``llvm.lifetime.start``' call does not relocate the object. + +The behavior of calling '``llvm.lifetime.start``' after another +'``llvm.lifetime.start``' to the same alive stack object is +implementation-defined and depends on the backend that is enabled. + +If ``ptr`` is syntactically pointing to at least one non-stack-allocated object, +or the object it points to is unknown, it is equivalent to +'``memset(ptr, undef, size)``'. If ``size`` is -1, it is equivalent to +memset undef from the begin to the end of the object. .. _int_lifeend: @@ -17793,8 +17853,8 @@ Overview: """"""""" -The '``llvm.lifetime.end``' intrinsic specifies the end of a memory -object's lifetime. +The '``llvm.lifetime.end``' intrinsic specifies the end of +:ref:`a memory object's lifetime <_objectlifetime>`. Arguments: """""""""" @@ -17806,10 +17866,16 @@ Semantics: """""""""" -This intrinsic indicates that after this point in the code, the value of -the memory pointed to by ``ptr`` is dead. This means that it is known to -never be used and has an undefined value. Any stores into the memory -object following this intrinsic may be removed as dead. +If ``ptr`` is syntactically pointing to a stack-allocated object(s), +the object that ``ptr`` points to is dead. See +:ref:`lifetime.start ` for the rules for syntactically finding +the object(s). +Calling ``llvm.lifetime.end`` on a dead alloca is no-op. + +If ``ptr`` is syntactically pointing to at least one non-stack-allocated object, +or the object it points to is unknown, it is equivalent to +'``memset(ptr, undef, size)``'. If ``size`` is -1, it is equivalent to +memset undef from the begin to the end of the object. '``llvm.invariant.start``' Intrinsic ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^